
# 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算法是简单取模，要求拆分列的值自身分布均衡才能保证哈希均衡。
