4.8 分区
分区功能并不是在存储引擎完成的,因此不是只有InnoDB存储引擎支持分区,常见的MyISAM,DNB等都支持。但也并不是所有存储引擎都支持,像CSV,MERGE,FEDORATED等就不支持
分区的过程是将一个表或者索引分解为多个更小,更可管理的部分。就访问数据库的应用而言,从逻辑上讲,只有一个表或者索引,但是在物理上这个表或者索引可能由数十个物理分区组成。每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理。
MySQL数据库支持的分区类型为水平分区,不支持垂直分区。此外MySQL数据库的分区是局部分区索引,一个分区中既存放了数据又存放了索引。而全局分区是指,数据存放在各个分区中,但是所有数据的索引放在一个对象中。目前,MySQL不支持全局分区。
可以使用如下命令查看当前数据库是否启动了分区功能
show variables like %partition%\G;
或者
show plugins
当MySQL数据库支持一下几种类型的分区:
- RANGE分区:行数据基于属于一个给定连续区间的列值被放入分区
- LIST分区:和RANGE分区类同,只是LIST分区面向的是离散的值
- HASH分区:根据用户自定义的表达式的返回值来进行分区,返回值不能为负数
- KEY分区:根据MySQL数据库提供的哈希函数来进行分区
不论创建何种分区,如果表中存在主键或者唯一索引时,分区列必须是唯一索引的一个组成部分,唯一索引可以是允许NULL值的,并且分区列只要是唯一索引的一个组成部分,不需要整个唯一索引列都是分区列,如果建表时没有指定主键,唯一索引,可以指定任何一个列为分区表
image.png image.png
4.8.2 分区类型
RANGE 分区
创建分区
create table t(id int)engine=innodb partition by range(id) (partition p0 values less than(10) ,partition p1 values less than(20));
查看物理文件
ll /var/lib/mysql/testmysql/ |grep t#P
-rw-r----- 1 mysql mysql 98304 Jan 2 07:26 t#P#p0.ibd
-rw-r----- 1 mysql mysql 98304 Jan 2 07:26 t#P#p1.ibd
接着插入数据
insert into t values (9);
insert into t values (10);
insert into t values (15);
可以通过information_schema架构下的PARTITIONS表来查看每个分区的具体信息:
select * from information_schema.PARTITIONS where
table_schema=database() and table_name='t'\G;
当插入一个不在分区定义的值时,MySQL数据库会抛出一个异常
image.png
RANGE分区主要用于日期列的分区,RANGE分区的查询,优化器只能对YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP()这类函数进行优化选择。
LIST分区
LIST分区和RANGE分区十分相似,只是分区列的值是离散的,而非连续的。在用INSERT插入的多行数据的过程中遇到分区未定义的值时,MyISAM和InnoDB存储引擎的处理完全不同。MyISAM引擎会将之前的行数据都插入,但之后的数据不会插入。而InnoDB引擎将其视为一个事务,因此没有任何数据插入。
HASH分区
HASH分区的目的是将数据均匀地分布到预先定义的各个分区中,保证各分区的数据数量大致都是一样的。
KEY分区
KEY分区和HASH分区相似,不同之处在于HASH分区使用用户定义的函数进行分区,KEY分区使用MySQL数据库提供的函数进行分区。
COLUMNS分区
在前面介绍的RANGE,LIST,HASH和KEY这四种分区中,分区的条件是:数据必须是整型的,如果不是整型的,那应该通过函数将其转化为整型,如果YEAR(),TO_DAYS(),MONTH()等函数。MySQL5.5开始支持COLUMNS分区。COLUMNS分区可以直接使用非整型的数据进行分区,分区根据类型直接比较而得,不需要转化为整型。
COLUMNS分区支持如下数据类型:
- 所有整型,如INT,SMALLINT,TINYINT,BIGINT。FLOAT和DECIMAL则不予支持
- 日期类型,如DATE和DATETIME,其余类型不予支持
- 字符串类型,如CHAR,VARCHAR,BINARY和VARBINARY
4.8.3 子分区
子分区是在分区的基础上再进行分区,有时也称这种分区为复合分区。MySQL数据库允许在RANGE和LIST的分区上再进行HASH和KEY的子分区。
建立子分区需要注意几个问题
- 每个子分区的数量必须相同
- 要在一个分区表的任何分区上使用SUBPARTITION来明确定义任何子分区,就必须定义所有的子分区
- 每个SUBPARTITION子句必须包括子分区的一个名字
- 子分区的名字必须是唯一的。
4.8.4 分区中的NULL值
MySQL数据库的分区总是视NULL值小于任何的一个非NULL值,这和MySQL数据库处理NULL值的ORDER BY操作是一样的,因此对于不同分区类型,MySQL数据库对于NULL值的处理也是各不相同的。
对于RANGE分区,如果向分区列插入了NULL值,则MySQL数据库会将该值放入最左边的分区。
LIST分区下要使用NULL值,则必须显式的指定哪个分区中放入NULL值,否则会报错。
HASH分区和KEY分区对于NULL的处理方式和RANGE分区、LIST分区不一样。任何分区函数都会将含有NULL值的记录返回为0
网友评论