现代 SQLite:你可能不知道的功能
Modern SQLite: Features You Didn't Know It Had

原始链接: https://slicker.me/sqlite/features.htm

## SQLite:比你想象的更强大 SQLite 正在超越简单的文件型数据库,提供以往只有大型系统才有的功能。它现在包含一个 **JSON 扩展**,用于直接在表中存储和查询 JSON 数据,从而实现灵活的模式和通过索引进行快速查询。 对于搜索,**FTS5** 提供强大的全文搜索功能 *在* SQLite 内部,无需外部服务。 **CTE 和窗口函数** 解锁了复杂的分析查询,例如运行总计,从而实现令人惊讶的丰富报告。 现代 SQLite 还引入了 **严格表**,通过强制类型检查来提高数据完整性,以及 **生成列** 以自动维护派生数据。 **预写式日志 (WAL)** 提高了性能,通过最大限度地减少读写阻塞来增强并发性。 这些补充功能保持了 SQLite 的简单性和可靠性,同时显著扩展了其功能,适用于从桌面工具到本地优先应用程序和小型服务的各种应用。

最近的 Hacker News 讨论强调了 SQLite 的一些鲜为人知的功能。虽然诸如预写式日志等核心功能已经存在多年,但较新的补充正在获得关注。用户称赞 SQLite 的 JSON 函数简化了 ETL 流程,消除了对 Python 等独立脚本语言的需求。“严格表”的引入也被认为是重要的改进,解决了长期以来对缺乏类型强制执行的批评——此前这一问题曾促使用户转向 PostgreSQL。 其他提到的功能包括用于模糊搜索的 `spellfix1` 扩展以及用于高效数据去重的 `ON CONFLICT`。然而,一些评论员指出,许多功能并非全新,对于高级类型需求,PostgreSQL 仍然是一个强大的替代方案。有人建议撰写一篇文章,详细介绍使用开源软件构建高度可用、跨区域复制系统的 SQLite 潜力。
相关文章

原文

Working with JSON data

SQLite ships with a JSON extension that lets you store and query JSON documents directly in tables. You can keep your schema flexible while still using SQL to slice and dice structured data.

Example: extracting fields from a JSON column:

CREATE TABLE events (
  id      INTEGER PRIMARY KEY,
  payload TEXT NOT NULL -- JSON
);

SELECT
  json_extract(payload, '$.user.id')   AS user_id,
  json_extract(payload, '$.action')    AS action,
  json_extract(payload, '$.metadata')  AS metadata
FROM events
WHERE json_extract(payload, '$.action') = 'login';

You can also create indexes on JSON expressions, making queries over semi-structured data surprisingly fast.

Full-text search with FTS5

SQLite’s FTS5 extension turns it into a capable full-text search engine. Instead of bolting on an external search service, you can keep everything in a single database file.

Example: building a simple search index:

CREATE VIRTUAL TABLE docs USING fts5(
  title,
  body,
  tokenize = "porter"
);

INSERT INTO docs (title, body) VALUES
  ('SQLite Guide', 'Learn how to use SQLite effectively.'),
  ('Local-first Apps', 'Why local storage and sync matter.');

SELECT rowid, title
FROM docs
WHERE docs MATCH 'local NEAR/5 storage';

You get ranking, phrase queries, prefix searches, and more—without leaving SQLite or managing a separate service.

Analytics with window functions and CTEs

SQLite supports common table expressions (CTEs) and window functions, which unlock a whole class of analytical queries that used to require heavier databases.

Example: computing running totals with a window function:

SELECT
  user_id,
  created_at,
  amount,
  SUM(amount) OVER (
    PARTITION BY user_id
    ORDER BY created_at
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS running_total
FROM payments
ORDER BY user_id, created_at;

Combine this with CTEs and you can build surprisingly rich reports and dashboards on top of a single SQLite file.

Strict tables and better typing

SQLite is famous (or infamous) for its flexible typing model. Modern SQLite adds STRICT tables, which enforce type constraints much more like PostgreSQL or other traditional databases.

Example: defining a strict table:

CREATE TABLE users (
  id        INTEGER PRIMARY KEY,
  email     TEXT NOT NULL,
  is_active INTEGER NOT NULL DEFAULT 1
) STRICT;

With strict tables, invalid types are rejected at insert time, making schemas more predictable and reducing subtle bugs—especially in larger codebases.

Generated columns for derived data

Generated columns let you store expressions as virtual or stored columns, keeping derived data close to the source without duplicating logic across your application.

Example: a normalized search field:

CREATE TABLE contacts (
  id          INTEGER PRIMARY KEY,
  first_name  TEXT NOT NULL,
  last_name   TEXT NOT NULL,
  full_name   TEXT GENERATED ALWAYS AS (
    trim(first_name || ' ' || last_name)
  ) STORED
);

CREATE INDEX idx_contacts_full_name ON contacts(full_name);

Now every insert or update keeps full_name in sync automatically, and you can index and query it efficiently.

Write-ahead logging and concurrency

Write-ahead logging (WAL) is a journaling mode that improves concurrency and performance for many workloads. Readers don’t block writers, and writers don’t block readers in the common case.

Enabling WAL is a single pragma call:

PRAGMA journal_mode = WAL;

For desktop apps, local-first tools, and small services, WAL mode can dramatically improve perceived performance while keeping SQLite’s simplicity and reliability.

联系我们 contact @ memedata.com