零:开篇
目录
Mycat 的分片 join,只支持分库表的 join(多库同名表),单库多表既 table 标签的 subtables 属性不支持 join 操作,会直接报错。
一:常见的 join 类型
INNER JOIN 内连接:也叫等值连接,inner join 产生同时符合 A 表和 B 表的一组数据。既只在笛卡尔积中取交集的数据
LEFT JOIN 左连接:从 A表(左) 产生一套完整的记录,与匹配的 B表记录(右表) .如果没有匹配, 右侧将包含 null, 在 MySQL 中 等同于 left outer join。不仅在笛卡尔积中取交集,还保留左表全部数据。
RIGHT JOIN 右连接: 同 Left join , AB 表互换即可。
Cross join 交叉连接:得到的结果是两个表的乘积,即笛卡尔积。笛卡尔(Descartes)乘积又叫直积。假设集合 A={a,b},集合 B={0,1,2},则两个集合的笛卡尔积为 {(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)} 。可以扩展到多个集合的情况。类似的例子有,如果 A 表示某学校学生的集合,B 表示该学校所有课程的集合,则 A 与 B 的笛卡尔积表示所 有可能的选课情况。
Full join 全连接:产生的所有记录(双方匹配记录)在表 A 和表 B。如果没有匹配,则对面将包含 null。
尽量避免使用 Left join 或 Right join,而用 Inner join。
在使用 Left join 或 Right join 时,ON 会优先执行,where 条件在最后执行,所以在使用过程中,条件尽可能的在 ON 语句中判断,减少 where 的执行
少用子查询,而用 join。
MyCat 目前版本支持跨分片的 join,主要实现的方式有四种。
全局表,ER 分片,catletT(人工智能) 和 ShareJoin,ShareJoin 在开发版中支持,前面三种方式 1.3.0.1 支持。
二:全局表实例实操测试
一个真实的业务系统中,往往存在大量的类似 字典表 的表格,它们与业务表之间可能有关系,这种关系,可 以理解为“标签”,而不应理解为通常的“主从关系”,这些表基本上 很少变动,可以根据主键 ID 进行缓存。
字典表具有以下几个特性:
-
变动不频繁
-
数据量总体变化不大
-
数据规模不大,很少有超过数十万条记录。
鉴于此,MyCAT 定义了一种特殊的表,称之为“全局表”,全局表具有以下特性:
-
全局表的插入、更新操作会实时在所有节点上执行,保持各个分片的数据一致性
-
全局表的查询操作,只从一个节点获取
-
全局表可以跟任何一个表进行 JOIN 操作
类似每个节点都维护一个表,该表的变动会传播给所有节点。查询时可以从任意库中选择,类似镜像节点
配置:声明该表 jointable 为一个全局表,所属节点 dn1 dn2
<table name="jointable" primaryKey="id" type="global" autoIncrement="true" dataNode="dn$1-2" />
lsqtable 是之前建立的单表分两库的表,配置如下
<table name="lsqtable" primaryKey="id" autoIncrement="true" dataNode="dn$1-2" rule="mod-long" />
查询语句:
explain SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id
dn1 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id
dn2 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id
如果在 on 语句中确定库,则只会发送到一个库中执行
explain SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id AND l.id = 3
dn2 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id AND l.id = 3
全局表的插入操作测试:确定了每个库中都会插入条数据
EXPLAIN INSERT INTO jointable (id, name) VALUES (2, 'wxf')
dn1 INSERT INTO jointable (id, name) VALUES (2, 'wxf')
dn2 INSERT INTO jointable (id, name) VALUES (2, 'wxf')
MyCat 说 join 操作最多两个表,尝试多个全局表 join 的可能性,证明多个全局表不影响 join 操作。
新加一个全局表
<table name="jointable" primaryKey="id" type="global" autoIncrement="true" dataNode="dn$1-2" />
<table name="otherjointable" primaryKey="id" type="global" autoIncrement="true" dataNode="dn$1-2" />
SELECT * FROM
jointable j INNER JOIN lsqtable l ON j.id = l.id
INNER JOIN otherjointable o ON j.id = o.id
dn1 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id INNER JOIN otherjointable o ON j.id = o.id
dn2 SELECT * FROM jointable j INNER JOIN lsqtable l ON j.id = l.id INNER JOIN otherjointable o ON j.id = o.id