mysql 分區學習筆記
(以下的排版我汗一個。。。 在編輯的時候顯示是有段落的,保存後居然是這個樣子的。。。)
分區的類型有 range,list,hash,key
1.range
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY RANGE (YEAR(separated)) (
PARTITION p0 VALUES LESS THAN (1991),
PARTITION p1 VALUES LESS THAN (1996),
PARTITION p2 VALUES LESS THAN (2001),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
range(exp) exp 計算結果必須在 values less than 的取值範圍當中
less than 的取值必須由小到大
2.list
其中“expr” 是某列值或一個基於某個列值、並返回一個整數值的表達式,然後通過“VALUES IN (value_list)”的方式來定義每個分區,其中“value_list”是一個通過逗號分隔的整數列表。
註釋:在MySQL 5.1中,當使用LIST分區時,有可能只能匹配整數列表。
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY LIST(store_id)
PARTITION pNorth VALUES IN (3,5,6,9,17),
PARTITION pEast VALUES IN (1,2,10,11,19,20),
PARTITION pWest VALUES IN (4,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);
刪除某個分區的數據:
ALTER TABLE employees DROP PARTITION pWest;
3.hash
HASH分區主要用來確保數據在預先確定數目的分區中平均分佈
PARTITION BY HASH (expr)”子句,其中“expr”是一個返回一個整數的表達式
PARTITIONS num”子句,其中num 是一個非負的整數,它表示表將要被分割成分區的數量。
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;
*最有效率的哈希函數是隻對單個表列進行計算,並且它的值隨列值進行一致地增大或減小,也就是說,表達式值和它所基於的列的值變化越接近,MySQL就可以越有效地使用該表達式來進行HASH分區。
換句話說,如果列值與表達式值之比的曲線圖越接近由等式“y=nx(其中n爲非零的常數)描繪出的直線,則該表達式越適合於 哈希
3.1 LINEAR HASH
1.) 找到下一個大於num.的、2的冪,我們把這個值稱爲V ,它可以通過下面的公式得到:
2.) V = POWER(2, CEILING(LOG(2, num)))
(例如,假定num是13。那麼LOG(2,13)就是3.7004397181411。 CEILING(3.7004397181411)就是4,則V = POWER(2,4), 即等於16)。
3.) 設置 N = F(column_list) & (V - 1).
4.) 當 N >= num:
設置 V = CEIL(V / 2)
設置 N = N & (V - 1)
按照線性哈希分區的優點在於增加、刪除、合併和拆分分區將變得更加快捷,有利於處理含有極其大量(1000吉)數據的表。它的缺點在於,與使用常規HASH分區得到的數據分佈相比,各個分區間數據的分佈不大可能均衡。
4.key
按照KEY進行分區類似於按照HASH分區,除了HASH分區使用的用戶定義的表達式,而KEY分區的 哈希函數是由MySQL 服務器提供
“CREATE TABLE ... PARTITION BY KEY”的語法規則類似於創建一個通過HASH分區的表的規則。它們唯一的區別在於使用的關鍵字是KEY而不是HASH,並且KEY分區只採用一個或多個列名的一個列表。
通過線性KEY分割一個表也是可能的。下面是一個簡單的例子:
CREATE TABLE tk (
col1 INT NOT NULL,
col2 CHAR(5),
col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;
二。
子分區: 子分區結合 range,list 與 hash,key 分區
CREATE TABLE ts (id INT, purchased DATE)
PARTITION BY RANGE(YEAR(purchased))
SUBPARTITION BY HASH(TO_DAYS(purchased))
SUBPARTITIONS 2
(
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN MAXVALUE
);
表ts 有3個RANGE分區。這3個分區中的每一個分區——p0, p1, 和 p2 ——又被進一步分成了2個子分區。實際上,整個表被分成了3 * 2 = 6個分區
CREATE TABLE ts (id INT, purchased DATE)
PARTITION BY RANGE(YEAR(purchased))
SUBPARTITION BY HASH(TO_DAYS(purchased))
(
PARTITION p0 VALUES LESS THAN (1990)
(
SUBPARTITION s0,
SUBPARTITION s1
),
PARTITION p1 VALUES LESS THAN (2000)
(
SUBPARTITION s2,
SUBPARTITION s3
),
PARTITION p2 VALUES LESS THAN MAXVALUE
(
SUBPARTITION s4,
SUBPARTITION s5
)
);
以上作用和上一個例子相同,但是要注意:
1.每個分區必須有相同數量的子分區。
2.每個SUBPARTITION 子句必須包括 (至少)子分區的一個名字
子分區可以用於特別大的表,在多個磁盤間分配數據和索引。假設有6個磁盤,分別爲/disk0, /disk1, /disk2等。現在考慮下面的例子:
CREATE TABLE ts (id INT, purchased DATE)
PARTITION BY RANGE(YEAR(purchased))
SUBPARTITION BY HASH(TO_DAYS(purchased))
(
PARTITION p0 VALUES LESS THAN (1990)
(
SUBPARTITION s0
DATA DIRECTORY = '/disk0/data'
INDEX DIRECTORY = '/disk0/idx',
SUBPARTITION s1
DATA DIRECTORY = '/disk1/data'
INDEX DIRECTORY = '/disk1/idx'
),
PARTITION p1 VALUES LESS THAN (2000)
(
SUBPARTITION s0
DATA DIRECTORY = '/disk2/data'
INDEX DIRECTORY = '/disk2/idx',
SUBPARTITION s1
DATA DIRECTORY = '/disk3/data'
INDEX DIRECTORY = '/disk3/idx'
),
PARTITION p2 VALUES LESS THAN MAXVALUE
(
SUBPARTITION s0
DATA DIRECTORY = '/disk4/data'
INDEX DIRECTORY = '/disk4/idx',
SUBPARTITION s1
DATA DIRECTORY = '/disk5/data'
INDEX DIRECTORY = '/disk5/idx'
)
);
三、MySQL分區處理NULL值的方式
MySQL 中的分區在禁止空值(NULL)上沒有進行處理,無論它是一個列值還是一個用戶定義表達式的值。一般而言,在這種情況下MySQL 把NULL視爲0。如果你希望迴避這種做法,你應該在設計表時不允許空值;最可能的方法是,通過聲明列“NOT NULL”來實現這一點。
四、分區管理語句
“REORGANIZE PARTITION”的基本語法是:
ALTER TABLE tbl_name REORGANIZE PARTITION partition_list INTO (partition_definitions);
拆分分區:(不丟失數據)
ALTER TABLE members REORGANIZE PARTITION p0 INTO (
PARTITION s0 VALUES LESS THAN (1960),
PARTITION s1 VALUES LESS THAN (1970)
);
合併分區:
ALTER TABLE members REORGANIZE PARTITION s0,s1 INTO (
PARTITION p0 VALUES LESS THAN (1970)
);
ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
PARTITION m0 VALUES LESS THAN (1980),
PARTITION m1 VALUES LESS THAN (2000)
);
注意點:
1.新分區模式不能有任何重疊的區間(適用於按照RANGE分區的表)或值集合(適用於重新組織按照LIST分區的表)。
2.partition_definitions 列表中分區的合集應該與在partition_list 中命名分區的合集佔有相同的區間或值集合。
3.對於按照RANGE分區的表,只能重新組織相鄰的分區;不能跳過RANGE分區。
4.不能使用REORGANIZE PARTITION來改變表的分區類型
如果想在不刪除和重建表的條件下實現這兩個任務,可以使用“ALTER TABLE ... PARTITION BY ....”,例如:
· ALTER TABLE members
· PARTITION BY HASH(YEAR(dob))
· PARTITIONS 8;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.