MySQL分表、分割槽
主從複製 - 讀寫分離要解決的是資料庫併發訪問壓力;
分表和分割槽解決的是單表資料量大時的SQL效能壓力,另外分表也能一定程度上提高併發;
1. 什麼是分表、分割槽?
分表和分割槽是不同層次的概念:
分表:
分表是開發人員的物理設計,目的是:在單表有大資料量的情況下保證SQL執行效能,也能提高併發。
我們可以將一個大表(指儲存了百萬級乃至千萬級條記錄的表)按照一定的規則分解成多張具有獨立儲存空間的子表。
程式讀寫表資料時可以根據建表時定好的規則而知道應該操作的表名,繼而去操作相應的字表。
分割槽:
分割槽是MySQL的一種技術設計,目的是:提高I/O。
MySQL將一個表的資料分段在多個位置存放,表還是那一張表,但是DB會依據自定義的條件去組織分割槽的資料。
查詢時DB會依據分割槽的結果自動去相應的分割槽中查詢。
2. 為什麼要分表、分割槽?
程式設計師的分表設計,以及MySQL的分割槽技術雖然實現方式不同,但目的是相同的,可以描述如下:
我們在日常開發中不可避免的會遇到大資料量表的情況,這樣的表過於龐大,導致進行資料庫查詢和更新時耗時太長,效能下降,如果有聯合查詢那麼效能會更糟糕。所以,分割槽和分表的目的就是減少資料庫的執行負擔,穩定SQL效能。
3. 分表、分割槽的關係與選擇
首先在設計上來說:
分表是按照程式設計師的意願,在物理上拆分表(分表可以在一定程度上提高併發);
分割槽是將一張表在邏輯上進行水平分割。
應用場景上來說:
對於訪問量不大,但是表資料很多的表,可以採用分割槽。
畢竟MySQL提出分割槽主要就是想提高磁碟I/O。但是從實際企業應用來看,MySQL的表分割槽、Cluster技術都還沒有被企業普遍接受。
對於訪問量大且資料多的表,可以採取分表和分割槽結合的方式
4. 分表
垂直分割(並不常用)
就是將一個表按照欄位來分,每張表保證有相同的主鍵就好。一般來說,將常用欄位和大欄位分表來放。
優勢:比沒有分表來說,提高了查詢速度,降低了查詢結果所用記憶體;
劣勢:沒有解決大量記錄的問題,對於單表來說隨著記錄增多,效能還是下降很快;
水平分割(重要)
水平分割是企業最常用到的,水平拆分就是大表按照記錄分為很多子表:
水平分的規則完全是自定義的,有以下幾種參考設計:
hash、自增id取模
對某個欄位進行hash來確定建立幾張表,並根據hash結果存入不同的表;
按時間
根據業務可以按照天、月、年來進行拆分;
按每個表的固定記錄數
一般按照自增ID進行拆表,一張表的資料行到了指定的數量,就自動儲存到下一張表中。比如規定一張表只能存1-1000個記錄;
將老資料遷移到一張歷史表
比如日誌表,一般只查詢3個月之內的資料,對於超過3個月的記錄將之遷移到歷史子表中;
分表時需要的設計:
查詢時:要根據預定義規則查詢不同的子表;
select/update/delete時:極有可能涉及多張表,必須在程式邏輯上的事務中都包括好所有的表。
5. 分割槽
分割槽其實最好檢視MySQL的官方文件,畢竟它做的這個技術現在還在不斷髮展。官方文件-分割槽地址
水平分割槽
有幾種模式如下:
Range:定義範圍來分
Hash:定義Hash來分
Key:Hash的一種延伸
List(預定義列表):自己定義幾個值來分
Composite(複合模式):對1234組合使用
垂直分割槽
一般將大text和BLOB列分到另一個區
語法
CREATE TABLE part_table
(
c1 int default NULL,
c2 varchar(30) default NULL,
c3 date default NULL
) engine=myisam
PARTITION BY RANGE (year(c3))
(
PARTITION p0 VALUES LESS THAN (1995),
PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,
PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,
PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,
PARTITION p7 VALUES LESS THAN (2002) , PARTITION p8 VALUES LESS THAN (2003) ,
PARTITION p9 VALUES LESS THAN (2004) , PARTITION p10 VALUES LESS THAN (2010),
PARTITION p11 VALUES LESS THAN MAXVALUE
);