SQLite 是世界上部署范围最广的关系型数据库管理系统,以"嵌入式、零配置、单文件"著称,被内置在几乎所有智能手机、浏览器和桌面应用中。本教程将介绍 SQLite 在 Windows 环境下的安装流程、命令行基本使用,以及在 Python 中操作 SQLite 数据库的方法;全程与系列教程中已介绍的 MySQL 进行类比分析,帮助已有 MySQL 基础的读者快速理解两者的异同,并为后续 AI 应用开发中常见的本地数据存储需求打下基础。

前置教程

如想快速开始学习本教程,你可能需要先完成以下前置教程:

资源下载

1. SQLite 是什么:先看懂它与 MySQL 的架构差异

1.1 什么是 SQLite

SQLite 是一个嵌入式的开源关系型数据库引擎。与 MySQL 不同,SQLite 无需单独安装、启动和管理,它本身是一个以 C 语言编写的程序库:应用程序把它链接进来,就获得了完整的数据库能力。

SQLite 的核心特征可以概括为三句话:

  • 数据库即文件:一个 SQLite 数据库就是磁盘上的一个 .db 文件,复制文件就等于备份了整个数据库。
  • 零配置:没有安装向导、没有初始化步骤、没有账号密码、没有监听端口,打开文件即可使用。
  • 无处不在:它采用公共领域授权(Public Domain),可免费用于任何用途,Android、iOS、Chrome、微信等海量软件内部都内置了 SQLite,这使它成为世界上部署数量最多的数据库引擎。

在 AI/ML 工具链中,SQLite 同样随处可见:LangChain、LlamaIndex 默认使用 SQLite 存储文档元数据,许多本地 Agent 工具用 SQLite 保存会话历史,部分轻量级向量数据库方案也构建在 SQLite 之上。后续学习 RAG 与 Agent 相关教程时,你会经常与它打交道。

1.2 架构对比:无服务的嵌入式 vs 客户端-服务器

SQLite 与 MySQL 最本质的区别在于架构。MySQL 是典型的客户端-服务器(C/S)架构mysqld 服务进程常驻后台,监听 3306 端口,任何客户端都要通过 TCP 连接、账号密码认证后才能访问数据。SQLite 则是嵌入式架构:数据库引擎直接嵌入应用程序进程内,对数据库文件进行本地读写,中间没有服务进程,也没有网络环节。

