开发者社区> 行者武松> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

【数据蒋堂】第17期:SQL的困难源于关系代数

简介:
+关注继续查看

640?wx_fmt=png&wxfrom=5&wx_lazy=1

在结构化数据处理领域,SQL无疑是应用最广泛的工作语言,不仅被所有关系数据库采用,许多新进的大数据平台也将实现SQL作为目标。但现实是,面对当前纷杂的计算查询需求,SQL在很多方面并不够好用。我们在前面说过SQL的过程性问题,这其实并不是最关键的问题,SQL的更大困难来源于其理论基础,即关系代数。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

关系代数是一种代数体系。我们无法在本文的篇幅中严格定义代数体系这个概念,只能通俗地解释。人们为解决某种运算问题,定义了一些数据对象及针对这些数据对象的一套运算规则,确保这些运算的封闭性和自洽性,就可以称为一种代数体系了。比如说我们熟悉的有理数及其上的四则运算就是一种用于解决日常生活中数值计算需求的代数体系。封闭性是指计算结果必须仍然是定义过的数据对象,比如有理数的四则运算结果仍然是有理数。而自洽性指这些运算不能出现矛盾的结果,比如我们要约定不能除以0,否则把某个数除以0规定成任何数都会推出逻辑矛盾来。

这里说的数据对象,和程序设计面向对象理论中数据对象不太一样。前者主要强调数据上的运算,而后者更多强调对象的封装性、继承性和重载能力。前者是为了更好的描述和实施数据运算,后者则主要是为了代码复用。

640?wx_fmt=png&wxfrom=5&wx_lazy=1

代数体系设计得好与不好,严重影响我们实施计算的方便度和效率!

举两个例子:

1. 我们从小学过的算术体系都采用阿拉伯数字,用来表示数值和做四则运算都很方便,但试想如果换成罗马数字会是个什么感觉?

2. 所有整数乘法都可以用加法表示,但如果我们在算术体系中引入了乘法来表示若干个相同数相加这种运算,就可以发明九九表来做而不必硬加,效率可显著提高。

要让计算机实施计算,还需要一套基于代数体系的形式化语言,用户把计算目标按约定的语法符号写成代码,就可以由计算机执行了。而用计算机解决问题的过程,也可以理解为把题目解法翻译成某种形式化语言的过程。如果代数体系及其形式化语言设计得不好,就可能发生翻译问题解法的难度大于解决问题本身的现象!用罗马数字来实施四则运算就是这个结果。

gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA

关系代数就是用来实现批量结构化数据计算的代数体系,其形式化语言就是SQL。讲述关系代数和SQL原理的资料很多,这里就不再赘述了。

那么用SQL解决结构化数据运算的效果如何呢?

人们通常关心两个效率问题。一是运算的描述效率,二是运算的执行效率。这两个效率很容易理解,如果描述效率太低,就意味着开发成本太高,很难写出程序进行计算;而如果执行效率低,则需要运行很久才能得到结果,那实用价值也就大打折扣了。实际上,执行高效在本质上也是个描述问题,在软件层面不可能提高硬件性能,但可能设计出更高效的算法,那么这个语言不能限制我们写出高效算法。

gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA

面对较复杂的大数据运算,SQL在这两方面表现都很差,我们分别举两个并不复杂的例子说明:

1. 找出一支股票最长连续上涨了多少天

这个问题对于Java或C++程序员来讲非常简单:做个初值为0的计数器,把数据按日期排序后遍历,发现上涨就将计数器加1,下跌则清0,最后看这个计数器出现过的最大值,这是个很自然的思路。但是用SQL实现就太困难了。关系代数延用了数学上的无序集合概念,数据排序只在输出时有效,无法规定数据的遍历次序,也就无法实施上述的自然思路。需要人为地制造出日期的序号后,再产生一个分组标志,把上涨的日期和前一天分成一组,下跌的日期分到另一组,然后计算最大的分组COUNT()值,实现思路很难理解。这就发生前面所说的翻译问题解法的难度大于解决问题本身的现象了。

 2. 从10亿条数据中找出最大的前10名

我们知道,这样的问题是不需要把10亿行数据全部排序的。先产生一个有10个成员的空集合,然后遍历数据,过程中始终保持这个小集合是当前已遍历过数据中最大的10个,这样整个10亿行数据只要遍历一次,内存占用很小,运算性能很好。但关系代数中没有显式的集合数据类型,无法描述这个算法,只能把10亿行数据大排序再取出前10后,剩下的已排序的数据没有用了。10亿行大排序的成本很高,如果内存装不下则还会设计多次外存数据倒换的问题,性能会严重下降。这就会发生我们明知有好的算法却无计可施的尴尬局面。这种情况常常就只能寄希望于数据库在工程上的优化,但情况复杂的SQL会超出数据库的优化能力(比如在分组中取每组的前10名)。

SQL中类似的问题还很多,远远不像传说中的那么强悍。限于篇幅我们不能在本文中一一罗列,以后会逐步撰文深入剖析。

gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAA

在运算简单的情况,并且性能要求不高时,用SQL还是比较方便的,毕竟掌握者众多,相关软件也很丰富。但现代应用中的数据需求越来越复杂,数据量也越来越大,继续采用SQL就会严重影响工作效率了。而且,SQL的不适应并非实现层面的问题,而是其基础理论的问题,这不是在工程上进行优化就能解决的。面临当前的数据运算需求,关系代数显得过于简单了,需要从数学上进行彻底的革新。


原文发布时间为:2017-8-1
本文作者:蒋步星
本文来自云栖社区合作伙伴“数据蒋堂”,了解相关信息可以关注“数据蒋堂”微信公众号

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
SQL中数据小数处理(向上取整、向下取整、四舍五入)
SQL中数据小数处理(向上取整、向下取整、四舍五入)
0 0
python读取错误excel记录生成sql,避免手工维护数据
python读取错误excel记录生成sql,避免手工维护数据
0 0
SQL server2019导入Access 2016数据失败解决方法
SQL server2019导入Access 2016数据失败解决方法
0 0
省市区管理sql数据表设计、以及全国省市区全部最新数据
省市区管理sql数据表设计、以及全国省市区全部最新数据
0 0
【Sql Server】进阶之行数据转为列显示
在开发系统维护阶段,经常需要进行各种数据统计,各种报表之类的。 这个时候,行数据转数据显示就发挥作用了。 场景:行数据的某列值想作为字段列显示
0 0
【Sql Server】创建表模拟批量添加数据以及添加的方式
在实际项目场景中,需要快速模拟大批量数据进行查询测试 基于这个需求,模拟大数据方式有很多,这里简答的写几个中在数据库模拟大数据的方式
0 0
【Sql Server】进阶之行数据转为列显示
在开发系统维护阶段,经常需要进行各种数据统计,各种报表之类的。 这个时候,行数据转数据显示就发挥作用了。 场景:行数据的某列值想作为字段列显示
0 0
MySql基础-笔记12 -重复数据处理、SQL注入、导入导出数据
MySql基础-笔记12 -重复数据处理、SQL注入、导入导出数据
0 0
SQL优化之数据复用操作
SQL优化之数据复用操作
0 0
+关注
行者武松
杀人者,打虎武松也。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
用SQL做数据分析
立即下载
阿里云流计算 Flink SQL 核心功能解密
立即下载
Comparison of Spark SQL with Hive
立即下载