更新时间:2023-07-25 GMT+08:00

MOD_HASH_CI算法

适用场景

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

使用说明

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

路由方式

实现原理同MOD_HASH算法一致,区别在于MOD_HASH_CI算法对大小写不敏感,而MOD_HASH算法对大小写敏感。

算法计算方式

方式一:拆分键是整型

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

条件

算法

举例

分库拆分键 ≠ 分表拆分键

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

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

分库 :16 % 8 = 0

分表:16 % 3 = 1

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

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

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

说明:

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

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

分库 :16 / 3 = 5

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

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

条件

算法

举例

分库拆分键 ≠ 分表拆分键

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

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

hash(‘abc’)=‘abc’.toUpperCase().hashCode()=64578

分库 :64578 % 8 = 2;

分表 :64578 % 3 = 0;

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

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

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

说明:

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

hash(‘abc’)=‘abc’.toUpperCase().hashCode()=64578

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

分库 :18 / 3=6

建表语法

  • 如果用户需要对ID列按MOD_HASH_CI函数进行分库不分表:
    create table mod_hash_ci_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_ci(ID);
  • 如果用户需要对ID列按MOD_HASH_CI函数进行既分库又分表:
    create table mod_hash_ci_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_ci(ID)
    tbpartition by mod_hash_ci(ID) tbpartitions 4;

注意事项

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