graph LR subgraph MySQL架构["MySQL:客户端-服务器架构"] M1["应用程序
(数据库客户端)"] -->|"TCP 连接,端口 3306
需用户名密码认证"| M2["mysqld 服务进程
常驻后台"] M2 --> M3["数据目录
多个数据文件"] end subgraph SQLite架构["SQLite:嵌入式架构"] S1["应用程序
内嵌 SQLite 引擎"] -->|"进程内直接读写
无需认证"| S2["单个 .db 文件
数据库即文件"] end style M2 fill:#d6eaf8 style S2 fill:#d5f5e3

架构差异带来了使用体验上的一系列连锁差别:

使用环节 MySQL SQLite
安装 安装服务软件,数百 MB 解压一个几 MB 的压缩包
启动 需注册并启动 Windows 服务 无服务,随应用程序启停
连接 TCP 连接 + 用户名密码认证 直接打开文件
备份 导出 SQL 转储文件 复制一个文件
权限 root 账号 + GRANT/REVOKE 体系 无用户体系,取决于文件系统权限
远程访问 天然支持多客户端远程连接 不支持,需应用层自行封装接口

1.3 选型建议:什么时候用 SQLite,什么时候用 MySQL

SQLite 和 MySQL 各有擅长的场景,选型的核心依据是数据由谁访问、从哪里访问

场景 推荐数据库 原因
桌面应用、单机工具的数据存储 SQLite 零配置,无需用户安装数据库服务
移动 App 本地数据 SQLite 移动端事实标准,系统内置
原型验证、课程示例、测试环境 SQLite 一分钟上手,随时删库重来
AI 应用的会话记录、元数据、缓存 SQLite 数据量中小、单进程访问为主
多用户 Web 服务的业务数据 MySQL 高并发读写、远程连接、权限管理
需要细粒度账号权限管理的系统 MySQL 内置用户与授权体系
多台服务器共享读写同一份数据 MySQL 客户端-服务器架构天然支持

简单判断:数据只被一个应用在本机读写,选 SQLite;数据要被多个用户、多台机器通过网络访问,选 MySQL。

2. 安装与配置 SQLite

2.1 安装方式选择

SQLite 官网不提供传统意义的"安装程序",只提供编译好的命令行工具压缩包。Windows 环境下有两种推荐安装方式:

安装方式 适用场景 推荐度
Winget 命令行安装 快速安装,自动配置 PATH 首选推荐
官网 zip 手动安装 需要指定版本或固定安装位置 备选

2.2 通过 Winget 安装(推荐)

Windows 10/11 系统默认自带 Winget 工具。以管理员身份打开 PowerShell,执行以下命令确认 Winget 可用:

winget --version

有版本号输出即可。随后执行安装命令:

winget install SQLite.SQLite

安装完成后,关闭当前终端并重新打开一个新终端(让 PATH 生效),进入下一节验证。

2.3 通过官网压缩包手动安装(备选)

如果无法使用 Winget,可从 SQLite 官网下载页面 获取工具包;网络环境不佳时,可直接从上方网盘地址下载(sqlite-tools 3.53.4 命令行工具包):

  1. 在页面中找到 sqlite-tools-win-x64 分类,下载对应的 zip 压缩包(约几 MB)
  2. 将压缩包解压到一个固定目录,例如 C:\sqlite
  3. 将该目录添加到系统环境变量 PATH

添加 PATH 的方式与 MySQL的安装与基本使用教程 中配置环境变量的步骤完全一致,可直接参考其"添加 MySQL 到系统 PATH"一节。命令行方式如下(需管理员权限):

[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "Machine") + ";C:\sqlite", "Machine")

执行后同样需要重新打开终端使配置生效。

2.4 验证安装

在新打开的终端中执行:

sqlite3 --version

预期输出类似:

3.53.4 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc (64-bit)

能正常显示版本号,说明 SQLite 命令行工具已就绪。

注意:Python 标准库中的 sqlite3 模块与这里的命令行工具是两回事。即便不安装命令行工具,Python 也自带 SQLite 引擎;但要在终端中直接敲 SQL 学习,仍需按本节安装命令行工具。

2.5 安装流程对比:SQLite 究竟省掉了什么

回顾 MySQL的安装与基本使用教程 的完整流程,再把 SQLite 的安装流程放在旁边,两者的工作量差异一目了然:

环节 MySQL SQLite
下载 MSI 安装包,数百 MB zip 压缩包,几 MB
安装 安装向导,数分钟 解压即用
环境变量 需手动添加 bin 目录到 PATH 需手动添加工具目录到 PATH
初始化 mysqld --initialize 初始化数据目录 无需初始化,首次连接自动建库
系统服务 注册 Windows 服务并启动 无服务进程
账号密码 初始化生成临时密码,首次登录后修改 无用户体系,无需认证
字符集 需配置 utf8mb4 避免中文乱码 TEXT 恒为 UTF-8,无需配置

SQLite 把 MySQL 安装过程中的初始化、服务、密码、字符集四个环节全部省去,这正是"零配置"的含义。代价则是它不提供网络服务能力,无法像 MySQL 那样被多台机器远程共享。

3. SQLite 基本使用

3.1 连接数据库:打开一个文件

MySQL 连接数据库的命令是 mysql -u root -p,需要输入密码;SQLite 连接数据库就是打开一个文件:

sqlite3 ai_ml_tutorial.db

执行后终端提示符变为 sqlite>,表示已进入 SQLite 交互环境。如果 ai_ml_tutorial.db 文件不存在,SQLite 会自动创建它——这一点与 MySQL 不同,MySQL 需要先执行 CREATE DATABASE 建库再 USE 切换,而 SQLite 把"建库"简化成了"创建一个文件"。

