数据库语言的目标要明确这个目标,首先要了解数据库是干什么的。数据库这个软件名字里有“图书馆”二字,让人以为它主要是用来存储的。其实数据库实现的有两个重要的功能:计算和事务!也就是我们常说的OLAP和OLTP。数据库的存储就是为这两件事服务的。纯存储不是数据库的目标。我们知道,SQL是目前数据库的主流语言。那么,用SQL来做这两件事不是很方便吗?事务功能主要解决读写时保持数据一致性的问题。实现这一点并不容易,但是应用程序的接口很简单,操作数据库读写的代码也很简单。.如果假设当前关系数据库的逻辑存储方式是合理的(即使用数据表和记录存储数据的合理性又是一个复杂的问题,这里不展开),那么SQL就无所谓了在描述交易功能时。一个大问题,因为不需要描述复杂的动作,复杂度在数据库内部解决了。但计算功能不同。这里所说的计算是一个更广泛的概念,不仅仅是简单的加法,加法,减法,查找和关联都可以看作是某种计算。什么样的计算系统被认为是好的?或者二:写的简单,运行的快。它编写简单,易于理解。是为了让程序员能够快速编写代码,让单位时间可以完成更多的工作;如果它运行得更快,就更容易理解。当然,我们希望在更短的时间内得到计算结果。其实SQL中的Q就是查询的意思。发明它的初衷主要是为了做查询(也就是计算),这也是SQL的主要目标。然而,SQL很难描述计算任务。SQL为什么不行先看写的简单题。SQL写的很像英文,有些查询可以用英文读写(网上有很多,就不举例了),应该算是简单了。等待!我们在课本上看到的SQL,往往只有两三行。这些SQL写起来确实简单,但是如果我们尝试一些稍微复杂一点的问题呢?这是一个其实并不复杂的例子:计算一只股票连续上涨了多少天?它是用SQL写成这样的:selectmax(consecutive_day)from(selectcount(*)(consecutive_dayfrom(selectsum(rise_mark)over(orderbytrade_date)days_no_gainfrom(selecttrade_date,casewhenclosing_price>lag(closing_price)over(orderbytrade_date)then0else1ENDrise_markfromstock_price))groupbydays_no_gain)这个语句的工作原理我就不解释了,反正有点绕,同学们可以自己试一下,这是招聘考试题润干公司,通过了,通过率不到20%;因为太难了,后来换了个方法:把SQL语句写出来,让应聘者说明是什么,通过率还是不高.这是什么意思呢?说明情况有点复杂,SQL变得难以理解和编写了!看跑得快的问题,还是一个简单的经常用到的例子:取top10一亿条数据中。这个任务用SQL写起来并不复杂:SELECTTOP10xFROMTORDERBYxDESC但是这个语句对应的执行逻辑是先对所有数据进行排序,然后取出前10个,不要后者。大家知道,排序是一个很慢的动作,而且会遍历很多次数据,如果数据量太大,内存装不下,就需要缓存到外存中,性能会进一步急剧下降.如果严格按照这句SQL所体现的逻辑,这个操作无论如何都跑不快。不过很多程序员都知道,这个操作不需要大排序,也不需要外存缓存。一次遍历用一点内存就可以完成,也就是有更高性能的算法。不幸的是,这样的算法不能用SQLAlgorithms来写,我们只能寄希望于数据库优化器足够聪明,将这条SQL转换成高性能的算法来执行,但是当情况复杂时,数据库优化器可能并不可靠。显然,SQL在这两方面做得不够好。这两个不复杂的问题就是这种情况。现实中,几千行的SQL代码写起来难度大,跑不快。为什么不用SQL?要回答这个问题,我们必须分析这些计算在程序代码中做了什么。从本质上讲,编写程序的过程就是将解决问题的思想转化为计算机可执行的精确形式化语言的过程。比如小学生做一道题。在分析问题并提出解决方案后,他们必须列出四种算术运算的表达式。用程序计算也是如此。你不仅要想出问题的解决方案,还必须将解决方案转化为计算机可以理解并执行的动作来完成它。用于描述计算方法的形式语言的核心在于所使用的代数系统。所谓代数系统,简单来说就是一些数据类型和对它们的运算规则。比如小学学的算术就是整数和加减乘除运算。有了这套工具,我们就可以用这个代数系统约定好的符号,也就是代码,把我们要做的计算写出来,然后计算机就可以执行了。如果这个代数系统的设计不周到,提供的数据类型和操作不方便,就会使算法的描述变得非常困难。这时候就会出现一个奇怪的现象:将解决方案翻译成代码的难度远大于解决问题本身。例如,我们从小就学会用阿拉伯数字进行日常计算。做加减乘除都非常方便。大家想当然地认为数值计算就应该是这样的。其实不一定!估计很多人都知道有一种东西叫罗马数字。你知道罗马数字的加减乘除吗?古罗马人是怎么上街买菜的?编写代码的难度主要是代数问题。下面我们来看看跑不快的原因。软件没有办法改变硬件的性能,CPU和硬盘应该有多快。但是,我们可以设计一个低复杂度的算法,也就是计算量较小的算法,这样计算机执行的动作就少了,自然也就快了。但是,仅仅想出一个算法是不够的,算法必须以某种形式的语言写成,否则计算机是不会执行的。而且写起来比较简单,写起来很麻烦,也不会有人用。所以,对于一个程序来说,跑得快和写得简单其实是同一个问题,背后是这个形式语言使用的代数问题。如果这个代数不好,就很难甚至无法实现高性能的算法,跑得快也无从谈起。上面说了,我们期望的小内存单遍历算法是SQL写不出来的,只能寄希望于优化器能不能跑的快。再打个比方:上过小学的同学大概都知道高斯计算1+2+3+...+100的故事。普通人就是一步步加100倍。高斯很聪明,发现1+100=101,2+99=101,...,50+51=101,结果是50乘以101,很快就回家吃午饭了。听完这个故事,我们都觉得高斯很聪明,能想到这么巧妙的方法,简单快捷。这没有错,但是大家很容易忽略一点:在高斯时代,人类的算术系统(也是代数)就已经有了乘法!前面说过,当我们从小学习四项算术运算时,我们会认为乘法是理所当然的,其实不然!乘法是在加法之后发明的。如果高斯时代没有乘法,即使是再聪明的高斯也无法快速解决这个问题。目前主流的数据库是关系型数据库,之所以这样称呼是因为它的数学基础叫关系代数,而SQL是在关系代数理论中发展起来的一种形式化语言。现在我们可以回答了,为什么SQL在这两个方面做得不够好?问题在于关系代数。关系代数就像一个算术系统,只会加法而不会发明乘法。很多事情做不好是必然的。关系代数是50年前发明的。50年前的应用需求和硬件环境与今天有很大的不同。继续用50年前的理论来解决今天的问题,听起来太过分了。过时的?然而,现实就是这样。由于现有用户众多,缺乏成熟的新技术,基于关系代数的SQL仍然是当今最重要的数据库语言。尽管在过去几十年中有所改进,但基本面没有改变。面对当代复杂的需求和硬件环境,SQL无能为力也在情理之中。而且,不幸的是,这个问题是理论上的,在工程上再怎么优化也于事无补。它只能在有限的范围内得到改善,无法根除。但是,大多数数据库开发人员并没有想到这一层,或者为了照顾现有用户的兼容性,他们并不打算想到这一层。于是,主流数据库行业一直在兜圈子。为什么SPL有效?那么如何让计算更容易编写并运行得更快呢?发明一个新的代数!代数中有“乘法”。以此为基础,设计了一种新的语言。这就是SPL的用武之地。它的理论基础不再是关系代数,称为离散数据集。基于这种新的代数设计的形式语言被命名为SPL(结构化过程语言)。SPL彻底改变了SQL的缺陷(更准确地说,是关系代数的离散数据集缺陷)。SPL在很多结构化数据中重新定义和扩展了操作,增加了离散性,加强了有序计算,实现了完全集合,支持对象引用,提倡分步操作。用SPL重写上一题有直接的感觉。一只股票最长连续上涨多少天:stock_price.sort(trade_date).group@i(closing_price
