前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Oracle 数据库编程语言 PL/SQL 的历史

Oracle 数据库编程语言 PL/SQL 的历史

作者头像
哒呵呵
发布2020-07-22 16:14:51
1.5K0
发布2020-07-22 16:14:51
举报
文章被收录于专栏:鸿的学习笔记鸿的学习笔记

这篇文章讲的是 Oracle 数据库编程语言 PL/SQL 的历史,也从开发者角度解释了创建 PL/SQL 过程中的一些抉择。原文如下,有删减:

  • http://oracle-internals.com/blog/2020/04/29/a-not-so-brief-but-very-accurate-history-of-pl-sql/

另外在阅读本文之前可以先参考下面两个链接,简单了解下编译器的相关知识。

  • https://zhuanlan.zhihu.com/p/53336801
  • http://www.ruanyifeng.com/blog/2014/11/compiler.html
前言

在世界编程语言排行榜里,PL/SQL 一直稳稳占据着前二十的位置。尽管我不是 Matthew Symonds,也与 Softwar 这本书无关,但我依然花费了大量的精力在研究 PL/SQL 的历史上。“Oracle 7 架构非常领先,并像 Sybase 数据库一样,Oracle 7 可以使用全新而优雅的 PL/SQL 编程语言进行编程” ,这也是我为什么会写下关于 PL/SQL 历史的文章的原因。

备注:

  • Matthew Symonds 是一名英国记者,参见维基链接:https://en.wikipedia.org/wiki/Matthew_Symonds
  • Softwar:讲述 Oracle 创始人 Larry Ellison 和 Oracle 故事的书

当第一次开始撰写这段历史时,我以为最多只有几段。然而随着对 PL/SQL 研究的加深和访谈了越来越多的人,发现一篇简短的文章无法囊括所有的 PL/SQL 历史,因此本文仅仅只涵盖了 PL/SQL 诞生历史的一部分内容,尽管关于 PL/SQL 的许多原始的基础代码仍然存在,但是本文并未涵盖编译器优化改进的历史。

画外音:很可惜没有编译器优化的历史,因为创造一门语言相对容易,但是要想使这门语言推广并大规模使用,编译器的优化可能会更加重要。

语言的诞生(第一版 PL/SQL)

Peter Clare 的职业生涯始于 1972 年的 Control Data Corporation(CDC)。尽管现在 CDC 已不复存在了,但在整个 1960 年代和 1970 年代,它是美国最顶级的大型机和超级计算机的公司之一。在软件方面,CDC 的编译器产品部创建了第一个商用的 Pascal 编译器,Peter 在这一部门负责语言和编译器开发,这些开发的目的是为了构建世界上最快的计算机语言处理器。在 CDC 工作的六年期间,Peter 不仅改进了 CDC 的编译器,而且还学习了很多关于语言开发的理论知识,更重要的是,与之相关的工程经验。后面,Peter 离开了 CDC,并成为了一名顾问。

画外音:Peter Clare 是 PL/SQL 的重要贡献者,因此要先介绍它的职业生涯,而在 CDC 的经历让 Peter 学习并精通了一门编程语言开发的方方面面,从而为后续的 PL/SQL 的开发奠定了基础。所以工作不仅仅是赚钱的手段,对于自己而言,也是攒经验的过程。

在1984年,Peter 为了找到额外的顾问工作,翻阅了当地的一家技术出版物,这本技术出版物里有着关于 Oracle 公司招聘的广告。然后 Peter 又通过小道消息得知,Oracle 公司正在将数据库移植到很多平台上,而其中的一个平台正好是 Peter 所擅长的。于是,Peter 认为这份工作很适合他,就打电话给了 Oracle 公司。过了几天后,Peter 接受了 Bob Miner 和 Bill Friend 的面试。

画外音:在远古时代的数据库可不像现在一样可以跨平台部署安装,都是只能一种平台上使用。

在这次面试中,Bob Miner 和 Bill Friend 先考察了 Peter 与平台移植相关的经验。因为当时的 Oracle 公司也在研究数据库的 SQL 预编译器和基于表单的界面(备注:类似于 Excel 界面),所以 Bob Miner 和 Bill Friend 也额外面试了 Peter 对编程语言和编译器开发的掌握程度。面试结束后,Bob 和 Bill 希望 Peter 能全职加入 Oracle 公司。于是,Peter 成为 Oracle 公司的第十三位开发人员。

画外音:可能 Bob Miner 和 Bill Friend 因为自己也在干这个,然后随口一问面试者是不是也懂编程语言开发,结果就发现 Peter 对这块很熟悉。我自己在面试时,有时也会问一些与现有岗位不同的东西,说不定就发现了面试者更大的世界。

