SQLite 变身文档数据库的秘诀

SQLite as a Document Database (2020)

SQLite 早已支持 JSON,但直到 3.31.0 版本引入 generated columns 功能,它才真正具备了作为文档数据库的潜力。通过 json_extract 函数,我们可以直接将 JSON 数据插入 SQLite,并自动提取字段进行索引和查询。这不仅让轻量级应用能享受类似 PostgreSQL 或 Elastic 的灵活查询能力,还能在插入时自动验证 JSON 格式,甚至强制要求特定字段存在。更妙的是,你可以从简单的单列 JSON 表开始,随着需求增长动态添加虚拟列和索引,非常适合处理 webhooks 等场景。

你可以从一张仅包含单个 JSON 列的表开始,然后随着你发现 JSON 中有用的数据,再逐步添加列和索引。
  1. stanac

    我用 SQLite 做文档数据库已经好几年了,是用于一个副项目。我写了一个自定义的 repository 基类,它可以将 blobs 存储在单独的列中,这样这类数据就不会包含在 json 文档里。如今还有 jsonb [1],据我记忆,json 和 jsonb 的所有函数用法都是一样的。

    另外,这个 repository 类还会将写入和删除时间戳作为单独的列存储,这样我就能实现 CDC。CDC 用于构建缓存的视图模型,并每 5 分钟推送到对象存储一次,以 NDJSON 格式进行备份。家里的另一台服务器上还有一个进程,每隔几分钟就恢复一次数据库,作为第二重备份,以便在需要时能立即投入使用。

    我知道有像 Litestream 这样的工具,但我想要的是进程内(in-process)的解决方案,并且能在备份失败时发送警报。

  2. wwalexander

    > it added a killer feature: generated columns

    要是 SwiftData 能通过 #Expression 宏,把 @Model 对象的计算属性转换成这些 generated columns,那就太酷了!

  3. WhitneyLand

    为什么人们总说“文档数据库”,其实他们指的不过是“json 数据库”?

  4. SleepyPenguin

    2009 年,我开发过一个应用,后端用 zope,前端用 extjs(现在是 Sencha)和 SQLite。表单和数据都以字符串形式存储在数据库中,联网后再同步到后端。这个应用的目标用户是第三世界国家的偏远地区医生,他们经常处于离线状态。当时有好几位医生告诉我,他们希望医疗数据能直接以和录入表单相同的格式存储,主要是因为习惯了纸质表单的形式。不久之后,医疗 ERP 系统开始大行其道,关系型数据库战胜了文档数据库。我敢打赌,现在再开发类似的应用(数据以采集时的格式存储和展示)会容易得多,但我不禁好奇,现在还有哪个市场会用这种方案。

  5. Insimwytim

    如果你要加 NOT NULL 约束,为什么不干脆把它从 json 里提取出来,存成单独的列呢?放在 json 里有什么用?

    如果你需要在结果中使用它,可以在检索时再把它拼回去。

同日更多故事

2026-08-29