⚡ 10 分钟快速上手

SQLite 完整教程

从零基础到高级特性,三个阶段系统掌握世界上使用最广泛的嵌入式数据库

🌱 初级 — 基础入门 (0~3 min) 🔥 中级 — 进阶查询 (3~7 min) 🚀 高级 — 精通特性 (7~10 min)
🌱 初级
基础入门 — 建库建表 + 增删改查 ⏱ 0 ~ 3 min
🗄️
什么是 SQLite?
无需安装服务器的关系型数据库

SQLite 是一个 嵌入式无服务器零配置的关系型数据库。整个数据库就是磁盘上的 一个文件(.db 或 .sqlite)。

📊 全球应用场景

  • 手机 App 本地存储(iOS/Android 内置)
  • 桌面软件配置与缓存数据
  • 浏览器(Chrome/Firefox 使用 SQLite)
  • Python 标准库内置支持
  • 小型 Web 服务后端存储
  • 开发测试与原型验证

⚡ 核心优势

  • 零安装,一个文件即是数据库
  • 支持完整 SQL 标准语法
  • 并发读取,事务安全写入
  • 跨平台,文件直接复制迁移
  • 体积极小(约 600KB)
  • 性能强劲,小数据远超 MySQL
💡 SQLite 官方数据:全球超过 1 万亿(1 Trillion)个 SQLite 数据库在使用,是部署最广泛的数据库引擎。
🚀
快速启动 — 创建数据库
命令行 / Python / Node.js 三种方式

SQLite 不需要安装数据库服务器,只需一行命令即可创建并进入数据库:

Shell(命令行)
# 安装(macOS)
brew install sqlite3

# 安装(Ubuntu/Debian)
sudo apt-get install sqlite3

# 创建/打开数据库文件
sqlite3 mydb.db

# 进入交互式 shell 后的常用命令
.help         -- 查看帮助
.tables       -- 显示所有表
.schema       -- 显示表结构
.mode column  -- 列格式输出
.headers on   -- 显示列名
.quit         -- 退出
Python
import sqlite3

# 创建/连接数据库
conn = sqlite3.connect('mydb.db')
cursor = conn.cursor()

# 内存数据库(临时)
conn = sqlite3.connect(':memory:')
Node.js
// npm install better-sqlite3
const Database = require('better-sqlite3')

// 创建/连接数据库
const db = new Database('mydb.db')
// 内存数据库
const db = new Database(':memory:')
🏷️
SQLite 5 大数据类型
动态类型系统,比 MySQL 更灵活

SQLite 使用 动态类型(Manifest Typing),类型是值的属性而非列的属性。只有 5 种存储类:

NULL
空值
NULL
INTEGER
有符号整数 1-8字节
1, -42, 0
REAL
IEEE 754 浮点数
3.14, -1.5
TEXT
UTF-8/16 字符串
'hello'
BLOB
二进制原始数据
x'0500'
⚠️ SQLite 接受 VARCHAR(255)DATETIME 等写法(与 MySQL 兼容),但内部都会映射到这 5 种类型,不会真正限制长度。
🏗️
CREATE TABLE — 建表
定义表结构,理解约束条件

CREATE TABLE 创建表,并通过约束(Constraint)保证数据完整性:

SQL
-- 创建用户表(完整约束示例)
CREATE TABLE IF NOT EXISTS users (
    id         INTEGER  PRIMARY KEY AUTOINCREMENT, -- 自增主键
    username   TEXT     NOT NULL UNIQUE,            -- 非空且唯一
    email      TEXT     NOT NULL,
    age        INTEGER  CHECK(age >= 0),             -- 检查约束
    score      REAL     DEFAULT 0.0,               -- 默认值
    created_at TEXT     DEFAULT (datetime('now'))   -- 默认当前时间
);