Peter 不是一般人眼中典型的 Oracle 开发人员。他的同事形容 Peter 为友好、随和、称职以及能力强的架构师,除此以外,Peter 不仅非常聪明,也非常喜欢水上和帆板运动,Peter 基本上每天都要玩这些运动。Peter 认为“work hard,play hard”,并努力实现工作和生活的平衡(work-life balance)。整个职业生涯中,Peter 一直在追求完美。

画外音:在翻译这段时,有点羡慕 Peter ,工作和生活的平衡是很多程序员追求的梦想吧。

在 Oracle 公司任职的头六个月里,Peter 更多的是负责项目管理,而不是技术方面。Bob 希望自己能专注于开发,而让 Peter 来管理日常项目中的任务。尽管 Peter 喜欢这项工作,但是团队内部的沟通变得越来越困难。Peter 回忆道:“那个时候,Bob 和 Larry 已经合作了一段时间,他们自然可以直接相互交流,但是我作为中间人,并没有让大家都意识到我的作用。” 于是,Peter 转成了技术人员。。

画外音:此时 Peter 表示我也能做开发,而因为自己是刚加入的,并不适合做沟通的工作。在一个小团队里,空降一个项目经理管理日常的任务,即使那个人能力很强,也不一定能起到润滑剂的作用。

考虑到自己在编程语言方面的背景,Peter 开始研究 Oracle 数据库的预编译器。但是不久后他发现另一个需要解决的问题:(数据库厂商间的)竞争。

此时,几个数据库的厂商都在研究数据库上的编程语言,他们的实现方式很相似:要在数据库中执行过程函数就需要用另一种语言写逻辑、编译最后再实现接口。PL/SQL 的第一位产品经理回忆道:“这些方法实际上是有局限性的,有些功能是无法实现的,而 Oracle 公司希望能超越竞争对手并在 Oracle 数据库中提供完整的编程能力。庆幸的是,Oracle 很早就发现了存储过程语言不应该受限于工具本身,而应该在各个工具间保持一致。”这门语言就是 PL/SQL,然后 Peter Clare 发明了它。

画外音:发现一个核心问题可能要比解决问题更重要。

为了完整地创建 PL/SQL,Peter 与 PL/SQL 的第一个正式的开发人员 Kendall Jensen 进行了紧密合作。Peter 说:“Kendall 是非常关键人物,他非常了解如何构建现代编译器,并且知道所有的最新工具。” 首先,Peter 请 Kendall 在 Ada 编程语言上找到他能找到的一切相关知识。

画外音:战略和战术的关系

Kendall 立刻就去了斯坦福图书馆去寻找任何可用的 Ada 编程语言的研究材料。Kendall 拿走了他所能拿走的所有副本,回到 Oracle 公司办公室,并开始阅读。他挑选的其中一本书是由 Gerhard Goos,William A. Wulf,Arthur Evans Jr. 和 Kenneth J. Butler 写的DIANA: An Intermediate Language for Ada。这本书是作为参考手册编写的,其中不仅包含 Ada 编程语言语法,还包含 Ada 编程语言的描述性中间属性表示法的接口描述语言(IDL)规范。在1987年1月,基于这些信息的 PL/SQL 的第一行代码诞生了。

画外音:

  • IDL 是用来描述软件组件界面的一种计算机语言,参考维基百科链接:https://en.wikipedia.org/wiki/Interface_description_language
  • DIANA (Descriptive Intermediate Attributed Notation For Ada)是为 Ada 编程语言设计的描述性中间属性表示法,类似于中间层:https://en.wikipedia.org/wiki/DIANA_(intermediate_language)

PL/SQL 编译器刚开始是完全复制 Ada 编程语言规范的。Kendall 使用 Ada 编程语法参考手册编写了最初的基于 YACC 的解析器,并直接从语法规则操作中生成了 DIANA 树。与其他编程语言的编译器通常会生成抽象的语法树然后将其转换为中间语言不同,这种方法对于类似 Ada 的编程语言更为有效。

画外音:生成抽象的语法树然后将其转换为中间语言,可以理解为 Java 语言使用 JVM 虚拟机作为中间层,这是编程语言设计里常用的套路。PL/SQL 没有选择这种套路的原因,下文也没有叙述,猜测可能因为省去了中间语言的翻译,提高了性能。

