MySQL分區(qū)之HASH分區(qū)詳解
介紹
基于給定的分區(qū)個(gè)數(shù),將數(shù)據(jù)分配到不同的分區(qū),HASH分區(qū)只能針對(duì)整數(shù)進(jìn)行HASH,對(duì)于非整形的字段只能通過(guò)表達(dá)式將其轉(zhuǎn)換成整數(shù)。表達(dá)式可以是mysql中任意有效的函數(shù)或者表達(dá)式,對(duì)于非整形的HASH往表插入數(shù)據(jù)的過(guò)程中會(huì)多一步表達(dá)式的計(jì)算操作,所以不建議使用復(fù)雜的表達(dá)式這樣會(huì)影響性能。
MYSQL支持兩種HASH分區(qū),常規(guī)HASH(HASH)和線性HASH(LINEAR HASH)。
一、常規(guī)HASH
常規(guī)hash是基于分區(qū)個(gè)數(shù)的取模(%)運(yùn)算。根據(jù)余數(shù)插入到指定的分區(qū)
CREATE TABLE tbhash ( id INT NOT NULL, store_id INT ) PARTITION BY HASH(store_id) PARTITIONS 4 ;
ALTER TABLE tbhash ADD INDEX ix_store_id(store_id);
INSERT INTO tbhash() VALUES(1,100),(1,101),(2,102),(3,103),(4,104); SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tbhash';
其中100,104對(duì)4取模是0所以這兩條數(shù)據(jù)被分配到了p0分區(qū)。
2.時(shí)間類型字段
CREATE TABLE employees ( id INT NOT NULL, hired DATE NOT NULL DEFAULT '1970-01-01', ) PARTITION BY HASH( YEAR(hired) ) PARTITIONS 4;
常規(guī)hash的分區(qū)非常的簡(jiǎn)便,通過(guò)取模的方式可以讓數(shù)據(jù)非常平均的分布每一個(gè)分區(qū),但是由于分區(qū)在創(chuàng)建表的時(shí)候已經(jīng)固定了。如果新增或者收縮分區(qū)的數(shù)據(jù)遷移比較大。
二、線性HASH(LINEAR HASH)
LINEAR HASH和HASH的唯一區(qū)別就是PARTITION BY LINEAR HASH
CREATE TABLE tblinhash ( id INT NOT NULL, hired DATE NOT NULL DEFAULT '1970-01-01' ) PARTITION BY LINEAR HASH( YEAR(hired) ) PARTITIONS 6;
線性HASH的計(jì)算原理如下:
假設(shè)分區(qū)個(gè)數(shù)num=6,N表示數(shù)據(jù)最終存儲(chǔ)的分區(qū)
sep1:V = POWER(2, CEILING(LOG(2, num))),LOG()是計(jì)算NUM以2為底的對(duì)數(shù),CEILING()是向上取整,POWER()是取2的次方值;如果num的值是2的倍數(shù)那么這個(gè)表達(dá)式計(jì)算出來(lái)的結(jié)果不變。
V=POWER(2,CEILING(LOG(2,6)))
V=POWER(2,3)
V=8
sep2:N=values&(V-1);&位與運(yùn)算,將兩個(gè)值都轉(zhuǎn)換成2進(jìn)行求與運(yùn)算,當(dāng)都為1才為1;當(dāng)num是2的倍數(shù)時(shí)由于V計(jì)算出來(lái)的結(jié)果不變,這時(shí)values&(V-1)=MOD(values/num)和時(shí)間HASH取模算出的結(jié)果是一致的,這時(shí)特殊情況只有當(dāng)分區(qū)是2的倍數(shù)才是這種 情況。values是YEAR(hired)的值
sep3:while N>=num
sep3-1:N=N& (CEIL(V/ 2)- 1)
例如:
1.當(dāng)插入的值是'2003-04-14'時(shí)
V = POWER(2, CEILING( LOG(2,6) )) = 8
N = YEAR('2003-04-14') & (8 - 1)
= 2003 & 7
=3
(3 >= 6 is FALSE: record stored in partition #3),N不大于num所以存儲(chǔ)在第3分區(qū),注意這里的3指的是P3,分區(qū)號(hào)是從P0開(kāi)始。
2.當(dāng)插入的值是‘1998-10-19’
V = POWER(2, CEILING( LOG(2,6) )) = 8
N = YEAR('1998-10-19') & (8-1)
= 1998 & 7
= 6
(6 >= 6 is TRUE: additional step required),由于N>=num所以要進(jìn)行第三步操作
N=N&(CEILING(8/2)-1)
=6&3
=2
(2>=6is FALSE:recored in partition #2),由于2不大于6所以存儲(chǔ)在第2個(gè)分區(qū),注意這里的3指的是P2,分區(qū)號(hào)是從P0開(kāi)始。
INSERT INTO tblinhash() VALUES(1,'2003-04-14'),(2,'1998-10-19'); SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tblinhash';
EXPLAIN SELECT * FROM tblinhash WHERE hired='2003-04-14';
三、分區(qū)管理
常規(guī)HASH和線性HASH的增加收縮分區(qū)的原理是一樣的。增加和收縮分區(qū)后原來(lái)的數(shù)據(jù)會(huì)根據(jù)現(xiàn)有的分區(qū)數(shù)量重新分布。HASH分區(qū)不能刪除分區(qū),所以不能使用DROP PARTITION操作進(jìn)行分區(qū)刪除操作;
只能通過(guò)ALTER TABLE ... COALESCE PARTITION num來(lái)合并分區(qū),這里的num是減去的分區(qū)數(shù)量;
可以通過(guò)ALTER TABLE ... ADD PARTITION PARTITIONS num來(lái)增加分區(qū),這里是null是在原先基礎(chǔ)上再增加的分區(qū)數(shù)量。
1.合并分區(qū)
減去3個(gè)分區(qū)
ALTER TABLE tblinhash COALESCE PARTITION 3;
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tblinhash';
注意:減去兩個(gè)分區(qū)后,數(shù)據(jù)根據(jù)現(xiàn)有的分區(qū)進(jìn)行了重新的分布,以'2003-04-14'為例:POWER(2, CEILING( LOG(2,3) ))=4,2003&(4-1)=3,3>=3,3&(CEILING(3/2)-1)=1,所以現(xiàn)在的'2003-04-14'這條記錄由原來(lái)的p3變成了p1
2.增加分區(qū)
增加4個(gè)分區(qū)
ALTER TABLE tblinhash add PARTITION partitions 4;
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tblinhash';
當(dāng)在3個(gè)分區(qū)的基礎(chǔ)上增加4個(gè)分區(qū)后,‘2003-04-14’由原來(lái)的p1變成了p3,而另一條記錄由原來(lái)的p2變成了p6
四、移除表的分區(qū)
ALTER TABLE tablename REMOVE PARTITIONING ;
注意:使用remove移除分區(qū)是僅僅移除分區(qū)的定義,并不會(huì)刪除數(shù)據(jù)和drop PARTITION不一樣,后者會(huì)連同數(shù)據(jù)一起刪除
分區(qū)系列文章:
RANGE分區(qū):http://chabaoo.cn/article/244269.htm
COLUMN分區(qū):http://chabaoo.cn/article/96515.htm
LIST分區(qū):http://chabaoo.cn/article/244256.htm
HASH分區(qū):http://chabaoo.cn/article/244277.htm
KEY分區(qū):http://chabaoo.cn/article/244282.htm
子分區(qū):http://chabaoo.cn/article/244294.htm
指定各分區(qū)路徑:http://chabaoo.cn/article/244296.htm
分區(qū)索引以及分區(qū)介紹總結(jié):http://chabaoo.cn/article/244300.htm
總結(jié)
常規(guī)HASH的數(shù)據(jù)分布更加均勻一些,也便于理解;目前還沒(méi)有徹底理解為什么線性HASH在收縮和增加分區(qū)時(shí)處理的速度會(huì)更快,同時(shí)線性HASH的數(shù)據(jù)分布不均勻。
到此這篇關(guān)于MySQL分區(qū)之HASH分區(qū)的文章就介紹到這了,更多相關(guān)MySQL HASH分區(qū)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL命令行界面中出現(xiàn)字符錯(cuò)誤提示的原因及解決方法
這篇文章主要介紹了MySQL命令行界面中出現(xiàn)字符錯(cuò)誤提示的原因及解決方法,同時(shí)文中還附帶了MySQL導(dǎo)入亂碼問(wèn)題的解決辦法提示,需要的朋友可以參考下2016-03-03MySQL系列之五 視圖、存儲(chǔ)函數(shù)、存儲(chǔ)過(guò)程、觸發(fā)器
視圖就是一條select語(yǔ)句執(zhí)行后返回的結(jié)果集;觸發(fā)器是與表有關(guān)的數(shù)據(jù)庫(kù)對(duì)象,在滿足定義條件時(shí)觸發(fā),并執(zhí)行觸發(fā)器中定義的語(yǔ)句集合;函數(shù)存儲(chǔ)著一系列sql語(yǔ)句,調(diào)用函數(shù)就是一次性執(zhí)行這些語(yǔ)句,而存儲(chǔ)過(guò)程就是一組可編程的函數(shù),需要的朋友可以參考下2021-07-07mysql查詢每小時(shí)數(shù)據(jù)和上小時(shí)數(shù)據(jù)的差值實(shí)現(xiàn)思路詳解
這篇文章主要介紹了mysql查詢每小時(shí)數(shù)據(jù)和上小時(shí)數(shù)據(jù)的差值,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04mysql 從 frm 文件恢復(fù) table 表結(jié)構(gòu)的3種方法【推薦】
這篇文章主要介紹了mysql 從 frm 文件恢復(fù) table 表結(jié)構(gòu)的3種方法 ,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09詳解mysql索引總結(jié)----mysql索引類型以及創(chuàng)建
索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個(gè)組成部分),它們包含著對(duì)數(shù)據(jù)表里所有記錄的引用指針。這篇文章主要介紹了詳解mysql索引總結(jié)----mysql索引類型以及創(chuàng)建,有興趣的可以了解一下。2016-11-11