比SQL还好用,又一门国产数据库语言诞生了

文章目录

    • 一、数据库语言的目标
      • 1、什么是数据库/li>
      • 2、什么样的计算体系才算好呢/li>
      • 3、SQL 中的 Q
    • 二、SQL为什么不行
      • 1、复杂的语句语法
      • 2、排序的复杂度
      • 3、程序代码实现计算到底是在干什么/li>
      • 4、跑不快的原因
      • 5、关系代数
    • 三、SPL为什么能行
      • 1、游离记录
      • 2、有序性
      • 3、离散性与集合化
      • 4、分组理解
      • 5、聚合理解
      • 6、有序支持的高性能
        • 1) 数据表对主键有序
        • 2) 分组运算是用HASH算法
        • 3) 数据表对键有序
        • 4) 大表作为外键表的连接

一、数据库语言的目标

??要说清这个目标,先要理解数据库是做什么的。

1、什么是数据库/h3>

??数据库这个软件,名字中有个“库”字,会让人觉得它主要是为了存储的。其实不然,数据库实现的重要功能有两条:计算事务!也就是我们常说的 OLAP 和 OLTP,数据库的存储都是为这两件事服务的,单纯的存储并不是数据库的目标。
??我们知道,SQL是目前数据库的主流语言。那么,用SQL做这两件事是不是很方便呢br>

??写着简单,很好理解,就是让程序员很快能写出来代码来,这样单位时间内可以完成更多的工作;跑得快就更容易理解,我们当然希望更短时间内获得计算结果。

3、SQL 中的 Q

??其实SQL中的 Q 就是查询的意思,发明它的初衷主要是为了做查询(也就是计算),这才是SQL的主要目标。然而,SQL在描述计算任务时,却很难说是很胜任的。

二、SQL为什么不行

??先看写着简单的问题。
??SQL写出来很象英语,有些查询可以当英语来读和写( 上多得很,就不举例了),这应当算是满足写着简单这一条了吧。

1、复杂的语句语法

??且慢!我们在教科书上看到的SQL经常只有两三行,这些SQL确实算是写着简单的,但如果我们尝试一些稍复杂化的问题呢br> ??这是一个其实还不算很复杂的例子:计算一支股票最长连续上涨了多少天SQL写出来是这样的:

??这个语句的工作原理就不解释了,反正有点绕,同学们可以自己尝试一下。
??这是润乾公司的招聘考题,通过率不足20%;因为太难,后来被改成另一种方式:把SQL语句写出来让应聘者解释它在算什么,通过率依然不高。
??这说明什么明情况稍有复杂,SQL就变得即难懂又难写!

2、排序的复杂度

??所以呢,对于程序来讲,跑得快和写着简单其实是同一个问题,背后还是这个形式语言采用的代数的问题。如果这个代数不好,就会导致高性能算法很难实现甚至实现不了,也就没办法跑得快了。就象上面说的,用SQL写不出我们期望的小内存单次遍历算法,能不能跑得快就只能寄希望于优化器。
??我们再做个类比:

上过小学的同学大概都知道高斯计算1+2+3+…+100的小故事。普通人就是一步步地硬加100次,高斯小朋友很聪明,发现1+100=101、2+99=101、…、50+51=101,结果是50乘101,很快算完回家午饭了。

??听过这个故事,我们都会感慨高斯很聪明,能想到这么巧妙的办法,即简单又迅速。这没有错,但是,大家容易忽略一点:在高斯的时代,人类的算术体系(也是一个代数)中已经有了乘法!象前面所说,我们从小学习四则运算,会觉得乘法是理所当然的,然而并不是!乘法是后于加法被发明出来的。如果高斯的年代还没有乘法,即使有聪明的高斯,也没办法快速解决这个问题。

??目前主流数据库是关系数据库,之所以这么叫,是因为它的数学基础被称为关系代数,SQL也就是关系代数理论上发展出来的形式语言。
??现在我们能回答,为什么SQL在期望的两个方面做得不够好strong>问题出在关系代数上,关系代数就像一个只有加法还没发明乘法的算术体系,很多事做不好是必然的。

5、关系代数

??关系代数已经发明五十年了,五十年前的应用需求以及硬件环境,和今天比的差异是很巨大了,继续延用五十年前的理论来解决今天的问题,听着就感觉太陈旧了而现实就是这样,由于存量用户太多,而且也还没有成熟的新技术出现,基于关系代数的SQL,今天仍然是最重要的数据库语言。虽然这几十年来也有一些改进完善,但根子并没有变,面对当代的复杂需求和硬件环境,SQL不胜任也是情理之中的事。
??而且,不幸的是,这个问题是理论上的,在工程上无论如何优化也无济于事,只能有限改善,不能根除。不过,绝大部分的数据库开发者并不会想到这一层,或者说为了照顾存量用户的兼容性,也没打算想到这一层。于是,主流数据库界一直在这个圈圈里打转转。

三、SPL为什么能行

??那么该怎样让计算写着更简单、跑得更快呢strong>发明新的代数!有“乘法”的代数。在其基础上再设计新的语言。
??这就是SPL的由来。它的理论基础不再是关系代数,称为离散数据集。基于这个新代数设计的形式语言,起名为SPL(Structured Process Language)。
??SPL针对SQL的不足(更确切地说法是,离散数据集针对关系代数的各种缺陷)进行了革新。SPL重新定义了并扩展许多结构化数据中的运算,增加了离散性、强化了有序计算、实现了彻底的集合化、支持对象引用、提倡分步运算。
??把前面的问题用SPL重写一遍有个直接感受。
??一支股票最长连续上涨多少天:

