• 表分区是将一个表的数据按照必定的规则水平划分为不一样的逻辑块,并分别进行物理存储,这个规则就叫作分区函数,能够有不一样的分区规则mysql
• 经过show plugins语句查看当前MySQL是否支持表分区功能;5.7表分区功能默认开启;算法
MySQL表分区介绍sql
• 当表中含有主键或惟一键时,则每一个被用做分区函数的字段必须是表中惟一键和主键的所有或一部分,不然就没法建立分区表函数
例:优化
mysql> CREATE TABLE tnp (id INT NOT NULL AUTO_INCREMENT,ref BIGINT NOT NULL,name VARCHAR(255),PRIMARY KEY pk (id),UNIQUE KEY uk (ref) ) PARTITION BY RANGE (id) ( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11));
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning functionui
mysql> CREATE TABLE tnp (id INT NOT NULL AUTO_INCREMENT,ref BIGINT NOT NULL,name VARCHAR(255),PRIMARY KEY pk (id),UNIQUE KEY uk (ref) ) PARTITION BY RANGE (ref) ( PARTITION p0 VALUES LESS THHAN (6), PARTITION p1 VALUES LESS THAN (11));
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning functionspa
• 表分区的主要优点在于:
• 能够容许在一个表里存储更多的数据,突破磁盘限制或者文件系统限制
• 对于从表里将过时或历史的数据移除在表分区很容易实现,只要将对应的分区移除便可
• 对某些查询和修改语句来讲,能够自动将数据范围缩小到一个或几个表分区上,优化语句执行效率。并且能够经过显示指定表分区来执行语句unix
例:code
SELECT * FROM t PARTITION (p0,p1) WHERE c < 5;blog
mysql表分区类型
表分区类型分为:
• RANGE表分区:范围表分区,按照必定的范围值来肯定每一个分区包含的数据
• LIST表分区:列表表分区,按照一个一个肯定的值来肯定每一个分区包含的数据
• HASH表分区:哈希表分区,按照一个自定义的函数返回值来肯定每一个分区包含的数据
• KEY表分区 :key表分区,与哈希表分区相似,只是用MySQL本身的HASH函数来肯定每一个分区包含的数据
RANGE表分区
• 范围表分区,按照必定的范围值来肯定每一个分区包含的数据,分区函数使用的字段必须只能是整数类型
• 分区的定义范围必须是连续的,且不能有重叠部分,经过使用VALUES LESS THAN来定义分区范围,表分区的范围定义是从小到大定义的
例:
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 NOT NULL, store_id INT NOT NULL )
PARTITION BY RANGE (store_id)
( PARTITION p0 VALUES LESS THAN (6), PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16), PARTITION p3 VALUES LESS THAN (21),PARTITION p4 VALUES LESS THAN MAXVALUE);
• MAXVALUE关键词的做用是表示可能的最大值,因此任何store_id>=21的数据都会被写入到p4分区里
• 对timestamp字段类型可使用的表达式目前仅有unix_timestamp,其余的表达式都不容许
• 分区函数中也可使用表达式
LIST表分区
• 列表表分区,按照一个一个肯定的值来肯定每一个分区包含的数据
• 经过PARTITION BY LIST(expr)分区函数表达式必须返回整数,取值范围经过VALUES IN (value_list)定义
例:
mysql> CREATE TABLE h2 (c1 INT, c2 INT )
PARTITION BY LIST(c1)
(PARTITION p0 VALUES IN (1, 4, 7),
PARTITION p1 VALUES IN (2, 5, 8));
• 对List表分区来讲,没有MAXVALUE特殊值,全部的可能取值都须要再VALUES IN中包含,若是没有定义的值则会报错
• 一样,当有主键或者惟一键存在的状况下,分区函数字段须要包含在主键或惟一键中
• 对range和list表分区来讲,分区函数能够包含多个字段
• 分区多字段函数所涉及的字段类型能够包括:
• TINYINT, SMALLINT, MEDIUMINT, INT (INTEGER), and BIGINT. DATE and DATETIME. CHAR, VARCHAR, BINARY, and VARBINARY; 其余的字段类型都不支持
• 范围多字段分区函数与普通的范围分区函数的区别在于:
a) 字段类型多样化
b) 范围多字段分区函数不支持表达式,只能用字段名
c) 范围多字段分区函数支持一个或多个字段
哈希表分区
• 按照一个自定义的函数返回值来肯定每一个分区包含的数据,这个自定义函数也能够仅仅是一个字段名字
• 经过PARTITION BY HASH (expr)子句来表达哈希表分区,其中的expr表达式必须返回一个整数,基于分区个数的取模(%)运算。根据余数插入到指定的分区
• 对哈希表分区来讲只须要定义分区的个数,其余的事情由内部完成
例:
• CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY HASH( YEAR(col3) ) PARTITIONS 4; ##不指定PARTITIONS默认为1
key表分区
与哈希表分区相似,只不过哈希表分区依赖于自定义的函数,而key表分区的哈希算法是依赖MySQL自己
• CREATE TABLE ... PARTITION BY KEY ()建立key表分区,括号里面能够包含0个或者多个字段,所引用的字段必须是主键或者主键的一部分,若是括号里面没有字段,则表明使用主键 ###若是表中没有主键但有唯一键,则使用唯一键,但唯一键必须定义为not null,不然会报错
MySQL表分区对Null值处理
不一样的表分区对NULL值的处理方式不一样
• 对范围表分区来讲,若是插入的是NULL值,则将数据放到最小的分区表里
• 对list表分区来讲,支持NULL值的惟一状况就是某个分区的容许值中包含NULL
• 对哈希表分区和Key表分区来讲,NULL值会被当成0值对待
MySQL表分区管理
删除表分区
• 经过alter table命令能够执行增长,删除,从新定义,合并或者拆分表分区的管理动做
• 对范围表分区和列表表分区来讲,删除一个表分区命令 ###删除表分区的动做不光会把分区删掉,也会把表分区里原来的数据给删除掉
例:
ALTER TABLE tablename DROP PARTITION 分区名称;
增长表分区
• 在原分区上增长一个表分区能够经过alter table … add partition语句来完成
• 但对范围表分区来讲,增长的表分区必须在尾部增长,在头部或者在中间增长都会失败;## 为解决这个问题,可使用REORGANIZE命令:
ALTER TABLE members REORGANIZE PARTITION p0 INTO ( PARTITION n0 VALUES LESS THAN (1970), PARTITION n1 VALUES LESS THAN (1980) );
• 对列表表分区来讲,只要新增长的分区对应的值在以前的表分区中没有出现过,就能够经过alter table… add partition来增长
其余管理命令
• 当须要去除分区碎片是,能够执行rebuild命令,至关于删除数据以后从新插入
• ALTER TABLE t1 REBUILD PARTITION p0, p1;
• 也能够执行OPTIMIZE命令回收分区中未使用的空间和从新获取统计资料
• ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;
• Analyzing partitions命令从新收集分区统计资料
• ALTER TABLE t1 ANALYZE PARTITION p3;
• Repairing partitions命令修复异常的分区
• ALTER TABLE t1 REPAIR PARTITION p0,p1;
• Checking partitions命令检查分区中数据或者索引数据是否损坏
• ALTER TABLE t1 CHECK PARTITION p1;
• ALTER TABLE ... TRUNCATE PARTITION命令用来删除分区中的全部数据
实际应用
项目需求:项目中按照时间划分分区使用range分区方式(每周为单位划分一个分区)
1.分区表表结构
表结构定义略...
PARTITION BY RANGE (TO_DAYS(publishtime))
(PARTITION p20190102 VALUES LESS THAN (737427))
2.实现自动增加分区方式
经过mysql事件调度存储过程来实现
具体SQL以下:
建立一个事件
CREATE DEFINER=`d5000`@`%` EVENT `Partition_base_data_event` ON SCHEDULE EVERY 7 DAY STARTS '2019-01-02 10:55:00' ON COMPLETION NOT PRESERVE ENABLE DO CALL create_partition_base_data()
建立存储过程
CREATE DEFINER=`d5000`@`%` PROCEDURE `create_partition_base_data`() BEGIN SET @Max_date= DATE(DATE_ADD(NOW(), INTERVAL 1 DAY))+0; SET @s1=CONCAT('ALTER TABLE base_data ADD PARTITION (PARTITION p',@Max_date,' VALUES LESS THAN (TO_DAYS (''',DATE_ADD(@Max_date, INTERVAL 7 DAY),''')))'); SELECT @s1; PREPARE stmt2 FROM @s1; EXECUTE stmt2; DEALLOCATE PREPARE stmt2; COMMIT ; END