如何实现一个跨库连表SQL生成器

发布时间:2021-11-24 15:01:00 作者:柒染
来源:亿速云 阅读:133

这篇文章将为大家详细讲解有关如何实现一个跨库连表SQL生成器,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

一 概述

ADC(Alibaba DChain Data Converger)项目的主要目的是做一套工具,用户在前端简单配置下指标后,就能在系统自动生成的大宽表里面查询到他所需要的实时数据,数据源支持跨库并支持多种目标介质。说的更高层次一点, 数据的全局实时可视化这个事情本身就是解决供应链数据“神龙效应”的有效措施。做ADC也是为了这个目标,整个ADC系统


架构解析:

其中,SQL生成器的上游和下游主要涉及:


主要从技术角度介绍下SQL生成器相关的内容。

二 技术实现

在项目实施阶段,需要从需求分析、技术方案设计、测试联调几个步骤展开工作。本文重点不放在软件开发流程上, 而是就设计模式选择和数据结构算法设计做下重点讲解。

需求分析

在需求分析阶段, 我们明确了自动生成SQL模块所需要考虑的需求点, 主要包含如下几点:

系统流程图

明确需求后, 我们把SQL生成器总体功能分为两块:

之所以把生成SQL阶段做成同步是因为同步阶段内存操作为主,如果发现数据有问题无法生成SQL能做到快速失败。发布阶段调用基础资源适配层需要同步等待较长时间, 每个发布步骤要做到有状态记录, 可回滚或者重试。所以异步实现。SQL生成器同步阶段的整体功能细化到小模块,如下图所示:

如何实现一个跨库连表SQL生成器

检查阶段

检查原始数据是否有问题, 无法生成SQL则快速失败。

数据同步

计算阶段

生成大宽表,填充SQL。

异步发布阶段会把SQL语句发布到Flink。

添加反向索引的原因

假如有A、B两表连接,那么连接方式为A表的非主键连接B表主键。从时序上来说可能有以下三种情况:

下面我们就这三种情况逐一分析。

场景1:B表数据先于A表数据多天产生

我们假如B表数据存储于某个支持高qps的数据库内,我们可以直接让A表数据到来时直接连接此表(维表)来实现连表。

场景2:B表数据后于A表数据多天产生

这种场景比较麻烦。A表数据先行产生,因此过早的落库,导致B表数据到来时即使连接B维表也拿不到数据。这种场景还有一个类似的场景:如果AB连接完成后B发生了更新,如何让B的更新体现在宽表中?

为了解决这种问题,我们增加了一个“反向索引表”。假如A的主键是id,连接键是ext_id,那么我们可以将ext_id和id的值存储在一张表内,当B的数据更新时,用B的主键连接这种表的ext_id字段,拉取到所有的A表id字段,并将A表id字段重新流入Flink。

三 设计模式

对系统整体流程有了解以后, 我们再来看看系统的设计模式选择,选择设计模式时,我们考虑到数据处理相关的开发工作存在一些共性:

由于数据处理任务的步奏比较冗长,而且由于每个阶段的结果与下阶段的执行有关系,又不能分开。

参考 PipeLine(流水线)设计模式[2],综合考虑后我们系统的整体设计如下图所示:

首先有一个全局的PipeLineContainer管理多个pipeLine和pipeline context, 每个pipeline可独立执行一个任务, 比如pipeline1执行同步生成sql任务。pipeline2执行异步发布任务。发布必须在生成SQL结束后执行, pipeline有状态并且按一定顺序串联。每个pipeline包含多个可重用的valve(功能)。valve可以重用, 任意组合,方便完成更多的数据处理任务(比如以后如果要支持Tisplus dump平台接入, 则简单拼接现有的valve就可以)。

四 数据结构和算法

问题说明

SQL生成器关键点, 就是把各个表(Meta节点)之间的关系表示出来。Meta之间的关系分为两类,分别是全连接关联和左连接关联(因为左连接关联涉及到数据的时序问题, 需要添加反向索引较为复杂, 所以和全连接区分了一下, 为了简化问题我们先执行全连接, 再执行左连接)。

我们要解决的问题是, 多个数据源同步数据进来之后, 按一定的优先级关联, 最终得到一个大宽表并需要自动发布。抽象到数据结构层面就是:

算法思路

下面说明下解决该问题的算法思路。

优先级队列

因为叶子节点之间连接执行优先级不同,先放入优先级队列。之后每次取出高优先级任务执行。相同优先级任务可以复用, 连续执行多次。优先级队列示意图如下:

如何实现一个跨库连表SQL生成器

构建树

有了优先级队列的概念, 我们来构建树。构建主要分以下步骤:

1.首先得到四种优先级的任务, 优先级从高到低分别为:

2.取优先级1的任务执行,同步进来六个数据源对应六个叶子。

3.取优先级2的任务并执行得到中间表1,2。

4.取优先级3的任务并执行,发现节点1、4有父节点, 则执行中间节点1、2分别和节点6 Left Join得到根节点。

5.取优先级4的任务并执行,发布根节点。

可以看到最终的数据结构是一棵树, 通过这种方式我们能支持复杂sql的自动构建。进一步抽象, 这种“一个队列驱动一棵树生成”的模式可以解决一类问题:

限于篇幅, 重点在于介绍自动生成sql功能开发中运用到的主要数据结构和设计模式思想。

目前我们实现了任意张表关联sql自动生成并发布, 整体延迟控制在2s以内。之后SQL生成器主要会针对方便接入更多第三方实时计算平台(比如Tisplus), 降低整体系统延迟工作展开。方便接入主要考验的是架构的设计, 也是本文着重写的点(包括数据结构和算法设计、设计模式的选择)。降低系统延迟则包括消息中间件优化,代码执行效率提升等。

关于如何实现一个跨库连表SQL生成器就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

推荐阅读:
  1. 如何实现跨库连接mysql
  2. mysql连表实现级联删除

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

sql

上一篇:django如何自定义jinja2的tag与filter

下一篇:小程序结合AI实现圣诞帽子自动戴的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》