本節提供 MySQL 8.4 中分割區的概念概述。
有關分割區限制和功能限制的資訊,請參閱第 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 8.4 不支援垂直分割區,其中表格的不同資料行會指派給不同的實體分割區。目前沒有計劃在 MySQL 中引入垂直分割區。
若要建立分割區表格,您必須使用支援它們的儲存引擎。在 MySQL 8.4 中,同一個分割區表格的所有分割區都必須使用相同的儲存引擎。但是,沒有任何東西會阻止您在同一個 MySQL 伺服器,甚至在同一個資料庫上,針對不同的分割區表格使用不同的儲存引擎。
在 MySQL 8.4 中,唯一支援分割區的儲存引擎是 InnoDB
和 NDB
。分割區不能與不支援它的儲存引擎一起使用;這些儲存引擎包含 MyISAM
、MERGE
、CSV
和 FEDERATED
儲存引擎。
使用 NDB
可以進行 KEY
或 LINEAR KEY
分割區,但使用此儲存引擎的表格不支援其他類型的使用者定義分割區。此外,使用使用者定義分割區的 NDB
表格必須具有明確的主鍵,並且表格分割區運算式中參考的任何資料行都必須是主鍵的一部分。但是,如果在用於建立或修改使用者分割區 NDB
表格的 CREATE TABLE
或 ALTER TABLE
陳述式的 PARTITION BY KEY
或 PARTITION BY LINEAR KEY
子句中未列出任何資料行,則該表格不需要有明確的主鍵。如需詳細資訊,請參閱第 25.2.7.1 節,「NDB 集群中不符合 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 8.4 中,這沒有任何作用。
除非另有說明,否則本討論中的其餘範例都假設 default_storage_engine
為 InnoDB
。
分割適用於資料表的所有資料和索引;您不能只分割資料而不分割索引,反之亦然,也不能只分割資料表的一部分。
每個分割區的資料和索引可以使用 CREATE TABLE
語句的 PARTITION
子句的 DATA DIRECTORY
和 INDEX DIRECTORY
選項指定到特定的目錄。
對於 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
也支援分割區選擇。有關更多資訊和範例,請參閱這些語句的說明。