接上一篇:企业实战_16_MyCat全局自增ID​

案例比较:
在垂直拆分场景中,针对字段个数少的类型为字典类型的表,我们可以使用全局表的方式解决。
在水平扩展场景中,针对数据量很大的表,怎样实现跨分片查询呢? ER分片

文章目录

一、跨分片查询的另一个场景

1. 思考

order_master表进行了切片操作,而order_detail没有进行切片操作, 2张表,不在一个分片中,现在这种关联属于跨分片关联,针对这种跨分片的查询应该如何处理呢?

2. 回顾!

  • 在垂直拆分场景中,针对这种跨分片查询的情况,有3种方式解决跨分片查询。

方式

应用场景/说明

api

结果拼接,比较耗时

数据冗余

数据冗余量大

全局表

字段少 字典类型的表

3. 目前,归纳

  • 在水平扩展场景,针对这种跨分片查询的情况,使用方式解决跨分片查询。

方式

应用场景/说明

ER分片

字段多,访问频繁,数据集大

  • 得出结论!

全局表:适用于字段少的字典类型的表的场景,而order_master订单表是一个非常庞大的表,调用比较频繁,因此并不适合使用全局表的应用场景。

ER分片表,是通过ER关系来进行分片的,可以把需要两个关联的表,根据他们的关联键,把要关联的这些数据分布到同一个分片内,那么,我们在同一个分片内来解决这个关联问题,以此来,解决跨分片查询的问题

mysql  -uapp_imooc -p123456 -h192.168.92.101 -P8066

mysql> select * from order_master a join order_detail b on a.order_id = b.order_id;
ERROR 1064 (HY000): invalid route in sql, multi tables found but datanode has no intersection sql:select * from order_master a join order_detail b on a.order_id = b.order_id
mysql>

企业实战_17_MyCat水平扩展_跨分片查询_ER分片_ooc


ER分片

#分别在order_db01、order_db02、order_db03、order_db04数据库中创建order_detail表

#登录node2节点,在order_db01、order_db02数据库中创建order_detail表
[root@node2 ~]# mysql -uroot -p123456
mysql> use order_db01;
mysql> use order_db02;
依次初始化创建表sql

#登录node3节点,在order_db03、order_db04数据库中创建order_detail表
[root@node3 ~]# mysql -uroot -p123456
mysql> use order_db03;
mysql> use order_db04;

初始化创建表sql

CREATE TABLE `order_detail` (
`order_detail_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键ID,订单详情表ID',
`order_id` int(10) unsigned NOT NULL COMMENT '订单表ID',
`product_id` int(10) unsigned NOT NULL COMMENT '订单商品ID',
`product_name` varchar(50) NOT NULL COMMENT '商品名称',
`product_cnt` int(11) NOT NULL DEFAULT '1' COMMENT '购买商品数量',
`product_price` decimal(8,2) NOT NULL COMMENT '购买商品单价',
`average_cost` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '平均成本价格',
`weight` float DEFAULT NULL COMMENT '商品重量',
`fee_money` decimal(8,2) NOT NULL DEFAULT '0.00' COMMENT '优惠分摊金额',
`w_id` int(10) unsigned NOT NULL COMMENT '仓库ID',
`modified_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`order_detail_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单详情表';

数据清理

# 删除order_master的数据
mysql -uapp_imooc -p123456 -h192.168.92.101 -P8066
use imooc_db;
delete from order_master;

添加分片配置
修改编辑schema.xml
order_master在的table标签中添加childTable 标签,并把下面以前定义的的order_detailtable标签删除

cd /app/mycat/conf/
vim
<table name="order_master"          primaryKey="order_id"          dataNode="ordb01,ordb02,ordb03,ordb04" rule="order_master" autoIncrement="true"/>
<childTable name="order_detail" primaryKey="order_detail_id" joinKey="order_id" parentKey="order_id" autoIncrement="true" />
</table>

注:在childTable标签中,没有定义 dataNode属性,因此,说明字表和父表公用此属性

  • joinKey 父表和字表关联的键
  • parentKey 父表主键
  • primaryKey order_detail表的主键
  • autoIncrement 全局自增id 一旦开启需要在配置文件中配置才可以生效

由于order_detail配置了​​autoIncrement="true"​​​ 这个属性,因此,我们需要配置order_detail表的全局自增id
配置order_detail表的全局自增id

二、配置order_detail表的全局自增id

需要在sequence_db_conf.properties文件中,添加order_detail的id数据节点

cd /app/mycat/conf/
vim sequence_db_conf.properties

#sequence stored in datanode
GLOBAL=mycat
ORDER_MASTER=mycat
ORDER_DETAIL=mycat

设置自增配置项‘

mysql -uroot -p123456
use mycat;

# 查询现有
mysql> select * from MYCAT_SEQUENCE;
+--------------+---------------+-----------+
| name | current_value | increment |
+--------------+---------------+-----------+
| GLOBAL | 1 | 1 |
| ORDER_MASTER | 11 | 1 |
+--------------+---------------+-----------+



# 插入新的自增配置项
mysql> insert into MYCAT_SEQUENCE values ('ORDER_DETAIL',1,1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from MYCAT_SEQUENCE;
+--------------+---------------+-----------+
| name | current_value | increment |
+--------------+---------------+-----------+
| GLOBAL | 1 | 1 |
| ORDER_DETAIL | 1 | 1 |
| ORDER_MASTER | 11 | 1 |
+--------------+---------------+-----------+
3 rows in set (0.00 sec)

# 为了演示好看,将自增ID都改成从1开始,生产环境不能操作,这一步也可以不操作
mysql> update MYCAT_SEQUENCE set current_value =1 where name ='ORDER_MASTER';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from MYCAT_SEQUENCE;
+--------------+---------------+-----------+
| name | current_value | increment |
+--------------+---------------+-----------+
| GLOBAL | 1 | 1 |
| ORDER_DETAIL | 1 | 1 |
| ORDER_MASTER | 1 | 1 |
+--------------+---------------+-----------+
3 rows in set (0.00 sec)

重启mycat

mycat stop

mycat start
# 登录mycat批量插入order_master和order_detail表的数据
mysql -uapp_imooc -p123456 -h192.168.92.101 -P8066

use imooc_db;

# 初始化脚本,批量插入order_master和order_detail表的数据

企业实战_17_MyCat水平扩展_跨分片查询_ER分片_ooc_02

企业实战_17_MyCat水平扩展_跨分片查询_ER分片_ooc_03


企业实战_17_MyCat水平扩展_跨分片查询_ER分片_mysql_04

从上面图的order_id中可以看出,order_master和order_detail都在通一个分片中

select a.order_id,order_sn,product_name from order_master a join order_detail b on a.order_id=b.order_id;

企业实战_17_MyCat水平扩展_跨分片查询_ER分片_ooc_05

到此,ER跨分片查询的问题已经解决!

下一篇:企业实战_18_MyCat_ZK集群安装部署