當mysql一張數據表中的數據達到一定的量時,在其中查詢某一個數據,需要花費大量的時間。爲了避免這種查詢的等待,可以對一張大的數據表做拆分。將其拆分成多張小的數據表。可以基於物理的拆分,將一張表拆分成多張小表,分別存放於不同的服務器上,以分散對mysql服務器的寫的壓力。也可以基於邏輯的拆分,將一張表存放到不同的區塊或磁盤上,以提高mysql的讀寫性能。
mysql數據拆分基於拆分方式的不同,又分爲水平拆分和垂直拆分,水平拆分也叫基於行的拆分,它不改變表結構,只是把多行數據分成多個表來進行存放,每個表只存放其中一部分行的數據。垂直拆分也叫基於列的拆分,它是將一張表中的多個列分開,拆分後的每張表只存放一部分列。
mysql分區是一種基於邏輯的水平拆分的方式。
二、分區優點
1、分區可以分在多個磁盤,存儲更大一點
2、根據查找條件,也就是where後面的條件,查找只查找相應的分區不用全部查找了
3、進行大數據搜索時可以進行並行處理。
4、跨多個磁盤來分散數據查詢,來獲得更大的查詢吞吐量
三、mysql分區的模式
1、RANGE
將數據按照某一列或者某幾列的範圍的不同進行劃分,例如可以將一個表通過年份劃分成三個分區,90年代的數據,2000到2010年之前的數據,2010年至今的數據。
1)創建一個range分區表:
mysql> CREATE TABLE IF NOT EXISTS `user` (
-> `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶ID',
-> `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名稱',
-> `sex` int(1) NOT NULL DEFAULT '0' COMMENT '0爲男,1爲女',
-> PRIMARY KEY (`id`)
-> ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
-> PARTITION BY RANGE (id) (
-> PARTITION p0 VALUES LESS THAN (3),
-> PARTITION p1 VALUES LESS THAN (6),
-> PARTITION p2 VALUES LESS THAN (9),
-> PARTITION p3 VALUES LESS THAN (12),
-> PARTITION p4 VALUES LESS THAN MAXVALUE
-> );
2)對現有表進行分區,並按照規則自動將表中現有數據分配到對應的分區中:
mysql> alter table aa partition by RANGE(id)
-> (PARTITION p1 VALUES less than (1),
-> PARTITION p2 VALUES less than (5),
-> PARTITION p3 VALUES less than MAXVALUE);
2、 LIST
系統通過預定義的列的值對所對應的行數據進行分區
1)創建一個list分區表:
mysql> CREATE TABLE IF NOT EXISTS `list_part` (
-> `id` int(11) PRIMARY KEY AUTO_INCREMENT NOT UNSIGNED NOT NULL COMMENT '用戶ID',
-> `province_id` int(2) NOT NULL DEFAULT 0 COMMENT '省',
-> `name` varchar(50) NOT NULL DEFAULT '' COMMENT '名稱',
-> `sex` int(1) NOT NULL DEFAULT '0' COMMENT '0爲男,1爲女'
-> ) ENGINE=INNODB DEFAULT CHARSET=utf8
-> PARTITION BY LIST (province_id) (
-> PARTITION p0 VALUES IN (1,2,3,4,5,6,7,8),
-> PARTITION p1 VALUES IN (9,10,11,12,16,21),
-> PARTITION p2 VALUES IN (13,14,15,19),
-> PARTITION p3 VALUES IN (17,18,20,22,23,24)
-> );
3、HASH
HASH分區主要用來確保數據在預先確定數目的分區中平均分佈,你所要做的只是基於將要被哈希的列值指定一個列值或表達式,以 及指定被分區的表將要被分割成的分區數量。
1)創建hash分區:
mysql> CREATE TABLE IF NOT EXISTS `hash_part` (
-> `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '評論ID',
-> `comment` varchar(1000) NOT NULL DEFAULT '' COMMENT '評論',
-> `ip` varchar(25) NOT NULL DEFAULT '' COMMENT '來源IP',
-> PRIMARY KEY (`id`)
-> ) ENGINE=INNODB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
-> PARTITION BY HASH(id)
-> PARTITIONS 3;
4、KEY
按照KEY進行分區類似於按照HASH分區,除了HASH分區使用的用戶定義的表達式,而KEY分區的哈希函數是由MySQL 服務器提供。
1)創建key分區:
mysql> CREATE TABLE IF NOT EXISTS `key_part` (
-> `news_id` int(11) NOT NULL COMMENT '新聞ID',
-> `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '新聞內容',
-> `u_id` varchar(25) NOT NULL DEFAULT '' COMMENT '來源IP',
-> `create_time` DATE NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '時間'
-> ) ENGINE=INNODB DEFAULT CHARSET=utf8
-> PARTITION BY LINEAR HASH(YEAR(create_time))
-> PARTITIONS 3;
5、Composite
也被稱之爲子分區。是分區表中每個分區的再次分割,子分區既可以使用HASH希分區,也可以使用KEY分區。
1)如果一個分區中創建了子分區,其他分區也要有子分區
2)如果創建了了分區,每個分區中的子分區數必有相同
3)同一分區內的子分區,名字不相同,不同分區內的子分區名子可以相同(5.1.50不適用)
4)創建子分區:
mysql> CREATE TABLE IF NOT EXISTS `sub_part` (
-> `news_id` int(11) NOT NULL COMMENT '新聞ID',
-> `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '新聞內容',
-> `u_id` int(11) NOT NULL DEFAULT 0s COMMENT '來源IP',
-> `create_time` DATE NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '時間'
-> ) ENGINE=INNODB DEFAULT CHARSET=utf8
-> PARTITION BY RANGE(YEAR(create_time))
-> SUBPARTITION BY HASH(TO_DAYS(create_time))(
-> PARTITION p0 VALUES LESS THAN (1990)(SUBPARTITION s0,SUBPARTITION s1,SUBPARTITION s2),
-> PARTITION p1 VALUES LESS THAN (2000)(SUBPARTITION s3,SUBPARTITION s4,SUBPARTITION good),
-> PARTITION p2 VALUES LESS THAN MAXVALUE(SUBPARTITION tank0,SUBPARTITION tank1,SUBPARTITION tank3)
-> );
四、MySQL分區管理
1、刪除分區
mysql> alter table user drop partition p4;
2、新增分區
1)range添加新分區:
mysql> alter table user add partition(partition p4 values less than MAXVALUE);
2)list添加分區:
mysql> alter table list_part add partition(partition p4 values in (25,26,28));
3)hash重新分區:
mysql> alter table hash_part add partition partitions 4;
4)key重新分區:
mysql> alter table key_part add partition partitions 4;
5)子分區添加新分區:
mysql> alter table sub1_part add partition(partition p3 values less than MAXVALUE);
3、重新分區:
1)range重新分區
mysql> ALTER TABLE user REORGANIZE PARTITION p0,p1,p2,p3,p4 INTO (PARTITION p0 VALUES LESS THAN MAXVALUE);
2)list重新分區
mysql> ALTER TABLE list_part REORGANIZE PARTITION p0,p1,p2,p3,p4 INTO (PARTITION p0 VALUES in (1,2,3,4,5));
linux及mysql交流羣:387283109