本文更新于2019-06-30,使用MySQL 5.7,作業系統為Deepin 15.4,
目錄
- 磁區型別
- Range磁區
- List磁區
- Columns磁區
- Hash磁區
- Key磁區
- 子磁區
- 磁區管理
- Range磁區和List磁區的磁區管理
- Hash磁區和Key磁區的磁區管理
磁區型別
可以使用SHOW PLUGINS查看是否安裝了磁區插件,
MySQL創建磁區表支持使用大部分存盤引擎,但不支持使用MERGE或CSV存盤引擎,同一個磁區表的所有磁區必須使用同一種存盤引擎,
MySQL磁區作用于整個表的所有資料和索引,其索引一定是本地LOCAL索引,
無論那種磁區型別,要么磁區表上沒有主鍵/唯一鍵,要么磁區表的主鍵/唯一鍵包含磁區鍵,
磁區表中的磁區名不區分大小寫,
可以通過查詢information_schema.PARTITIONS得知磁區中的行數,來間接確定記錄是插入到那一個磁區中的:
SELECT PARTITION_NAME, PARTITION_EXPRESSION, PARTITION_DESCRIPTION, TABLE_ROWS
FROM information_schema.PARTITIONS
WHERE TABLE_SCHEMA = dbname AND TABLE_NAME = tablename
Range磁區
CREATE TABLE tablename (...) [[STORAGE] ENGINE=engine]
PARTITION BY RANGE [COLUMNS] (partitionkey[, ...]) (
PARTITION partitionname VALUES LESS THAN (value)|MAXVALUE
[, ...]
)
如不使用COLUMNS,則Range磁區的磁區鍵必需為INT型別的某一列,或某一回傳INT型別的運算式,如使用COLUMNS,則為Range Columns磁區,磁區鍵可為非INT型別,可為多列磁區,不能為運算式,
Range磁區的區間必須連續且不能互相重疊,區間為左閉右開區間,每個磁區都是按順序進行定義的,從最低到最高,
磁區鍵的值如果是NULL則會被當作最小值來處理,
List磁區
CREATE TABLE tablename (...) [[STORAGE] ENGINE=engine]
PARTITION BY LIST [COLUMNS] (partitionkey[, ...]) (
PARTITION partitionname VALUES IN (value[, ...])
[, ...]
)
如不使用COLUMNS,List磁區的磁區鍵必需為INT型別的某一列,或某一回傳INT型別的運算式,如使用COLUMNS,則為List Columns磁區,磁區鍵可為非INT型別,可為多列磁區,不能為運算式,
List磁區的宣告不必按照特定的順序,
磁區鍵的值如果是NULL則必須出現在磁區定義的列舉串列中,
Columns磁區
Columns磁區可分為Range Columns磁區和List Columns磁區,其磁區鍵都支持整數、日期時間、字串資料型別,
- 所有整數型別,即
TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,不支持其他數值型別, - 日期時間型別
DATE和DATETIME,磁區日期處理支持的函式有YEAR()、TO_DAYS()、TO_SECONDS(), - 字串型別
CHAR、VARCHAR、BINARY、VARBINARY,不支持[*]TEXT和[*]BLOB,
Columns磁區可使用一列或多列作為磁區鍵,即支持多列磁區,不支持運算式作為磁區鍵,其磁區鍵是基于元組的比較,即多列排序,
Hash磁區
CREATE TABLE tablename (...) [[STORAGE] ENGINE=engine]
PARTITION BY [LINEAR] HASH(partitionkey)
PARTITIONS count
MySQL支持兩種Hash磁區,常規Hash磁區和線性Hash磁區,常規Hash磁區使用的是取模演算法,線性Hash磁區使用的是一個線性的2的冪的運演算法則,常規Hash磁區在磁區管理(增加、洗掉、合并、拆分磁區)時代價較大,執行緒Hash磁區在磁區管理時能處理得更迅速,但各個磁區之間資料分布不太均勻,常規Hash磁區將記錄保存到磁區編號為MOD(partitionkey, count)的磁區中,線性Hash磁區保存的磁區編號按照如下規則計算,當線性Hash磁區的個數為2的冪的時候,其和常規Hash磁區的磁區結果是一致的,
- 找到下一個大于等于
count的2的冪V = Power(2, Ceiling(Log(2, count))),V有可能大于count, - 設定
N = partitionkey & (V - 1),由上一步得,V - 1為一個所有位都為1的整數,運算結果N共有V種可能(0至V - 1), - 當
N > count時,設定V = Ceiling(V / 2),由第一步得知該值肯定小于count且為一個2的冪,使用新的V設定N = N & (V - 1)即為磁區編號,
Hash磁區的磁區鍵必需為INT型別的某一列,或某一回傳INT型別的運算式,
磁區鍵的值如果是NULL則會將其當作零值處理,
Key磁區
CREATE TABLE tablename (...) [[STORAGE] ENGINE=engine]
PARTITION BY [LINEAR] KEY ([partitionkey[, ...]])
PARTITIONS count
Key磁區的磁區鍵可為除[*]TEXT和[*]BLOB型別以外的一列或多列,不能為運算式,如未指定磁區鍵,則使用主鍵作為磁區鍵;若無主鍵,則選擇非空唯一鍵作為磁區鍵,MySQL使用服務器的HASH函式計算列的散列值,
磁區鍵的值如果是NULL則會將其當作零值處理,
Key磁區表不能執行ALTER TABLE DROP PRIMARY KEY來洗掉主鍵,否則會回傳錯誤:Field in list of fields for partition function not found in table,
Key磁區使用LINEAR和Hash磁區有相同的作用,
子磁區
Range磁區和List磁區可再進行子磁區(復合磁區),子磁區可以使用Hash磁區或Key磁區,
CREATE TABLE tablename (...) [[STORAGE] ENGINE=engine]
PARTITION BY RANGE|LIST [COLUMNS] (partitionkey1[, ...])
SUBPARTITION BY HASH|KEY (partitionkey2[, ...])
SUBPARTITIONS count
(
PARTITION partitionname VALUES {LESS THAN (value)|MAXVALUE}|{IN (value[, ...])}
[, ...]
)
PARTITION子句的VALUES根據磁區是Range磁區還是List磁區填寫(下同),
磁區管理
Range磁區和List磁區的磁區管理
洗掉磁區,會同時洗掉磁區中的資料:
ALTER TABLE tablename
DROP PARTITION partitionname
增加磁區,Range磁區只能添加磁區至磁區串列最大一端:
ALTER TABLE tablename
ADD PARTITION (
PARTITION partitionname VALUES {LESS THAN (value)|MAXVALUE}|{IN (value[, ...])}
)
重定義磁區,不會丟失原有資料,可以用來拆分一個磁區為多個磁區,也可以用來合并多個相鄰磁區(指定義陳述句相鄰)為一個磁區或多個磁區,同時重定義的磁區范圍必需與原磁區相同:
ALTER TABLE tablename
REORGANIZE PARTITION partitionname1[, ...] INTO (
PARTITION partitionname2 VALUES {LESS THAN (value)|MAXVALUE}|{IN (value[, ...])}
[, ...]
)
如不使用相鄰磁區重定義,則會回傳錯誤:When reorganizing a set of partitions they must be in consecutive order,
Hash磁區和Key磁區的磁區管理
合并磁區:
ALTER TABLE tablename
COALESCE PARTITION count
不能通過加大count值來增加磁區的數量,否則會回傳錯誤:Cannot remove all partitions, use DROP TABLE instead!,
增加磁區,為新增count個磁區,而不是增加到count個磁區:
ALTER TABLE tablename
ADD PARTITION PARTITIONS count
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/12687.html
標籤:MySQL
上一篇:遇見SQL(1)
下一篇:MySQL日志突然暴漲
