3、Hash分区

Hash分区的目的就是将数据尽量均匀地分布在各个分区中。在RANGE和LIST分区中,需要指定范围,而在HASH分区中,MYSQL会自动安排完成这些工作。用户需要做的就是对要进行HASH分区的列值指定一个列值或者表达式,以及指定将要被分成的区块数。

对一个表进行HASH分区,首先需要在CREATE TABLE语句上加上一个PARTITION BY

HASH(expr),其中expr代表一个返回整数的表达式,也可以是一个整数列。此外还需要加上PARTITION num

示例:

CREATE TABLE b(
    Id  INT,
    b  datetime
)
PARTITION BY HASH(YEAR(b))
PARTITIONS 4;

示例数据:‘2010-09-01’

SELECT MOD(YEAR('2010-09-01'),4);

通过MOD函数来判断具体插入的分区:MOD(YEAR(‘2010-09-01’))=2,因此’2010-09-01’这条数据就会存到P2分区。

针对日期这种数据本身可是离散的,因此HASH分区并不一定能够保证均匀地分布到各区。但是如果是一些连续的数据,HASH分区则能保证比较均匀地分布到各区。

4、KEY分区

KEY分区和HASH分区类似,只不过HASH分区的分区值可以为表达式,而KEY里的只能是整数列。KEY分区使用的是MYSQL内部自己的函数,对于INNODB引擎来说,这个内部函数也就是HASH函数。

示例:

CREATE TABLE b(
              Id  INT,
              b  datetime
)
PARTITION BY KEY(b)
PARTITIONS 4;

5、COLUMNS分区

之前介绍的四种分区:RANGE、LIST、HASH、KEY,分区的值都需要是整数列。如果不是整型,则需要通过函数转换为整数。在MYSQL5.5版本后,开始支持COLUMNS分区,可认为是RANGE和LIST的进化,COLUMNS分区可以直接使用非整数型字段,分区根据类型直接比较而得,不需要转换成整数型。此外,RANGE还支持了多列组合分区。

COLUMNS支持分区的列类型:

□ 所有的整型类型,如INT、SMALLINT、TINYINT、BIGINT。FLOAT和DECIMAL则不予支持。

□ 日期类型,如DATE和DATETIME。其余的日期类型不予支持。

□ 字符串类型,如CHAR、VARCHAR、BINARY和VARBINARY。BLOB和TEXT类型不予支持。

示例:RANGE多列分区

CREATE TABLE b_1(
       Id  INT,
       b  datetime,
       c  CHAR(3)
)
PARTITION BY RANGE COLUMNS(b,c)(
PARTITION P1 VALUES LESS THAN ('2009-09-01','cc'),
PARTITION P2 VALUES LESS THAN ('2009-10-01','gg')
);

对于多列分区,从前往后判断,满足一个,即加入该分区。

6、子分区

子分区是在分区的基础,在进行分区。有时也称为复合分区。

子分区建立需要注意以下几个问题:

       □ 每个子分区的数量必须相同。

□ 要在一个分区表的任何分区上使用SUBPARTITION来明确定义任何子分区,就必须定义所有的子分区,下面这种就是错误定义:

distribute by hash是什么意思 db2 db2 hash分区_数据

 

□ 每个SUBPARTITION子句必须包括子分区的一个名字

□ 子分区的名字必须是唯一的。因此下面的创建语句是错误的:

distribute by hash是什么意思 db2 db2 hash分区_字段_02

 

7、分区中的NULL值处理

RANGE分区中,NULL值会分到最左侧的分区

LIST分区,需要特殊指定NULL值得分区,否则插入会报错

distribute by hash是什么意思 db2 db2 hash分区_数据_03

 

HASH和KEY分区,函数值都默认返回为0。

8、分区的性能

对于一张表来说,不一定分区会带来查询速度的上升,反而可能造成速度的下降。

数据库的应用主要分为两类:一类OLTP(在线事务处理),如:网络游戏,电子商务等,一类是OLAP(数据分析),如:数据仓库,数据集市。在某一个实际的应用场景,可能两者都会出现,如网络游戏中,玩家操作的游戏数据库应用就是OLTP的,但是游戏厂商可能需要对游戏产生的日志进行分析,通过分析得到的结果来更好地服务于游戏,预测玩家的行为等,而这却是OLAP的应用。

对于OLAP,我们可能会需要频繁的去扫描一张很大的数据表,如果对这张表的时间戳字段加个分区,那么我们获取某一时间段的数据的查询效率会大大提高。

然而对于OLTP的应用,分区应该非常小心。在这种应用下,通常不可能会获取一张大表中10%的数据,大部分都是通过索引返回几条记录即可。而根据B+树索引的原理可知,对于一张大表,一般的B+树需要2~3次的磁盘IO。因此B+树可以很好地完成操作,不需要分区的帮助,并且设计不好的分区会带来严重的性能问题。

具体就是如果我们频繁操作的表,经常查询的字段做分区会给我们带来效率的提高,但是如果使用别的字段来做查询,这样分区不但没有起到加速的效果,反而我们会对每个分区的数据都进行查询,io次数则可能是原来一张表io次数的分区数倍。从而查询效率会降低很多。