1 应用场景

这篇来说下mycat中自带的er关系分片,所谓er关系分片即可以理解为有关联关系表之间数据分片。类似于订单主表与订单详情表间的分片存储规则。

本文所说的er分片分为两种:

a. 依据主键进行数据分片,验证发现主表数据保存在第1个datanode中,子表数据根据分片规则存储。

b. 依据分片关键字段进行分片,验证发现主表与子表根据分片规则存储,且保存在相同的分片内。

接下来,可以下实际配置与数据验证

2 环境说明

参考  《MyCat 学习笔记》第六篇.数据分片 之 按月数据分片  http://www.cnblogs.com/kaye0110/p/5160826.html

3 参数配置

3.1 server.xml 配置

同上参考

3.2 schema.xml 配置

<schema name="RANGEDB" checkSQLschema="false" sqlMaxLimit="100">
  <!-- 方案a. 以主键进行分片 ,采用 sharding-by-pid 规则(根据 t_er_child_1.cid 的值 / 256 进行分片) -->

  <table name="t_er_parent_1" dataNode="dn$4-7" rule="sharding-by-pid">
    <childTable name="t_er_child_1" primaryKey="cid" joinKey="pid" parentKey="pid" />
  </table>

  <!-- 方案b.根据主表分片字段分页,子表数据会跟着主表走 -->

  <table name="t_er_order" dataNode="dn$4-7" rule="sharding-by-long">
    <childTable name="t_er_detail" primaryKey="detail_id" joinKey="order_id" parentKey="order_id" />
  </table>

</schema>

3.3 rule.xml 配置

<tableRule name="sharding-by-long">
  <rule>
    <columns>sharding_long</columns>
    <algorithm>func2</algorithm>
  </rule>
</tableRule>

<!--  partitionCount 与 partitionLength 相乘的值需要等于 1024  -->

<function name="func2" class="org.opencloudb.route.function.PartitionByLong">
  <property name="partitionCount">4</property>
  <property name="partitionLength">256</property>
</function>

4 数据验证

4.1 方案a的验证

CREATE TABLE `t_er_parent_1` (
`pid` INT NOT NULL,
`pname` VARCHAR(45) NULL,
PRIMARY KEY (`pid`));

CREATE TABLE `t_er_child_1` (
`cid` INT NOT NULL,
`pid` INT NOT NULL,
`cname` VARCHAR(45) NULL,
PRIMARY KEY (`cid`));

insert into t_er_parent_1 (pid,pname) values (1,'parent 255');
insert into t_er_child_1(cid,pid,cname) values (1,255,'child 255');

insert into t_er_parent_1 (pid,pname) values (2,'parent 256');
insert into t_er_child_1(cid,pid,cname) values (2,256,'child 256');

insert into t_er_parent_1 (pid,pname) values (3,'parent 512');
insert into t_er_child_1(cid,pid,cname) values (3,512,'child 512');

insert into t_er_parent_1 (pid,pname) values (4,'parent 768');
insert into t_er_child_1(cid,pid,cname) values (4,768,'child 768');

mysql> select * from t_er_parent_1;
+-----+------------+
| pid | pname |
+-----+------------+
| 1 | parent 255 |
| 2 | parent 256 |
| 3 | parent 512 |
| 4 | parent 768 |
+-----+------------+
4 rows in set (0.01 sec)

mysql> select * from t_er_child_1;
+-----+-----+-----------+
| cid | pid | cname |
+-----+-----+-----------+
| 1 | 255 | child 255 |
| 4 | 768 | child 768 |
| 2 | 256 | child 256 |
| 3 | 512 | child 512 |
+-----+-----+-----------+
4 rows in set (0.01 sec)

看下方案a的日志 ,所有主表数据都进入了第1个数据结点dn4,不过子表数据进入dn7

