企业实战_17_MyCat水平扩展_跨分片查询_ER分片
原创
©著作权归作者所有:来自51CTO博客作者gblfy的原创作品,请联系作者获取转载授权,否则将追究法律责任
接上一篇:企业实战_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>
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标签删除
<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批量插入order_master和order_detail表的数据
mysql -uapp_imooc -p123456 -h192.168.92.101 -P8066
use imooc_db;
# 初始化脚本,批量插入order_master和order_detail表的数据
从上面图的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;
到此,ER跨分片查询的问题已经解决!
下一篇:企业实战_18_MyCat_ZK集群安装部署