MySQL 5.1 分區技術初探(一)

【轉】MySQL 5.1 分區技術初探(一)




  MySQL分區技術是用來減輕海量數據帶來的負擔,解決數據庫性能下降問題的一種方式,其他的方式還有建立索引,大表拆小表等等。
  MySQL分區按照分區的參考方式來分有RANGE分區、LIST分區、HASH分區、KEY分區。本文對這幾種分區方式進行了詳細的介紹,並且給出了簡單的示例,文章簡潔明瞭,對於想要初步瞭解MySQL分區技術的同學來說是很不錯的參考材料。 


一、背景介紹

  當 MySQL中一個表的總記錄數超過了1000萬,會出現性能的大幅度下降嗎?答案是肯定的。但性能下降的比率由系統的架構、應用程序、數據庫索引、服務器硬件等多種因素而定。數據庫多達上億的數據量,分表之後的單個表也已經突破千萬,那麼單個表的更新等均影響着系統的運行效率。甚至是一條簡單的SQL都有可能壓垮整個數據庫,如整個表對某個字段的排序操作等。

  目前,針對海量數據的優化主要有2種方法:大表拆小表的方式、SQL語句的優化

  SQL語句的優化:可以通過增加索引等來調整,但是數據量的增大將會導致索引的維護代價增大。在此不詳述,建議大家參考相應的《High Performance MySQL》等書籍。

  大表拆小表的方式主要有兩種:

  1,垂直分表:

  

    圖1,垂直分區示意圖

  對於垂直分表,它將一個N1+N2個字段的表Tab拆分成N1字段的子表Tab1和(N2+1)字段的子表Tab2;其中子表Tab2包含了關於子表Tab1的主鍵信息,否則兩個表的關聯關係就會丟失。當然垂直分表會帶來程序端SQL的修改,若是應用程序已經應用很長的一段時間,然後程序的升級將是耗時而且易出錯的,即升級的代價將會很大。

  2,水平分表:

  

    圖2,水平分區示意圖

  水平分區技術將一個表拆成多個表,比較常用的方式是將表中的記錄按照某種Hash算法進行拆分,簡單的拆分方法如取模方式。同樣,這種分區方法也必須對前端的應用程序中的SQL進行修改方可使用。而且對於一個SQL,它可能會修改兩個表,那麼你必須得寫成2個SQL語句從而可以完成一個邏輯的事務,使得程序的判斷邏輯越來越複雜,這樣也會導致程序的維護代價高,也就失去了採用數據庫的優勢。因此,分區技術可以有力地避免如上的弊端,成爲解決海量數據存儲的有力方法。


二、MySQL分區介紹

  MySQL的分區技術不同與之前的分表技術,它與水平分表有點類似,但是它是在邏輯層進行的水平分表,對與應用程序而言它還是一張表。MySQL5.1有5種分區類型:

  RANGE分區:基於屬於一個給定連續區間的列值,把多行分配給分區;

  LIST分區:類似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇;

  HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。這個函數可以包含MySQL中有效的、產生非負整數值的任何表達式;

  KEY分區:類似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL服務器提供其自身的哈希函數。

  1,RANGE分區

  對於RANGE分區,舉個例子:

  例1:假定你創建了一個如下的表,該表保存有20家音像店的職員記錄,這20家音像店的編號從1到20。如果你想將其分成4個小分區,那麼你可以採用RANGE分區,創建的數據庫表如下:

  

    圖3,RANGE分區實例1

  在這個例子,key是一個整型的數據,那是否對於其它類型的字段就無法作爲key呢?答案是否定的,例子2說明這種情況。

  例2:假定你創建了一個如下的表,該表保存有20家音像店的職員記錄,這20家音像店的編號從1到20。你想把不同時期離職的員工進行分別存儲,那麼你可以將日期字段separated(即離職時間)作爲一個key,創建的SQL語句如下:

  

    圖4,RANGE分區實例2

  這樣你就可以對一個日期類型的字段調用mysql的日期函數YEAR()轉換爲一種整數類型,從而可以作爲RANGE分區的key。這個時候你可以看到,分區後的物理文件是相對獨立的: 

  

    圖5,RANGE分區後物理文件

  可知,每個分區有自己獨立的數據文件和索引文件,這是爲什麼你對某一個查詢,它只會訪問它需要訪問的數據塊,而不訪問根本不是結果的物理塊,從而可以大大提高系統的效率。

  2,LIST分區

  LIST分區與RANGE分區有類似的地方,舉個與例1類似的例子如下:

  例3:假定你創建了一個如下的一個表,該表保存有20家音像店的職員記錄,這20家音像店的編號從1到20。而這20個音像店,分佈在4個有經銷權的地區,如下表所示:

  

    圖6,LIST分區實例3

  那麼你可以採用如下的LIST分區語句創建數據表:

  

    圖7,LIST分區實例SQL語句

  同樣,它在物理文件上也會標識不同的分區:

  

    圖8,LIST分區後物理文件

  3,HASH分區

  HASH分區主要用來確保數據在預先確定數目的分區中平均分佈。它可以基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。

  例4:假定你創建了一個如下的一個表,該表保存有20家音像店的職員記錄,這20家音像店的編號從1到20。你想把不同時期加入的員工進行分別存儲,那麼你可以將日期字段hired(即離職時間)作爲一個key,創建的SQL語句如下:

  

    圖9,HASH分區實例4

  那麼要插入一個在2005-09-15日入職的員工E1,那麼按照取模函數會將其放置到第2分區中:

  MOD(YEAR(‘2005-09-01’), 4)= MOD(2005,4)= 1 //即第2分區

  4,KEY分區

  與HASH分區類似,但它的key可以不是整數類型,如字符串等類型的字段。MySQL 簇(Cluster)使用函數MD5()來實現KEY分區;對於使用其他存儲引擎的表,服務器使用其自己內部的哈希函數,這些函數是基於與PASSWORD()一樣的運算法則。

  5,不同分區技術的對比

  如上分別列出了不同的分區技術,接下來進行對比,如下表所示:

  

    圖10,不同分區技術對比



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章