01/28 21:44:25.559 DEBUG [$_NIOREACTOR-0-RW] (ServerQueryHandler.java:56) -ServerConnection [id=2, schema=RANGEDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=RANGEDB]insert into t_er_parent_1 (pid,pname) values (4,'parent 768')
01/28 21:44:25.559 DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=2, schema=RANGEDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=RANGEDB]insert into t_er_parent_1 (pid,pname) values (4,'parent 768'), route={
1 -> dn4{insert into t_er_parent_1 (pid,pname) values (4,'parent 768')}
} rrs
01/28 21:44:25.562 DEBUG [$_NIOREACTOR-1-RW] (NonBlockingSession.java:229) -release connection MySQLConnection [id=15, lastTime=1453988665553, user=root, schema=range_db_4, old shema=range_db_4, borrowed=true, fromSlaveDB=false, threadId=179, charset=utf8, txIsolation=3, autocommit=true, attachment=dn4{insert into t_er_parent_1 (pid,pname) values (4,'parent 768')}, respHandler=SingleNodeHandler [node=dn4{insert into t_er_parent_1 (pid,pname) values (4,'parent 768')}, packetId=0], host=localhost, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
01/28 21:44:25.562 DEBUG [$_NIOREACTOR-1-RW] (PhysicalDatasource.java:403) -release channel MySQLConnection [id=15, lastTime=1453988665553, user=root, schema=range_db_4, old shema=range_db_4, borrowed=true, fromSlaveDB=false, threadId=179, charset=utf8, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=localhost, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
01/28 21:44:25.564 DEBUG [$_NIOREACTOR-0-RW] (ServerQueryHandler.java:56) -ServerConnection [id=2, schema=RANGEDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=RANGEDB]insert into t_er_child_1(cid,pid,cname) values (4,768,'child 768')
01/28 21:44:25.565 DEBUG [$_NIOREACTOR-0-RW] (RouterUtil.java:650) -found partion node (using parent partion rule directly) for child table to insert dn7 sql :INSERT INTO t_er_child_1 (cid, pid, cname)
VALUES (4, 768, 'child 768')
01/28 21:44:25.565 DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=2, schema=RANGEDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=RANGEDB]insert into t_er_child_1(cid,pid,cname) values (4,768,'child 768'), route={
1 -> dn7{INSERT INTO t_er_child_1 (cid, pid, cname)
VALUES (4, 768, 'child 768')}
} rrs

看下物理表的数据 range_db_4 对应的就是dn4结点。

mysql> select * from range_db_4.t_er_parent_1;

select * from range_db_4.t_er_child_1;
+-----+------------+
| pid | pname |
+-----+------------+
| 1 | parent 255 |
| 2 | parent 256 |
| 3 | parent 512 |
| 4 | parent 768 |
+-----+------------+
4 rows in set (0.00 sec)

+-----+-----+-----------+
| cid | pid | cname |
+-----+-----+-----------+
| 1 | 255 | child 255 |
+-----+-----+-----------+
1 row in set (0.00 sec)

4.2 方案b的验证

CREATE TABLE `t_er_order` (
`order_id` INT NOT NULL,
`prod_info` VARCHAR(45) NULL,
`sharding_long` VARCHAR(45) NULL,
PRIMARY KEY (`order_id`));

CREATE TABLE `t_er_detail` (
`detail_id` INT NOT NULL,
`order_id` INT NOT NULL,
`detail_info` INT NOT NULL,
PRIMARY KEY (`detail_id`));

insert into t_er_order (order_id,prod_info,sharding_long) values (1,'prod_1',200);
insert into t_er_order (order_id,prod_info,sharding_long) values (2,'prod_256',256);
insert into t_er_order (order_id,prod_info,sharding_long) values (3,'prod_512',512);
insert into t_er_order (order_id,prod_info,sharding_long) values (4,'prod_1024',1024);
insert into t_er_order (order_id,prod_info,sharding_long) values (5,'prod_1025',1025);
insert into t_er_order (order_id,prod_info,sharding_long) values (6,'prod_795',795);

insert into t_er_detail (detail_id,order_id,detail_info) values (1,1,200);
insert into t_er_detail (detail_id,order_id,detail_info) values (2,2,256);
insert into t_er_detail (detail_id,order_id,detail_info) values (3,3,512);
insert into t_er_detail (detail_id,order_id,detail_info) values (4,4,1024);
insert into t_er_detail (detail_id,order_id,detail_info) values (5,5,1025);
insert into t_er_detail (detail_id,order_id,detail_info) values (6,6,795);

mysql> select * from t_er_order;
+----------+-----------+---------------+
| order_id | prod_info | sharding_long |
+----------+-----------+---------------+
| 1 | prod_1 | 200 |
| 4 | prod_1024 | 1024 |
| 5 | prod_1025 | 1025 |
| 2 | prod_256 | 256 |
| 3 | prod_512 | 512 |
| 6 | prod_795 | 795 |
+----------+-----------+---------------+
6 rows in set (0.08 sec)

mysql> select * from t_er_detail;
+-----------+----------+-------------+
| detail_id | order_id | detail_info |
+-----------+----------+-------------+
| 2 | 2 | 256 |
| 1 | 1 | 200 |
| 4 | 4 | 1024 |
| 5 | 5 | 1025 |
| 3 | 3 | 512 |
| 6 | 6 | 795 |
+-----------+----------+-------------+
6 rows in set (0.01 sec)

查询物理表

mysql> select * from range_db_6.t_er_order;select * from range_db_6.t_er_detail;

+----------+-----------+---------------+
| order_id | prod_info | sharding_long |
+----------+-----------+---------------+
| 3 | prod_512 | 512 |
+----------+-----------+---------------+
1 row in set (0.00 sec)

+-----------+----------+-------------+
| detail_id | order_id | detail_info |
+-----------+----------+-------------+
| 3 | 3 | 512 |
+-----------+----------+-------------+
1 row in set (0.00 sec)

再来看下日志

新增主表数据,根据分片规则数据应该进入第2个数据结点 dn5

01/28 20:50:10.274 DEBUG [$_NIOREACTOR-0-RW] (NonBlockingSession.java:113) -ServerConnection [id=1, schema=RANGEDB, host=0:0:0:0:0:0:0:1, user=test,txIsolation=3, autocommit=true, schema=RANGEDB]insert into t_er_order (order_id,prod_info,sharding_long) values (2,'prod_256',256), route={
1 -> dn5{insert into t_er_order (order_id,prod_info,sharding_long) values (2,'prod_256',256)}
} rrs

份数据库中进行主键搜索确认,并进入数据缓存

01/28 20:50:10.544 DEBUG [BusinessExecutor2] (EnchachePool.java:76) -ER_SQL2PARENTID miss cache ,key:RANGEDB:select t_er_order.order_id from t_er_order where t_er_order.order_id=2
01/28 20:50:10.544 DEBUG [BusinessExecutor2] (FetchStoreNodeOfChildTableHandler.java:73) -find child node with sql:select t_er_order.order_id from t_er_order where t_er_order.order_id=2
01/28 20:50:10.545 DEBUG [BusinessExecutor2] (FetchStoreNodeOfChildTableHandler.java:81) -execute in datanode dn4
01/28 20:50:10.545 DEBUG [BusinessExecutor2] (PhysicalDBPool.java:452) -select read source hostM3306 for dataHost:localhost3306
01/28 20:50:10.545 DEBUG [$_NIOREACTOR-0-RW] (PhysicalDatasource.java:403) -release channel MySQLConnection [id=16, lastTime=1453985410540, user=root, schema=range_db_4, old shema=range_db_4, borrowed=true, fromSlaveDB=false, threadId=175, charset=utf8, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=localhost, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
01/28 20:50:10.745 DEBUG [BusinessExecutor2] (FetchStoreNodeOfChildTableHandler.java:81) -execute in datanode dn5
01/28 20:50:10.745 DEBUG [BusinessExecutor2] (PhysicalDBPool.java:452) -select read source hostM3306 for dataHost:localhost3306
01/28 20:50:10.746 DEBUG [$_NIOREACTOR-1-RW] (FetchStoreNodeOfChildTableHandler.java:154) -received rowResponse response,2 from MySQLConnection [id=19, lastTime=1453985410743, user=root, schema=range_db_5, old shema=range_db_5, borrowed=true, fromSlaveDB=false, threadId=176, charset=utf8, txIsolation=3, autocommit=true, attachment=dn5, respHandler=org.opencloudb.mysql.nio.handler.FetchStoreNodeOfChildTableHandler@6be897cc, host=localhost, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
01/28 20:50:10.746 DEBUG [$_NIOREACTOR-1-RW] (PhysicalDatasource.java:403) -release channel MySQLConnection [id=19, lastTime=1453985410743, user=root, schema=range_db_5, old shema=range_db_5, borrowed=true, fromSlaveDB=false, threadId=176, charset=utf8, txIsolation=3, autocommit=true, attachment=null, respHandler=null, host=localhost, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]

明确插入dn5结点
01/28 20:50:10.945 DEBUG [BusinessExecutor0] (RouterUtil.java:1213) -found partion node for child table to insert dn5 sql :insert into t_er_detail (detail_id,order_id,detail_info) values (2,2,256)

本篇完。

MyCat 学习笔记 第十篇.数据分片 之 ER分片的更多相关文章

  1. MyCat 学习笔记 第八篇.数据分片 之 求摸运算分片

    1 应用场景 Mycat 自带了多套数据分片的机制,其实根据数值取摸应该是最简单的一种. 优点:数据离散概率较为平均,可以有效的提高应用的数据吞吐. 缺点:比较明显,后期数据运维与迁移比较困难.好在M ...

  2. MyCat 学习笔记 第七篇.数据分片 之 按数据范围分片

    1 应用场景 Mycat 其实自带了2个数据范围分片的方案,一个是纯数据范围的分片,比如 1至 10000 号的数据放到分片1 ,10001 至 20000号数据放到分片2里. 另一个是数据常量形式的 ...

  3. MyCat 学习笔记 第六篇.数据分片 之 按月数据分片

    1 应用场景 Mycat 有很多数据分库规则,接下来几篇就相关觉得常用的规则进行试用与总结. 一般来说,按自然月份来进行数据分片的规则比较适用于商城订单查询,类似最近1周.2周.3个月内的数据.或是报 ...

  4. MyCat 学习笔记 第十三篇.数据分片 之 通过HINT执行存储过程

    1 环境说明 VM 模拟3台MYSQL 5.6 服务器 VM1 192.168.31.187:3307 VM2 192.168.31.212:3307 VM3 192.168.31.150:  330 ...

  5. MyCat 学习笔记 第十一篇.数据分片 之 分片数据查询 ( select * from table_name limit 100000,100 )

    1 环境说明 VM 模拟3台MYSQL 5.6 服务器 VM1 192.168.31.187:3307 VM2 192.168.31.212:3307 VM3 192.168.31.150:  330 ...

  6. MyCat 学习笔记 第十二篇.数据分片 之 分片事务处理

    1 环境说明 VM 模拟3台MYSQL 5.6 服务器 VM1 192.168.31.187:3307 VM2 192.168.31.212:3307 VM3 192.168.31.150:  330 ...

  7. kettle学习笔记(十)——数据检验、统计、分区与JS脚本

    一.概述 数据剖析和数据检验: 用于数据的检查.清洗 . 统计步骤: 提供数据采样和统计的功能 分区: 根据数据里某个字段的值,拆分成多个数据块.输出到不同的库表和文件中. 脚本: Javascrip ...

  8. Django学习笔记第十篇--实战练习六--发送邮件

    一.发送邮件需要引入的包依赖文件(Django1.8 Python2.7) from django.core.mail import send_mail,send_mass_mail 其中send_m ...

  9. MyCat 学习笔记 第九篇.数据分片 之 数值分布

    1 应用场景 Mycat 自带了多套数据分片的机制,其实根据数值分片也是比较简单,其实这个和数据取摸是类似的实现. 优.缺点同上一篇 2 环境说明 参考  <MyCat 学习笔记>第六篇. ...

随机推荐

  1. 快速暴力解决Eclipse ADT和Android Studio兼容问题,创建同时兼容ADT和AS的安卓工程

    环境:AS 2.1.2+Java1.7+Gradle 2.14+ADT 24.0.2+MyEclipse 2015 前言:因为比赛要求使用ADT,而我本身比较习惯使用AS开发,遂想办法打造兼容两个ID ...

  2. java版复利计算器升级

    github地址:https://github.com/iamcarson/Carson 伙伴:彭宏亮 学号:201406114148 与伙伴工作帅照: 本次升级的地方: 1.改善了界面显示,让界面整 ...

  3. Linq专题之对象初始化器

    在C#3.0之前,如果创建一个新的对象,往往需要调用类的构造函数来初始化该对象的值,在c#3.0提供了一个"对象初始化器"的机制,使得开发人员在创建新的对象时不通过调用类的构造函数 ...

  4. HTML5实现音频播放

    Web 上的音频 直到现在,仍然不存在一项旨在网页上播放音频的标准. 今天,大多数音频是通过插件(比如 Flash)来播放的.然而,并非所有浏览器都拥有同样的插件. HTML5 规定了一种通过 aud ...

  5. 【C#】1.1 第1章学习要点

    分类:C#.VS2015 创建日期:2016-06-14 教材:十二五国家级规划教材<C#程序设计及应用教程>(第3版) 一.配套源程序(VS2015版)的运行截图 VS2015版的配套源 ...

  6. WebApi传参总动员(五)

    上回说到涉及多个实体的传参,用常规的方法已经不能解决了.这回我们用终极大招搞定她. WebApi:注意要引用JSON.Net [HttpPost] public string GetData(stri ...

  7. git 给远程库 添加多个url地址

     目录[-] 前提 使用流程 原理解析 注意 Other 参考文章 作者:shede333主页:http://my.oschina.net/shede333 && http://blo ...

  8. Android 手机卫士18--流量统计

    //获取手机下载流量 //获取流量(R 手机(2G,3G,4G)下载流量) long mobileRxBytes = TrafficStats.getMobileRxBytes(); //获取手机的总 ...

  9. tomcat学习笔记一:安装和配置

    安装 配置环境: win7 + centos7虚拟机 安装步骤: 到http://tomcat.apache.org/下载最新的tomcat安装包(8.0.24) 移到对应的目录并解压 安装问题: 安 ...

  10. mysql root强密码的必要性max_allowed_packet被改成1024引起的风险

    前两天运维反馈说,有些机器的max_allowed_packet隔两天就会被改成1024,导致客户端调用时出错,网上有说内存不够的,也有人工修改的. 运维小姑娘一口咬定肯定没有改过的,而且my.cnf ...