为什么 PL/SQL 的语法和功能集是按照 Ada 编程语言建模的呢?因为在1980年代,Ada 编程语言被认为是 Pascal 编程语言的继任者,是一种新兴的编程语言,在美国政府中特别流行。因此有人猜测 Oracle 公司会选择 Ada 编程语言是因为它与政府的友好关系,虽然这种猜测有一定的可信度,但是选择 Ada 编程语言并不是带有意识形态的决定,而是基于 Ada 编程语言潜在的好处选择的。实际上,开发团队希望 PL/SQL 是一种强类型的语言,因为那时的大多数编程语言都是强类型的语言,Oracle 公司并不想在数据库提供不完美的编程语言。尽管后来开发人员在数据库的数据和 PL/SQL 引擎之间的类型转换做了一定的妥协,但后来依然觉得有些遗憾。毕竟,Ada 编程语言是一种简单、安全和模块化的语言,就像 PL/I 是 SQL 和 Ada 的基础一样,它们拥有许多相似之处,使得 Ada 成为了 Oracle 数据库的存储过程语言的建模基础。

画外音:

  • PL/I 是一种程序式、指令式编程语言。由IBM公司在1950年代发明的第三代高级编程语言,用于IBM的MVS、或迪吉多的VAX/VMS等操作系统中。参考维基链接:https://zh.wikipedia.org/wiki/PL/I
  • 有时候一个软件为什么要选型某种架构或者是某种原因,只有创始人才知道原因,也许真的是因为技术上的原因,也许是个人喜好。

最终,由于开发 PL/SQL 的任务量超过了 Peter 和 Kendall 两个人所能承担的的任务量,这个团队就开始加入其它的开发人员。尽管 Kendall 在继续开发他喜欢的解析器和整体的 PL/SQL 语言特征,但是对于每一个新加入的开发者而言,只会专门研究某一个特定的组件。首先,Laurence Hughes 进行了一些清理工作,整理了一些零碎工作,然后让 PL/SQL 朝着面向对象编程语言的方向发展,并开始监督代码生成和执行的工作。Pierre Dufour 加入后不久就对解析器进行了一些改进,然后重点关注于语义层和改进 DIANA 树语义。最后一个加入的是 Gray Clossman。

Gray 回忆道:“当我来到 Oracle 时,这个小组已经为编译器和解释器实现了控制流命令和标量数据类型。PL/SQL 的发展之所以令人兴奋,是因为许多编程语言的概念已经在学术界进行了探索,但尚未使用在商业产品的脚本语言。”Gray 在编程语言设计的多个方面进行了研究,例如他改善了编程语言的内存管理,并接管了 Laurence 在面向对象编程支持方面的最初工作。Peter回忆道:“Gray 比我更了解我之前从未接触的编程语言。他在函数式编程方面拥有丰富的经验,并且对与之相关的所有问题都有清晰的理解。” 虽然有多个开发人员都在为 PL/SQL 工作,只有一个人的工作内容与 PL/SQL 语言本身无关:James Mallory。

在1987年斯坦福大学暑假期间,James 开始了他在 Oracle 公司的工作。作为“第一位不开发编程语言本身的 PL/SQL 程序员”,他编写了经典的“Hello World”程序以及 PL/SQL 质量测试组件的第一个版本。Peter 回忆道:“我们从事这个语言已有一段时间了,当你自己测试这种语言时,你知道要避免某些编译器无法处理的事情(备注:从而无法测试出编译器潜在的问题),因此偶尔用新的眼光去重新理解这种语言是很好的。”

画外音:

  • 所有编程语言入门的第一个程序都是在电脑上打印出“Hello World”。
  • 很喜欢 Peter 这句话,自己是很难发现自己的一些错误。

随着时间的推移,Kendall 预先制定的整个 PL/SQL 的规范充分体现了它的远见卓识,因为这个规范不仅仅只支持 PL/SQL 第一个版本的,也极大地帮助了随后的 PL/SQL 第二个版本的开发。比如在 PL/SQL 第一个版本中只支持简单的过程,而在 PL/SQL 第二个版本中需要在代码生成器和解释器增加新的包,然后发现大部分都已经在 解析器和 DIANA 存在了。Gray 回忆道,“Kendall 始终对项目保持着清醒的认识,他从不迷失在杂草之中,总是冷静地注意到最优先的事项,并且能有力地帮助解决棘手的问题。”

画外音:这种超出现有的问题,并提前看到未来将会面临的问题的能力值得借鉴。

现在开始下一个课题:将 PL\SQL 整合进 Oracle 数据库里。

整合进 Oracle 7(第二个版本的 PL\SQL)

