本節提供 MySQL 9.0 中分區的概念概述。
有關分區限制和功能局限的資訊,請參閱第 26.6 節,「分區的限制與局限」。
SQL 標準在資料儲存的物理方面沒有提供太多指導。SQL 語言本身旨在獨立於任何資料結構或媒體工作,這些結構或媒體是它使用的結構、表格、列或欄位的基礎。儘管如此,大多數先進的資料庫管理系統已經發展出某種方法,以確定用於在檔案系統、硬體甚至兩者中儲存特定資料片段的實體位置。在 MySQL 中,InnoDB
儲存引擎長期以來一直支援表空間的概念(請參閱第 17.6.3 節,「表空間」),而 MySQL 伺服器,甚至在引入分區之前,也可以配置為使用不同的實體目錄來儲存不同的資料庫(有關如何執行此操作的說明,請參閱第 10.12.2 節,「使用符號連結」)。
分區將此概念更進一步,允許您根據您大致需要的規則,將個別表格的部分分佈在檔案系統中。實際上,表格的不同部分會以不同的表格形式儲存在不同的位置。用於完成資料分割的使用者選定規則稱為分區函數,在 MySQL 中,它可以是模數、簡單地與一組範圍或值列表匹配、內部雜湊函數或線性雜湊函數。該函數會根據使用者指定的分區類型選擇,並將使用者提供的運算式的值作為參數。此運算式可以是欄位值、作用於一或多個欄位值的函數,或一或多個欄位值的集合,具體取決於使用的分區類型。
在 RANGE
、LIST
和 [LINEAR
] HASH
分區的情況下,分區欄位的值會傳遞至分區函數,該函數會傳回一個整數值,表示應儲存特定記錄的分區編號。此函數必須是非恆定且非隨機的。它可能不包含任何查詢,但可以使用在 MySQL 中有效的 SQL 運算式,只要該運算式傳回 NULL
或整數 intval
,使得
-MAXVALUE <= intval <= MAXVALUE
(MAXVALUE
用於表示所討論的整數類型之最小上界。-MAXVALUE
表示最大下界。)
對於 [LINEAR
] KEY
、RANGE COLUMNS
和 LIST COLUMNS
分區,分區運算式包含一或多個欄位的列表。
對於 [LINEAR
] KEY
分區,分區函數由 MySQL 提供。
有關允許的分區欄位類型和分區函數的更多資訊,請參閱第 26.2 節,「分區類型」,以及第 15.1.20 節,「CREATE TABLE 陳述式」,其中提供了分區語法說明和其他範例。有關分區函數限制的資訊,請參閱第 26.6.3 節,「與函數相關的分區限制」。
這稱為水平分區 — 也就是說,表格的不同列可能會被指派給不同的實體分區。MySQL 9.0 不支援垂直分區,其中表格的不同欄位會被指派給不同的實體分區。目前沒有計劃在 MySQL 中引入垂直分區。
若要建立分區表格,您必須使用支援它們的儲存引擎。在 MySQL 9.0 中,同一個分區表格的所有分區都必須使用相同的儲存引擎。但是,沒有任何事情阻止您在同一個 MySQL 伺服器上或甚至在同一個資料庫中使用不同的儲存引擎來處理不同的分區表格。
在 MySQL 9.0 中,唯一支援分區的儲存引擎是 InnoDB
和 NDB
。分區不能與不支援它的儲存引擎一起使用;這些包括 MyISAM
、MERGE
、CSV
和 FEDERATED
儲存引擎。
使用 NDB
可以使用 KEY
或 LINEAR KEY
進行分區,但使用此儲存引擎的表格不支援其他使用者定義的分區類型。此外,使用使用者定義分區的 NDB
表格必須具有明確的主索引鍵,且表格的分區運算式中引用的任何欄位都必須是主索引鍵的一部分。但是,如果 CREATE TABLE
或 ALTER TABLE
陳述式的 PARTITION BY KEY
或 PARTITION BY LINEAR KEY
子句中未列出任何欄位,則用於建立或修改使用者分區的 NDB
表格則不需要具有明確的主索引鍵。如需更多資訊,請參閱第 25.2.7.1 節,「NDB Cluster 中不符合 SQL 語法」。
建立分區表格時,會使用預設的儲存引擎,就像建立任何其他表格一樣;若要覆寫此行為,只需使用 [STORAGE] ENGINE
選項,就像您針對未分區的表格所做的那樣。目標儲存引擎必須提供原生分區支援,否則陳述式會失敗。您應該記住,[STORAGE] ENGINE
(和其他表格選項) 需要列在 任何 分區選項用於 CREATE TABLE
陳述式之前。此範例顯示如何建立一個通過雜湊分為 6 個分區且使用 InnoDB
儲存引擎的表格 (無論 default_storage_engine
的值為何)
CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE)
ENGINE=INNODB
PARTITION BY HASH( MONTH(tr_date) )
PARTITIONS 6;
每個 PARTITION
子句都可以包含 [STORAGE] ENGINE
選項,但在 MySQL 9.0 中,這沒有任何作用。
除非另有指定,本討論中剩餘的範例皆假設 default_storage_engine
為 InnoDB
。
分割適用於資料表的所有資料和索引;您不能只分割資料而不分割索引,反之亦然,也不能只分割資料表的一部分。
每個分割區的資料和索引可以使用 CREATE TABLE
陳述式的 PARTITION
子句的 DATA DIRECTORY
和 INDEX DIRECTORY
選項,將資料和索引指派到特定目錄。CREATE TABLE
陳述式用於建立分割資料表。
對於 InnoDB
資料表的個別分割區和子分割區,僅支援 DATA DIRECTORY
選項。在 DATA DIRECTORY
子句中指定的目錄必須是 InnoDB
所知的。如需更多資訊,請參閱 使用 DATA DIRECTORY 子句。
資料表分割運算式中使用的所有欄位,都必須是資料表可能擁有的每個唯一鍵的一部分,包括任何主鍵。這表示像是以下 SQL 陳述式所建立的資料表,將無法被分割:
CREATE TABLE tnp (
id INT NOT NULL AUTO_INCREMENT,
ref BIGINT NOT NULL,
name VARCHAR(255),
PRIMARY KEY pk (id),
UNIQUE KEY uk (name)
);
由於索引鍵 pk
和 uk
沒有共同的欄位,因此沒有欄位可用於分割運算式。此情況下可行的解決方法包括將 name
欄位新增至資料表的主鍵、將 id
欄位新增至 uk
,或直接移除唯一索引鍵。如需更多資訊,請參閱 第 26.6.1 節「分割索引鍵、主鍵和唯一索引鍵」。
此外,MAX_ROWS
和 MIN_ROWS
可以分別用於決定每個分割區中可以儲存的最大和最小列數。如需有關這些選項的更多資訊,請參閱 第 26.3 節「分割管理」。
MAX_ROWS
選項也可用於建立具有額外分割區的 NDB Cluster 資料表,進而允許儲存更多的雜湊索引。如需更多資訊,請參閱 DataMemory
資料節點設定參數的說明文件,以及 第 25.2.2 節「NDB Cluster 節點、節點群組、片段複本和分割區」。
以下列出分割的一些優點:
分割使得在單一資料表內儲存比單一磁碟或檔案系統分割區所能容納的更多資料成為可能。
通常可以透過捨棄僅包含該資料的分割區,輕鬆地從已分割的資料表中移除不再有用的資料。反之,透過新增一個或多個新的分割區來專門儲存該資料,在某些情況下可以大大簡化新增新資料的流程。
由於滿足給定
WHERE
子句的資料只能儲存在一個或多個分割區中,這會自動將任何剩餘的分割區排除在搜尋範圍之外,因此可以大幅最佳化某些查詢。由於分割區可以在建立分割資料表之後進行變更,因此您可以重新組織資料以增強在首次設定分割方案時可能不常使用的頻繁查詢。這種排除不符分割區(以及其中包含的任何列)的能力通常稱為分割修剪。如需更多資訊,請參閱 第 26.4 節「分割修剪」。此外,MySQL 支援查詢的明確分割區選擇。例如,
SELECT * FROM t PARTITION (p0,p1) WHERE c < 5
僅會選取分割區p0
和p1
中符合WHERE
條件的列。在此情況下,MySQL 不會檢查資料表t
的任何其他分割區;當您已經知道要檢查哪個或哪些分割區時,這可以大大加快查詢速度。資料修改陳述式DELETE
、INSERT
、REPLACE
、UPDATE
和LOAD DATA
、LOAD XML
也支援分割區選擇。如需更多資訊和範例,請參閱這些陳述式的說明。