17611538698
info@21cto.com

SQL的复兴:一门拥有50年历史的语言如何重塑自我

数据库 0 10 1天前
图片

导读:SQL是一个历史悠久、规范清晰与发展稳定的“语言”,但它仍然没有停止自我更新,不断地重塑自己。

从浏览器到后端,曾经“枯燥乏味”的SQL如今正在焕发新生。


在本文里,我们将探讨三大趋势是如何汇聚,使 SQL 重回舞台中心的。


原型设计是我最喜欢的编程环节,我喜欢构建新东西,并让它们正常运行。因此说,我也喜爱 MongoDBNoSQL就不足为奇了。别误会,我一直都很欣赏SQL 的优点,只是在JavaScript中使用 MongoDB 的流畅体验让我彻底的折服。

在充满活力的PostgreSQL团队的带领下,SQL最近上演了一场令人瞩目的复兴。我们看到 SQL 从未停止在企业数据处理中扮演核心角色。现如今,它既是传统的首选,也是最值得关注的新兴技术之一。

那么,这一切是如何发生的?

SQL的复兴之路


一切始于轻量级关系型数据库SQLite将 SQL 引入浏览器。

浏览器中的 SQL 催生了一种基于客户端后端同步的新架构,其中 SQL 而非 JSON 成为核心。语言工具也随之发展,使得在任何平台上使用 SQL 都更加便捷。关系型架构易于理解且可预测的特性持续赢得用户的青睐,而 PostgreSQL 的出现,则以其全新的无模式jsonb类型,进一步巩固了这一优势。

事情便是这样发生的:正当你以为 SQL 已经过时的时候,它又重新流行起来了。

“无图式”的神话


JavaScript 中的 NoSQL 之所以如此吸引人,是因为你无需离开语言范式就能思考或管理数据库结构(也就是模式)。

如果你想在编码过程中插入新的类型,只需要这样做:

await db.collection ( ' cats' ). insertOne ({ name : 'Fluffy' , mood : 'Judgmental' });
即使数据尚不存在,也会为你创建它。

数据“shape”(例如 ``和 ` `)也是如此。最棒的是,你可以直接把 JSON 对象 mood 放进去。

这似乎是实现“无摩擦数据处理”的理想状态:数据库和代码都支持 JSON。你无需停下来编写CREATE TABLE语句,无需运行迁移脚本,也无需考虑数据本身;只需按需创建数据,数据存储即可自动适应。

但是,随着我们的原型逐渐发展成为生产系统,我们发现了一个令人不安的事实:模式仍然存在,但现在它存在于我们的代码中。它是隐式的,看起来是这样的:

if (cat && cat.mood && typeof cat.mood === 'string')

或者,如果你也喜欢这样写:

const mood = cat ?.mood ?? 'neutral' ;

现在代码强制执行了模式,这在无模式世界中是一个持续存在的系统性事实。当然,即使在严格的模式中,你也会为了验证而进行类似的操作(无论是在代码中还是通过验证框架),但真正的记录一致性是在数据库本身中保存的。

构建大型系统时,如果缺乏强一致性,就会带来巨大的压力,令人焦虑。开发人员真正想要的是强大的数据完整性和低摩擦。而现在,三大趋势的融合使得 SQL 能够实现如下几点:

  • 前端 SQL 同步
  • 更好的 SQL 客户端
  • 使用无模式类型(JSONB)的 SQL


第一种方法是大胆创新;第二种方法是普通的工程技术;最后一种方法是进化适应。

让我们再仔细看看。

前端 SQL


第一个解决方案需要彻底重新思考数据库的存放位置。30年以来,数据库就像一个笨重的怪物,被锁在服务器机房里。浏览器只是一个沉默的终端,只能被动地向API请求数据。

但得益于WebAssembly (WASM),我们现在可以直接在浏览器中运行实际的数据库引擎。像 PGlite(WASM 中的 PostgreSQL)和 SQLite(通过标准化的浏览器构建)这样的技术已经将数据库转变为客户端技术。

前端化也推动了无服务器 SQL 在分析和边缘计算领域的兴起。像DuckDB这样的工具让开发者能够在用户设备或边缘端处理数百万行分析数据,而无需庞大的云数据仓库。

这项进展本身虽然有趣,但并不算惊天动地,除非引入像 ElectricSQL 这样的同步技术。同步的概念在 NoSQL 领域的 PouchDB 等知名项目中早已存在,如今也开始在 SQL 中流行起来。同步允许我们在浏览器和服务器端使用同一个数据存储,而同步引擎会自动处理协商过程。