本教程沿用系列教程的数据约定,使用 ai_ml_tutorial 作为数据库名(即文件 ai_ml_tutorial.db),并沿用 MySQL 教程中的 users 表和数据,便于逐项对照学习。

进入交互环境后,可用点命令确认当前连接的数据库:

.databases

输出中的 main 就是当前打开的 ai_ml_tutorial.db 文件。如果中途想切换到另一个数据库文件,无需退出,使用 .open 命令:

.open another.db

3.2 点命令:SQLite 的"元命令"体系

sqlite3 命令行客户端提供了一批以 . 开头的点命令,用于查看元数据、调整输出格式等客户端操作。注意区分:点命令不属于 SQL 语言,结尾不加分号;而 SQL 语句仍然以分号结尾。

先打开表头显示和表格化输出,让查询结果更像 MySQL 客户端的效果:

.headers on
.mode box
需求 SQLite 点命令 MySQL 中的做法
查看当前连接的数据库 .databases SELECT DATABASE();
查看所有表 .tables SHOW TABLES;
查看表结构 .schema users DESC users;
查看建表语句 .schema users SHOW CREATE TABLE users;
查看帮助 .help 查阅官方文档
退出客户端 .quit.exit EXIT;

MySQL 的 SHOW DATABASESSHOW TABLESDESC 等都是 SQL 语句;SQLite 的对应功能则由点命令承担。这是命令行使用中两边最大的习惯差异,记住"点命令看元数据,SQL 语句管数据"即可。

3.3 创建数据表:建表语句逐项对照

sqlite> 提示符下执行以下建表语句:

CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT NOT NULL UNIQUE,
    age INTEGER DEFAULT 0,
    created_at TEXT DEFAULT CURRENT_TIMESTAMP
);

把它与 MySQL 教程中的建表语句并排放置,差异一目了然:

CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    age INT DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
差异点 MySQL 写法 SQLite 写法
自增主键 INT AUTO_INCREMENT PRIMARY KEY INTEGER PRIMARY KEY AUTOINCREMENT
字符串类型 VARCHAR(50),超长报错 TEXT,长度仅作声明不强制
时间类型 DATETIME 独立类型 惯用 TEXT 存 ISO 格式字符串

关于自增主键需要展开说明:SQLite 要求自增列的类型必须写成 INTEGER(不能写成 INT),因为 INTEGER PRIMARY KEY 是行号 rowid 的别名,本身就具备自增能力;末尾的 AUTOINCREMENT 关键字只是额外保证"已删除行的编号不会被复用",日常使用可以省略。而 MySQL 中 AUTO_INCREMENT 是实现自增的必要关键字,两者心智模型不同。

.schema users 确认建表结果:

.schema users

3.4 数据的增删改查(CRUD)

建表之后的数据操作,SQLite 与 MySQL 的语法几乎完全一致,以下语句可原样运行在两边:

-- 插入数据
INSERT INTO users (name, email, age) VALUES
    ('张三', 'zhangsan@example.com', 25),
    ('李四', 'lisi@example.com', 30),
    ('王五', 'wangwu@example.com', 28);

-- 查询所有数据
SELECT * FROM users;

-- 条件查询 + 排序 + 分页
SELECT * FROM users WHERE age >= 25 ORDER BY age DESC LIMIT 2 OFFSET 0;

-- 更新数据
UPDATE users SET age = 26 WHERE name = '张三';

-- 删除数据
DELETE FROM users WHERE name = '王五';

-- 删除表
DROP TABLE users;

已掌握 MySQL 的读者可以直接把增删改查的 SQL 搬进 SQLite 使用。两个数据库的真正差异集中在"库怎么建、元数据怎么看、类型怎么定"这些外围操作上,核心 SQL 能力完全通用。此外,事务语法(BEGINCOMMITROLLBACK)和 LIKE 模糊查询在两边也完全一致。

