我希望现代关系查询语言具备这些特性,你怎么看? 📅 发布时间:2026/8/25 6:40:05 👁 浏览次数: 太空叉勺派对我希望现代关系查询语言具备的特性这是一篇搁置多年的旧草稿。最近关于新查询语言如 Acadia的讨论促使作者重新审视、修订并发布这篇文章。作者认为 NoSQL 兴起的一个主要原因是SQL 虽强大但实现方式往往笨拙且陈旧。一种借鉴 SQL 的语言能让程序员更便捷地处理关系型数据。作者将结合实际场景中遇到的问题思考一种更优秀的查询语言如何提供帮助也期待大家一起探讨还能做些什么。作者使用 RDBMS 的经验作者使用 RDBMS 的经验主要集中在 MySQL 和 Db2但也使用过 SQLite、SQL Server、Oracle 和 Postgres熟悉程度依次递减。更优语法作者个人对语法的美观性并不挑剔但很多人很在意。程序员就像小孩子更喜欢简单易懂的东西。基于 PL/I 的语法是 20 世纪 70 年代 IBM 的选择放在今天可能行不通。由于大家的普遍需求新的查询语言可能会借鉴 C 或 Python 的语法风格或许还会受到 ML 或 Prolog 的影响就像 Rust 那样。有了更好的语法也有望出现更优秀的解析器。作者特别讨厌 MySQL 的解析器它从不明确指出问题所在或问题是什么除非遇到像 DELIMITER 这样荒谬的语法错误。不过传统实现中也有更好的 SQL 解析器比如 Oracle 在报错时能清晰告知预期内容这一点就很出色。作者给出的示例仅作展示并不拘泥于特定的语法也不强行规定必须采用何种语法。这些示例很可能受 F#ML 家族、Erlang类似 Prolog和 Elixir类似 Erlang 和 Ruby的影响。对函数式编程友好的函数式编程语言SQL 作为 4GL 语言其强大之处在于只需描述想要的数据而无需手动循环处理这与许多函数式编程范式如惰性求值就像 Haskell非常相似。遗憾的是大多数 SQL 方言的标准库在这方面有所欠缺它们主要针对 20 世纪 80 年代的过程式程序进行优化。大多数 SQL 方言最终都支持存储过程而存储过程本质上是过程式的这与 SQL 的声明式特性相悖。这也反映在大多数用户的 SQL 代码中他们往往模仿语言和标准库容易实现的风格涉及大量可变状态如游标和过程而非函数。默认设置很重要。更透明的查询规划器虽然作为 4GL 语言编译器和优化器能强大地优化大部分代码但也容易因一个小错误导致查询成本大幅增加。而且除非你是 SQL 优化专家否则查询规划器的输出可能让人摸不着头脑再次吐槽 MySQL 的 “explain” 工具实在太差劲了。虽然这与编程语言理论PLT没有严格关联但却是当前 SQL 实现中的薄弱环节计算机科学家对此已经有了很多研究。更出色的用户自定义类型一些 RDBMS 提供了 “域domain” 的概念用于指定用户自定义数据类型这也是 SQL 规范的可选部分但这些域的功能有限通常只是对范围或检查的简单封装。似乎只有 Postgres 支持这一特性Oracle 最近才开始支持而且似乎比 Postgres 更灵活。遗憾的是作者对它们的实际使用情况了解不多。不过“域” 的概念在 Codd 的《关系模型》 _The Relational Model_ 中有提及这本书是 RDBMS 的奠基之作。考虑到 Postgres 源自 Ingres而 Ingres 基于 QUELQUEL 比 SQL 更接近 Codd 对 RDBMS 的设想所以 Postgres 支持这一特性也就说得通了。求和类型、带标签的联合类型和模式匹配以一个返回栈帧信息的函数为例展示了现代函数式编程技术如何应用于关系查询语言。这里提到的操作系统 IBM i在 “服务” 框架下提供了许多用于系统管理的 SQL 函数。虽然这对从 DBA 转型的系统管理员在调试时非常有用但使用起来很笨拙因为实际上有些列 “组” 是互斥的因此有很多可空列而且字符串字段实际上是枚举类型。其中一些问题是由于糟糕的模式设计可能还因为必须在 _单个_ 表中返回结果返回多个表或许是个有趣的改进方向字符串枚举类型可以通过在充当枚举的表上添加外键约束来解决。不过部分问题也源于实现中语言的表达能力不足。基于这个想法作者尝试给出一个更好的示例让查询更简洁、更不易出错。如果能合并互斥的列集也会让数据可视化变得更简单。例如若能将这些列转换为每行大列中的子列或根据不同类型以不同字符串显示就无需频繁左右滚动查看数据了。支持多类型匹配的外键假设作者有 “Software”、“Version” 和 “Download” 表类似 WEMI 层次结构每个表都可能关联图片用 “Picture” 表存储图片信息。通常每种关系都需要一个多对多表如 “SoftwarePicture”、“VersionPicture” 等。但如果能有一个多对多表其外键采用带标签的联合类型就可避免这种无意义的重复。关于文章的评论文章有 6 条评论其中 James K. Lowden 表示 20 年来一直在思考并钻研这个问题还在 Ingres 会议上做过相关报告他知道答案剩下的就是编程实现的小问题了。他未完成的演示项目叫 coddb其语法基于 Scheme。表是 Scheme 变量关系运算符是 Scheme 函数没有查询优化器。相反程序员可以完全控制并遵循一个约定每个运算符根据输入定义性能。这让数据库编程不再神秘与普通编程处于同一水平。由于 Scheme 是一种普通的图灵完备语言而且比大多数语言更具扩展性应用程序编程和数据库编程之间的界限消失了。在 Scheme 中方便实现的功能都可以用它完成其他部分可以用 “宿主语言” 处理具体用什么语言都行。Barney Keene 则表示这篇文章引起了他强烈的共鸣他一直觉得当必须将新语法 “编译” 成 SQL之后 SQL 又会被编译回去时这个过程感觉抽象边界太多。他正在开发一个新的关系数据库可能会很有意思。它不使用 SQL 作为接口而是像 LLVM 这样的编译器工具链一样暴露一个中间表示IR。这让你可以用任何语言作为前端无论是应用程序代码类似 ORM但 ORM 无需拼接字符串而是操作一个更接近逻辑查询计划的节点图还是 SQL 降级处理或其他方式都可以在数据库外部可以在网关或应用程序代码中实现。他很希望听到大家对这个项目叫 Rad的反馈。文章相关信息文章还列出了近期文章、近期评论、文章存档、文章分类、元信息等内容。