上接RANGE分区
HASH分区:
hash分区的目的是将数据均匀的分布到预先定义的各个分区中,保证各分区的数据数量大致一致。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中;而在HASH分区中,MYSQL自动完成这些工作,用户所要做的只是基于将要被散列的列值指定一个列值或者表达式,以及指定呗分区的表将要被分割成的分区数量。
要使用HAHS分区来分割一个表,要在CREATE TABLE语句上添加一个PARTITION BY HASH(expr)子句,其中“expr”是返回一个整数的表达式。expr可以仅仅是字段类型为整型的列名。此外,用户很可能需要在后面再添加一个PARTITITIONS num子句,其中num是YGI额非负的整数,它表示将要被分割成分区的数量。如果没有包含一个PARTITIONS子句,分区数量默认为1.
mysql> create table t_hash (
-> a int,
-> b datetime)
-> partition by hash (YEAR(b))
-> partitions 4;
Query OK, 0 rows affected (0.85 sec)
插入2010-04-01进入表t_hash,那么
MOD(YEAR('2010-04-01'),4)
=MOD(2010,4)
=2
因此该记录会被放入分区p2中。
mysql> insert into t_hash select 1,'2010-01-01';
Query OK, 1 row affected (0.14 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from information_schema.partitions
-> where table_schema=database() and table_name='t_hash'\G;
*************************** 1. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: test
TABLE_NAME: t_hash
PARTITION_NAME: p0
SUBPARTITION_NAME: NULL
PARTITION_ORDINAL_POSITION: 1
SUBPARTITION_ORDINAL_POSITION: NULL
PARTITION_METHOD: HASH
SUBPARTITION_METHOD: NULL
PARTITION_EXPRESSION: YEAR(b)
SUBPARTITION_EXPRESSION: NULL
PARTITION_DESCRIPTION: NULL
TABLE_ROWS: 0
AVG_ROW_LENGTH: 0
DATA_LENGTH: 16384
MAX_DATA_LENGTH: NULL
INDEX_LENGTH: 0
DATA_FREE: 0
CREATE_TIME: NULL
UPDATE_TIME: NULL
CHECK_TIME: NULL
CHECKSUM: NULL
PARTITION_COMMENT:
NODEGROUP: default
TABLESPACE_NAME: NULL
*************************** 2. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: test
TABLE_NAME: t_hash
PARTITION_NAME: p1
SUBPARTITION_NAME: NULL
PARTITION_ORDINAL_POSITION: 2
SUBPARTITION_ORDINAL_POSITION: NULL
PARTITION_METHOD: HASH
SUBPARTITION_METHOD: NULL
PARTITION_EXPRESSION: YEAR(b)
SUBPARTITION_EXPRESSION: NULL
PARTITION_DESCRIPTION: NULL
TABLE_ROWS: 0
AVG_ROW_LENGTH: 0
DATA_LENGTH: 16384
MAX_DATA_LENGTH: NULL
INDEX_LENGTH: 0
DATA_FREE: 0
CREATE_TIME: NULL
UPDATE_TIME: NULL
CHECK_TIME: NULL
CHECKSUM: NULL
PARTITION_COMMENT:
NODEGROUP: default
TABLESPACE_NAME: NULL
*************************** 3. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: test
TABLE_NAME: t_hash
PARTITION_NAME: p2
SUBPARTITION_NAME: NULL
PARTITION_ORDINAL_POSITION: 3
SUBPARTITION_ORDINAL_POSITION: NULL
PARTITION_METHOD: HASH
SUBPARTITION_METHOD: NULL
PARTITION_EXPRESSION: YEAR(b)
SUBPARTITION_EXPRESSION: NULL
PARTITION_DESCRIPTION: NULL
TABLE_ROWS: 1
AVG_ROW_LENGTH: 16384
DATA_LENGTH: 16384
MAX_DATA_LENGTH: NULL
INDEX_LENGTH: 0
DATA_FREE: 0
CREATE_TIME: NULL
UPDATE_TIME: NULL
CHECK_TIME: NULL
CHECKSUM: NULL
PARTITION_COMMENT:
NODEGROUP: default
TABLESPACE_NAME: NULL
*************************** 4. row ***************************
TABLE_CATALOG: def
TABLE_SCHEMA: test
TABLE_NAME: t_hash
PARTITION_NAME: p3
SUBPARTITION_NAME: NULL
PARTITION_ORDINAL_POSITION: 4
SUBPARTITION_ORDINAL_POSITION: NULL
PARTITION_METHOD: HASH
SUBPARTITION_METHOD: NULL
PARTITION_EXPRESSION: YEAR(b)
SUBPARTITION_EXPRESSION: NULL
PARTITION_DESCRIPTION: NULL
TABLE_ROWS: 0
AVG_ROW_LENGTH: 0
DATA_LENGTH: 16384
MAX_DATA_LENGTH: NULL
INDEX_LENGTH: 0
DATA_FREE: 0
CREATE_TIME: NULL
UPDATE_TIME: NULL
CHECK_TIME: NULL
CHECKSUM: NULL
PARTITION_COMMENT:
NODEGROUP: default
TABLESPACE_NAME: NULL
4 rows in set (0.04 sec)
可以看到P2分区有一条记录。当前这个例子并不能把数据均匀的分布到各个分区,因为按照YEAR函数进行的,该值本身是离散的。如果对连续的值进行HASH分区,如自增长的主键,则可以较好地将数据平均分布。
MYSQL还支持一种LINEAR HASH分区,分区算法不一样,算法如下:
mysql> create table t_hash (
-> a int,
-> b datetime)
-> partition by linear hash (YEAR(b))
-> partitions 4;
取大于分区数量4的下一个2的幂值V,V=POWER(2,CEILING(LOG(2,num)))=4
所在分区N=YEAR('2010-04-01')&(V-1)=2.
LINEAR HASH分区的优点在于增加、删除、合并和拆分分区将变得更加快捷,有利于处理含有
大量数据的表。缺点在于,与使用HASH分区得到的数据分布相比,各个分区间数据的分布可能不大均衡。
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