3.5 数据类型与亲和性:最容易被低估的差异

MySQL 的列类型是强约束:声明为 INT 的列写入字符串会报错或被强制转换。SQLite 采用类型亲和性(Type Affinity)机制:建表时声明的类型只是给存储引擎的"建议",实际几乎可以存入任何类型的数据。SQLite 底层只有 5 种存储类型:NULLINTEGERREAL(浮点数)、TEXTBLOB

列声明的类型按以下规则映射到亲和性:

列声明中含有的字符串 亲和性 示例
INT INTEGER INTBIGINT 均归为 INTEGER
CHAR、CLOB、TEXT TEXT VARCHAR(50)TEXT 均归为 TEXT
BLOB 或未声明类型 BLOB 原样存储
REAL、FLOA、DOUB REAL DOUBLEFLOAT 均归为 REAL
其余情况 NUMERIC 尽可能转为数值存储

据此可以整理出一张 MySQL 到 SQLite 的类型迁移对照表:

MySQL 类型 SQLite 惯用写法 说明
INT / BIGINT INTEGER 自增主键必须写 INTEGER
VARCHAR(N) TEXT 长度 N 不强制校验
DATETIME TEXT 惯用 ISO 8601 字符串
DECIMAL(M,D) NUMERICREAL 无精确定点类型,金额计算需注意精度
TINYINT(1)(布尔) INTEGER 用 0 和 1 表示假和真
BLOB BLOB 一致

这是把 MySQL 应用迁移到 SQLite 时最容易踩的坑:SQLite 对列中存储的数据类型来者不拒,脏数据要靠应用层校验。反过来,这也让 SQLite 的表结构非常灵活,不需要因为"字段加长"而修改表定义。

4. 与 MySQL 的差异对照手册

4.1 常用命令速查表

将本教程涉及的命令汇总成一张速查表,便于从 MySQL 快速切换到 SQLite:

操作 MySQL SQLite
连接数据库 mysql -u root -p sqlite3 ai_ml_tutorial.db
查看所有数据库 SHOW DATABASES; .databases(一个文件即一个库)
选择数据库 USE mydb; 打开文件即选中,或 ATTACH 'x.db' AS x;
查看所有表 SHOW TABLES; .tables
查看表结构 DESC users; .schema users
查看建表语句 SHOW CREATE TABLE users; .schema users
查看当前时间 SELECT NOW(); SELECT datetime('now','localtime');
字符串拼接 CONCAT(a, b) a \|\| b
退出客户端 EXIT; .quit.exit

4.2 语法细节差异

除速查表中的命令差异外,还有几处 SQL 语法细节值得留意:

  • 当前时间函数:MySQL 用 NOW();SQLite 用 datetime('now') 返回 UTC 时间,加 localtime 修饰符返回本地时间。SQLite 还提供了 date()time()strftime() 等日期函数家族。
  • 标识符引用:MySQL 惯用反引号包住表名列名(如 `order`);SQLite 推荐双引号(如 "order"),同时也兼容反引号。
  • 存储过程与调度:MySQL 支持存储过程、事件调度器;SQLite 均不支持,业务逻辑需放在应用层实现。全文检索方面,SQLite 需启用 FTS5 扩展模块。
  • 表结构修改:MySQL 可用 ALTER TABLE ... MODIFY COLUMN 随意改列类型;SQLite 的 ALTER TABLE 仅支持改名、加列和删列,修改列类型需要"新建表、复制数据、删旧表、重命名"四步操作。

4.3 权限与并发模型差异

权限方面,MySQL 拥有完整的用户体系:root 账号、GRANT/REVOKE 授权、按库表粒度控制访问。SQLite 没有任何用户和权限概念,谁能读写数据库文件,完全由操作系统的文件权限决定。因为没有监听端口,SQLite 也不存在"数据库端口被扫描爆破"这类攻击面,安全性边界清晰。

