更新时间:2024-10-18 GMT+08:00
分享

MOD_HASH算法

适用场景

适用于需要按用户ID或订单ID进行分库的场景。

使用说明

  • 拆分键的数据类型必须是整数类型(INT, INTEGER, BIGINT, MEDIUMINT, SMALLINT, TINYINT, DECIMAL(支持精度为0的情况))或字符串类型(CHAR,VARCHAR)。
  • 在SQL语句中对整数类型拆分键设置值时不要进行类型转换,类型转换可能造成路由计算失败后路由至默认分片,造成目标数据查询不到。

路由方式

根据拆分键的键值直接按分库数/分表数取余。如果键值是字符串,则字符串会被计算成哈希值再进行计算,完成路由计算(大小写敏感)。

例如:MOD_HASH('8')等价于8%D(D是分库数目/分表数)。

算法计算方式

方式一:拆分键是整型

表1 拆分键是整型时的计算方式

条件

算法

举例

分库拆分键 ≠ 分表拆分键

分库路由结果 = 分库拆分键值 % 分库数

分表路由结果 = 分表拆分键值 % 分表数

分库 :16 % 8 = 0

分表:16 % 3 = 1

分库拆分键 = 分表拆分键(拆分键)

分表路由结果 = 拆分键值 % (分库数 * 分表数)

分库路由结果 = 分表路由结果 / 分表数

说明:

分库路由结果四舍五入到最接近的整数。

分表:16 % (8 * 3) = 16

分库 :16 / 3 = 5

方式二:拆分键是字符类型

表2 拆分键是字符型时的计算方式

条件

算法

举例

分库拆分键 ≠ 分表拆分键

分库路由结果 = hash(分库拆分键值) % 分库数

分表路由结果 = hash(分表拆分键值) % 分表数

hash(‘abc’)=‘abc’.hashCode()=96354

分库 :96354 % 8 = 2;

分表 :96354 % 3 = 0;

分库拆分键 = 分表拆分键(拆分键)

分表路由结果 = hash(拆分键值) % (分库数 * 分表数)

分库路由结果 =分表路由结果 / 分表数

说明:

分库路由结果四舍五入到最接近的整数。

hash(‘abc’)=‘abc’.hashCode()=96354

分表 :96354% (8 * 3) = 18

分库 :18 / 3=6

建表语法

  • 如果用户需要对ID列按MOD_HASH函数进行分库不分表:
    create table mod_hash_tb(
    	id int,
    	name varchar(30) DEFAULT NULL,
    	create_time datetime DEFAULT NULL,
    	primary key(id)
    ) ENGINE = InnoDB DEFAULT CHARSET = utf8 dbpartition by mod_hash(ID);
  • 如果用户需要对ID列按MOD_HASH函数进行既分库又分表:
    create table mod_hash_tb(
    	id int,
    	name varchar(30) DEFAULT NULL,
    	create_time datetime DEFAULT NULL,
    	primary key(id)
    ) ENGINE = InnoDB DEFAULT CHARSET = utf8
    dbpartition by mod_hash(ID) tbpartition by mod_hash(ID) tbpartitions 4;

注意事项

MOD_HASH算法是简单取模,要求拆分列的值自身分布均衡才能保证哈希均衡。

相关文档