[数据分片]分片算法简介
    Mycat2支持常用的(自动)HASH型分片算法也兼容1.6的内置的(cobar)分片算法.

    HASH型分片算法默认要求集群名字以c为前缀,数字为后缀,c0就是分片表第一个节点,c1就是第二个节点.该命名规则允许用户手动改变.

    以下阐述区别
    Mycat2 Hash型分片算法多数基于MOD_HASH(MOD对应JAVA的%运算,
    实际上是取余运算,而且
    abs(n)/count等价于abs(n/count)
    其中n是有符号long,有最大值,mycat hash型算法总是对最后的值取绝对值,所以不会有负数
    Mycat2 Hash型分片算法对于值的处理,总是把分片值转换到列属性的数据类型再运算,而1.x系列的分片算法统一转换到字符串类型再运算且只能根据一个分片字段计算出存储节点下标。
    Mycat2 Hash型分片算法适用于等价条件查询,而1.x系列由于含有用户经验的路由规则。1.x系列的分片规则总是先转换成字符串再运算。

    需要使用between,<=,>=进行分区剪裁,使用规则分片,1.21已结支持对hash的between进行分区剪裁

    1. 自动hash对于字符串类型的分片键会使用以下算法先进行hash再处理
    2. public static int hashCode(String value) {
    3. if (value == null) value = "null";
    4. return hashCode(value, 31);
    5. }
    6. public static int hashCode(String value, int randSeed) {
    7. int h = 0;
    8. for (int i = 0; i < value.length(); i++) {
    9. h = randSeed * h + value.charAt(i);
    10. }
    11. return h;
    12. }

    STR_HASH可以指定randSeed

    分片算法 描述 分库 分表 数值类型
    MOD_HASH 取模哈希 数值,字符串
    UNI_HASH 取模哈希 数值,字符串
    RIGHT_SHIFT 右移哈希 数值
    RANGE_HASH 两字段其一取模 数值,字符串
    YYYYMM 按年月哈希 DATE,DATETIME
    YYYYDD 按年月哈希 DATE,DATETIME
    YYYYWEEK 按年周哈希 DATE,DATETIME
    HASH 取模哈希 数值,字符串,如果不是,则转换成字符串
    MM 按月哈希 DATE,DATETIME
    DD 按日期哈希 DATE,DATETIME
    MMDD 按月日哈希 DATE,DATETIME
    WEEK 按周哈希 DATE,DATETIME
    STR_HASH 字符串哈希 字符串

    所有分片算法都可以用于分表,但是涉及单独按周,月的HASH算法不能用于分库

    1. /*+ mycat:createTable{
    2. "schemaName":"db1",
    3. "shadingTable":{
    4. "createTableSQL":"create table travelrecord(id int)",
    5. "function":{
    6. "properties":{
    7. "dbNum":2,
    8. "mappingFormat":"c${targetIndex}/db1_${dbIndex}/travelrecord_${tableIndex}",
    9. "tableNum":2,
    10. "tableMethod":"mod_hash(id)",
    11. "storeNum":2,
    12. "dbMethod":"mod_hash(id)"
    13. }
    14. }
    15. },
    16. "tableName":"travelrecord"
    17. } */;

    mappingFormat使用样例(文件配置)

    1. "shardingTables":{
    2. "log":{
    3. "createTableSQL":"CREATE TABLE cloud.log (\n\t`id` BIGINT(20) DEFAULT NULL,\n\t`user_id` BIGINT(20) DEFAULT NULL,\n\t`service_id` INT(11) DEFAULT NULL,\n\t`submit_time` DATETIME DEFAULT NULL\n) ENGINE = INNODB CHARSET = utf8\nDBPARTITION BY YYYYDD(submit_time) DBPARTITIONS 2\nTBPARTITION BY MOD_HASH(id) TBPARTITIONS 8",
    4. "function":{
    5. "properties":{
    6. "dbNum":"2",
    7. "mappingFormat":"c${targetIndex}/cloud_${java.time.LocalDate.now().plus(dbIndex.toInteger()).toString().replace(\"-\",\"\")}/log_${tableIndex}",
    8. "tableNum":"8",
    9. "tableMethod":"MOD_HASH(id)",
    10. "storeNum":2,
    11. "dbMethod":"YYYYDD(submit_time)"
    12. }
    13. }
    14. }
    15. }

    image.png
    targetIndex是目标下标
    tableIndex是物理分表下标
    dbIndex是物理分库下标
    index是总物理分表下标

    完全自定义分区

    1. /*+ mycat:createTable{
    2. "schemaName":"db1",
    3. "shadingTable":{
    4. "createTableSQL":"create table travelrecord(id int)",
    5. "function":{
    6. "properties":{
    7. "dbNum":2,
    8. "mappingFormat":"c${targetIndex}/db1_${dbIndex}/travelrecord_${tableIndex}",
    9. "tableNum":2,
    10. "tableMethod":"mod_hash(id)",
    11. "storeNum":2,
    12. "dbMethod":"mod_hash(id)"
    13. }
    14. },
    15. "partition":{
    16. "data":[["c0","db1","t2","0","0","0"],["c1","db1","t2","1","1","1"]] }
    17. },
    18. "tableName":"sharding"
    19. } */;
    20. data内填写分区信息