Supabase 推出浏览器版 PostgreSQL,集成 AI 接口可自然语言生成 SQL,大幅降低数据库操作门槛。
提醒一下——postgres.new 即将更名为 database.build。为什么?
database.build(原 postgres.new)正式发布:这是一个带 AI 辅助功能、运行在浏览器内的 Postgres 沙箱。通过 database.build,你可以立即创建无限数量的 Postgres 数据库,让它们直接在浏览器中运行;而且很快就能将数据库部署到 S3。
每个数据库都会搭配一个大语言模型(LLM),由此开启了一些颇有意思的使用场景:
拖放导入 CSV(即时生成数据表)
生成并导出报告
构建数据库图表
所有操作都完全在浏览器本地进行。有点像把 Postgres 和 ChatGPT 合并到了同一个界面中。
在这个演示中,我们介绍了几个有趣的使用场景:
你有一个 CSV 文件,想快速查询其中的数据并将其可视化。你可以把它加载到 Excel 中,但你很熟悉 SQL,真正想要的其实是像查询数据库一样查询它。
你正在让 ChatGPT 帮忙编写一些 SQL,但理想情况下,你希望能在真实数据库中运行这些 SQL,以确认它们是否正确。毕竟,LLM 并不完美。
你正在开发下一个业余项目,现在该规划数据库了。同样的事情你已经做过 1000 次,只希望能直接“描述”自己的需求,然后让 AI 完成 ER 图和 SQL migration 的创建工作。
database.build 中的所有查询都直接在浏览器内运行。背后既没有远程 Postgres 容器,也没有 WebSocket 代理。
这是怎么做到的?真正的主角是 PGlite——一个可以直接在浏览器中运行的 WASM 版 Postgres。几个月前,我们在 ElectricSQL 的朋友找到了将真正的 Postgres 源码编译成 WebAssembly 的方法,随后发布了 PGlite(稍后会进一步介绍)。
我们希望通过 database.build 实现以下几个目标:
AI 驱动的开发:我们希望重新构想 Postgres 与 AI 之间的交互方式。这种环境为犯错留出了很大的余地,而 AI 有时确实会犯错(说实话,开发者也一样)。
Postgres 沙箱:我们非常喜欢沙箱和 notebook。由于 PGlite 在浏览器内运行,它用起来既快,又可以随时丢弃。你可以创建“一百万头小象”,使用日常开发中熟悉的同一套 Postgres 界面进行数据分析。
极其便宜的数据库:我们一直在寻找以更低成本为开发者提供更多数据库的方法。PGlite 仍处于早期阶段,但我们已经看到了它的潜力:创建数百万个低成本数据库,并通过 S3 存储和读取它们。这可以覆盖我们在 Supabase 社区中看到的多种使用场景。
那么,database.build 到底能做什么?这些功能在底层又是如何运作的?
我们将 PGlite 与一个大语言模型(目前是 GPT-4o)组合在一起,让模型可以完全掌控数据库,不受权限限制,也不需要用户确认。这其实是一个非常重要的细节——它打开了新的大门,解决了其他 AI + Postgres 工具难以应对的问题。
打个比方,团队里最得力的成员,往往是不需要持续微观管理、也能完成工作的人。只有在真正遇到困难或需要第二意见时,他们才会过来寻求帮助。
赋予 AI 模型对数据库的完全自主权,意味着它可以毫无延迟地连续执行多个操作。这让 AI 感觉更像人,也更加实用。真正让这一切成为可能的,是一个可以随时丢弃、运行在浏览器内的数据库,因为你完全不必担心数据丢失。
只需将 CSV 文件直接拖放到聊天窗口中,就能立即得到一张新表,文件中的数据会被自动导入。语言模型会扫描 CSV 的表头和几行样本数据,以决定每一列应该使用哪种数据类型。
不过,AI 和人类一样,不可能每次都判断正确。CSV 中可能存在某一行被它漏掉了,而这一行的数据不符合它预期的数据类型,最终导致导入失败。为了解决这个问题,我们为 AI 加入了自我修复能力。Postgres 返回的任何 SQL 错误都会反馈给语言模型,让它可以继续尝试几次来解决问题。只要 AI 执行 SQL,这一机制就会触发,并不局限于 CSV 导入。
除了导入,你还可以让 AI 把任意查询结果导出为 CSV。如果你想针对某个数据集快速生成几份报告,然后在其他程序中继续使用这些数据,这项功能会非常实用。
图表是聊天界面中的一等公民。只需在消息中加入“图表”或意思相近的词,AI 就会使用 SQL 执行适当的查询,然后构建一张呈现这些数据的图表。
我们的目标是让数据可视化尽可能迅速。只用一条聊天请求,你就能生成所需的一切,不必再像往常那样先把 CSV 加载到 Excel、调整数据,然后在图表工具中来回操作。
在底层,我们使用 Chart.js 渲染这些图表。它是 JavaScript 生态中较为成熟的图表库之一。之所以选择 Chart.js,很大程度上是受语言模型(GPT-4o)的影响,因为模型对它的语法和配置相当熟悉。模型只需把 SQL 输出转换成对应的 Chart.js 语法,再将其渲染到页面上。
这样做还有一个很好的附带效果:你可以让 AI 调整图表类型、颜色、坐标轴、标题,或其他任何内容,让图表完全按照你的想法呈现——前提是 Chart.js 支持你所要求的功能。
值得注意的是,Chart.js 有时需要相当冗长的输入,这会增加成本和延迟。未来,我们希望尝试其他输入更加简洁的图表方案。
通常,ER 图会在编写任何 SQL 之前创建。毕竟,如果你真正关心的只是准确表达应用的数据及其关系需求,又何必过早陷入 SQL 语法的细节?
但有了 AI,这套工作流会发生一些变化。语言模型只需几秒就能生成高质量的 CREATE 和 ALTER 语句。这么一来,为什么不让模型直接在 Postgres 沙箱中执行真正的 DDL,再根据这些表生成 ER 图呢?
采用这套工作流,我们从一开始就能保证,设计出来的字段和关系确实可以在真实数据库中实现。如果不能,数据库会直接抛出错误,然后由 AI 修复。此外,完成设计后,我们还能直接获得真正可用的 SQL 代码。等到时机成熟,就可以把这些代码复制到新应用中。
在底层,我们使用兼容浏览器的 postgres-meta 版本,将 PGlite 数据表加载到 JavaScript 中,然后使用 schema visualizer 渲染。对于 migration,我们会扫描聊天记录,将所有与 DDL 相关的 SQL 查询拼接到一个视图中。
未来,我们还希望支持一个“seeds”部分,用来输出语言模型为样本数据创建的 INSERT 语句。遗憾的是,我们不能像处理 migration 那样,简单地把这些查询拼接起来,因为表和字段的结构可能随时间变化,导致早期的 seed 失效。
要正确实现这项功能,我们需要类似 WASM 版 pg_dump 的工具,以便在最后导出全部数据。敬请期待——ElectricSQL 团队正在开发它!
ElectricSQL 一直在努力让 PGlite 支持真正的 Postgres 扩展,并将它们编译成 WASM。其中,优先级很高的一个扩展是 pgvector,它可以在浏览器内实现向量搜索。
database.build 默认启用 pgvector,这意味着你可以立即在任意数据表上创建和查询向量字段。当然,只有真正的 embedding 可供使用时,这项功能才有意义。因此,我们让 AI 可以访问 Transformers.js,以便直接在浏览器内生成文本 embedding,再将其存储到 PGlite 中或对其进行查询。
在底层,我们将 embedding 存储在 meta.embeddings 表中,然后把每个 embedding 对应的 ID 返回给 AI。之所以这样做,是因为 embedding 向量很大,在模型和应用之间来回传输不仅成本高,也很容易出错。
语言模型会知道 meta.embeddings 表的存在,需要访问某个 embedding 时,只需通过子查询获取即可。
我们非常期待看到大家会用这个工具做出什么。我们发现,它提供了一个非常理想的沙箱,可以在低风险环境中尝试语义搜索和 RAG。
通过 database.build,我们预计将在本周结束前支持只读部署。这一点非常重要,主要原因只有一个:在 S3 上托管 PGlite 数据库的成本极低。
尽管运行一个完整的 Postgres 数据库并不算昂贵,但在某些使用场景中,开发者希望获得 Postgres 的大部分功能,却不想承担运行完整数据库的成本。通过 S3 提供服务的 PGlite,将为大量使用场景打开闸门:为每个用户提供一个复制数据库;为加快读取速度提供只读物化数据库;在边缘托管搜索功能;甚至可能打造一个精简版 Supabase。
PGlite 本身是一个嵌入式数据库,这意味着你无法像连接普通 Postgres 数据库那样,通过 TCP 连接访问它。为了支持由 PGlite 提供底层能力的部署,我们需要一种方法来重新实现 Postgres 的 TCP server 组件,同时解析真正的 wire protocol 消息,让用户可以通过任何常规 Postgres 客户端连接到自己的数据库。
pg-gateway 就这样诞生了:这是一个从服务端实现 Postgres wire protocol 的 TypeScript 库。它提供了一组 API,你可以接入这些 API,自行处理身份验证请求、查询以及其他客户端消息。
在底层,PGlite 确实支持 wire protocol 消息(详见下文),但只支持启动和身份验证握手完成后会出现的消息。因此,我们设计 pg-gateway 来处理启动、TLS 和身份验证消息,再把后续消息直接交给 PGlite。
我们还为 pg-gateway 构建了许多更有意思的功能,不过这些内容只能留到它自己的博客文章中再介绍了。
如果没有 ElectricSQL 朋友们开发的 PGlite,这一切都不可能实现。
PGlite 是 Postgres 的 WASM(WebAssembly)构建版本,并被封装成一个 TypeScript/JavaScript 客户端库。你可以用它在浏览器、Node.js 和 Bun 中运行 Postgres,不需要安装任何额外依赖。在以下许多使用场景中,它可能比完整的 Postgres 数据库更合适:
单元测试和 CI 测试:PGlite 的启动和销毁速度非常快,非常适合单元测试——你可以为每个测试提供一个全新且独立的 Postgres。
本地开发:开发时,你可以用 PGlite 替代完整的本地 Postgres,从而简化开发环境。
远程开发或本地 Web 容器:PGlite 非常轻量,可以轻松嵌入远程容器化开发环境或浏览器内的 Web 容器。
PGlite 支持多种数据持久化后端:
在 Node 中使用时,支持原生文件系统
在浏览器中使用时,支持 IndexedDB 和 OPFS
它的速度很快,CRUD 类型的查询可以在 0.3 毫秒内执行完毕,非常适合用于存储 Web 应用的本地状态。
PGlite 支持大量 Postgres 扩展。下面是两个在嵌入式环境中特别有用的扩展:
pgvector 可用于索引和搜索 embedding,通常是 AI 工作流(retrieval augmented generation,检索增强生成)的一部分。随着 AI 逐渐迁移到用户设备上,在靠近模型的位置执行向量搜索,对于降低延迟至关重要。
这是 ElectricSQL 新开发的一项扩展,用作其同步引擎的客户端。它可以将 Postgres 数据库的一个子集实时同步到用户设备或边缘服务。
Postgres 通常采用多进程 fork 模型运行。每个客户端连接都会由 postmaster 进程移交给一个子进程。不过,WASM 不支持 fork 进程,对线程的支持也很有限。
幸运的是,Postgres 内置了一种相对不为人知的“单用户模式”,它既是单进程,也是单线程。该模式主要用于引导创建新数据库,或者进行灾难恢复。
PGlite 以单用户模式为基础,增加了对 Postgres wire protocol 的支持。标准 Postgres 在单用户模式下只支持一个功能极为有限的基础 cancel REPL,而加入 wire protocol 支持后,就能执行参数化查询,并在 Postgres 类型和宿主语言类型之间进行转换。
为了让 Postgres 能够与 WASM 配合使用,PGlite 还修改了其他许多部分,包括:
支持在单用户模式下启动时为连接指定用户,使权限和 RLS 能够生效。
支持 COPY,以便把 CSV 或 Postgres binary copy 格式的数据加载到数据库中。其实现方式是在 VFS 上创建一个虚拟设备 /dev/blob,让 COPY 命令可以对它执行读写操作,并在查询中用一个 JavaScript Blob 对象来表示它。
新增 dumpDataDir 和 loadDataDir,用于导出和加载 Postgres datadir 的 tarball。
修改 pg_notify,使其可以在单进程模式下运行,为基于 NOTIFY 和 LISTEN 构建实时响应式查询接口奠定基础。
为浏览器新增 OPFS(origin private filesystem)VFS,提供更好的性能,并支持容量远超内存大小的数据库。
Supabase 一向喜欢尽早发布、频繁迭代,因此 backlog 中还有许多功能:
部署数据库:我们正在加入将数据库部署到 S3 的能力,让你可以从互联网的任何地方访问它——初期仅支持只读访问。
支持更多文件类型:我们计划支持 Word 文档、图片(通过 image embedding)等更多格式。
数据库共享:就像 CodeSandbox 一样,你很快就能通过唯一 URL 与其他人共享数据库。
PGlite OPFS 支持:目前数据库存储在 IndexedDB 中,未来我们会迁移到 OPFS,直接在宿主文件系统中存储文件。
数据库导出:你很快就可以对数据库运行 pg_dump,并将其恢复到任意 Postgres 数据库中。
一如既往,我们完成的工作都是开源的,并采用宽松许可证,Electric 团队的工作也是如此。如果你想为它们点一颗 star、提交 issue,或者亲自贡献一些代码,下面列出了所有开源仓库:
PGlite(Apache 2.0):Postgres 的 WASM 构建版本。
pg-gateway(MIT):服务端的 Postgres wire protocol 实现。
database-build(Apache 2.0):database.build 的 frontend。
transformers.js:直接在浏览器中运行 Transformers。