微课程 | 第八课《Global 表简介》

匆匆过客 提交于 2019-12-13 18:33:29

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

https://v.youku.com/v_show/id_XNDQ2ODE3NTAxMg==.html

上一期我们主要介绍了一些不同拆分规则的表怎样使用,接下来我们介绍一下 Global 表。

什么是 Global 表?

我们有一个定义:对于数据量不大的字典表(比如超市商品)。对于零售系统来说,比如超市商品 SKU 可能有几十万规模的数据量,并且 SKU 不会出现大量增删改,也不会出现并发增删改。对于这样的数据特性来说,非常适合做 Global 全局表。

全局表就是在多个分片上都有一份同样的副本。

我们在这里举了一个这样的例子。sales 表是详细销售情况表,按照时间日期来拆分的。我们可以按照左边的 date 是 20190211,右边的 date 是 20190212,按照 date 字段拆分的,而商品表可以完全一模一样复制一份到每个库。因为商品表不经常做增删改,也没有很大的并发压力,是非常适合做全局表。

这样一个设计有什么好处呢,就是当我在做 JOIN 的时候,我可以只按照 sales 表的分布区路由数据,而不用关心商品表的分布。这样直接路由下发是正确的,我们来看在 DBLE 当中 Global 表是怎么配置的。

Global 表配置操作

https://v.youku.com/v_show/id_XNDQ2ODE3OTA3Ng==.html

我们去看 schema.xml 文件当中,我们之前预定义了两个 Global 表。可以看到这里有 tb_global1 和 tb_global2 两个配置。有两个属性,一个 type,一个 datanote。

tb_global2 表的 datanode 是 dn1-4,指向四个节点。这样的话它的副本数量就是四份,需要在四个节点中维护一个一模一样的表数据。

这样如果别的拆分表涉及到的分片也是这四个,或者是它的范围子集的话。跨库 INNER JOIN 时就可以通过 SQL 的整体下发在中间件,简单合并来得到正确的结果。

Global 的 JOIN 操作

现在还是 tb_mod,还是按照 4 求模拆分的这张表。另外一张 Global 表只有两条数据,放在了此表配置的各个节点。这时候我去做 JOIN ,结果会怎么样呢,我们来看案例。

https://v.youku.com/v_show/id_XNDQ2ODE4MDM4MA==.html

首先我们要展示一下 Global 表的能力,也就是 Global 表怎么样在四个节点上工作。我们现在看一下 Global 表,应该是预先写好了两条数据。现在我新增一条数据上去,看怎么样在这四张表当中去维护。这是一条 insert 数据,id 我们指定为1024,可以查到。然后我们去真正的数据库节点上,端口 33061 和 33062。我们刚才已经看到 dn1 到 dn4。对于 33061 这个实例来说就是 db_1 和 db_3。我们去看接下来数据状态,我们可以看到 tb_global_2 里面已经有这条数据了。我们换一下从 db_3 当中去查一次也是三条数据。我们换一下,从 33062 端口里面去演示一下其实 DBLE 内部是通过两阶段提交的分布式事务来做到。四个节点数据保持一致的 Global 表基本构成就是这样的。所以我们现在回到 8066 端口来做一下 tb_mod 表和 Global 表的 JOIN。

我们先讲一下 INNER JOIN,INNER JOIN 是比较简单的一种情况。我们直接和本地的数据库 JOIN 就可以。结果是正确的,因为现在只有两条数据。然后我们通过 EXPLAIN 看一下,是不是跟普通 JOIN 步骤一样。我把所有数据收集到中间件节点再做 JOIN,结果应该有六行。其实前四个 SQL 内容都是一样的,只不过被路由到了不同的节点。整个 JOIN 被直接下发下去,然后在中间件简单合并一下就结束了。

我们再看 LEFT JOIN,拆分表 LEFT JOIN Global 表是可以的。RIGHT JOIN其实是 LEFT JOIN 反过来,相当于 Global 表作为左表的 LEFT JOIN 拆分表。这时候我们可以发现查询结果已经不一样了。已经回到我们讲过的的跨库 JOIN,这样一个执行的方式,是把所有表的数据都收集起来。然后在中间件去做 JOIN,而不是语句直接下发。

大家可以想象一下为啥 RIGHT JOIN 不行?

其实这涉及到了 MySQL 语义,如果我整体的去把 JOIN 下发的话,因为我的 RIGHT JOIN 需要筛选出 Global 表有的拆分表没有的。如果我直接下发的话 RIGHT JOIN,每个分片都会丢一部分这类型的数据。

虽然 Global 表和拆分表的 INNER JOIN 可以优化,但是 LEFT JOIN 还是会回到跨库查询,所以大家业务需要严格审核 SQL,避免带来性能问题。

好,我们今天先介绍到这里。

图文稿为了方便阅读,在不影响学习的情况下优化了一些口语化词汇,文稿与视频会尽量保持一致。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!