MySQL - 分表架构-范围分片

1,450 阅读2分钟

配置分表之前请先自行安装 mycat 运行环境和 mysql 环境

mycat运行环境配置

演示环境介绍

    数据表:
        item_user
        item_user_1
        item_user_2
        item_user_3
    
    数据表结构:
        id                  bigint          20  
        user_name           varchar         255
        user_localhost      varchat         255
        user_password       varchat         255
        user_auto           varchat         255

配置步骤

    (1): 修改server.xml[/usr/local/mycat/conf/server.xml]
    
        # 将Sequnce模式切换到2 
            <!-- 
                0 = 从本地文件读取ID, 
                1 = 从数据表读取ID, 
                2 = 使用时间戳 [ID= 64 位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重复累加)]
            -->
        '<property name="sequnceHandlerType">1</property>'
        
        
        # 添加访问用户 (如已配置过登录用户则可以跳过此步骤)
        <! --
            user 标签解释
                name = 后端服务器访问账号
                passsword = 后端服务器访问密码
                schemas = 需要调用的配置实例
        -->
        <user name="root" defaultAccount="true">
                <property name="password">123456</property>
                <property name="schemas">sqlcat</property>
        </user>
    
    (2):修改逻辑节点规则[/usr/local/mycat/conf/schema.xml]
        <?xml version="1.0"?>
        <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
        <mycat:schema xmlns:mycat="http://io.mycat/">

                <schema name="sql" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
                    #   在name值为sqlcat的schema标签内添加内容
                    #   primaryKey = 用来做分配的字段,可自定义
                    <table name="item_user" primaryKey="id" autoIncrement="true" subTables="item_user_$1-3" dataNode="dn1" rule="mod-long" />
                </schema>
                <dataNode name="dn1" dataHost="localhost1" database="sql" />
                <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                        <heartbeat>select user()</heartbeat>
                        <writeHost host="hostM1" url="localhost:3306" user="root" password="root"></writeHost>
                </dataHost>
        </mycat:schema>
        
    (3):使用mysql账户创建主键计步表
        
        DROP TABLE IF EXISTS MYCAT_SEQUENCE;  
        CREATE TABLE MYCAT_SEQUENCE (  
        NAME VARCHAR (50) NOT NULL COMMENT '分片表名',  
        current_value INT NOT NULL COMMENT '当前自增id数',  
        increment INT NOT NULL DEFAULT 100 NULL COMMENT '自增步长数',  
        PRIMARY KEY (NAME)  
        ) ENGINE = INNODB ;  

        INSERT INTO MYCAT_SEQUENCE(NAME,current_value,increment) VALUES ('TEST_CENSUS', 1, 1);  
      
        DROP FUNCTION IF EXISTS `mycat_seq_currval`;  
        DELIMITER ;;  
        CREATE FUNCTION `mycat_seq_currval`(seq_name VARCHAR(50))   
        RETURNS VARCHAR(64) CHARSET utf8  
            DETERMINISTIC  
        BEGIN DECLARE retval VARCHAR(64);  
                SET retval="-999999999,null";    
                SELECT CONCAT(CAST(current_value AS CHAR),",",CAST(increment AS CHAR) ) INTO retval   
                  FROM MYCAT_SEQUENCE WHERE NAME = seq_name;    
                RETURN retval ;   
        END  
        ;;  
        DELIMITER ;  

        DROP FUNCTION IF EXISTS `mycat_seq_nextval`;  
        DELIMITER ;;  
        CREATE FUNCTION `mycat_seq_nextval`(seq_name VARCHAR(50)) RETURNS VARCHAR(64)  
         CHARSET utf8  
            DETERMINISTIC  
        BEGIN UPDATE MYCAT_SEQUENCE    
                         SET current_value = current_value + increment   
                          WHERE NAME = seq_name;    
                 RETURN mycat_seq_currval(seq_name);    
        END  
        ;;  
        DELIMITER ;  

        DROP FUNCTION IF EXISTS `mycat_seq_setval`;  
        DELIMITER ;;  
        CREATE FUNCTION `mycat_seq_setval`(seq_name VARCHAR(50), VALUE INTEGER)   
        RETURNS VARCHAR(64) CHARSET utf8  
            DETERMINISTIC  
        BEGIN UPDATE MYCAT_SEQUENCE    
                           SET current_value = VALUE    
                           WHERE NAME = seq_name;    
                 RETURN mycat_seq_currval(seq_name);    
        END  
        ;;  
        DELIMITER ; 
   
    (4):设置子表数量[/usr/local/mycat/conf/rule.conf]
        <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
            <!-- 子表总数 -->
            <property name="count">3</property> 
        </function>5):修改mycat计步规则[/usr/local/mycat/conf/sequence_db_conf.properties]
       
        # 在底部添加内容,重启mycat即可测试
        ITEM_USER=dn1
   
    (6):重启mycat,程序读写数据测试
    
        # 写入测试
        'insert into item_user (user_name, user_localhost, user_password, user_auto) values ('1260127359848288257', 1589272749.158313, 1589272749.158313, 1589272749.158313, 1589272749.158313);'
        
        # 读取测试
        'select * from item_user where id = xxxx;'

注意:

(1):后续如果其他表需要进行分片需更改如下操作

 [server.xml -> schema标签下新增一个table标签]
 [MYCAT_SEQUENCE表内新增一条数据,分片表名称,当前自增主键值,步长]
 [sequence_db_conf.properties文件底部新增分片表名称]

(2):分片后的数据表在使用新增语句使用需参照如下规则

错误示例
    
    insert into xxx values (xxx,  xxx)
    
正确示例 
    
    insert into xxx (key, key) values (val, val)

(3):使用mysql自带的某些函数会报错[java.lang.NullPointerException]

    # 目前已知的有
    substr