这一切都始于 Bob Miner 位于的 Pacific Heights 的家庭办公室的讨论,在那里 Bob,Peter 和 Roger Bamford 就如何使 Oracle 数据库能更轻松地扩展核心服务的功能交换了意见。Peter 回忆道,“与 Roger 的面对面交流让我受益匪浅,他是一个非常聪明的人,我总是能从他那里学到许多关于数据库的知识,他也从我这里学习到了很多 PL/SQL 的知识。”

作为 Oracle 产品的组件之一,PL/SQL 引擎的架构为 Oracle 数据库提供了许多帮助。首先,这个引擎使用数据库本身作为服务器端去执行命令。其次,这个引擎也可以在客户端运行,并集成到其他 Oracle 产品(例如SQL * Forms)中去。最后,这个引擎可以以类似的客户端方式给 TimesTen 中提供了 PL/SQL 支持。

画外音:TimesTen 是 Oracle 公司提供的内存型关系型数据库,参考链接:https://www.oracle.com/database/technologies/related/timesten.html

尽管大多数人都熟悉服务器端的 PL/SQL,但是熟练使用 PL/SQL 依然需要花费大量的时间和精力。Pierre 回忆道:“让 PL/SQL 在服务器端运行是一场噩梦。在 PL/SQL 设计之初,它不适合在服务器端运行,所以要让 PL/SQL 在 Oracle 7 中运行是一件繁琐的工作,然而却是一件必须要完成的事。还好 PL/SQL 在第一个版本中的没有实现完全,因为数据库团队和 PL/SQL 团队都互相学习到了许多东西。每个团队都从另一个团队中注意到其它团队的问题。”

画外音:首先先把核心功能实现出来,然后再考虑细节和增加其它功能

从客户端的角度来看,PL/SQL 引擎不仅可以在 Forms 中使用,而且还可以在几种定制的工具中使用。Gray 回忆道:“我们与 Oracle 客户端产品的设计师进行了紧张的会议,试图展示他们如何通过作用域而不是命名空间在 PL/SQL 中为应用程序的建模。”

画外音:

  • Forms 类似于 Oracle 数据库的接口。参考链接:https://en.wikipedia.org/wiki/Oracle_Forms
  • 作用域的概念参考文章:https://liujiacai.net/blog/2016/05/28/scope-closure/
  • 命名空间参考链接:https://zh.wikipedia.org/wiki/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4
  • 在编程语言中,命名空间是对作用域的一种特殊的抽象,它包含了处于该作用域内的标识符,且本身也用一个标识符来表示,这样便将一系列在逻辑上相关的标识符用一个标识符组织了起来。

尽管 PL/SQL 引擎依赖于与 Oracle 数据库共享的大量底层平台支持和内存管理代码,但 PL/SQL 引擎选择了将抽象游标接口传递给底层数据库。Kendall 回忆道:“我们想出的将数据库与 PL/SQL 游标接口进行分开是(整个设计)最巧妙的部分之一。” 在 Oracle 中,PL/SQL 游标接口是映射到数据库内核查询层,而在 TimesTen 中,它是与 TimesTen 引擎的独立连接的。

画外音:合理的抽象是减少工作量的必要途径之一。

在1989年末或1990年初,Oracle 公司取得了长足的发展,内部多个开发团队被合并为更大的团队,PL/SQL 团队也不例外。预编译器团队里的其他几位成员也加入到 PL/SQL 的开发中。鉴于开发人员掌握技能的相似性,这次重组对 Oracle 公司是有利,这立即导致了几项对PL/SQL 的改进措施。值得注意的改进是 Terry 和 Jeffrey Olkin 的工作所产生的成果,其它团队里的人亲切地把他们称为“The Wonder twins”。

Pierre 回忆道:“Terry 拥有超强的技术能力,他熟悉我们的 YACC 技术,该技术是 PL/SQL 和预编译器的基础。”Terry 对编程语言一直都充满着热情。Terry 说:“建立一种编程语言,使用户可以从高层指定计算机应该做什么,并将这种想法转化为计算机可以理解并可以执行的功能,对我来说是一件很神奇的事。” 因此,在加入 PL/SQL 开发之前,他花了几年时间改进 Oracle 的预编译器。在那段时间里,Terry 还对 SQLLIB 进行了重大改进,SQLLIB 是所有 Oracle 预编译器为其生成代码的基础共享库,并创建了 PLAX,直到今天 PL/SQL 仍依赖于解析器生成器 SLAX。然而并不是为了 PL/SQL 而创建的 SLAX。

