了解应用程序如何在内部与 SQLite 交互
I’m happy to help translate the article, but I need the text you’d like translated. Could you please paste the content (or the portion you want translated) here? I’ll keep the source link unchanged and preserve all formatting, markdown, and technical terms as requested.
Source:
SQLite 概述
SQLite 的一个决定性优势在于应用程序与其交互的方式既简洁又可预测。
不同于客户端‑服务器数据库,SQLite 直接运行在应用程序进程内部,提供了一个小而强大的 C API,让开发者能够精确控制查询执行、内存使用和性能。
核心数据结构
sqlite3→ 表示 数据库连接sqlite3_stmt→ 表示 已准备好的 SQL 语句
应用程序对 SQLite 的所有操作都围绕这两个对象展开。

从 SQL 文本到可执行字节码
当应用程序向 SQLite 发送 SQL 时,引擎 不会直接执行原始文本。
相反,SQLite 采用编译‑执行模型,类似于现代编程语言。

sqlite3_prepare — 将 SQL 编译为字节码
sqlite3_prepare(db, sql, -1, &stmt, NULL);
内部发生的过程至关重要:
- 解析 SQL。
- 验证 模式对象(表、索引、列)。
- 翻译 SQL 为 内部字节码程序。
- 包装 该程序到
sqlite3_stmt对象中(预编译语句)。
在 SQLite 术语中:
- 预编译语句 就是 字节码程序。
- 字节码程序 是 SQLite 虚拟机执行的抽象指令序列。
如果准备成功,sqlite3_prepare 返回 SQLITE_OK;否则返回详细的错误码(语法错误、缺少表等)。
此时 尚未执行任何操作——语句已编译但处于休眠状态,就像已加载等待运行的程序。
执行预处理语句逐行
sqlite3_step — 驱动 SQLite 虚拟机
sqlite3_step(stmt);
每次调用 sqlite3_step 都会运行字节码程序,直到出现以下两种情况之一:
- 产生一行新的结果,或
- 程序执行完毕。
返回值告诉应用程序到底发生了什么:
| 返回码 | 含义 |
|---|---|
SQLITE_ROW | 行已准备好读取 |
SQLITE_DONE | 执行已完成 |
SELECT 语句
- 游标最初位于 第一行之前。
- 每次调用
sqlite3_step都会将游标 向前 移动。 - 行会 一次产生一行(不会向后移动)。
INSERT / UPDATE / DELETE / CREATE / DROP
- 不产生行。
sqlite3_step会立即返回SQLITE_DONE。
这种逐行执行模型是 SQLite 极其节省内存的关键原因。
读取列数据的安全方法
sqlite3_column_* — 从行中提取值
当 sqlite3_step 返回 SQLITE_ROW 时,可以使用特定类型的 API 读取列值:
sqlite3_column_intsqlite3_column_int64sqlite3_column_doublesqlite3_column_textsqlite3_column_blob
每个函数都保证返回的值已转换为请求的 C 类型。
对于文本和 BLOB 数据,大小至关重要。SQLite 提供:
int bytes = sqlite3_column_bytes(stmt, col_index);
这会告诉应用程序列实际占用的字节数,对安全的内存处理至关重要。
错误处理在执行期间
在逐步执行语句时,SQLite 可能会遇到运行时问题。在这种情况下,sqlite3_step 可以返回:
| 返回码 | 含义 |
|---|---|
SQLITE_BUSY | 数据库被锁定;应用程序可以稍后重试。 |
SQLITE_ERROR | 发生运行时错误(例如约束冲突)。必须停止执行。 |
SQLITE_MISUSE | API 使用不当(例如在已完成的语句上调用 sqlite3_step)。 |
这些明确的返回码让 SQLite 清晰地说明了出错原因以及应用程序接下来应采取的措施。
清理:结束语句生命周期
sqlite3_finalize — 销毁预处理语句
sqlite3_finalize(stmt);
完成后会执行以下操作:
- 删除字节码程序。
- 释放与该语句关联的所有内存。
- 永久使
sqlite3_stmt句柄失效。
如果语句仍在执行,SQLite 将把完成视为一次中断:
- 未完成的更改将被回滚。
- 执行被中止,返回
SQLITE_ABORT。
未能完成语句的终结是 SQLite 应用程序中最常见的资源泄漏原因之一。
SQLite 应用中的源泄漏
关闭数据库连接
sqlite3_close — 释放数据库句柄
sqlite3_close(db);
这将释放与该连接关联的所有资源。
重要规则:
如果 仍有任何已准备好的语句处于活动状态,sqlite3_close 会返回 SQLITE_BUSY。
连接会保持打开,直到所有语句都被 finalize。
此严格规则确保数据库完整性并防止悬挂的执行上下文。
综合运用:SQLite 执行模式
在实际使用中,SQLite 的使用遵循一个非常一致的生命周期:
- 打开数据库连接(
sqlite3_open) - 预编译 SQL 语句(
sqlite3_prepare) - 如有需要,绑定数值
- 使用
sqlite3_step执行(可能需要多次) - 使用
sqlite3_column_*读取列值 - 如需复用语句,重置语句
- 结束语句(
sqlite3_finalize) - 关闭数据库连接(
sqlite3_close)
这套小而有纪律的 API 表面是 SQLite 在全球操作系统、浏览器、移动应用和嵌入式系统中受到信赖的主要原因。
我关于 SQLite 的实验和实际操作将会放在这里:
lovestaco/sqlite
参考文献
欢迎任何反馈或贡献!
它是在线的、开源的,随时可供任何人使用。
⭐ 在 GitHub 上给它加星: FreeDevTools
