45 年前,两名年轻的 IBM 研究员将一门关系型语言带到了数据库领域,旨在使用声明性的方式来操作数据。从 Don Chamberlin 和 Ramond Boyce 发表“SEQUEL:一门结构化的英语查询语言”以来,关系型模型和 SQL 已经得到了广泛扩展,并被用在大量的技术中,如 OLTP、OLAP、对象数据库、对象关系型数据库,甚至是 NoSQL 数据库。SQL 也为非关系型数据库带去了设计灵感,比如用于对象数据库的 SQL、用于对象关系的 SQL、用于 XML 的 SQL、用于空间数据的 SQL、用于搜索的 SQL、用于 JSON 的 SQL、用于时序数据的 SQL、用于流的 SQL,等等。各种与数据打交道的 BI 工具也使用了 SQL。事实上,SQL 是最成功的第四代语言。
SQL 之所以神秘,是因为它的强大。
SQL 以关系代数为基础,目标是提供一种接近英语的查询语言:
- 具有声明性;
- 可以通过组合的方式写出复杂的查询;
- 可以利用由 Edger F Codd 开发的关系型模型。
大数据试图在数据仓库领域补足或替换关系型系统,但它们仍然使用了 SQL。Hive、Impala、drill、BigSQL 都使用了基于 SQL 的语言、优化器,并使用了与 SQL 相似的大规模并行处理。它们还时不时地增加新的 SQL 特性。SQL 中的数据存储格式、数据模型和查询处理的分离带来了一些非常重要的好处。在 SQL 诞生以来的 45 年当中,很多数据库来了又去。NoSQL 运动浪潮甚至在无意中暗示了 SQL 和 SQL 数据库即将死掉。但 SQL 阵营很坦然地面对这个问题,Don Chamberlin 最近表示:“当一门语言被广泛认可,以至于其他语言开始标榜自己不同于这一门语言时,说明这门语言一定表现得很好”。
另一个数据库阵营是 NoSQL。虽然现在对 NoSQL 的定义是“Not Only SQL”,但其实 NoSQL 在最开始想要远离 SQL,并尝试使用其他语言和框架,比如 map-reduce。但在十年之后,几乎每一个流行的 NoSQL 数据库都有了 SQL 变种:Couchbase 的 N1QL、Cassandra 的 CQL 和 Elasticsearch 的 ElasticSearch SQL。你可能会说:“MongoDB 并没有 SQL”。但我敢肯定地说:“它将会有一个非常简单的 SQL 实现”。
关系型模型已经非常成功了,不过数据库还支持其他各种数据模型:JSON、图、XML、时序、空间、长列、列式、文档,等等。这些数据库当中大部分都有自己的 SQL 实现版本,即使是 NoSQL 数据库也实现了 SQL 或者受 SQL 启发的查询语言。即使是在最性感的“数据科学”领域,SQL 仍然是一项非常被看重的技能。
现在,NoSQL 数据库中的 SQL 项目比 SQL 数据库中的 SQL 项目还要多。
为什么 SQL 会如此成功?
- 可声明性:你只要声明好要输出什么,查询引擎会为你找到最优化的方式来执行查询。Pat Seliner 等人在 1979 年发明的基于成本的优化器一直在持续地提升 SQL 的查询速度。这也提高了其他新进者的准入门槛。最近的一篇Apache Hive 论文解释了优化器的复杂性。
- SQL 不只是被用在“查询”方面,它也被用来更新数据,而存储过程、UDF(用户自定义函数)通过结合过程语言和声明性的 SQL 扩展了 SQL 的能力。
- SQL 具有非常好的可延展性。SQL 标准经过多次扩展,每次都加入了很多新特性、新语法和新的关键字。可以肯定的是,并不是所有 SQL 标准都是一样的。即使是 RDBMS 的传统 SQL 实现也不会完全兼容,除非在写 SQL 时非常小心地考虑兼容性问题。除了这些之外,SQL 的精髓都是一样的。SQL++ 是 SQL 进化的一个很好的例子。Don Chamberlin 和 Mike Carey 就 SQL 是否需要支持复杂的数据模型进行过讨论,以便让用户和开发人员可以方便地访问 JSON 格式的数据。Don 撰写的“SQL++ For SQL User: A Tutorial”一书介绍了 SQL++ 的发展情况,SQL++ 是一门被设计用来处理 JSON 数据模型的语言,同时与 SQL 兼容。
- SQL 为我们带来了新的想法,扩展了新的数据类型、访问方式和应用场景。
- SQL 本身与数据表示是分离的,可以被用在非关系型数据上,比如 CSV、JSON 以及其他所有的大数据格式。有些人认为关系型模型表示非常死板,所以认为 SQL 也是死板的。但事实上,对于给定的 schema,SQL 可以实现任意数据格式的 SELECT、连接、分组、聚合。
SQL 的支持情况
既然 SQL 现在已经无处不在,我们就有必要对 SQL 的支持情况进行一番了解。
- 了解每种工作负载的特点和目标。例如,是交互式的应用程序还是交互式分析?抑或是批次分析或 BI?
- SQL 所支持的语句反应了运维能力。
- 在表达式(标量、聚合、布尔值)、连接(内连接、左 / 右 / 全连接)、子查询、视图、排序、分页(LIMIT/OFFSET)方面的能力。
- 索引:没有索引的 SQL 只是一个图灵机原型。
- 优化器:查询重写、选择正确的访问路径、创建最优的查询执行路径让 SQL 成为最成功的第四代语言。有一些带有基于规则的优化器,有一些则带有基于成本的优化器,有一些二者兼而有之。优化器是非常重要的一个因素,一般的测试基准(如 TPC-C、TPC-DS、YCSB、YCSB-JSON)在这方面帮不上什么忙。
- 有句话是这么说的:“性能、性能和性能是数据库最重要的三件东西”。对工作负载进行性能方面的测试是非常关键的,YCSB 和它的扩展 YCSB-JSON 可以在这方面帮上忙。
- SDK:丰富的 SDK 和语言支持可以加快开发速度。
- BI 工具支持:对于大型的数据分析来说,BI 工具的支持是非常重要的。
N1QL 作者 Gerald Sangudi 曾经表示,SQL 是非常成功的,因为它代表了数据处理的基本操作。SQL 支持一组丰富的操作,SELECT、连接、嵌套、分组、聚合、HAVING、WINDOW、排序、分页,等等。在谈到数据操作时,这些就是我们要考虑的所有东西吗?这个问题还有待观察,不过我们可以肯定的是,其他语言(比如 Python 和 Java)正在为这些数据操作添加运算符。或许其他的语言也会跟风。SQL 已经走到了关系型模型没能走到的地方。