IBM i 系统里有个函数,专门返回程序调用栈信息。字段列了一长串:激活组、ASP、库名、服务程序名、模块名、位数、系统调用标志。这些字段大多互斥——一条 Java 栈帧的行里,AIX 相关的列全是空的;一条 OPM 栈帧的行里,Java 相关的列也全是空的。开发者要靠一堆 nullable 列和字符串枚举,去猜这一行到底是哪种调用记录。

这段吐槽出自一篇存了好几年的旧稿,最近因为 Acadia 这类新查询语言的讨论被重新翻出来。它不是新数据库发布,也不是 Acadia 的正式路线图,只是一位长期写 SQL 的开发者,把自己攒了多年的“现代 SQL 愿望清单”重新整理了一遍。核心判断很直接:SQL 该退休的不是关系模型,是它几十年攒下来的语法包袱——NoSQL 当年能崛起,这是被低估的一个诱因,但绝不是唯一原因。

四个诉求,一张清单

清单很短,每一条都是踩过坑之后才敢认真提出来的。

诉求具体痛点现状对照
语法与报错语法底子是七十年代 PL/I 的产物MySQL 报错含糊;Oracle 报错相对清楚,说明这是实现水平差距,不是技术做不到
函数式表达SQL 描述“要什么”本该和惰性求值很搭多数方言的标准库仍围绕存储过程设计——过程式、靠游标、靠可变状态
透明查询计划优化器判断失误时,普通开发者读不懂 EXPLAINMySQL 在这方面同样是反面教材
更强的用户类型domain 概念早就写进标准,多数实现只是范围/check 约束的糖衣PostgreSQL 支持较完整;Oracle 近几版本新增了相关能力,看起来更灵活,但作者自己承认对两家实际用法都不算熟
想要的四层诉求 语法与报错 脱离 PL/I 老语法,报错要说清哪里错 函数式友好 标准库不再默认逼人写存储过程和游标 透明查询计划 普通开发者也能看懂优化器为什么这样选 更强的用户类型 domain 之外,还要有联合类型和模式匹配

这四条不是新标准,只是一份个人愿望清单。但每一条都对着行业里一个真实存在的落差。

两个设计范例:联合类型和多态外键

回到 IBM i 栈帧的例子。如果查询语言支持联合类型(sum types)和模式匹配,ILE、OPM、AIX、Java 这几种调用帧可以各自定义只属于自己的字段。不再共用一张挤满 nullable 列的大表。

查询时用 match 按类型分支处理,编译器还能强制覆盖所有分支,少判一种类型都会报错。这比现在“猜哪几列有值”靠谱得多。

同样的思路能用在外键上。设想 Software、Version、Download 都能挂图片,传统做法是各建一张多对多表:SoftwarePicture、VersionPicture、DownloadPicture,结构完全一样,纯粹是重复劳动。如果外键能带一个判别类型,一张 ObjectPictures 表就能同时关联三种对象,写入时标出这行指向哪张表,查询按类型过滤即可。

这两个设计都是概念推演,没有哪个主流数据库现成支持这套语法。读者不必去搜某个产品支不支持。

谁该看这份清单,谁可以先不理

对长期维护复杂 SQL 的后端和数据库开发者,这份清单不是号召立刻换语言。该做的事更朴素:把真正该用联合类型表达的多态数据——日志、事件、多态关联——挪到应用层,用 TypeScript 的联合类型或 Rust 的 enum 处理。数据库层继续靠 check 约束和 domain 打底线,别指望 SQL 帮你把这活儿干完。

对 Acadia 这类新查询语言和数据库工具的设计者,这份清单更像一份来自一线的需求书。作者反复强调的两点——报错要说清楚哪里错,查询计划要让人看懂——恰恰是过去几十年最容易被牺牲的两项,因为它们不直接体现在 benchmark 分数里。

现实约束也要说清楚。domain 这套用户自定义类型,PostgreSQL 做得比较完整,Oracle 最近几个版本也补了类似能力,但作者自己承认对两家的实际用法都不算熟,这不是“只有 Postgres 支持”的定论。更大的限制是生态:就算某个新语言把联合类型和透明查询计划都做出来了,ORM、驱动、迁移工具跟不上,开发者照样用不起来——这条路,Postgres 自己也走了二十多年才把 domain 做到能用。

接下来最该观察的,不是 Acadia 会不会红,而是有没有哪个新语言真的把这四条一起做全,还是又变成一个语法好看、生态空荡的小众方言。

“工欲善其事,必先利其器。”E.F. Codd 提出关系模型的时候,domain 这个概念就已经写在里面了,只是后来 SQL 标准和各家实现选择性地忽视了它。“用集合和关系描述数据”这个想法足够老,也足够耐用,没必要淘汰。真正老化的,是裹在它外面、几十年没怎么长进的语法和工具。

关系模型没输给时代,输的是几十年没更新的语法和工具链。

【锐评】关系模型没输给谁,输的是那套七十年代 PL/I 味的语法和永远语焉不详的报错。