ER 表是一个什么样的概念,我们可以看一下上图的右边。sales 和 sales_detail 这两个表其实就有逻辑外键关系的两张表。有外键关系的表可以用外键来拆分,或者是依赖于外键节点。
比如某个列 A 和外键列关系是 1: N,外键可以唯一决定它路由的归属。中间件可以通过某个列 A 拆分以后,在另一张表按照对应列进行拆分,因为它有外键关系,在业务当中也会通过外键关系来关联,并且去查我实际的数据也可以通过整体下发来避免二次查询来确定路由。
我们举个例子。看上图的配置部分,就是一个典型的 ER 表的一个配置。我们可以看到有 parent 有 child,child 可以继续有 child,理论上是可以无限拆下去,实际上我们不建议大家超过三层。我们来看前两行,第一行是我们最普通的一种拆分方式。第二行 childTable,有一个 joinKey,代表它自己的列和它的父亲列产生关系的那一列。parent key 是它父亲的那一列。换句话说也就是这张表的 child1_id 和 tb_parent 表的 id 是一个外键关系。我们知道这样一个关系以后,相关的查询就可以直接下发了。
实现方法 1我们来看一个例子。
通过 select * from tb_parent 查看表中的数据情况。预先插入了几条测试数据,两个表数据基本上一致。我们主要关心的是否有正确结果。通过两个表 JOIN 去观察一下结果,再观察一下是怎么去下发的。EXPLAIN 语句再加 \G。
我们来看一下查询计划,结果一共是四行,两个 SQL 整体下发以后,再把结果简单合并一下,这是关联键的执行计划。如果我换 id 作为 JOIN 列,不是刚刚的列。就会又回到我们跨库查询的方式,JOIN 还是需要一个中间件内部计算 on 条件的结果。我们可以看到先是 order by 然后在合并,最后通过中间件去做 JOIN。
结论
所以使用 ER 表的结论是,只有你设置的外键关系符合你的业务逻辑,他才会进行优化,将SQL整体下发。大家在使用的时候要分析业务是不是能符合这种情况。