UNI_HASH算法
适用场景
适用于需要按用户ID或订单ID进行分库的场景。
使用说明
拆分键的数据类型必须是整数类型(INT, INTEGER, BIGINT, MEDIUMINT, SMALLINT, TINYINT, DECIMAL, NUMERIC)或字符串类型。
路由方式
根据分库键的键值按分库/表数取余。如果键值是字符串,则字符串会被计算成哈希值再对分库/表数取余。
例如,UNI_HASH('6')等价于6 % D(D是分库数目)。
算法计算方式
方式一:拆分键是整型
条件 |
计算方式 |
举例 |
---|---|---|
分库拆分键 ≠ 分表拆分键 |
分库路由结果 = 分库拆分键值 % 分库数 分表路由结果 = 分表拆分键值 % 分表数 |
分库 :16 % 8 = 0 分表:16 % 3 = 1 |
分库拆分键 = 分表拆分键 |
分库路由结果 = 拆分键值 % 分库数 分表路由结果 = (拆分键值%分库数)*分表数+(拆分键值 /分库数)%分表数 |
分库 :16 % 8 = 0 分表:(16 % 8) *3 + (16/8)%3 = 2 |
方式二:拆分键是字符类型
条件 |
计算方式 |
举例 |
---|---|---|
分库拆分键 ≠ 分表拆分键 |
分库路由结果 = hash(分库拆分键值) % 分库数 分表路由结果 = hash(分表拆分键值) % 分表数 |
hash(‘abc’)=‘abc’.hashCode()=96354 分库 :96354 % 8 = 2; 分表 :96354 % 3 = 0; |
分库拆分键 = 分表拆分键 |
分库路由结果 = hash(拆分键值) % 分库数 分表路由结果 = (hash(拆分键值) %分库数)*分表数+( hash(拆分键值) /分库数)%分表数 |
分库 :96354% 8 = 2 分表 :( 96354 % 8) *3 + (96354/8)%3 = 8 |
建表语法
create table uni_hash_tb( id int, name varchar(30) DEFAULT NULL, create_time datetime DEFAULT NULL, primary key(id) )ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by UNI_HASH(ID) tbpartition by UNI_HASH(name) tbpartitions 3;
注意事项
- 拆分键和键值皆不能修改。
- UNI_HASH算法是简单取模,要求拆分列的值自身分布均衡才能保证哈希均衡。
与MOD_HASH的比较
- 在使用 UNI_HASH 分库但不分表时,UNI_HASH 和 MOD_HASH 的路由方式一样,都是根据分库键的键值按分库数取余。
- 分库和分表都使用同一个拆分键进行 MOD_HASH 时,随着分表数的变化,同一个键值分到的分库不是固定的。
- 分库和分表都使用同一个拆分键进行 UNI_HASH 时,无论分表数是多少,同一个键值总是分到相同的分库。
- 如果两张逻辑表需要根据同一个拆分键进行分库分表,但分表数不同,那么当两张表按该拆分键进行 JOIN 时,如果使用 MOD_HASH 会出现跨库 JOIN,而 UNI_HASH 不会有跨库 JOIN。