-- 创建订单表(外键示例)
CREATE TABLE IF NOT EXISTS orders (
    id        INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id   INTEGER NOT NULL,
    amount    REAL    NOT NULL,
    status    TEXT    DEFAULT 'pending',
    FOREIGN KEY (user_id) REFERENCES users(id)  -- 外键
);
使用 CREATE TABLE IF NOT EXISTS 可以避免表已存在时报错,是良好实践。
CRUD — 增删改查(最核心)
INSERT / SELECT / UPDATE / DELETE
➕ INSERT
🔍 SELECT
✏️ UPDATE
🗑️ DELETE
SQL — INSERT 插入数据
-- 插入单条记录
INSERT INTO users (username, email, age, score)
VALUES ('alice', 'alice@example.com', 25, 98.5);

-- 批量插入多条(性能更好)
INSERT INTO users (username, email, age, score) VALUES
    ('bob',     'bob@example.com',   30, 88.0),
    ('charlie', 'charlie@example.com', 22, 72.3),
    ('diana',   'diana@example.com',  28, 95.1);

-- INSERT OR REPLACE:存在则替换,不存在则插入
INSERT OR REPLACE INTO users (username, email) 
VALUES ('alice', 'newalice@example.com');
SQL — SELECT 查询数据
-- 查询所有列
SELECT * FROM users;

-- 查询指定列
SELECT username, age, score FROM users;

-- WHERE 条件过滤
SELECT * FROM users WHERE age > 25;
SELECT * FROM users WHERE username LIKE 'a%';  -- 模糊匹配

-- ORDER BY 排序
SELECT * FROM users ORDER BY score DESC;     -- 降序
SELECT * FROM users ORDER BY age ASC;       -- 升序

-- LIMIT / OFFSET 分页
SELECT * FROM users LIMIT 10 OFFSET 20;       -- 第3页,每页10条

📤 查询结果示例

idusernameemailagescore
1alicealice@example.com2598.5
2bobbob@example.com3088.0
3charliecharlie@example.com2272.3
4dianadiana@example.com2895.1
SQL — UPDATE 更新 & DELETE 删除
-- UPDATE:更新指定记录(务必加 WHERE!)
UPDATE users
SET    score = 99.0, age = 26
WHERE  username = 'alice';

-- DELETE:删除指定记录(务必加 WHERE!)
DELETE FROM users WHERE id = 3;

-- 清空整张表(不可回滚)
DELETE FROM users;  -- ← 危险!没有 WHERE 就是清空!
🔥 最常见的惨案:UPDATE 和 DELETE 忘记加 WHERE 子句,导致全表被修改/清空。操作前先用 SELECT 验证条件。
🔥 中级
进阶查询 — 聚合 · JOIN · 子查询 · 事务 ⏱ 3 ~ 7 min
📊
聚合函数 + GROUP BY
COUNT / SUM / AVG / MAX / MIN / GROUP BY / HAVING

聚合函数将多行数据汇总为单个值,GROUP BY 按分组聚合,HAVING 过滤分组结果(类似 WHERE 但用于聚合):

SQL — 聚合函数
-- 基础聚合
SELECT
    COUNT(*)      AS total_users,    -- 总行数
    AVG(age)      AS avg_age,        -- 平均年龄
    MAX(score)    AS max_score,      -- 最高分
    MIN(score)    AS min_score,      -- 最低分
    SUM(score)    AS total_score     -- 总分
FROM users;

-- GROUP BY:按年龄段分组统计
SELECT
    age,
    COUNT(*)    AS count,
    AVG(score) AS avg_score
FROM  users
GROUP BY age
ORDER BY age;

-- HAVING:过滤分组(平均分 > 80 的年龄组)
SELECT age, AVG(score) AS avg_score
FROM   users
GROUP BY age
HAVING AVG(score) > 80
ORDER BY avg_score DESC;
🧠 WHERE vs HAVING 区别:WHERE 在分组前过滤行,HAVING 在分组后过滤组。WHERE 不能用聚合函数,HAVING 可以。
🔗
JOIN — 多表联查
INNER JOIN / LEFT JOIN / 多表关联

JOIN 是关系型数据库的精髓,将多张表按关联条件合并查询:

🔵 INNER JOIN

取两表的交集,只返回两表中都有匹配记录的行