在1980年代,Oracle 支持 Ada,C/C ++,COBOL,FORTRAN,Pascal 和 PL/I 宿主编程语言(host programming languages)的 SQL 预编译器。当时,每个预编译器都使用一个手写的解析器,这使得很难跟踪每个编程语言所支持的功能。又或者可以通过使用解析器生成器,开发人员可以更轻松地指定宿主编程语言的语法并生成用于对其进行解析的代码。不幸的是,尽管这使定义预编译器(通过 EXEC SQL)和宿主编程语言支持的嵌入式 SQL 的语法变得容易,但同时进行解析却成了一个问题。

画外音:宿主编程语言参考链接:https://www.oreilly.com/library/view/access-database-design/1565926269/ch07s07.html

从技术角度来看,要使 YACC 在同一解析器中实现多个语法之间切换,必须使用一种用户看不见的特定符号。然后,解析器和词法分析器必须要根据被标记的语言进行相应的词法分析和解析。当词法分析器识别出 island grammar 时,就会切换状态并必须加入特定符号,以便 YACC 可以选择适当的 island grammar 语法规则(而不是宿主语言规则)。同样,当 YACC 认为它已经解析了 island grammar 时,它必须通知词法分析器它应该将其状态切换回宿主语言。尽管这些都可以使用 YACC,但实现所有的语言语法是非常痛苦的一件事。由于预编译器组需要将相同的嵌入式 SQL 解析器集成到多种宿主语言中,因此他们需要一种工具来使他们轻松地做到这一点。这个工具就是 SLAX。

画外音:island grammar 参考维基链接:https://en.wikipedia.org/wiki/Island_grammar

SLAX 是内部兼容 YACC 的解析器生成器。虽然它看起来像是首字母缩写词,但事实并非如此。SLAX 是 Segmented Language YACC 的意思。虽然 SLAX 与 YACC 没有共同的代码,Terry 依然决定向 YACC 表示敬意,因此命名为 SLAX。刚开始时,SLAX 做的不错,到后来 SLAX 进行了修改并最终被重写。John Ciminski 改写了 Terry 所说的“正确的方式”,此时 SLAX 变成了一种行之有效的工具,可以替代 PL/SQL 解析器对 YACC 的使用。Terry 在1990年某个时候开始从事 PL/SQL 的工作之前,就将 PL/SQL 从 YACC 转换为 SLAX,然后改进了基础解析器本身。

画外音:这段有些艰深了,不太好翻译,感兴趣的可以读读原文。

最初,开发团队只关注了 PL/ SQL 语言本身,对性能并不是很关注,也不是很关键。但是,随着越来越多的客户开始使用 PL/SQL,性能便成为问题所在。这里的主要的性能瓶颈是第一个版本的 PL/SQL 虚拟机(“VM”),该版本是基于堆栈的字节码解释器,与当时的标准 Pascal 字节码(p-code)解释器相似。

在基于堆栈的虚拟机中,表达式操作算子被压入堆栈,然后在需要进行计算时弹出。对于当时的机器性能而言,这太慢了。在软件中解释每个字节码指令的开销很大,一个简单的计算可能都需要数十条指令,而执行所花费的大部分时间都花在了那笔开销上。

在 Ada 中,情况更糟,因为操作算子可以引用在多个作用域和多个包中的变量。所以 Jeffrey 首先重写了所有内容,并为操作算子创建了一种“迷你解释器。因此,无论操作算子的地址多么复杂,都可以将其作为单字节代码指令的一部分进行检索。这次的变化大大减少了指令解码的开销,并使大型 PL/SQL 程序有了可行度。关于这项改进,Kendall 回忆道:“我依然记得它,这是辉煌而美丽的代码,确实很优雅。”James 于1990年再次加入 Oracle 公司,他也提到新虚拟机的效率也要比之前高得多。

画外音:还是那句话,首先得关注功能的完整性,最后再考虑性能这些。

PL/SQL 的尾声

最终,每个人都将从 PL/SQL 转移到其他项目或者离开 Oracle 公司。Gray Clossman 继续在 Oracle 公司创建其他与语言相关的功能,例如 SQLJ。Pierre Dufour 转到了应用程序端,在那里他从事 CRM 的工作,并构建了仅供内部使用的 PL/SQL 编译器 Rosetta,这使得 Java 和 PL/SQL 之间进行调用而无需进行修改成为可能。在周末观看了实现 ANSI SQL 模块语言的工具的演示之后,Terry Olkin 建立了一个原型,该原型对 Oracle 也有帮助,从而导致了 SQL * Module 产品的创建。

画外音:一切都有终章,当 PL/SQL 成熟并流行后,开发团队就不需要那么多人了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 语言的诞生(第一版 PL/SQL)
  • 整合进 Oracle 7(第二个版本的 PL\SQL)
  • PL/SQL 的尾声
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档