并发方面,两者差异更大:MySQL 的 InnoDB 引擎支持大量连接同时写入,行级锁让不同行的修改互不阻塞;SQLite 在同一时刻只允许一个写事务,多个连接的写入操作会串行排队,后来的写入者在锁被占用时会收到"database is locked"错误。读取方面,SQLite 默认模式下读写互斥,启用 WAL(Write-Ahead Logging)模式后,读操作可与写操作并发进行:

PRAGMA journal_mode=WAL;

单机、低频写入是 SQLite 的舒适区;一旦出现"多个进程频繁写同一个库"的需求,就需要更换为 MySQL 或其他数据库了。

4.4 从 MySQL 迁移到 SQLite 的注意事项

把一个基于 MySQL 的项目改为 SQLite 存储(或反向迁移)时,按以下清单逐项核对:

  • 时间字段:MySQL 的 DATETIME DEFAULT CURRENT_TIMESTAMP 填的是服务器本地时区时间;SQLite 的 CURRENT_TIMESTAMP 填的是 UTC 时间,比北京时间早 8 小时。否则会出现迁移后时间"慢了 8 小时"的问题。
  • 类型校验前移:SQLite 不校验列类型,原本依赖 MySQL 报错兜底的数据质量检查,需要移到应用层。
  • 存储过程改写:MySQL 中的存储过程和调度事件无法迁移,需改写为应用代码。
  • 并发写入评估:确认新场景下是否有多进程并发写需求,必要时启用 WAL 模式并设置 busy_timeout
  • 数据导入:从 MySQL 导出的 INSERT 语句大多可直接在 SQLite 中执行,导入前去除 SQLite 不支持的函数(如 NOW() 改为 datetime('now'))即可。

5. 在 Python 中使用 SQLite

5.1 标准库自带,无需安装驱动

MySQL 教程中操作数据库需要先 pip install mysql-connector-python 安装第三方驱动;Python 则将 SQLite 引擎直接内置在标准库中,import sqlite3 即可使用。

对比项 Python + SQLite Python + MySQL
驱动来源 标准库 sqlite3,无需安装 第三方 mysql-connector-python
连接参数 一个文件路径 host、port、user、password、database
SQL 占位符 ? %s
建库前提 文件不存在时自动创建 需先 CREATE DATABASE

5.2 连接与增删改查示例

本教程配套了一个示例项目 sqlite-demo:一个基于标准库的命令行增删改查工具,支持 init(建表并写入示例数据)、addlistfindupdatedelete 六个子命令,可从资源下载区的网盘地址获取。项目结构如下:

sqlite-demo/
├── sqlite_demo.py   # 命令行工具入口
└── README.md        # 运行说明

其核心代码片段如下:

import sqlite3

# 连接数据库(文件不存在时自动创建)
conn = sqlite3.connect("ai_ml_tutorial.db")
cursor = conn.cursor()