适合:确保双方都有数据时使用

🟢 LEFT JOIN

返回左表所有行,右表无匹配则填 NULL

适合:查用户是否下过单(可能没单)

SQL — JOIN 示例
-- INNER JOIN:查有订单的用户及订单信息
SELECT
    u.username,
    u.email,
    o.amount,
    o.status
FROM       users  u
INNER JOIN orders o ON u.id = o.user_id;

-- LEFT JOIN:查所有用户,即使没有订单也显示
SELECT
    u.username,
    COUNT(o.id)  AS order_count,    -- 订单数(无订单为0)
    SUM(o.amount) AS total_spent    -- 总消费(无订单为NULL)
FROM      users  u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY  u.id, u.username
ORDER BY  total_spent DESC NULLS LAST;

📤 LEFT JOIN 结果示例

usernameorder_counttotal_spent
alice3580.00
diana1299.00
bob0NULL
charlie0NULL
🪆
子查询(Subquery)
嵌套 SELECT,强大的数据筛选方式

子查询是嵌套在另一个 SQL 语句中的 SELECT 语句,可用在 WHERE、FROM、SELECT 子句中:

SQL — 子查询三种用法
-- ① WHERE 中:查分数高于平均分的用户
SELECT username, score
FROM   users
WHERE  score > (SELECT AVG(score) FROM users);

-- ② IN 子查询:查有订单的用户
SELECT * FROM users
WHERE id IN (
    SELECT DISTINCT user_id FROM orders
);

-- ③ FROM 子查询(派生表):按分数分级统计
SELECT grade, COUNT(*) AS count
FROM (
    SELECT
        username,
        CASE
            WHEN score >= 90 THEN 'A'
            WHEN score >= 80 THEN 'B'
            WHEN score >= 60 THEN 'C'
            ELSE 'D'
        END AS grade
    FROM users
) AS graded
GROUP BY grade;
🔐
事务(Transaction)— 保证数据安全
BEGIN / COMMIT / ROLLBACK

事务确保一组操作要么全部成功,要么全部回滚,绝不会出现"转账扣钱了但没到账"的中间状态:

SQL — 事务
-- ① 手动事务
BEGIN TRANSACTION;  -- 或 BEGIN;

    UPDATE accounts SET balance = balance - 100 WHERE id = 1; -- A 扣款
    UPDATE accounts SET balance = balance + 100 WHERE id = 2; -- B 到账

COMMIT;   -- 提交,两步都成功则永久保存

-- ② 回滚示例(遇到错误时)
BEGIN TRANSACTION;
    UPDATE accounts SET balance = balance - 100 WHERE id = 1;
    -- 如果 B 不存在,或余额不足...
ROLLBACK; -- 回滚,A 的扣款也撤销,保持一致性
Python — 事务最佳实践
import sqlite3

conn = sqlite3.connect('mydb.db')
try:
    cursor = conn.cursor()
    cursor.execute("UPDATE accounts SET balance=balance-100 WHERE id=1")
    cursor.execute("UPDATE accounts SET balance=balance+100 WHERE id=2")
    conn.commit()   # ✅ 两步都成功,提交
    print("转账成功")
except Exception as e:
    conn.rollback()  # ❌ 出错,回滚
    print(f"转账失败,已回滚: {e}")
finally:
    conn.close()
💡 SQLite 默认每条 SQL 语句都是独立事务(自动提交)。大量插入时,用手动事务包裹可提升 100倍以上的性能!
索引(Index)— 查询加速
B-Tree 索引,让查询从 O(n) 变 O(log n)

索引是加速查询的关键。没有索引,每次 WHERE 查询需要全表扫描;有索引则通过 B-Tree 快速定位,速度提升数十到数百倍:

全表扫描 (无索引):
[id=1] → [id=2] → [id=3] → ... → [id=1000000] ← O(n) 逐行扫描

B-Tree 索引查找:
[50]
┌──────────┘└──────────┐
[25] [75]
┌──┘└──┐ ┌──┘└──┐
[10] [30] [60] [90] ← O(log n) 二分查找
SQL — 索引操作
-- 创建普通索引
CREATE INDEX idx_users_age ON users(age);

