MySQL 到 Elasticsearch 宽表构建
· 阅读需 7 分钟
简述
CloudCanal 2.0.X 版本近期支持了宽表构建能力,在数据预处理领域向前走了一步。
方案特点
- 相对灵活,对业务数据和结构贴合性好
- 能很好的支持事实表与维表打宽表需求
本文以 MySQL 到 Elasticsearch 单事实表双维表为案例,介绍 CloudCanal 宽表构建和同步的操作步骤。
技术点
打宽表的必要性
关系型数据库为了应对在线业务对于并发、毫秒级响应,同时操作 相对趋向 kv 化,一般基于关系范式进行设计,通过外键或约定外键(非物理约束)进行关联。
当业务需求涉及到多张关联表(业务运营、报表、BI 需求),查询表的先后顺序成为操作响应时间的关键要素,但排列组合式种类随关联表数量(n)增加会膨胀非常快(n!),导致查询效率低下。
| 关联表数量 | 排列种类 |
|---|---|
| 2 | 2 |
| 3 | 6 |
| 4 | 24 |
| 5 | 120 |
| 6 | 720 |
| 7 | 5040 |
| 8 | 40320 |
| 9 | 362880 |
| 10 | 3628800 |
| 11 | 39916800 |
数据库或者数仓做 join 查询(特别是5张表以上),最难的事情变成了如何从这么多可能性中(搜索空间)找到最好的那一个。
数据迁移和同步 以相对比较小的代价,将多张关联表进查询库或者数据仓库之前,通过 反查 或者 窗口等待变更数据做关联,打成一张宽表写入对端,显著减轻后续查询对于 SQL 优化器的要求。
宽表的种类和方式
这里的宽表种类指其数据来源表种类(常见但不全面),常见的我们分 事实表 和 维度表,比如订单表被定义成事实表,用户表被定义成维度表,商品表被定义成维度表。
一般事实表和维度表数据具备类似 n:1 的关系,也就是 1 个用户会有 n 个订单 (1个订单属于1个用户),1 个商品也会存在 n 个订单 (1个订单会关联 1 个或有限个数商品)。
打宽表的 方式有多种,根据场景,最常见的包含以下两种
- 多事实表 打宽表
- 一般场景是在有限的时间内,关联的变更在这些表上发生(多流join),打宽表工具只要在一定的时间范围内等到这些数据(window),即可打成宽表数据。
- 单事实表和多维度表打宽表
- 一般场景是事实表变更,但是维度表没有任何变化,这时打宽表工具需要通过事实表变更数据反查维度表数据,打成宽表。
CloudCanal 目前打宽表的方式主要通过反查实现,对于多流 join , 实际上也可以通过反查实现,只是可能缺乏数据一致性。
操作示例
前置条件:
- 下载安装 CloudCanal 私有部署版本,使用参见快速上手文档
- 准备好 MySQL 数据库(本例使用 5.7 版本)和 Elasticsearch 数据库(本例使用 6.x 版本)
- MySQL 上创建 1 张事实表(order)和 2 张维表 (user 、product)
- Elasticsearch 上创建 1 个索引 order , 并额外包含两张维表相关数据
- user_id (关联user.id), user_name(对应user.name)
- product_id(关联product.id) ,product_name(对应product.name),product_price (对应product.price)
