MyCat 子表 | Eddie'Blog
MyCat 子表

MyCat 子表

eddie 498 2020-11-05

目录

前言

概念 :比如说用户表或者订单表,通常这些表都会有一张主体表,用户表有用户id、姓名、手机号等等,而订单表也会有订单的id,金额、状态、收货人姓名、收货人手机号、收货人地址、创建时间等等,都是和订单主体相关的。
子表 :通常就是我们说的,order_item 表里面通常都会有购买商品的id、商品的名称、商品购买人的金额,存放类似这样的信息。
场景 :订单表是按订单的id去进行水平切分的,订单对id进行取模,0分配到第一个数据库、1分配到第二个数据库,那么现在我要插入订单明细表,那么需要按照什么方式进行水平切分呢?

子表

一、schema.xml配置

  • childTable标签,定义分片子表
  • name属性,子表名称
  • joinKey属性,标记子表中的列, 用于与父表做关联
  • parentKey标签, 标记父表中的列, 与joinKey对应
  • primaryKey属性,子表主键,同table标签
  • needAddLimit属性,同table标签

schema.xml

[root@localhost bin]# cat /opt/mycat/conf/schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="user" checkSQLschema="true" sqlMaxLimit="100">
                <!-- auto sharding by id (long) -->
                <table name="user" dataNode="dn246,dn247" rule="mod-long" />
                <table name="province" dataNode="dn246,dn247" type="global"/>

                <!-- 子表 start  -->
                <table name="o_order" dataNode="dn246,dn247" rule="auto-sharding-long" >
                   <!-- 
                        表名: order_item 
                        用于子表关联的id: order_id
                        父表中的主键key: id
                    -->
                   <childTable name="order_item" joinKey="order_id" parentKey="id"/>
                </table>
		<!-- 子表 end -->

                <!-- <table name="oc_call" primaryKey="ID" dataNode="dn1$0-743" rule="latest-month-calldate"
                        /> -->
        </schema>
        <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
                /> -->
        <dataNode name="dn246" dataHost="db246" database="user_246" />
        <dataNode name="dn247" dataHost="db247" database="user_247" />
        <!-- <dataNode name="dn3" dataHost="localhost1" database="db3" />  -->

        <!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" />
         <dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" />
        <dataNode       name="jdbc_dn2" dataHost="jdbchost" database="db2" />
        <dataNode name="jdbc_dn3"       dataHost="jdbchost" database="db3" /> -->

        <dataHost name="db246" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="M1" url="192.168.8.246:3306" user="eddie" password="Abc@123456">
                        <readHost host="S1" url="192.168.8.245:3306" user="eddie" password="Abc@123456" /> 
                </writeHost>

                <!-- <writeHost host="M2" url="192.168.8.245:3306" user="eddie" password="Abc@123456"/> -->

                <!-- <writeHost host="hostS1" url="localhost:3316" user="root"
                                   password="123456" /> -->

                <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
        </dataHost>

        <dataHost name="db247" maxCon="1000" minCon="10" balance="0"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="M1" url="192.168.8.247:3306" user="eddie"
                                   password="Abc@123456">
                        <!-- can have multi read hosts -->
                        <!-- <readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" /> -->
                </writeHost>
                <!-- <writeHost host="hostS1" url="192.168.8.247:3316" user="root"
                                                        password="123456" /> -->

                <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> -->
        </dataHost>


        <!--
                <dataHost name="sequoiadb1" maxCon="1000" minCon="1" balance="0" dbType="sequoiadb" dbDriver="jdbc">
                <heartbeat>             </heartbeat>
                 <writeHost host="hostM1" url="sequoiadb://1426587161.dbaas.sequoialab.net:11920/SAMPLE" user="jifeng"  password="jifeng"></writeHost>
                 </dataHost>

          <dataHost name="oracle1" maxCon="1000" minCon="1" balance="0" writeType="0"   dbType="oracle" dbDriver="jdbc"> <heartbeat>select 1 from dual</heartbeat>
                <connectionInitSql>alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'</connectionInitSql>
                <writeHost host="hostM1" url="jdbc:oracle:thin:@127.0.0.1:1521:nange" user="base"       password="123456" > </writeHost> </dataHost>

                <dataHost name="jdbchost" maxCon="1000"         minCon="1" balance="0" writeType="0" dbType="mongodb" dbDriver="jdbc">
                <heartbeat>select       user()</heartbeat>
                <writeHost host="hostM" url="mongodb://192.168.0.99/test" user="admin" password="123456" ></writeHost> </dataHost>

                <dataHost name="sparksql" maxCon="1000" minCon="1" balance="0" dbType="spark" dbDriver="jdbc">
                <heartbeat> </heartbeat>
                 <writeHost host="hostM1" url="jdbc:hive2://feng01:10000" user="jifeng"         password="jifeng"></writeHost> </dataHost> -->

        <!-- <dataHost name="jdbchost" maxCon="1000" minCon="10" balance="0" dbType="mysql"
                dbDriver="jdbc"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1"
                url="jdbc:mysql://localhost:3306" user="root" password="123456"> </writeHost>
                </dataHost> -->
</mycat:schema>

返回 rule.xml 确认,分片键是否 id

<tableRule name="auto-sharding-long">
        <rule>
            <!-- 分片列:按照这个列分片 -->
            <columns>id</columns>
            <algorithm>rang-long</algorithm>
        </rule>
</tableRule>

进入 ip:9066 reload 配置

mysql> reload @@config_all;
Query OK, 1 row affected (0.24 sec)
Reload config success

二、创建测试表

分别在 192.168.8.246 和 192.168.8.247 运行DDL语句

CREATE TABLE `o_order` (
  `id` int NOT NULL,
  `total_amount` decimal(10,2) NOT NULL,
  `order_status` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;


CREATE TABLE `order_item` (
  `id` int NOT NULL,
  `order_id` int NOT NULL,
  `product_name` varchar(255) DEFAULT NULL,
  `num` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

MyCat:8066 插入测试数据

-- o_order 插入与查询语句
INSERT INTO `user`.`o_order`(`id`, `total_amount`, `order_status`) VALUES (1, 10, 1)
SELECT * FROM `user`.`o_order` WHERE `id` = 1 AND `total_amount` = 10 AND `order_status` = 1 LIMIT 1

-- order_item 插入与查询语句:order_id需要和o_order.id一致
INSERT INTO `user`.`order_item`(`id`, `order_id`, `product_name`, `num`) VALUES (1, 1, '测试商品', 1)
SELECT * FROM `user`.`order_item` WHERE `id` = 1 AND `order_id` = 1 AND `product_name` = '测试商品' AND `num` = 1 LIMIT 1

autopartition-long.txt 规则条件 0-500M=0,所以数据也会同步到 192.168.8.246

继续在 MyCat:8066 插入测试数据 order_id = 6000000

INSERT INTO `user`.`order_item`(`id`, `order_id`, `product_name`, `num`) VALUES (2, 6000000, '测试商品2', 2)
SELECT * FROM `user`.`order_item` WHERE `id` = 2 AND `order_id` = 6000000 AND `product_name` = '测试商品2' AND `num` = 2 LIMIT 1

autopartition-long.txt 规则条件 500M-1000M=1,所以数据也会同步到 192.168.8.247