MOD_HASH算法
适用场景
适用于需要按用户ID或订单ID进行分库的场景。
使用说明
- 拆分键的数据类型必须是整数类型(INT, INTEGER, BIGINT, MEDIUMINT, SMALLINT, TINYINT, DECIMAL(支持精度为0的情况))或字符串类型(CHAR,VARCHAR)。
- 在SQL语句中对整数类型拆分键设置值时不要进行类型转换,类型转换可能造成路由计算失败后路由至默认分片,造成目标数据查询不到。
路由方式
根据拆分键的键值直接按分库数/分表数取余。如果键值是字符串,则字符串会被计算成哈希值再进行计算,完成路由计算(大小写敏感)。
例如:MOD_HASH('8')等价于8%D(D是分库数目/分表数)。
算法计算方式
方式一:拆分键是整型
条件 |
算法 |
举例 |
---|---|---|
分库拆分键 ≠ 分表拆分键 |
分库路由结果 = 分库拆分键值 % 分库数 分表路由结果 = 分表拆分键值 % 分表数 |
分库 :16 % 8 = 0 分表:16 % 3 = 1 |
分库拆分键 = 分表拆分键(拆分键) |
分表路由结果 = 拆分键值 % (分库数 * 分表数) 分库路由结果 = 分表路由结果 / 分表数
说明:
分库路由结果四舍五入到最接近的整数。 |
分表:16 % (8 * 3) = 16 分库 :16 / 3 = 5 |
方式二:拆分键是字符类型
条件 |
算法 |
举例 |
---|---|---|
分库拆分键 ≠ 分表拆分键 |
分库路由结果 = 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算法是简单取模,要求拆分列的值自身分布均衡才能保证哈希均衡。