mycat 取模分片,ER分片

1、业务场景:用户购物下单。

要求:把订单分片,商家要查询购买在订单,用户要查询自己的订单。

表设计:用户,商家订单,订单明细,买方订单

分片规则:

“用户表”---user_id 取模,“商家订单”----seller_user_id 取模

“订单明细”----“商家订单”ER 分片,“买家订单”----buyer_user_id 取模

2、表
CREATE TABLE tb_user (
login_name VARCHAR (32) comment '登录名',
user_id BIGINT comment '用户标识',
TYPE INT comment '用户类型 1 商家,2买家',
passwd VARCHAR (128) comment '密码',
primary key (user_id)
) ;
alter table tb_user comment '用户表';

CREATE TABLE tb_seller_order (
seller_user_id BIGINT comment '商家标识',
buyer_user_id BIGINT comment '用户标识',
order_id BIGINT comment '订单标识',
price BIGINT comment '价格',
STATUS INT comment '状态',
primary key (order_id)
);
alter table tb_seller_order comment '商家订单表';

CREATE TABLE tb_order_detail(
  seller_user_id BIGINT comment '商家标识',
  order_detail_id BIGINT comment '订单明细标识',
  order_id BIGINT comment '订单标识',
  goods_id BIGINT comment '标识',
  goods_name VARCHAR(32) comment '商品名称',
  cnt INT comment '数量',
  unit_price INT comment '单价',
  primary key (order_detail_id)
);
alter table tb_order_detail comment '订单明细';

CREATE TABLE tb_buyer_order (
  buyer_user_id BIGINT comment '用户标识',
  seller_user_id BIGINT comment '商家标识',
  order_id BIGINT comment '订单标识',
  price BIGINT comment '价格',
  STATUS INT comment '状态',
  primary key (order_id)
);
alter table tb_buyer_order comment '买家订单';

3、服务器分配:

mysql:
主 192.168.109.128    备192.168.109.130
主     192.168.109.131
主     192.168.109.132

mycat:

192.168.109.129


