SQLite 数据库检查器
像 SQLite 自己那样直接从字节读取数据库文件,不经过 SQL 引擎,文件也不会离开你的机器。100 字节的头部给出页大小、文本编码、处于回滚模式还是 WAL 模式、空闲列表上有多少页、应用写入的 user_version 与 application_id,以及最后写入该文件的 SQLite 版本。随后遍历第 1 页上的 sqlite_schema b 树,列出每张表、索引、视图和触发器及其 CREATE 语句,并逐一遍历每张表自己的 b 树直到叶子,因此行数是数出来的而不是估算的。有两点需要先知道:WAL 模式下最新的提交往往还留在 -wal 文件里而不在主文件中,未做检查点的数据库报出的行数会少于应用看到的;WITHOUT ROWID 表把行存放在索引 b 树中,因此其行数显示为未知而不是给出错误的数字。列名、声明类型以及 PRIMARY KEY 和 NOT NULL 标记来自对 CREATE 语句文本的解析,普通结构没问题,遇到少见的 DDL 可能偏差,所以原始语句始终一并显示。包括 SQLCipher 在内的加密数据库会被拒绝而不是读一半,因为它们的头部同样被加密,开头没有那串魔数。行内容有意不显示:这个工具回答文件里有什么、有多大,而不是某条记录写了什么。
使用方法
- 把 .sqlite、.db 或 .sqlite3 文件拖到方框里,或点击选择。文件留在浏览器中。
- 先看头部:页大小乘以页数就是文件大小,空闲页则是 VACUUM 能归还的空间。
- 确认日志模式。若为 WAL,仍在 -wal 中的提交不在此文件里,行数应视为下限。
- 浏览表列表,查看行数、列及其声明类型,以及每张表上的索引。
- 当解析出的列看起来不对时,展开表下方的 CREATE 语句,以原始 DDL 为准。
常见问题
- 为什么这里的行数和我的应用不一样?
- 多半是预写日志的缘故。WAL 模式下 SQLite 把新增和修改的页追加到单独的 -wal 文件,只有在检查点时才合并进主库,因此不带该文件复制出来的数据库是上次检查点时的快照。本工具只读你给的这个文件,所以最近的插入可能缺失。复制前执行 PRAGMA wal_checkpoint(TRUNCATE),或把 -wal 和 -shm 一并带上。另一个原因是 WITHOUT ROWID 表,这种情况会显示为未知而不是给出错误数字。
- 能打开用 SQLCipher 加密的数据库吗?
- 不能,而且会明确告诉你,而不是显示一堆无意义的内容。SQLCipher 连头部一起加密,所以加密文件开头不是 "SQLite format 3" 这几个字节,没有密钥就无从解析。这项检查也能区分加密文件和损坏文件:被截断但未加密的数据库头部仍可读,工具会尽量读出内容,并提示页数与文件长度对不上。
- 空闲页是什么?需要执行 VACUUM 吗?
- 删除行并不会让 SQLite 文件变小,腾出的页会进入空闲列表,供之后的插入重复使用。也就是说空闲页是文件已经占有、以后还会再用的空间。VACUUM 会不带这些页重建数据库,把空间还给文件系统,在大批删除之后或分发数据库之前值得做,但它要重写整个文件并使已打开的连接失效,因此不是可以随手对线上库执行的操作。
- user_version 和 application_id 是什么?
- 这是头部中 SQLite 自己从不改动、留给应用随意使用的两个 32 位字段。常见做法是把 user_version 当作结构迁移的计数器,应用拿它和代码期望的版本比较并执行中间的迁移;把 application_id 当作标识文件格式的魔数,好让 file(1) 之类的工具区分不同种类的 SQLite 文件。没人设置过时两者都是 0。
- 结构版本和结构格式有什么区别?
- 结构版本,SQLite 称为 schema cookie,是每次结构变化就递增的计数器,预编译语句靠比较它来判断是否需要重新编译。结构格式是文件布局的代次,取值 1 到 4,表示该文件可以使用哪些特性:4 允许降序索引和布尔字面量,近二十年的 SQLite 写出的都是 4。
- 文件会被上传到什么地方吗?
- 不会。数据库用浏览器自带的 File API 读取,由页面里的 JavaScript 解析;没有任何内容发往服务器,也不存在可以接收它的服务端组件。你可以打开页面后断开网络再检查文件来验证,一切照常工作,因为整个工具已经在页面里了。
相关工具
NumPy .npy / .npz 检查器
在浏览器里读取 .npy、.npz 的文件头:dtype、shape、字节序、字段布局和前若干个值,无需 NumPy,也不上传文件。
Ogg 容器检查器
逐页解析 .ogg、.oga 或 .opus:颗粒位置、段表、CRC32 校验,以及容器里承载的各个逻辑流。
gzip(.gz)结构检查器
逐字段读取 .gz 头部,遍历每个成员,并在浏览器中重新计算 CRC32 和真实大小来校验尾部记录。
TZif(zoneinfo)时区文件解析器
在浏览器中打开编译好的 zoneinfo 文件:头部、本地时间类型、全部转换、闰秒,以及解析后的 POSIX TZ 结尾字符串。
ELF 二进制检查器
在浏览器中打开 Linux 可执行文件、.so 或 .o:架构、依赖的共享库、构建 ID,以及是否启用 PIE、NX 和 RELRO。
ICS 日历查看器与重复规则展开
打开 .ics 邀请或日历导出文件,看清里面究竟有什么,并把重复规则展开成真正的日期。