同步功能也为本地优先数据库架构带来了可能。前端代码无需编写复杂的 API 端点(例如GET /cats`get_database_name`和 `get_database_name`),也无需加载加载指示器,只需与本地数据库交互即可。

在本地 INSERT创建一条记录,操作立即完成。然后,后台同步引擎(例如 ElectricSQL 或 Replicache)会处理将数据同步到服务器,等类似这些繁琐工作。这样就完全省去了 API 层。

当然,转向本地优先策略需要认真地重新调整思维方式,并且也对架构产生了影响。但是,将关系数据库直接置于浏览器中,使得 SQL 有望成为新的通用数据语言。

更好的 SQL 客户端


第二个因素归功于程序员们的辛勤工作;在这种情况下,指的是多年来对数据库客户端的持续迭代。

事实证明,SQL之所以以前被认为笨重老旧,很大程度上是由于工具不足造成的。无论使用哪种语言,编写SQL都意味着要么拼接字符串,要么与笨重而神秘的ORM(对象关系映射)搏斗。

尽管像Hibernate/JPA这样的 ORM 工具允许开发者使用他们选择的语言(在本例中是 Java)来管理数据,但它们对底层机制的抽象程度过高,以至于难以理解其运作原理。数据流的推理变得令人困惑,也更容易出错。

但新一代轻量级 ORM 工具正在努力弥合这一差距。

像 Drizzle(用于TypeScript)、Exposed(用于Kotlin)和 jOOQ(用于 Java)这样的工具,都专注于提升开发者体验。它们将 SQL 的僵化特性映射到编程语言的惯用法上。例如,Drizzle 可以让查询表的操作感觉就像在 TypeScript 中筛选 JSON 数组一样,但同时又具备完整的类型安全:

const grumpyCats = await db  .select()  .from(cats)  .where(eq(cats.mood, 'Judgmental'));

有了这些工具,开发者无需再猜测代码是否与数据匹配。它们让我们感觉更像 MongoDB,代码和数据使用同一种语言,同时又不牺牲模式的完整性。

使用无模式类型的 SQL


Postgres 团队提出了这样一个问题:如果一个关系型数据库能够使用无模式 JSON 会怎样?答案就在JSONB。

虽然PostgreSQL做为使用先驱,其他数据库也纷纷效仿。它允许开发人员在需要时使用无模式文档,但仍然保留在关系型数据库的结构框架内。

这减少了对多语言持久化架构的需求(这种理念在 2015 年很流行,即事务需要 PostgreSQL,目录需要 MongoDB)。

相反,JSONB 为关键数据(例如财务交易和 PID)提供了严格的 ACID 合规性,同时为配置和日志等复杂数据提供了灵活的 JSON 数据块——而且所有这些都在同一行中完成。我们意识到,我们无需为了灵活性而放弃 SQL;相反,SQL 只需要稍微放宽一些限制。

JSONB 还支持索引,这意味着即使使用涉及标准字段和 JSON 的混合语句,也能获得索引表的性能。

使用单一数据存储的优势如此巨大,在架构上不容忽视。

摩擦力作为一种特征

当然,长期的经验告诉我们不要操之过急。

业界短期内不会弃用REST API(如果我们真想弃用,直接用HTML就行了)。当前技术栈的发展势头强劲,而且理由充分:客户端与数据库解耦是一种久经考验的成熟模式。

SQL也有其自身的局限性。你仍然需要管理连接池,仍然需要编写迁移脚本(即便工具可以简化这些步骤),而且扩展关系数据库仍然比扩展文档存储要困难。

这场变革并非意味着 SQL 一夜之间取代一切;它更像是钟摆摆回中间位置的过程。我们逐渐意识到,SQL 的“摩擦”(即定义类型和关系的必要性)并非缺陷,而是一种特性。它迫使你在构建系统之前先进行设计。

SQL 与林迪效应


林迪效应指的是,“一项技术存在的时间越长,它继续存在的可能性就越大”。

SQL 经历了大型机时代、个人电脑革命、互联网时代、移动时代,如今又迈入了人工智能时代。它之所以能够生存下来,并非因为只是固执己见,而是因为其强大的适应能力。

到现在为止,SQL 已经吸收了 JSON,调整自身以适应 Web 浏览器,并与现代编程语言集成。但 SQL 的“复仇”并非在于摧毁其他替代方案,而在于始终专注于本质,证明有时看似平淡普通的方式才是真正的基石。

作者:洛逸

参考:

https://www.infoworld.com/article/4140734/the-revenge-of-sql-how-a-50-year-old-language-reinvents-itself.html

评论

我要赞赏作者

请扫描二维码,使用微信支付哦。

分享到微信