存算分离下设计数据库计算引擎的思路
在数据库存存算分离架构下,数据库提供基本的存储功能,可能不支持存储过程、视图、一些窗口函数,应用负责业务数据的计算。一般情况下对原先开发的存储过程等需要用其他语言重新改写。这里提供另外一种方案,设计一个数据库计算引擎,对原先不支持的进行计算,从而保护了既有数据资产。
1) 对于视图。计算时将视图内容代入即可
2) 存储过程,识别单个 sql 语句,变量赋值以及程序流程控制等由引擎执行
3) 子查询中的不支持函数处理较为复杂,下面就在一个项目中的情况(使用 td-sql 的某版本)举例详细说明。
Rownum()函数不支持:
start connect 层级查询语句不支持:
引擎进行计算的过程:
1) 解析。识别原先数据库语法。本例中为 oracle 语法
2) 识别要替换的表格(或子查询),如
中红框部分中包含 row_number 函数,此部分子查询需要引擎计算。
3) 参数填充、
子查询本身若有参数,需将参数带进。
4) 查询/条件优化
子查询,本身可能没有条件,如果不优化将导致查询出大量行,但和其关联的表有条件,通过先查询出关联表的行,再用这些行和子查询关联。
假定 C 为要计算的子查询:
1) A join B join C … where A.xx=xx, 可以通过关联表 A 的条件最终找到 C 的行。
对于关联表,根据表行数估算,如果关联表小而子查询表大,需要先查询出关联表行,再用这些行和子查询关联。(通过关联表行限制子查询行)
2) A join B join C … where C.xx=xx, 可以通过子查询 C 的条件找到 C 的行。
此处子查询外部的条件(C.xx=xx)可以代入子查询内部。(子查询外部条件代入内部)
5) 执行。
将子查询分为下推给数据的和引擎计算的 2 部分。数据库没有的函数或表达式或语句引擎来实现,如上面中的 rownum()。执行结果可保存为临时表
6) 将执行结果代入原语句中,下推给数据库执行。
假定第 2)部识别的子查询结果保存的临时表为 TMP_1,则给数据库执行的语句为:
以上设计作者验证中,欢迎斧正。
评论