-- 创建唯一索引(同时保证唯一性约束)
CREATE UNIQUE INDEX idx_users_email ON users(email);

-- 创建复合索引(联合多列,注意列顺序!)
CREATE INDEX idx_orders_user_status ON orders(user_id, status);

-- 查看查询是否用到索引(执行计划)
EXPLAIN QUERY PLAN
SELECT * FROM users WHERE age = 25;
-- 输出: SEARCH TABLE users USING INDEX idx_users_age (age=?)

-- 删除索引
DROP INDEX IF EXISTS idx_users_age;
⚠️ 索引不是越多越好:索引会占用额外存储,且每次 INSERT/UPDATE/DELETE 都需要更新索引,影响写入性能。建议只在 频繁查询的 WHERE/JOIN/ORDER BY 列上建索引。
🚀 高级
精通特性 — CTE · 窗口函数 · JSON · 全文搜索 · 性能优化 ⏱ 7 ~ 10 min
🔮
CTE — 公共表表达式(WITH 子句)
让复杂查询变清晰,支持递归查询

CTE(Common Table Expression)用 WITH 关键字定义临时命名结果集,让复杂查询更易读、可复用,还支持递归查询(树形结构):

SQL — 普通 CTE
-- 用 CTE 分步计算:找出消费前3名的用户详情
WITH user_spending AS (
    -- Step 1: 计算每个用户的总消费
    SELECT
        user_id,
        SUM(amount) AS total_spent,
        COUNT(*)    AS order_count
    FROM  orders
    GROUP BY user_id
),
top_spenders AS (
    -- Step 2: 取消费前3名
    SELECT * FROM user_spending
    ORDER BY total_spent DESC
    LIMIT 3
)
-- Step 3: 关联用户表取完整信息
SELECT
    u.username,
    u.email,
    ts.total_spent,
    ts.order_count
FROM       top_spenders ts
INNER JOIN users u ON u.id = ts.user_id;
SQL — 递归 CTE(树形结构)
-- 场景:组织架构表,查某人下面所有子级
-- 表结构:employees(id, name, manager_id)

WITH RECURSIVE subordinates AS (
    -- 锚点:起始节点(CEO,id=1)
    SELECT id, name, manager_id, 0 AS level
    FROM   employees
    WHERE  id = 1

    UNION ALL

    -- 递归:找所有下属
    SELECT e.id, e.name, e.manager_id, s.level + 1
    FROM   employees    e
    JOIN   subordinates s ON e.manager_id = s.id
)
SELECT printf('%s', substr('            ', 1, level*2) || name) AS org_tree
FROM  subordinates;
🪟
窗口函数(Window Function)
OVER / PARTITION BY / ROW_NUMBER / RANK / LAG / LEAD

窗口函数在不折叠行数的前提下执行聚合计算,是数据分析的利器(SQLite 3.25.0+ 支持):

SQL — 窗口函数
-- ROW_NUMBER: 按分数排名(组内排名)
SELECT
    username,
    score,
    ROW_NUMBER() OVER (ORDER BY score DESC) AS rank,
    RANK()       OVER (ORDER BY score DESC) AS rank_with_gap
-- RANK 遇到相同分数会跳号(1,2,2,4),ROW_NUMBER 不跳
FROM users;

-- PARTITION BY: 按年龄段分组后各自排名
SELECT
    username,
    age,
    score,
    DENSE_RANK() OVER (
        PARTITION BY (age / 10) -- 按10岁一组分区
        ORDER BY score DESC
    ) AS group_rank
FROM users;

-- 滑动窗口:累计平均 & 前后值对比
SELECT
    id,
    amount,
    AVG(amount) OVER (
        ORDER BY id
        ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
    ) AS moving_avg_3,           -- 3期移动平均
    LAG(amount, 1) OVER (ORDER BY id) AS prev_amount,  -- 上一期
    LEAD(amount, 1) OVER (ORDER BY id) AS next_amount  -- 下一期
