SQLite 是程序内部的数据库
你听说过的大多数数据库,比如 MySQL、Postgres、SQL Server,都是作为独立程序运行的。你先启动一个服务器,它监听某个端口,然后应用程序通过网络连接上去向它发起查询。SQLite 彻底抛弃了这套模式。
SQLite 是一个库。你把它链接进自己的程序,它就给你一个存放在磁盘单个文件里的 SQL 数据库。没有服务器,没有端口,没有守护进程,也不需要 pg_ctl start。应用程序打开一个文件,这个文件本身就是数据库。
sqlite3 mydata.db
这条命令会打开(或创建)一个名为 mydata.db 的文件,并给你一个 SQL 提示符。你做的所有操作,包括表、行和索引,都存进这一个文件。把它复制到另一台机器,数据库就跟着过去了;把它删掉,数据库也就没了。
快速浏览 SQL 写法
SQL 本身和在其他地方看到的没什么两样。如果你用过别的数据库,几乎所有内容都会很眼熟:
都是标准 SQL:CREATE TABLE、INSERT、SELECT、ORDER BY。SQLite 支持日常真正会用到的那部分 SQL 标准,还有 CTE、窗口函数 和 JSON 函数这些现代功能。它和 Postgres 或 MySQL 的区别主要在类型和少数语法细节上,后面会讲到。
“嵌入式”和“无服务器”到底是什么意思
说到 SQLite,总会反复出现两个词,值得先弄清楚。
嵌入式指 SQLite 和你的应用程序运行在同一个进程里,没有单独的数据库进程。当你的 Python 脚本调用 sqlite3.connect("data.db") 时,SQL 引擎就运行在你的 Python 进程内部,直接读写那个文件。
无服务器指没有需要安装、配置、运行、加固或备份的服务器。对比一下开始使用数据库的步骤:
- Postgres:安装 Postgres,启动服务,创建用户,创建数据库,配置
pg_hba.conf,再通过 TCP 连接。 - SQLite:打开一个文件。
区别就这么多。能力少一些,繁琐的步骤少得多。
整个数据库就是一个文件
这一点常常让人意外。它的文件格式有公开文档,而且非常稳定。一个 .db 文件(也可以叫 .sqlite 或 .sqlite3,扩展名只是约定)可以:
- 用邮件发给同事。
- 提交到 git(至少小文件可以)。
- 用
cp复制一份,立刻就是备份。 - 在任何操作系统上用任何 SQLite 工具打开。
ls -lh mydata.db
# -rw-r--r-- 1 you staff 28K Apr 23 14:02 mydata.db
这一个文件里装着你的表、索引、结构定义和数据。磁盘上的 SQLite 数据库在 Windows、macOS、Linux、iOS 和 Android 之间逐字节完全一致。这个格式稳定到美国国会图书馆都推荐用它来长期保存数据。
你其实早就在用 SQLite
你正在阅读本文的这台设备上,几乎肯定有成百上千个 SQLite 数据库。它支撑着:
- iOS 和 Android 的系统存储,以及两个平台上的大量应用。
- Firefox、Chrome 和 Safari(历史记录、书签、Cookie)。
- macOS(邮件、照片、程序坞)。
- 大多数需要本地存储的 Linux 桌面应用。
- Skype、WhatsApp、Signal 的聊天记录。
- Adobe Lightroom 的目录、Dropbox 的元数据、Steam 的游戏库。
它被称为世界上部署最广泛的数据库引擎,这话多半属实。原因很简单:应用需要结构化的本地存储时,SQLite 就是阻力最小的选择。
SQLite 不是什么
它不是客户端/服务器数据库。两台不同机器上的程序无法通过网络同时连接同一个 SQLite 数据库,因为根本没有可连接的网络层。如果你需要这种能力,应该用 Postgres 或 MySQL。
它不是为高并发写入设计的。SQLite 使用文件级锁(WAL 模式 下有一些巧妙的优化),所以多个读取者可以并行工作,但同一时间只有一个写入者能提交。对单用户应用或访问量不大的网站来说,这根本不是问题;但对每秒要处理几千次写入的多租户 SaaS 来说,它就是选错了工具。
它不管理用户和权限。访问数据库就是访问文件,谁能读这个文件,谁就能读里面的数据。对独占自己数据库文件的应用来说没问题,但不适合多方共享的多租户环境。
为什么要选它
你用一部分可能永远用不上的扩展空间,换来了简单:
- 零配置。 不用运行任何服务,开发环境和生产环境之间不会有版本不一致,也不会出现“数据库挂了”,因为压根没有数据库服务器。
- 快。 对大多数工作负载,尤其是读多写少的场景,SQLite 比网络数据库更快,因为每次查询都省掉了一次套接字往返。
- 可靠。 它的测试做到了近乎偏执的程度。SQLite 项目的测试代码远远多于源代码,文件格式从 2004 年起就保持稳定。
- 公有领域。 任何用途都免费,包括商业用途,也没有许可证要读。
- 可移植。 一个文件,所有平台通用。
对于本地应用、原型、嵌入式设备、命令行工具、测试套件、数据分析脚本以及中小型网站,SQLite 往往就是正确的默认选择,而不是迈向“真正”数据库之前的过渡。
下一篇:SQLite 与 MySQL 对比
接下来自然会想问:SQLite 和你更常听说的那些数据库服务器相比如何?我们先从 MySQL 说起:各自擅长什么,以及怎么判断哪一个适合你手上的项目。
常见问题
SQLite 是什么?
SQLite 是一个 SQL 数据库引擎,它作为库运行在你的应用程序内部,而不是一个独立的服务器。整个数据库,包括表、索引、结构定义和数据,都保存在磁盘上的一个文件里。你通过 C 库(或你所用语言的绑定)用普通的 SQL 和它交互。
SQLite 用来做什么?
凡是需要一个真正的 SQL 数据库、又不想运行服务器的地方都能用:移动应用(iOS 和 Android 都内置了它)、桌面应用、浏览器、嵌入式设备、小型网站、本地缓存、测试套件和数据分析脚本。如果你的数据放得进一台机器,并且同一时间只有一个进程在写入,SQLite 通常就很合适。
SQLite 算是真正的数据库吗?
算。它支持事务、ACID 保证、外键、连接、子查询、窗口函数、CTE、触发器、视图和 JSON。它缺少服务器数据库的一些能力,比如网络访问、多写入者并发和用户账号,因为这些本来就不是它的职责。对单进程应用来说,它和 Postgres 一样“真”。
SQLite 免费吗?
免费。SQLite 属于公有领域,比开源许可还要宽松。你可以把它用在商业产品里、修改它、随产品发布,都不需要署名,也不用付授权费。正因如此,它成了全世界部署最广泛的软件之一。