SQLite 文档
简洁、以示例为主的 SQLite 参考文档。先读概念,再看代码,然后在 Coddy 学习旅程中动手练习。
开始课程入门
- SQLite 是什么SQLite 是一个无服务器、基于文件的 SQL 数据库,直接运行在你的应用程序内部。本文讲清它到底是什么、和数据库服务器有什么不同,以及它最擅长的场景。
- SQL 命令列表你每天都会用到的 SQL 命令,按用途分组(DDL、DML、DQL 和 TCL),每条都附有可以在 SQLite 中运行的示例。
- SQLite vs MySQLSQLite 和 MySQL 到底有什么不同:架构、并发、数据类型,以及各自适合什么样的项目。
- SQLite 与 PostgresSQLite 和 PostgreSQL 的真正区别:架构、并发、类型,以及各自最适合的项目类型。
- 什么时候用 SQLite一份实用指南:什么时候 SQLite 是合适的数据库,什么时候应该改用 Postgres 或 MySQL。
- 安装 SQLite如何在 Windows、macOS 和 Linux 上安装 SQLite:获取命令行工具,把它加入 PATH,并验证一切正常。
- SQLite 命令行如何使用 sqlite3 命令行工具:打开数据库、运行查询、点命令,以及不离开终端就能导入或导出数据。
- 可视化工具实用指南:用图形界面工具打开、浏览和编辑 SQLite 数据库文件,包括 DB Browser for SQLite、SQLiteStudio 和在线查看器。
- 创建数据库如何创建 SQLite 数据库:基于文件的心智模型、`sqlite3` 命令,以及为什么没有 `CREATE DATABASE` 语句。
- 内存数据库SQLite 内存数据库的工作原理,什么时候该用 `:memory:`,以及它和可以长期保存的文件数据库有什么不同。
表与类型
- CREATE TABLE如何在 SQLite 中创建表:列定义、约束、IF NOT EXISTS、临时表,以及 CREATE TABLE AS SELECT。
- 数据类型SQLite 如何存储值:五种存储类、为什么类型是动态的,以及从 Postgres 或 MySQL 转过来的人常踩的坑。
- 类型亲和性SQLite 的类型亲和性如何工作:五种亲和性、根据列声明选出亲和性的规则,以及为什么 INTEGER 列也能存字符串。
- STRICT 表SQLite 的 STRICT 表如何关闭灵活类型存储、拒绝类型不符的值,给你一直以来预期的类型检查。
- 主键SQLite 中主键的工作原理:特殊的 INTEGER PRIMARY KEY、复合主键、AUTOINCREMENT,以及容易让新手踩坑的特殊行为。
- ROWIDSQLite 中的 ROWID 到底是什么,什么时候 INTEGER PRIMARY KEY 会让它变成你的列,以及为什么会有 WITHOUT ROWID 表。
- NOT NULL 与默认值SQLite 中 NOT NULL 和 DEFAULT 的工作方式:它们到底约束了什么、CURRENT_TIMESTAMP 技巧,以及给已有表添加它们时的坑。
- CHECK 约束如何在 SQLite 中用 CHECK 约束给列的值加上规则:单列检查、多列检查、命名约束,以及需要注意的坑。
- UNIQUE 约束SQLite 中 UNIQUE 约束如何工作:列级和表级写法、联合唯一、NULL 的特殊行为,以及约束失败时该怎么办。
- DROP 与 ALTER TABLE如何在 SQLite 中删除、重命名和修改表:ALTER TABLE 支持什么、不支持什么,以及处理它做不到的改动时用的重建技巧。
插入与修改数据
- INSERTSQLite 中 INSERT 的用法:插入单行、一次插入多行、INSERT...SELECT、默认值,以及 OR IGNORE / OR REPLACE 冲突处理修饰符。
- SQL UPDATE 语句如何在 SQLite 中修改已有的行:UPDATE 语法、保证安全的 WHERE 子句、一次更新多列,以及跨表修改用的 UPDATE ... FROM。
- DELETESQLite 中 DELETE 的工作方式:写出安全的 WHERE 子句、删除所有行、级联删除关联表,以及用 RETURNING 取回被删除的行。
- UPSERTSQLite 中 UPSERT 如何工作:ON CONFLICT 子句、excluded 表、DO NOTHING 和 DO UPDATE 的区别,以及它和 INSERT OR REPLACE 有什么不同。
- RETURNING 子句SQLite 中 RETURNING 子句的工作原理:不用第二条查询,就能取回 INSERT、UPDATE 或 DELETE 刚刚改动的行。
- 导入 CSV如何用 .import 命令把 CSV 文件导入 SQLite:处理表头、导入已有的表、自定义分隔符,以及最常见的错误。
- 导出数据如何把数据从 SQLite 中导出:带表头的 CSV、JSON、完整的 SQL 转储,以及用 sqlite3 命令行工具备份单张表。
查询数据
- SELECT 基础SQLite 中 SELECT 语句的工作原理:选择列、计算表达式、给结果起别名,以及你今后写的每一条查询背后的思维方式。
- WHERE 子句WHERE 子句在 SQLite 中如何筛选行:比较运算符、AND/OR、LIKE、IN、BETWEEN,以及几乎人人都会踩的 NULL 陷阱。
- 运算符与 NULLSQLite 运算符遇到 NULL 时如何工作:为什么 `=` 和 `<>` 的表现和你想的不一样,以及真正管用的 IS、IS NOT、COALESCE 和 IFNULL。
- ORDER BYSQLite 中 ORDER BY 的用法:升序和降序排序、用多列打破平局、处理 NULL,以及不区分大小写的排序。
- LIMIT 与 OFFSETSQLite 中 LIMIT 和 OFFSET 的用法:限制行数、跳过行、安全地分页,以及在大表上要避开的性能陷阱。
- DISTINCTSQLite 中 SELECT DISTINCT 的工作方式:单列、多列、NULL 的处理、COUNT(DISTINCT),以及什么时候 GROUP BY 才是更合适的工具。
- SQL CASE 语句CASE 在 SQLite 中如何工作:简单形式和搜索形式,在 SELECT、ORDER BY 和 WHERE 中的用法,以及什么时候该改用 IIF。
函数与聚合
- 字符串函数SQLite 中实用的字符串函数:拼接、SUBSTR、INSTR、REPLACE、TRIM,以及在查询中清洗和改造文本的常用写法。
- 数值函数如何在 SQLite 中做算术运算:ROUND、ABS、CEIL、FLOOR、MOD、POWER、SQRT、RANDOM,以及几乎人人都会踩一次的整数除法陷阱。
- 日期和时间SQLite 如何存储和处理日期:五个日期函数、格式字符串、修饰符,以及能让查询保持高效的存储选择。
- SQL 聚合函数SQLite 的聚合函数如何把多行数据汇总成一个值:COUNT、SUM、AVG、MIN、MAX、GROUP_CONCAT,以及 DISTINCT、FILTER 和 NULL 的处理规则。
- GROUP BY 与 HAVINGSQLite 中 GROUP BY 如何把行归入分组,HAVING 如何在聚合之后过滤这些分组,并用具体例子讲清 WHERE 与 HAVING 的区别。
关系与连接
- 外键SQLite 外键的工作原理:如何声明 REFERENCES,如何用 PRAGMA 开启外键约束检查,以及如何选择合适的 ON DELETE 行为。
- INNER JOINSQLite 中 INNER JOIN 的工作原理:思维模型、ON 子句、连接三张表,以及 USING 简写。
- LEFT JOINSQLite 中 LEFT JOIN 的工作原理:保留没有匹配的行、理解 NULL、安全地过滤,以及连接两张以上的表。
- 自连接SQLite 自连接的工作原理:用别名把同一张表中的行配对,附员工与经理、层级数据的完整示例。
- 子查询如何在 SQLite 中把一个 SELECT 嵌套在另一个里面:标量子查询、IN/EXISTS、派生表、相关子查询,以及什么时候用 JOIN 更清楚。
- CTESQLite 中公用表表达式的工作原理:用 WITH 给子查询命名、串联多个 CTE,写出能从上往下读的查询。
- 递归 CTESQLite 递归 CTE 的工作原理:锚点查询加递归查询的结构、遍历父子树、生成序列,以及如何避免无限循环。
索引与性能
- 索引SQLite 索引的工作原理,什么时候有帮助,什么时候有害,以及如何判断查询规划器是否真的在用它们。
- 复合索引SQLite 中多列索引如何工作、为什么列顺序很重要,以及复合索引什么时候能提速、什么时候只是白占空间。
- 部分索引SQLite 中部分索引的工作原理:只为你真正查询的行建索引,以及让它物有所值的几种模式(软删除、部分唯一、热点子集)。
- EXPLAIN QUERY PLAN如何在 SQLite 中用 EXPLAIN QUERY PLAN 查看查询是否用到了索引、SCAN 和 SEARCH 的含义,以及如何阅读连接的执行计划。
- ANALYZE 和 VACUUM`ANALYZE` 和 `VACUUM` 如何让 SQLite 数据库保持快速、紧凑:它们各自到底做了什么、什么时候运行,以及值得了解的几种变体。
高级功能
- 事务SQLite 中的事务如何工作:BEGIN、COMMIT、ROLLBACK、自动提交,以及决定何时加锁的 DEFERRED/IMMEDIATE/EXCLUSIVE 模式。
- 保存点SQLite 保存点的工作原理:在事务中设置带名字的标记,回滚到这里时不必放弃整个事务。
- 视图SQLite 中视图如何工作:把查询保存成虚拟表,什么时候用临时视图,以及为什么 SQLite 的视图默认是只读的。
- 触发器SQLite 触发器如何工作:BEFORE 和 AFTER、视图上的 INSTEAD OF、OLD 和 NEW 行引用,以及什么时候适合用触发器。
- JSON 支持SQLite 如何存储和查询 JSON:提取字段、更新值、用 json_each 展开数组,以及给 JSON 路径建索引来提速。
- 全文搜索如何用 FTS5 为 SQLite 加上全文搜索:创建虚拟表、使用 MATCH 运算符、BM25 排序,以及让索引与数据保持同步。
- 窗口函数SQLite 中的窗口函数怎么用:OVER、PARTITION BY、排名函数、LAG/LEAD,以及用于计算累计值的窗口框架子句。
- 生成列SQLite 生成列的工作原理:如何声明,如何在 VIRTUAL 和 STORED 之间选择,以及如何给它们建立索引来加快查找。
- ATTACH DATABASEATTACH DATABASE 如何让你在一个连接中打开多个 SQLite 文件,用 schema 前缀跨文件查询,并在用完后分离。
安全与应用集成
- 预处理语句SQLite 中的预处理语句是什么、为什么需要它,以及每个驱动都在封装的 prepare/bind/step/finalize 生命周期。
- 参数绑定SQLite 中的参数绑定如何工作:位置占位符、命名参数,以及从应用中安全传值的规则。
- SQL 注入为什么字符串拼接很危险,SQL 注入到底是怎么发生的,以及 SQLite 的参数化查询如何彻底杜绝它。
- 应用连接应用程序如何打开和使用 SQLite 数据库:连接字符串、文件路径、各语言的驱动,以及第一天就该设置好的几项配置。
- 数据库迁移如何用 PRAGMA user_version、按顺序执行的迁移脚本和事务,安全地逐步演进 SQLite 表结构,并让每一步都可以回退。
- WAL 与并发SQLite 的预写日志(write-ahead logging)如何改变并发方式:读者和写者不再互相阻塞,以及 -wal 和 -shm 文件到底是做什么的。