FROM orders;

📤 窗口函数排名效果

usernamescoreROW_NUMBERRANK
alice98.511
diana95.122
bob88.033
charlie72.344
📦
JSON 支持(SQLite 3.38+)
存储和查询 JSON 数据,灵活应对半结构化数据

SQLite 内置 JSON 函数,可直接操作存储在 TEXT 列中的 JSON 数据,无需额外扩展:

SQL — JSON 函数
-- 表结构(JSON 存在 TEXT 列)
CREATE TABLE products (
    id    INTEGER PRIMARY KEY,
    name  TEXT,
    attrs TEXT  -- 存 JSON
);

INSERT INTO products VALUES (
    1, 'iPhone 16',
    '{"color":"black","storage":256,"tags":["phone","apple"]}'
);

-- json_extract: 提取 JSON 字段值
SELECT
    name,
    json_extract(attrs, '$.color')   AS color,
    json_extract(attrs, '$.storage') AS storage,
    json_extract(attrs, '$.tags[0]') AS first_tag
FROM products;

-- 按 JSON 字段过滤
SELECT * FROM products
WHERE json_extract(attrs, '$.storage') >= 128;

-- json_set: 更新 JSON 字段
UPDATE products
SET   attrs = json_set(attrs, '$.color', 'white')
WHERE id = 1;

-- json_array_length: 获取数组长度
SELECT json_array_length(json_extract(attrs, '$.tags')) FROM products;
🔍
全文搜索 FTS5
比 LIKE 快百倍的文本搜索

FTS5(Full-Text Search 5)是 SQLite 内置的倒排索引全文搜索引擎,支持布尔运算、短语搜索、前缀搜索,比 LIKE '%keyword%' 快几十到上百倍:

SQL — FTS5 全文搜索
-- 创建 FTS5 虚拟表
CREATE VIRTUAL TABLE articles_fts USING fts5(
    title,
    body,
    content='articles',  -- 内容表(可选)
    tokenize='unicode61' -- Unicode 分词
);

-- 插入并建索引
INSERT INTO articles_fts SELECT title, body FROM articles;

-- 全文搜索(比 LIKE 快 100x)
SELECT * FROM articles_fts
WHERE articles_fts MATCH 'sqlite AND database';  -- AND 运算

-- 短语搜索(引号包裹)
SELECT * FROM articles_fts
WHERE articles_fts MATCH '"full text search"';

-- 前缀搜索
SELECT * FROM articles_fts
WHERE articles_fts MATCH 'data*';  -- 匹配 data, database, datastore...

-- 按相关度排序(bm25 算法)
SELECT *, bm25(articles_fts) AS relevance
FROM  articles_fts
WHERE articles_fts MATCH 'sqlite'
ORDER BY relevance;
⚙️
PRAGMA 性能调优 + WAL 模式
生产级配置,读写性能提升 3-10x

SQLite 通过 PRAGMA 语句调整运行时参数,合理配置可大幅提升性能:

SQL — 生产推荐配置(连接后立即执行)
-- ✅ WAL 模式:写时允许并发读(最重要!)
PRAGMA journal_mode = WAL;

-- ✅ 同步模式:NORMAL 安全且快(比 FULL 快 3x)
PRAGMA synchronous = NORMAL;

-- ✅ 缓存大小:内存页数(负数=KB,正数=页数)
PRAGMA cache_size = -64000;  -- 64MB 缓存

-- ✅ mmap 内存映射:大文件读取加速
PRAGMA mmap_size = 268435456; -- 256MB

-- ✅ 外键约束开关(默认关闭!)
PRAGMA foreign_keys = ON;

-- ✅ temp_store:临时表存在内存
PRAGMA temp_store = MEMORY;

-- 查看当前配置
PRAGMA journal_mode;
PRAGMA page_size;
PRAGMA cache_size;
🔮 WAL 模式是最重要的优化:默认的 DELETE 日志模式写操作会加排他锁阻塞读。WAL(Write-Ahead Logging)允许 1 写 + N 读同时进行,并发性能提升 3-10 倍。
Python — 推荐的生产连接模板
import sqlite3