4、表主键生成策略使用mycat全局序列生成(mycat 全局序列号:http://blog.csdn.net/convict_eva/article/details/51917499)

添加mycat全局序列号:

USER_ID_SQUE=dn_master
ORDER_ID_SQUE=dn_master
DETAIL_ID_SQUE=dn_master
在dn_master结点执行:
insert into MYCAT_SEQUENCE(NAME,current_value,increment) 
values('USER_ID_SQUE',1,100),('ORDER_ID_SQUE',1,100),('DETAIL_ID_SQUE',1,100);

重启mycat测试:
SELECT NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE;
SELECT NEXT VALUE FOR MYCATSEQ_ORDER_ID_SQUE;
SELECT NEXT VALUE FOR MYCATSEQ_DETAIL_ID_SQUE;
5、配置分片规则
在mycat conf 目录下的rule.xml 是分片规则的配置文件。
5.1 配置function 标签,找到function 标签name="mod-long" 的function 配置,修改总结点数为3(和使用的mysql 结点数一致)。
    <function name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
        <!-- how many data nodes -->
        <property name="count">3</property>
    </function>

5.2 配置表分片(name 要全局唯一),rule.xml 配置添加如下配置

        <!-- user分片规则 -->
        <tableRule name="tb_user_mod-long">

                <rule>

                        <!--  分片使用的字段  -->

                        <columns>user_id</columns>

                        <!--  分片使用的方法,对应function 名称  -->

                        <algorithm>mod-long</algorithm>
                </rule>
         </tableRule>


        <!-- 卖家订单分片规则 -->
        <tableRule name="seller_order_mod-long">
                <rule>
                        <columns>seller_user_id</columns>
                        <algorithm>mod-long</algorithm>
                </rule>
        </tableRule>


        <!-- 买家订单分片规则 -->
        <tableRule name="buyer_order_mod-long">
                <rule>
                        <columns>buyer_user_id</columns>
                        <algorithm>mod-long</algorithm>
                </rule>
        </tableRule>

6 schema.xml 配置


<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" >
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
                <!-- auto sharding by id (long) -->
                <table name="tb_a" dataNode="dn_master"/>
                <!-- 全局表,使用type属性指定,多个结点要都执行建表语句。所有结点的数据一致。  -->
                <table name="tb_global_test" dataNode="dn_master,dn_master2,dn_master3" type="global" />

                <!-- 配置表所在的分片结点,指定主键和分片规则。指定主键是为了使用主键查询时mycat什么缓存主键对应的dn,提高查询效率。-->
                <table name="tb_user" rule="tb_user_mod-long" primaryKey="user_id" dataNode="dn_master,dn_master2,dn_master3" />

                <table name="tb_seller_order" rule="seller_order_mod-long" primaryKey="order_id" dataNode="dn_master,dn_master2,dn_master3" >
   <!-- 配置ER 分片,子表的存储依赖于主表,并且物理上紧邻存放。 -->
                    <childTable name="tb_order_detail" primaryKey="order_detail_id" joinKey="order_id" parentKey="order_id" />
                </table>

                <table name="tb_buyer_order" rule="buyer_order_mod-long" primaryKey="order_id" dataNode="dn_master,dn_master2,dn_master3" />
        </schema>

<!-- 配置数据结点 -->
        <dataNode name="dn_master" dataHost="master" database="test_db" />
        <dataNode name="dn_master2" dataHost="master2" database="test_db" />
        <dataNode name="dn_master3" dataHost="master3" database="test_db" />

<!-- ddata node host 配置 -->

        <dataHost name="master" maxCon="1000" minCon="10" balance="3"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
<!-- 主从心跳语句配置 -->
                <heartbeat>show slave status</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="192.168.109.128:3306" user="root" password="Abc123!@#">
                        <!-- 从库 -->
                         <readHost host="hostS2" url="192.168.109.130:3306" user="root" password="Abc123!@#" />
                </writeHost>
        </dataHost>

        <dataHost name="master2" maxCon="1000" minCon="10" balance="0"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM2" url="192.168.109.131:3306" user="root" password="Abc123!@#"></writeHost>
        </dataHost>

        <dataHost name="master3" maxCon="1000" minCon="10" balance="0"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <writeHost host="hostM3" url="192.168.109.132:3306" user="root" password="Abc123!@#"></writeHost>
        </dataHost>

</mycat:schema>


重启mycat,使用SQLyog连接到mycat,并执行建表语句。


7、测试

7.1、插入user 
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-1',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-2',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-3',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-4',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-5',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-6',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-7',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-8',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-9',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-10',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-11',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-12',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-13',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-14',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-15',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-16',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-17',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-18',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-19',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-20',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-21',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-22',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('name-23',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,1,'passwd-A');




109.128数据为:
mysql> select * from tb_user;
+------------+---------+------+----------------------+
| login_name | user_id  | TYPE | passwd   |
+------------+---------+------+----------------------+
| name-1      |     225    |    1 | passwd-A |
| name-4      |     228    |    1 | passwd-A |
| name-7      |     231    |    1 | passwd-A |
| name-10    |     234    |    1 | passwd-A |
| name-13    |     237    |    1 | passwd-A |
| name-16    |     240    |    1 | passwd-A |
| name-19    |     243    |    1 | passwd-A |
| name-22    |     246    |    1 | passwd-A |
+------------+---------+------+----------+
8 rows in set (0.00 sec)


109.131数据为:
mysql> select * from tb_user;
+------------+---------+------+----------+
| login_name | user_id | TYPE | passwd   |
+------------+---------+------+----------+
| name-2     |     226 |    1 | passwd-A |
| name-5     |     229 |    1 | passwd-A |
| name-8     |     232 |    1 | passwd-A |
| name-11    |     235 |    1 | passwd-A |
| name-14    |     238 |    1 | passwd-A |
| name-17    |     241 |    1 | passwd-A |
| name-20    |     244 |    1 | passwd-A |
| name-23    |     247 |    1 | passwd-A |
+------------+---------+------+----------+
8 rows in set (0.00 sec)


109.132 数据为:
mysql> select * from tb_user;
+------------+---------+------+----------+
| login_name | user_id | TYPE | passwd   |
+------------+---------+------+----------+
| name-3     |     227 |    1 | passwd-A |
| name-6     |     230 |    1 | passwd-A |
| name-9     |     233 |    1 | passwd-A |
| name-12    |     236 |    1 | passwd-A |
| name-15    |     239 |    1 | passwd-A |
| name-18    |     242 |    1 | passwd-A |
| name-21    |     245 |    1 | passwd-A |
+------------+---------+------+----------+
7 rows in set (0.00 sec)


通过数据的id取模,取模为0的在109.128 机器,取模为1的在109.131机器,取模为2的在109.132机器。




7.2 下单测试
上面创建的是商家用户,下面创建买家用户。
INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('buyer-1',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,2,'passwd-A');


INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('buyer-2',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,2,'passwd-A');


INSERT INTO `tb_user`(`login_name`,`user_id`,`TYPE`,`passwd`)
VALUES ('buyer-3',NEXT VALUE FOR MYCATSEQ_USER_ID_SQUE,2,'passwd-A');


所有的用户如下:
mysql> select * from tb_user order by login_name;
+------------+---------+------+----------+
| login_name | user_id | TYPE | passwd   |
+------------+---------+------+----------+
| buyer-1    |     248 |    2 | passwd-A |
| buyer-2    |     249 |    2 | passwd-A |
| buyer-3    |     250 |    2 | passwd-A |
| name-1     |     225 |    1 | passwd-A |
| name-10    |     234 |    1 | passwd-A |
| name-11    |     235 |    1 | passwd-A |
| name-12    |     236 |    1 | passwd-A |
| name-13    |     237 |    1 | passwd-A |
| name-14    |     238 |    1 | passwd-A |
| name-15    |     239 |    1 | passwd-A |
| name-16    |     240 |    1 | passwd-A |
| name-17    |     241 |    1 | passwd-A |
| name-18    |     242 |    1 | passwd-A |
| name-19    |     243 |    1 | passwd-A |
| name-2     |     226 |    1 | passwd-A |
| name-20    |     244 |    1 | passwd-A |
| name-21    |     245 |    1 | passwd-A |
| name-22    |     246 |    1 | passwd-A |
| name-23    |     247 |    1 | passwd-A |
| name-3     |     227 |    1 | passwd-A |
| name-4     |     228 |    1 | passwd-A |
| name-5     |     229 |    1 | passwd-A |
| name-6     |     230 |    1 | passwd-A |
| name-7     |     231 |    1 | passwd-A |
| name-8     |     232 |    1 | passwd-A |
| name-9     |     233 |    1 | passwd-A |
+------------+---------+------+----------+


下单:


SELECT NEXT VALUE FOR MYCATSEQ_ORDER_ID_SQUE;




INSERT INTO `tb_seller_order`(`seller_user_id`,`buyer_user_id`,`order_id`,`price`)
VALUES (225,248,201,1222);


INSERT INTO `tb_order_detail`
(`seller_user_id`,`order_detail_id`,`order_id`,`goods_id`,`goods_name`,`cnt`,`unit_price`)
VALUES (225, NEXT VALUE FOR MYCATSEQ_DETAIL_ID_SQUE,201,11,'goods_name',1,1220);
INSERT INTO `tb_order_detail`
(`seller_user_id`,`order_detail_id`,`order_id`,`goods_id`,`goods_name`,`cnt`,`unit_price`)
VALUES (225, NEXT VALUE FOR MYCATSEQ_DETAIL_ID_SQUE,201,11,'goods_name2',1,2);




说明:商家225 在109.128 上,tb_seller_order表根据seller_user_id 取模分片,所有此订单数据存储在与user id为225 的商家同一分片
tb_order_detail 表使用的是与tb_seller_order ER 分片,使用order_id 关联,所以tb_order_detail 存储的分片与相同的order_id 的tb_seller_order 的数据在同一分片。


再测试一条数据:user_id为238 的用户存储在109.131 分片上。


INSERT INTO `tb_seller_order`(`seller_user_id`,`buyer_user_id`,`order_id`,`price`)
VALUES (238,248,203,1222);


INSERT INTO `tb_order_detail`
(`seller_user_id`,`order_detail_id`,`order_id`,`goods_id`,`goods_name`,`cnt`,`unit_price`)
VALUES (238, NEXT VALUE FOR MYCATSEQ_DETAIL_ID_SQUE,203,11,'goods_name',1,1220);
INSERT INTO `tb_order_detail`
(`seller_user_id`,`order_detail_id`,`order_id`,`goods_id`,`goods_name`,`cnt`,`unit_price`)
VALUES (238, NEXT VALUE FOR MYCATSEQ_DETAIL_ID_SQUE,203,11,'goods_name2',1,2);


测试结果:
109.128数据为:
mysql> select * from tb_user;
+------------+---------+------+----------+
| login_name | user_id | TYPE | passwd   |
+------------+---------+------+----------+
| name-1     |     225 |    1 | passwd-A |
| name-4     |     228 |    1 | passwd-A |
| name-7     |     231 |    1 | passwd-A |
| name-10    |     234 |    1 | passwd-A |
| name-13    |     237 |    1 | passwd-A |
| name-16    |     240 |    1 | passwd-A |
| name-19    |     243 |    1 | passwd-A |
| name-22    |     246 |    1 | passwd-A |
| buyer-2    |     249 |    2 | passwd-A |
+------------+---------+------+----------+
9 rows in set (0.00 sec)


mysql> select * from tb_seller_order;
+----------------+---------------+----------+-------+--------+
| seller_user_id | buyer_user_id | order_id | price | STATUS |
+----------------+---------------+----------+-------+--------+
|            225 |           248 |      201 |  1222 |   NULL |
+----------------+---------------+----------+-------+--------+
1 row in set (0.00 sec)


mysql> select * from tb_order_detail;
+----------------+-----------------+----------+----------+-------------+------+------------+
| seller_user_id | order_detail_id | order_id | goods_id | goods_name  | cnt  | unit_price |
+----------------+-----------------+----------+----------+-------------+------+------------+
|            225 |             201 |      201 |       11 | goods_name  |    1 |       1220 |
|            225 |             202 |      201 |       11 | goods_name2 |    1 |          2 |
+----------------+-----------------+----------+----------+-------------+------+------------+
2 rows in set (0.00 sec)






109.131数据为:
mysql> select * from tb_user;
+------------+---------+------+----------+
| login_name | user_id | TYPE | passwd   |
+------------+---------+------+----------+
| name-2     |     226 |    1 | passwd-A |
| name-5     |     229 |    1 | passwd-A |
| name-8     |     232 |    1 | passwd-A |
| name-11    |     235 |    1 | passwd-A |
| name-14    |     238 |    1 | passwd-A |
| name-17    |     241 |    1 | passwd-A |
| name-20    |     244 |    1 | passwd-A |
| name-23    |     247 |    1 | passwd-A |
| buyer-3    |     250 |    2 | passwd-A |
+------------+---------+------+----------+
9 rows in set (0.00 sec)


mysql> select * from tb_seller_order;
+----------------+---------------+----------+-------+--------+
| seller_user_id | buyer_user_id | order_id | price | STATUS |
+----------------+---------------+----------+-------+--------+
|            238 |           248 |      203 |  1222 |   NULL |
+----------------+---------------+----------+-------+--------+
1 row in set (0.00 sec)


mysql> select * from tb_order_detail;
+----------------+-----------------+----------+----------+-------------+------+------------+
| seller_user_id | order_detail_id | order_id | goods_id | goods_name  | cnt  | unit_price |
+----------------+-----------------+----------+----------+-------------+------+------------+
|            238 |             203 |      203 |       11 | goods_name  |    1 |       1220 |
|            238 |             204 |      203 |       11 | goods_name2 |    1 |          2 |
+----------------+-----------------+----------+----------+-------------+------+------------+
2 rows in set (0.00 sec)




本想写存储过程测试,发现存储过程只能写的某一个结点,然后通过mycat指定结点调用,这样就不能使用mycat的全局序列,所以就手动写了sql。

转载:https://blog.csdn.net/convict_eva/article/details/52022696

参考:https://blog.csdn.net/mchdba/article/details/50655304

猜你喜欢

转载自blog.csdn.net/dhfzhishi/article/details/81286297