??计算思路和前面的SQL相同,但因为引入了有序性后,表达起来容易多了,不再绕了。
??1亿条数据中取前10名:

??SPL有更丰富的集合数据类型,容易描述单次遍历上实施简单聚合的高效算法,不涉及大排序动作。
??限于篇幅,这里不能介绍SPL(离散数据集)的全貌。我们在这里列举SPL(离散数据集)针对SQL(关系代数)的部分差异化改进:

1、游离记录

??离散数据集中的记录是一种基本数据类型,它可以不依赖于数据表而独立存在。数据表是记录构成的集合,而构成某个数据表的记录还可以用于构成其它数据表。比如过滤运算就是用原数据表中满足条件的记录构成新数据表,这样,无论空间占用还是运算性能都更有优势。
??关系代数没有可运算的数据类型来表示记录,单记录实际上是只有一行的数据表,不同数据表中的记录也不能共享。比如,过滤运算时会复制出新记录来构成新数据表,空间和时间成本都变大。
??特别地,因为有游离记录,离散数据集允许记录的字段取值是某个记录,这样可以更方便地实现外键连接。

2、有序性

??关系代数是基于无序集合设计的,集合成员没有序 的概念,也没有提供定位计算以及相邻引用的机制。SQL实践时在工程上做了一些局部完善,使得现代SQL能方便地进行一部分有序运算。
??离散数据集中的集合是有序的,集合成员都有序 的概念,可以用序 访问成员,并定义了定位运算以返回成员在集合中的序 。离散数据集提供了符 以在集合运算中实现相邻引用,并支持针对集合中某个序 位置进行计算。
??有序运算很常见,却一直是SQL的困难问题,即使在有了窗口函数后仍然很繁琐。SPL则大大改善了这个局面,前面那个股票上涨的例子就能说明问题。

3、离散性与集合化

??关系代数中定义了丰富的集合运算,即能将集合作为整体参加运算,比如聚合、分组等。这是SQL比Java等高级语言更为方便的地方。
??但关系代数的离散性非常差,没有游离记录。而Java等高级语言在这方面则没有问题。
??离散数据集则相当于将离散性和集合化结合起来了,既有集合数据类型及相关的运算,也有集合成员游离在集合之外单独运算或再组成其它集合。可以说SPL集中了SQL和Java两者的优势。
??有序运算是典型的离散性与集合化的结合场景。次序的概念只有在集合中才有意义,单个成员无所谓次序,这里体现了集合化;而有序计算又需要针对某个成员及其相邻成员进行计算,需要离散性。
??在离散性的支持下才能获得更彻底的集合化,才能解决诸如有序计算类型的问题。
??离散数据集是即有离散性又有集合化的代数体系,关系代数只有集合化。

4、分组理解

??分组运算的本意是将一个大集合按某种规则拆成若干个子集合,关系代数中没有数据类型能够表示集合的集合,于是强迫在分组后做聚合运算。
??离散数据集中允许集合的集合,可以表示合理的分组运算结果,分组和分组后的聚合被拆分成相互独立的两步运算,这样可以针对分组子集再进行更复杂的运算。
??关系代数中只有一种等值分组,即按分组键值划分集合,等值分组是个完全划分。
??离散数据集认为任何拆分大集合的方法都是分组运算,除了常规的等值分组外,还提供了与有序性结合的有序分组,以及可能得到不完全划分结果的对位分组。

5、聚合理解

??关系代数中没有显式的集合数据类型,聚合计算的结果都是单值,分组后的聚合运算也是这样,只有SUM、COUNT、MAX、MIN等几种。特别地,关系代数无法把TOPN运算看成是聚合,针对全集的TOPN只能在输出结果集时排序后取前N条,而针对分组子集则很难做到TOPN,需要转变思路拼出序 才能完成。
??离散数据集提倡普遍集合,聚合运算的结果不一定是单值,仍然可能是个集合。在离散数据集中,TOPN运算和SUM、COUNT这些是地位等同的,即可以针对全集也可以针对分组子集。
??SPL把TOPN理解成聚合运算后,在工程实现时还可以避免全量数据的排序,从而获得高性能。而SQL的TOPN总是伴随ORDER BY动作,理论上需要大排序才能实现,需要寄希望于数据库在工程实现时做优化。

6、有序支持的高性能

??离散数据集特别强调有序集合,利用有序的特征可以实施很多高性能算法。这是基于无序集合的关系代数无能为力的,只能寄希望于工程上的优化。
??下面是部分利用有序特征后可以实施的低复杂度运算:

1) 数据表对主键有序

??数据表对主键有序,相当于天然有一个索引。对键字段的过滤经常可以快速定位,以减少外存遍历量。随机按键值取数时也可以用二分法定位,在同时针对多个键值取数时还能重复利用索引信息。

2) 分组运算是用HASH算法

??通常的分组运算是用HASH算法实现的,如果我们确定地知道数据对分组键值有序,则可以只做相邻对比,避免计算HASH值,也不会有HASH冲突的问题,而且非常容易并行。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年2月21日
下一篇 2022年2月21日

相关推荐