MyCat10——分片技术之ER表

2023-11-27 20:17:23 浏览数 (2)

1 问题

在实际工作中,经常会遇到多张表进行 join 查询的操作,例如 orders 表被我们做了水平拆分,表中记录分散存储在两个数据分片中,但是 order_details 表并没有做分片,因此在对这两张表做 join 查询时,数据库1仅能在分片后的数据中进行查询,数据库2因为没有找到 order_details 表而返回空,那么整个查询结果将是实际结果的一个子集。

mycat中的join查询结果

创建 order_details 表并使用join进行查询

create table order_details(id int auto_increment primary key,order_id int, detail varchar(200));

数据库1中的记录

数据库2中的记录

那么为了解决这个问题,引入了ER表。

2 ER表

ER表是为了解决跨分片进行表的关联查询的,有关联关系的表放到一个分片里,没关联关系的随意。

子表的存储位置将依赖于父表,并且在物理上紧邻存放,根据这个思路,采用基于E-R关系的数据分片策略,这样就解决了在数据分片时,join查询遇到的问题。

例如,customer 表中的数据,当与父表 orders 数据存在关联时,该部分数据将被分配到同一个分片里,以方便进行关联操作。

3 实现

3.1 修改 schema.xml 配置

在 table 节点下,增加 childTable 子节点。

增加的内容如下:

<childTable name="order_details" primaryKey="id" joinKey="order_id" parentKey="id"/>

  • name 要table关联的子表表名;
  • primaryKey 子表的主键;
  • joinKey 做join连接查询的列名;
  • parentKey 用于join连接查询的列在父表中对应的列名

添加后,效果如下

3.2 重启mycat

修改配置后,重新启动mycat服务

mycat restart

3.3 在数据库2创建子表

此时,在mycat中进行join查询时,会报错

mysql> select * from orders as o left JOIN order_details as od on od.order_id=o.id;

ERROR 1146 (42S02): Table 'orders.order_details' doesn't exist

因为在数据库2中并不存在 order_details 表。

因此,需要先在数据库2中创建 order_details 表。

3.4 在mycat中重新查询

进入到mycat数据端口,重新执行1中的查询。

所有记录都能被查询出来。

3.5 插入数据

向 order_details 表中插入几条记录

insert into order_details(detail, order_id) values("details001", 1);

insert into order_details(detail, order_id) values("details002", 2);

insert into order_details(detail, order_id) values("details003", 3);

需要注意的是:

这里向子表中插入数据时,用来进行关联的列的值,应在父表中存在对应的数据,否则会遇到报错

ERROR 1064 (HY000): can't find (root) parent sharding node for sql

3.6 数据查询

分别进入各数据库分片进行查询,可以发现子表中,与父表关联的数据,被存储于同一个数据库分片中。

数据库分片1

数据库分片2

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