MySQL中的HASH分区(附带实例)
HASH 分区基于用户定义的表达式的返回值来选择分区,该表达式使用将要插入表中的这些行的列值进行计算。hash() 函数中可以包含 MySQL 中有效的、产生非负整数值的任何表达式。
HASH 分区主要用来确保数据在预先确定数目的分区中平均分布。在 RANGE 和 LIST 分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中;而在 HASH 分区中,MySQL 自动完成这些工作,用户所要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。
【实例】创建 HASH 分区,命令如下:
例如,表 htable 中插入一条 birthdate 为“2010-09-23”的记录,可以通过如下方法计算该记录的分区:
先看下面的例子:
如果表 htable2 中插入一条 hired 为“2010-09-23”的记录,记录将要保存到的分区是 num 个分区中的分区 N,可以通过如下方法计算 N:
1) 找到下一个大于 num 的 2 的幂次方数,把这个值称作 V,即 V = POWR(2,CEILING(LOG(2,num)))。假设,num 的值是 13,那么 LOG(2,13) 就是 3.70043,CEILING(3.70043) 就是 4,则 V = POWER(2,4)=16。
2) 计算 N = F(column_list) & (V – 1),当 N≥num 时,执行 V = CEIL(V/2),此时 N = N &(V−1)。
【实例】演示通过线性哈希分区算法计算分区 N 的值。线性哈希分区表 t1 通过下面的语句创建。
现在假设要插入两条记录到表 th1 中,其中一条记录的 col3 列的值为“2003-04-14”,另一条记录的 cols 列值为“1998-10-19”。
1) 第一条记录要保存到的分区序号的计算过程如下,记录将要保存到的 num 个分区中的分区 N,假设 num 是 7 个分区,表 t1 使用线性 HASH 分区且有 4 个分区。
2) 第二条记录将要保存到的分区序号计算如下:
N 的值是 6,很显然 6≥4 成立,所以会继续执行:
线性哈希分区的优点在于增加﹑删除﹑合并和拆分分区更加快捷,有利于处理含有极大量(1000GB)数据的表。它的缺点在于,与使用常规 HASH 分区得到的数据分布相比,各个分区间数据的分布可能不大均衡。
HASH 分区主要用来确保数据在预先确定数目的分区中平均分布。在 RANGE 和 LIST 分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中;而在 HASH 分区中,MySQL 自动完成这些工作,用户所要做的只是基于将要被哈希的列值指定一个列值或表达式,以及指定被分区的表将要被分割成的分区数量。
【实例】创建 HASH 分区,命令如下:
mysql> create table htable( id int, name varchar(20), birthdate date not null, salary int ) partition by hash(year(birthdate)) partitions 4; Query OK, 0 rows affected (0.00 sec)当使用“partition by hash”时,MySQL 将基于用户函数结果的模数来确定使用哪个编号的分区。将要保存记录的分区编号为 N = MOD(表达式, num)。
例如,表 htable 中插入一条 birthdate 为“2010-09-23”的记录,可以通过如下方法计算该记录的分区:
mod(year(’2010-09-23’),4)=mode(2010,4) =2此时,该条记录的数据将会存储在分区编号为 2 的分区空间。
线性HASH分区
线性 HASH 分区和 HASH 分区的区别在于,线性哈希功能使用的是一个线性的 2 的幂运算法则,而 HASH 分区使用的是哈希函数的模数。先看下面的例子:
mysql> create table htable2( id int not null, name varchar(20), hired date not null default '1999-09-09', deptno int ) partition by linear hash(year(hired)) partitions 4; Query OK, 0 rows affected (0.03 sec)
如果表 htable2 中插入一条 hired 为“2010-09-23”的记录,记录将要保存到的分区是 num 个分区中的分区 N,可以通过如下方法计算 N:
1) 找到下一个大于 num 的 2 的幂次方数,把这个值称作 V,即 V = POWR(2,CEILING(LOG(2,num)))。假设,num 的值是 13,那么 LOG(2,13) 就是 3.70043,CEILING(3.70043) 就是 4,则 V = POWER(2,4)=16。
2) 计算 N = F(column_list) & (V – 1),当 N≥num 时,执行 V = CEIL(V/2),此时 N = N &(V−1)。
【实例】演示通过线性哈希分区算法计算分区 N 的值。线性哈希分区表 t1 通过下面的语句创建。
mysql> create table th1( col1 int, col2 char(5), col3 date ) partition by linear hash( year(col3) ) partitions 6; Query OK, 0 rows affected (0.59 sec)
现在假设要插入两条记录到表 th1 中,其中一条记录的 col3 列的值为“2003-04-14”,另一条记录的 cols 列值为“1998-10-19”。
1) 第一条记录要保存到的分区序号的计算过程如下,记录将要保存到的 num 个分区中的分区 N,假设 num 是 7 个分区,表 t1 使用线性 HASH 分区且有 4 个分区。
V = POWR(2,CEILING(LOG(2,num))) V = POWR(2,CEILING(LOG(2,7))) = 8 N = YEAR('2003-04-14') & (8 - 1) = 2003 & 7 = 3N 的值是 3,很显然 3≥4 不成立,所以附件条件不执行,第一条记录的信息将存储在 3 号分区中。
2) 第二条记录将要保存到的分区序号计算如下:
V = POWR(2,CEILING(LOG(2,num))) V = POWR(2,CEILING(LOG(2,7))) = 8 = YEAR('1998-10-19') & (8 - 1) = 1998 & 7 = 6
N 的值是 6,很显然 6≥4 成立,所以会继续执行:
V = CEIL(6/2) = 3 N = N & (V-1) = 6 & 2 = 2此时 2≥4 不成立,记录将被保存到 2 号分区中。
线性哈希分区的优点在于增加﹑删除﹑合并和拆分分区更加快捷,有利于处理含有极大量(1000GB)数据的表。它的缺点在于,与使用常规 HASH 分区得到的数据分布相比,各个分区间数据的分布可能不大均衡。