SQLite 版本:现代化默认设置的提案

SQLite 版本:现代化默认设置的提案

SQLite 因其作为库而非独立进程的特性,被广泛视为本地数据存储的行业标准。然而,它的传统默认值与现代数据库的期望之间存在显著差距。为在不破坏向后兼容性的前提下弥合这一差距,提出了引入“版本”(editions)的方案——一个 pragma 可以一次性启用一套现代默认设置。

SQLite 版本的理由

在像 SQLite 这样无处不在的项目中更改默认设置通常会被避免,以防破坏数百万现有安装。提议的解决方案是一个“超级 pragma”,例如 PRAGMA edition = 2026;,它相当于一组现代配置的别名。该思路受 Rust 版本的启发,允许引擎随时间演进其默认值(例如,将来的 PRAGMA edition = 2034 可以引入 WAL2 等新技术),同时保持旧数据库不受影响。

需要更新的关键默认值

若干核心 SQLite 默认值被认定为对现代应用开发不友好,导致数据不一致、bug 和性能瓶颈。

1. 外键约束的执行

默认情况下,SQLite 会忽略外键约束。这会产生悬挂引用和数据不一致的问题。由于 SQLite 可能会复用 ROWID 值,被删除记录的 ID 可能会被新记录使用,从而导致悬挂引用指向错误的数据而不是直接报错。

解决办法: 通过 PRAGMA foreign_keys = ON; 启用外键。

2. 类型安全与严格表

SQLite 传统上使用“灵活类型”(affinity),列可以存储任何类型的值,而不管声明的类型。例如,INTEGER 列如果无法转换为数字,也可以存储字符串。

解决办法: 使用 STRICT 表来强制数据类型。为保留自定义类型名称(目前仅作文档用途)的实用性,提案建议加入对 SQL‑99 标准 CREATE DOMAIN 语句的支持,以便使用带约束的自定义类型别名。

3. 并发写入处理

默认情况下,并发写入尝试会立即返回 SQLITE_BUSY 错误。如果开发者没有手动实现重试循环,这往往会导致应用崩溃。

解决办法: 设置 busy_timeout,让 SQLite 在报错前等待锁释放。 推荐设置: PRAGMA busy_timeout = 5000;(5 秒)。

4. 写入性能

默认的 SQLite 性能对类似服务器的工作负载往往不够理想,因为写前日志(WAL)默认是关闭的。

解决办法: 启用 WAL 模式并调整同步设置,可显著提升写入速度。 推荐设置:

  • PRAGMA journal_mode = WAL;
  • PRAGMA synchronous = NORMAL;

社区观点与反驳

该提案在开发者中引发了激烈讨论,涉及 SQLite 设计哲学和实现的实际可行性。

反对版本的论点

  • 设计意图: 有人认为 SQLite 的宽松类型和简单锁机制是为嵌入式环境刻意设计的。他们建议需要严格 ACID 保证或复杂并发的用户使用 PostgreSQL 等其他 RDBMS。
  • C 级实现: 批评者指出,修改如 SQLITE_BUSY 之类的默认值会迫使 C 程序员实现更严格的错误处理和重试,这对某些人来说并不理想。
  • 工具碎片化: 担心如果版本信息存储在数据库文件中,旧版本的 sqlite3 CLI 工具可能无法读取由新版本创建的数据库。
  • WAL 限制: 有人指出,WAL 模式是一种不同的文件格式,在某些平台上不受支持,并且存在更高的静默损坏风险。

支持版本的论点

  • 开发者体验: 支持者认为当前的默认值是“陷阱”,会误导不了解专业设置所需 pragma 的开发者。
  • 替代方案: 有人建议与其新增 pragma,不如让包装库继续提供合理的默认值,只是缺少一种标准化、跨运行时的引用方式会更稳健。
  • 实现策略: 为避免在嵌入式系统中产生膨胀,有人建议 PRAGMA edition 应当是库层面的快捷方式,展开为单独的命令,而不是永久存储在数据库文件中。

“2026 版”默认值的汇总

如果实现,PRAGMA edition = 2026; 命令相当于以下配置:

设置 建议默认值 作用
foreign_keys ON 强制引用完整性
busy_timeout 5000 在返回 SQLITE_BUSY 前等待 5 秒
journal_mode WAL 提升写入性能和并发性
synchronous NORMAL 在不冒腐败风险的前提下降低磁盘同步
表模式 STRICT 对所有表强制声明的数据类型

SUMMARY:

提出在 SQLite 中引入类似 Rust 的“版本”机制,以在不破坏向后兼容性的前提下启用一套现代、安全且高性能的默认设置。

TITLE:

SQLite 版本:现代化默认设置的提案

Sources