MySQL 資料庫在 5.1 版本時添加了對分區(partitioning)的支援。分區的過程是将一個表或索引分解成多個更小、更可管理的部分。就通路資料庫的應用而言,從邏輯上來講,隻有一個表或一個索引,但是在實體上這個表或索引可能由數十個實體分區組成。
MySQL 分區功能并不是在存儲引擎層完成的,是以不是隻有 InnoDB 存儲引擎支援分區,常見的存儲引擎 MyISAM、NDB 等都支援。
MySQL 資料庫支援的分庫類型為水準分區(指将同一表中不同行的記錄配置設定到不同的實體檔案中),并不支援垂直分區(指将同一表中不同列的記錄配置設定到不同的實體檔案中)。
MySQL 資料庫的分區是局部分區索引,一個分區中既存放了資料又存放了索引。而全局分區是指,資料存放在各個分區中,但是所有資料的索引放在一個對象中。MySQL 資料庫目前不支援全局分區。
MySQL 檢視資料庫分區。
SHOW VARIABLES LIKE '%partitions%';
MySQL 資料庫支援以下幾種類型的分區。1 如果表中存在主鍵/唯一索引時,分區列必須是主鍵/唯一索引的一個組成部分。2 對于 RANGE、LIST、HASH 和 KEY 這四種分區中,分區的條件是:資料必須是整型,如果不是整型,那應該需要通過函數将其轉化為整型,如 YEAR(),TO_DAYS(),MONTH() 等函數。
- RANGE 分區:行資料基于屬于一個給定連續區間的列值被放入分區。
- LIST 分區:和 RANGE 分區類似,隻是 LIST 分區面向的是離散的值。
- HASH 分區:根據使用者自定義的表達式(可以僅僅是字段列名)的傳回值來進行分區,傳回值不能為負數。
- LINEAR HASH 分區:線性 HASH 分區,使用的一個線性的2的幂(powers-of-two)算法來确定新行插入到分區的什麼位置。LINEAR HASH 分區的優點在于,增加、删除、合并和拆分分區将變得更加快捷,這有利于處理含有大量資料的表。缺點在于,與 HASH 分區相比,各個分區間資料的分布可能不太均衡。
- KEY 分區:和 HASH 分區類似,不過是根據 MySQL 資料庫内部提供的哈希函數來進行分區。
- LINEAR KEY 分區:和 LINEAR HASH 類似,分區的編号是通過2的幂(powers-of-two)算法得到的。
- COLUMNS 分區:1 5.5 版本後開始支援,可視為 RANGE 分區和 LIST 分區的一種進化,可以直接使用非整型的資料進行分區,分區根據類型直接比較而得,不需要轉化為整型。2 此外,RANGE COLUMNS 分區可以對多個列的值進行分區。3 對于之前的 RANGE 和 LIST 分區,使用者可以用 RANGE COLUMNS 和 LIST COLUMNS 分區進行很好的代替。
子分區(subpartitioning)是在分區的基礎上再進行分區,有時也稱為這種分區為複合分區(composite partitioning)。MySQL 資料庫允許在 RANGE 和 LIST 的分區上再進行 HASH 或 KEY 的子分區。進行子分區後,分區的數量應該為(分區數量 x 子分區數量)個。
MySQL 資料庫允許對 NULL 值做分區,視 NULL 值小于任何一個非 NULL 值(和 ORDER BY 處理 NULL 值的規則一緻)。
對于 OLAP(線上分析處理) 的應用,分區的确是可以很好地提高查詢的性能,因為 OLAP 應用大多數查詢需要頻繁地掃描一張很大的表。假設有一張 1 億行的表,其中有一個時間戳屬性列。使用者的查詢依據時間為次元,如果按照時間戳進行分區,則隻需要掃描對應的分區即可。
對于 OLTP(線上事務處理)的應用,通常不可能會擷取一張大表中 10% 的資料,大部分都是通過索引傳回幾條記錄即可。是以分區應該非常小心,對于一張大表,一般的 B+ 樹需要 2~3 次 IO 就能檢索到資料。通過根據主鍵 ID 做 10 個 HASH 的分區後,對于查詢就需要掃描所有的 10 個分區,這無疑加重了 IO 的負擔。
我們通過 Navicat 來操作下資料庫分區,表 -> 右鍵點選'設計表' -> 選項 -> 分割區,可以看到如下内容。

來看看分區後,磁盤中 MySQL 資料庫是怎麼存儲的。
通過 EXPLAIN 分析資料檢索的分區。
EXPLAIN PARTITIONS SELECT * FROM t_materiel_config