def get_connection(db_path: str) -> sqlite3.Connection:
    """生产级 SQLite 连接配置"""
    conn = sqlite3.connect(
        db_path,
        timeout=30,                           # 等锁超时30秒
        isolation_level=None,                # 手动控制事务
        check_same_thread=False,             # 多线程可用
    )
    conn.row_factory = sqlite3.Row          # 结果可按列名访问
    conn.execute("PRAGMA journal_mode = WAL")
    conn.execute("PRAGMA synchronous = NORMAL")
    conn.execute("PRAGMA foreign_keys = ON")
    conn.execute("PRAGMA cache_size = -64000")
    return conn

# 使用示例:按列名访问结果
conn = get_connection('app.db')
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE id=?", (1,))
user = cursor.fetchone()
print(user['username'])  # 按列名访问
🧩
视图(View)& 触发器(Trigger)
封装复杂查询 + 自动化业务逻辑

🔭 视图 — 把复杂 SELECT 封装为虚拟表

SQL
-- 创建视图
CREATE VIEW v_user_stats AS
SELECT
    u.id,
    u.username,
    COUNT(o.id) AS orders,
    COALESCE(SUM(o.amount), 0) AS spent
FROM      users  u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id;

-- 像普通表一样查询视图
SELECT * FROM v_user_stats
WHERE spent > 100;

触发器 — 自动执行业务逻辑

SQL
-- 自动记录更新时间
CREATE TRIGGER trg_user_updated
AFTER UPDATE ON users
FOR EACH ROW BEGIN
    UPDATE users
    SET updated_at = datetime('now')
    WHERE id = NEW.id;
END;

-- BEFORE/AFTER INSERT/UPDATE/DELETE
-- NEW.col = 新值,OLD.col = 旧值
📊
SQLite vs MySQL vs PostgreSQL — 选型指南
什么场景用什么数据库?
维度 SQLite MySQL PostgreSQL
部署方式 嵌入式,无服务器 独立服务进程 独立服务进程
最大数据量 ~281TB(理论值) 实践上限为数百 TB 无限(PB级)
并发写入 单写多读(WAL) 多写多读 多写多读(MVCC)
配置复杂度 零配置 中等 较复杂
窗口函数 支持(3.25+) 支持(8.0+) 全面支持
JSON 支持 内置(3.38+) 支持(5.7+) JSONB 原生支持
全文搜索 FTS5 内置 支持(有限) 内置 + tsvector
适用场景 移动端、桌面、测试、中小Web 中大型 Web 应用 复杂业务、高并发

🎯 10分钟实战项目:用 SQLite 构建一个博客系统数据库

综合运用本教程所有知识点,从零构建一个完整博客系统的数据层:

  1. 创建 blog.db,建表:userspostscommentstagspost_tags(多对多关系表)
  2. 开启 WAL 模式 + 外键约束,批量插入测试数据(使用事务包裹)
  3. 创建索引:posts.user_idposts.created_at,用 EXPLAIN QUERY PLAN 验证
  4. 写 JOIN 查询:文章列表(含作者名、评论数、标签列表)
  5. 用 CTE + 窗口函数查出:每个作者发文最多的3个月份
  6. 创建 FTS5 全文搜索表,对文章标题和内容建索引,实现搜索功能
  7. 创建视图 v_post_stats 封装复杂统计,创建触发器自动更新 updated_at
🌱
初级掌握
数据类型 · CREATE TABLE
INSERT / SELECT / UPDATE / DELETE
WHERE / ORDER BY / LIMIT
NOT NULL / UNIQUE / DEFAULT
🔥
中级掌握
COUNT / SUM / AVG · GROUP BY
INNER JOIN / LEFT JOIN
子查询 · CASE WHEN
事务 · 索引 · EXPLAIN
🚀
高级掌握
CTE · 递归查询
窗口函数 · JSON 函数
FTS5 全文搜索
PRAGMA 调优 · WAL 模式