# 建表
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT NOT NULL UNIQUE,
    age INTEGER DEFAULT 0,
    created_at TEXT DEFAULT CURRENT_TIMESTAMP
)
""")

# 插入数据,占位符为问号,可防止 SQL 注入
cursor.execute(
    "INSERT INTO users (name, email, age) VALUES (?, ?, ?)",
    ("张三", "zhangsan@example.com", 25)
)
conn.commit()

# 查询数据
cursor.execute("SELECT * FROM users WHERE age >= ?", (20,))
for row in cursor.fetchall():
    print(row)

# 让查询结果支持按列名访问
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT name, age FROM users")
for row in cursor.fetchall():
    print(row["name"], row["age"])

# 关闭连接
conn.close()

与 MySQL 驱动的用法相比,有三处习惯差异需要适应:连接参数从一个文件路径取代了五项服务器配置;SQL 占位符从 %s 换成了 ?;增删改之后同样需要 conn.commit() 提交事务。

完整代码请查看网盘资源中的 sqlite-demo/sqlite_demo.py。使用方式:

python sqlite_demo.py init                              # 建表并写入三条示例数据
python sqlite_demo.py add --name 赵六 --email zhaoliu@example.com --age 22
python sqlite_demo.py list                              # 列出全部用户
python sqlite_demo.py find --keyword                  # 按姓名或邮箱模糊查找
python sqlite_demo.py update --name 张三 --age 26       # 按姓名修改年龄
python sqlite_demo.py delete --name 王五                # 按姓名删除用户

如果你想把 MySQL 教程中的 fastapi-mysql 前后端项目改造为 SQLite 版本,只需替换连接代码和占位符,其余业务 SQL 几乎可以原样保留,这也是验证"SQL 能力通用"的好练习。

6. 可视化管理工具

与 MySQL 生态中的 HeidiSQL 对应,SQLite 最常用的免费图形化工具是 DB Browser for SQLite:开源、跨平台、安装即用,从官网下载安装后,点击"打开数据库"选择 .db 文件即可开始管理。

工具界面围绕三个选项卡组织,可以对应 HeidiSQL 的功能来理解:

  • 数据库结构:查看和修改表结构,相当于 HeidiSQL 的"编辑表"
  • 浏览数据:像 Excel 一样直接增删改单元格,相当于 HeidiSQL 的"编辑数据"
  • 执行 SQL:输入并运行 SQL 语句,相当于 HeidiSQL 的"查询"选项卡

此外,HeidiSQL 本身也支持 SQLite:在会话的"网络类型"中选择 SQLite,指定数据库文件路径即可连接。对于已经在使用 HeidiSQL 管理 MySQL 的读者,可以零成本复用既有工具。

7. 总结

7.1 核心内容回顾

  • SQLite 是嵌入式关系型数据库:无服务进程、无端口、无账号体系,一个 .db 文件就是一个完整数据库,复制文件即完成备份。
  • 安装极简:通过 winget install SQLite.SQLite 或官网压缩包即可获得命令行工具,相比 MySQL 省去了初始化、服务、密码、字符集四个环节。
  • 命令行使用中,元数据查看靠点命令(.tables.schema.quit),与 MySQL 的 SHOWDESC 体系一一对应。
  • 增删改查 SQL 与 MySQL 几乎完全一致;差异集中在类型系统(类型亲和性)、自增主键写法、时间函数时区和并发写入模型上。
  • Python 标准库自带 sqlite3 模块,连接参数、占位符写法与 MySQL 驱动不同,业务 SQL 可直接复用。
  • 选型口诀:单机单应用选 SQLite,多用户多机器网络访问选 MySQL。

7.2 常见问题与解答

问:SQLite 能完全替代 MySQL 吗?

答:不能一概而论。SQLite 没有服务进程和用户权限体系,不适合多用户远程访问、高并发写入的场景;但对于单机应用、移动端存储、原型验证和低流量网站,SQLite 更简单可靠。两者是互补关系,很多项目的做法是开发测试阶段用 SQLite、生产环境用 MySQL。

问:SQLite 数据库如何实现远程访问?

答:SQLite 本质是对本地文件的读写,不提供网络协议。如需远程访问,通常由应用服务器(如 FastAPI 后端)封装 HTTP 接口对外提供服务,多个客户端通过网络调用接口间接读写数据。

问:为什么我插入的时间比本地时间早了 8 小时?

答:SQLite 的 CURRENT_TIMESTAMPdatetime('now') 返回的都是 UTC 时间,而 MySQL 的 CURRENT_TIMESTAMP 使用服务器本地时区。需要本地时间时改用 datetime('now', 'localtime'),或读取数据后自行换算时区。

问:一个 .db 文件相当于 MySQL 的一个库,那怎么同时打开多个库?

答:使用 ATTACH DATABASE '文件路径' AS 别名; 可以在同一连接中挂载多个数据库文件,之后用"别名.表名"跨库访问,用 .databases 查看当前挂载的所有库。

问:往 TEXT 列里插入数字、往 INTEGER 列里插入字符串会报错吗?

答:不会。SQLite 的类型亲和性机制不强制校验列类型,几乎任何值都能存进去。这与 MySQL 的强类型约束不同,数据合法性检查需要在应用层完成。