当前位置: 首页 > news >正文

支付网站建设费会计分录科丰化工东莞网站建设

支付网站建设费会计分录,科丰化工东莞网站建设,建设网站需要申请报告,wordpress插件的选择返回#xff1a;SQLite—系列文章目录 上一篇:SQLite 4.9的虚拟表机制(十四) 下一篇#xff1a;SQLite超详细的编译时选项#xff08;十六#xff09; ► 目录 本文档描述和定义磁盘上的数据库文件 自 SQLite 以来所有版本使用的格式 版本 3.0.0 #xff08;2004-06-18…  返回SQLite—系列文章目录    上一篇:SQLite 4.9的虚拟表机制(十四) 下一篇SQLite超详细的编译时选项十六 ► 目录 本文档描述和定义磁盘上的数据库文件 自 SQLite 以来所有版本使用的格式 版本 3.0.0 2004-06-18. 1. 数据库文件 SQLite数据库的完整状态通常是 包含在磁盘上的单个文件中称为“主数据库文件”。 在事务期间SQLite存储其他信息 在称为“回滚日志”的第二个文件中或者如果 SQLite 处于 WAL 模式则为预写日志文件。 1.1. 热门期刊 如果应用程序或 主机在事务完成之前崩溃然后回滚 日志或预写日志包含所需的信息 将主数据库文件还原到一致状态。回滚时 日志或预写日志包含恢复所需的信息 数据库的状态它们被称为“热日志”或“热WAL文件”。 热日志和WAL文件只是错误恢复过程中的一个因素 场景等并不常见但它们是 SQLite 状态的一部分 数据库等不能忽视。本文档定义了格式 回滚日志和预写日志文件但重点是 在主数据库文件上。 1.2. 页面 主数据库文件由一个或多个页面组成。的大小 Page 是介于 512 和 65536 之间的 2 次幂含。内所有页面 相同的数据库具有相同的大小。数据库文件的页面大小 由位于 从数据库文件开头开始的 16 个字节。 页码以 1 开头。最大页码为 42949672942,32-2。最小尺寸 SQLite 数据库是一个 512 字节的页面。 最大大小的数据库将是 4294967294 页每 65536 字节 页面或 281,474,976,579,584 字节约 281 TB。通常 SQLite 会 达到底层文件系统或磁盘的最大文件大小限制 硬件早在它达到自己的内部大小限制之前。 在通常的使用中SQLite数据库的大小往往从几千字节不等 到几千兆字节尽管已知存在 TB 大小的 SQLite 数据库 在生产中。 在任何时间点主数据库中的每个页面都有一个 使用以下方法之一 锁定字节页面自由列表页面 自由列表主干页面自由列表叶页面b 树页面 表格b-tree内页表 b 树叶页索引 b 树内页索引 b 树叶页有效负载溢出页面指针映射页 对主数据库文件的所有读取和写入都从一页开始 boundary 和 all writes 的大小为整数页数。读 通常也是整数页的大小但有一个例外 当数据库首次打开时前 100 个字节的 数据库文件数据库文件头作为子页面大小单位读取。 在修改数据库的任何信息页面之前 该页面的原始未修改内容将写入 回滚日志。如果事务中断并且需要 回滚然后可以使用回滚日志来恢复 数据库恢复到其原始状态。Freelist 叶子页没有 需要在回滚时还原的信息因此它们 在修改之前没有写入期刊以便 减少磁盘 I/O。 1.3. 数据库头 数据库文件的前 100 个字节构成数据库文件 页眉。数据库文件头分为多个字段如下所示 下表。数据库文件头中的所有多字节字段都是 首先使用最高有效字节 big-endian 存储。 数据库头格式 偏移大小说明016标头字符串“SQLite 格式 3\000”162数据库页面大小以字节为单位。必须是 2 之间的 512 次幂 和 32768含 32768或值 1 表示页面大小为 65536。181文件格式写入版本。1 用于遗产;2 表示 WAL。191文件格式读取版本。1 用于遗产;2 表示 WAL。201每页末尾未使用的“保留”空间的字节数。通常为 0。211最大嵌入有效载荷分数。必须年满 64 岁。221最小嵌入式有效载荷分数。必须年满 32 岁。231叶片有效载荷分数。必须年满 32 岁。244文件更改计数器。284数据库文件的大小以页为单位。“in-header 数据库大小”。324第一个自由列表主干页面的页码。364免费列表页面总数。404架构 cookie。444架构格式编号。支持的架构格式为 1、2、3 和 4。484默认页面缓存大小。524自动抽真空或 增量真空模式否则为零。564数据库文本编码。值为 1 表示 UTF-8。值为 2 表示 UTF-16le。值 3 表示 UTF-16be。604由user_version编译指示读取和设置的“用户版本”。644增量真空模式为 True非零。否则为 false零。684PRAGMA 设置的“应用程序 ID”application_id。7220保留用于扩展。必须为零。924version-valid-for 编号。964SQLITE_VERSION_NUMBER 1.3.1. 魔术头字符串 每个有效的 SQLite 数据库文件都以下列 16 个字节开头 十六进制53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00。此字节序列 对应于 UTF-8 字符串“SQLite format 3”包括 nul 末尾的终结者角色。 1.3.2. 页面大小 从偏移量 16 开始的双字节值决定了 数据库。对于 SQLite 版本 3.7.0.1 2010-08-04 在更早的时候这个值是 解释为大端整数并且必须是 2 之间的幂 512 和 32768含。从 SQLite 版本 3.7.1 2010-08-23 开始一个页面 支持 65536 字节的大小。值 65536 不适合 双字节整数因此要指定 65536 字节的页面大小值 偏移量为 16 0x00 0x01。 此值可以解释为大端 1 并被认为是一个表示 65536 页面大小的幻数。 或者可以将两字节字段视为一个小字节数然后说 它表示页面大小除以 256。这两个 对 page-size 字段的解释是等效的。 1.3.3. 文件格式版本号 偏移的文件格式写入版本和文件格式读取版本 18 和 19 旨在允许增强文件格式 在 SQLite 的未来版本中。在当前版本的 SQLite 中两者都 对于回滚日记模式这些值为 1对于 WAL 日记模式这些值为 2。如果 SQLite 的版本编码为当前 文件格式规范遇到一个数据库文件其中读取 version 为 1 或 2但写入版本大于 2则数据库 文件必须被视为只读。如果具有读取版本的数据库文件 如果遇到大于 2则无法读取或写入该数据库。 1.3.4. 每页保留字节数 SQLite能够在 每个页面的末尾供扩展使用。这些额外的字节是 例如SQLite 加密扩展用于存储随机数 和/或与每个页面关联的加密校验和。这 偏移量 20 处的 1 字节整数中的“保留空间”大小是数字 每页末尾的字节空间以保留扩展名。 此值通常为 0。该值可能是奇数。 数据库页的“可用大小”是 标头中偏移量 16 处的 2 字节整数减去“保留”空间大小 记录在标头偏移量 20 处的 1 字节整数中。可用 页面大小可能是奇数。但是可用尺寸不是 允许小于 480。换句话说如果页面大小为 512 则预留空间大小不能超过 32。 1.3.5. 有效载荷分数 最大和最小嵌入有效载荷分数和叶片 有效负载分数值必须为 64、32 和 32。这些值是 最初打算成为可用于 修改 B 树算法的存储格式。但是那 不支持功能并且当前没有要添加的计划 未来的支持。因此这三个字节固定在 指定的值。 1.3.6. 文件更改计数器 文件更改计数器是一个 4 字节的大端整数位于 每当数据库文件解锁时递增的偏移量 24 修改后。 当两个或多个进程读取同一个数据库文件时每个进程 进程可以通过监视来检测来自其他进程的数据库更改 找零钱计数器。 在以下情况下进程通常希望刷新其数据库页缓存 另一个进程修改了数据库因为缓存已过时。 文件更改计数器便于执行此操作。 在 WAL 模式下使用 wal-index 检测对数据库的更改 因此不需要找零计数器。因此更改计数器可能 在 WAL 模式下每个事务都不会递增。 1.3.7. Header 数据库大小 偏移量为 28 处的 4 字节大端整数进入标头 以页为单位存储数据库文件的大小。如果此 in-header datasize size 无效见下一段则数据库 大小是通过查看来计算的 以数据库文件的实际大小。SQLite 的旧版本 忽略头数据库大小使用实际文件大小 惟独。较新版本的 SQLite 使用 in-header 数据库 size如果可用但回退到实际文件大小如果 In-Header 数据库大小无效。 仅当以下情况时才认为标头内数据库大小有效 它不为零如果 4 字节更改计数器在偏移量 24 处 与偏移量 92 处的 4 字节 version-valid-for 数字完全匹配。 标头内数据库大小始终有效 当仅使用最新版本的 SQLite 修改数据库时 版本 3.7.0 2010-07-21 及更高版本。 如果旧版本的SQLite写入数据库则不会 知道更新 In-Header 数据库大小因此 In-Header 数据库大小可能不正确。但是SQLite的旧版本 还将保持偏移量 92 处的 version-valid-for 编号不变 所以它不会与更改计数器匹配。因此无效的 in-header 可以通过观察何时来检测并忽略数据库大小 更改计数器与 version-valid-for 编号不匹配。 1.3.8. 免费页面列表 数据库文件中未使用的页面存储在自由列表上。这 偏移量 32 处的 4 字节大端整数存储 自由列表的第一页如果自由列表为空则为零。 偏移量 36 处的 4 字节大端整数存储总计 自由列表上的页数。 1.3.9. 架构 cookie 架构 cookie 是一个偏移量为 40 的 4 字节大端整数 每当数据库架构发生更改时该值都会递增。一个 准备好的语句是针对特定版本的 数据库架构。当数据库架构发生更改时语句 必须重新准备。当准备好的语句运行时它首先检查 架构 cookie以确保值与语句时的值相同 已准备如果架构 cookie 已更改则语句 自动重新准备并重新运行否则会因SQLITE_SCHEMA错误而中止。 1.3.10. 模式格式编号 架构格式编号是偏移量为 44 处的 4 字节大端整数。 架构格式编号类似于文件格式读取和写入 偏移量 18 和 19 处的版本号但架构格式号除外 指高级 SQL 格式而不是低级 b 树 格式。目前定义了四个架构格式编号 格式 1 被所有版本的 SQLite 理解到版本 3.0.0 2004-06-18。格式 2 添加了同一表中行的功能 具有不同数量的列以支持 ALTER TABLE ...ADD COLUMN 功能。支持 读写格式 2 在 2005-02-20 的 SQLite 版本 3.1.3 中添加了。格式 3 添加了 ALTER TABLE 添加的额外列的功能...ADD COLUMN 设置为非 NULL 默认值 值。此功能是在 2005-03-11 的 SQLite 版本 3.1.4 中添加的。格式 4 导致 SQLite 遵循 DESC 关键字 on 索引声明。DESC 关键字在索引中被忽略 格式 1、2 和 3。 格式 4 还添加了两个新的布尔记录类型值序列号类型 8 和 9。在 SQLite 3.3.0 中添加了对格式 4 的支持 2006-01-10. 默认情况下SQLite 创建的新数据库文件使用格式 4。 legacy_file_format编译指示可用于导致 SQLite 使用格式 1 创建新的数据库文件。 格式版本号可以通过以下方式默认为 1 而不是 4 在编译时设置 SQLITE_DEFAULT_FILE_FORMAT1。 1.3.11. 建议的缓存大小 偏移量为 48 处的 4 字节大端有符号整数是建议的 数据库文件的缓存大小以页为单位。该值是一个建议 只有SQLite没有义务履行它。绝对值 的整数用作建议的大小。建议的缓存大小 可以使用default_cache_size Pragma 进行设置。 1.3.12. 增量真空设置 使用偏移量 52 和 64 处的两个 4 字节大端整数 管理auto_vacuum和incremental_vacuum模式。如果 偏移量 52 处的整数为零则指针映射 PTRMAP 页面为 从数据库文件中省略既不auto_vacuum也不 支持incremental_vacuum。如果偏移量 52 处的整数为 非零则它是 数据库文件数据库文件将包含 ptrmap 页面并且 mode 必须是 auto_vacuum 或 incremental_vacuum。在后者中 情况下偏移量 64 处的整数对于 incremental_vacuum 和 auto_vacuum为 false。如果偏移量 52 处的整数为零则 偏移量 64 处的整数也必须为零。 1.3.13. 文本编码 偏移量 56 处的 4 字节大端整数确定编码 用于存储在数据库中的所有文本字符串。 值为 1 表示 UTF-8。 值 2 表示 UTF-16le。 值 3 表示 UTF-16be。 不允许使用其他值。 sqlite3.h 头文件将 C 预处理器宏SQLITE_UTF8定义为 1 SQLITE_UTF16LE 为 2SQLITE_UTF16BE为 3用于代替 文本编码的数字代码。 1.3.14. 用户版本号 偏移量为 60 处的 4 字节大端整数是用户版本其 由user_version Pragma 设置和查询。用户版本是 SQLite未使用。 1.3.15. 应用程序 ID 偏移量 68 处的 4 字节大端整数是一个“应用程序 ID”它 可以通过 PRAGMA application_id 命令进行设置以识别 数据库属于特定应用程序或与特定应用程序相关联。 应用程序 ID 用于用作应用程序文件格式的数据库文件。应用程序 ID 可由实用程序使用 比如 file1 来确定具体的 文件类型而不仅仅是报告“SQLite3 数据库”。列表 通过查阅 SQLite 源存储库中的 magic.txt 文件可以查看分配的应用程序 ID。 1.3.16. 写入库版本号和版本有效号 偏移量 96 处的 4 字节大端整数存储了 SQLite 库的SQLITE_VERSION_NUMBER值该值最 最近修改了数据库文件。4 字节大端整数 偏移量 92 是版本号时更改计数器的值 被存储。偏移量 92 处的整数表示哪个事务 版本号对 有效有时称为 “version-valid-for 编号”。 1.3.17. 为扩展保留的标题空间 数据库文件头的所有其他字节都保留给 将来的扩展并且必须设置为零。 1.4. 锁字节页面 锁字节页是数据库文件的单个页 包含 1073741824 和 1073742335 之间偏移的字节 包容。小于或等于 1073741824 字节的数据库文件 in size 不包含锁字节页。大于 1073741824只包含一个锁字节页。 锁字节页被留出供特定于操作系统的 VFS 实现在实现数据库文件锁定基元时使用。 SQLite 不使用锁字节页。SQLite核心 永远不会读取或写入锁字节页 尽管特定于操作系统的 VFS 实现可以选择在锁字节上读取或写入字节 页面根据 底层系统的需求和倾向。内置到 SQLite 中的 unix 和 win32 VFS 实现不会写入 锁定字节页面但第三方 VFS 实现 其他操作系统可能。 锁字节页面源于支持 Win95 的需要Win95 是 设计此文件格式时的主要操作系统以及 仅支持强制文件锁定。所有现代操作系统 我们知道支持咨询文件锁定因此锁定字节页面是 实际上不再需要但保留以向后兼容。 1.5. 自由列表 数据库文件可能包含一个或多个不在 积极使用。例如当信息出现时可能会出现未使用的页面 将从数据库中删除。未使用的页面存储在自由列表中 并在需要其他页面时重复使用。 freelist 被组织为自由列表主干页面的链表 每个主干页面都包含零个或多个 freelist 的页码 叶页。 freelist 主干页面由一个 4 字节大端整数数组组成。 数组的大小与可用空间中容纳的整数一样多 一页。最小可用空间为 480 字节因此数组将始终 长度至少为 120 个条目。freelist 主干上的第一个整数 page 是列表中下一个 freelist 主干页面的页码或零 如果这是最后一个 freelist 主干页面。自由列表上的第二个整数 主干页是要遵循的叶页指针的数量。 调用自由列表主干页 L 上的第二个整数。 如果 L 大于零则数组索引介于 2 和 之间的整数 L1含包含自由列表叶页的页码。 自由列表叶页不包含任何信息。SQLite 避免读取或 编写 freelist 叶页以减少磁盘 I/O。 3.6.0 之前的 SQLite 版本中的错误 2008-07-16 导致数据库 如果 Freelist 主干页面中的最后 6 个条目中的任何一个被报告为损坏 数组包含非零值。较新版本的 SQLite 没有 这个问题。但是较新版本的 SQLite 仍然避免使用 Freelist 主干页面数组中的最后六个条目以便该数据库 由较新版本的 SQLite 创建的文件可以由旧版本读取 的 SQLite。 自由列表页数存储为 4 字节大端整数 在数据库标头中与文件开头的偏移量为 36。 数据库头还存储第一个自由列表主干的页码 page 作为 4 字节大端整数从开头偏移量为 32 的文件。 1.6. B树页面 b 树算法提供具有唯一和 面向页面的存储设备上的排序键。 有关 b 树的背景信息请参阅 b 树。 Knuth《计算机编程的艺术》第 3 卷“排序” 和搜索“第 471-479 页。b 树的两种变体由 SQLite的。“表 b 树”使用 64 位有符号整数键并存储 叶子中的所有数据。“索引 b 树”使用任意键并存储 no 根本没有数据。 b 树页可以是内页也可以是叶页。 叶页包含键如果是表则包含每个键 b 树 键具有关联的数据。内页包含 K 键以及指向子 b 树页面的 K1 指针。 内部 b 树页面中的“指针”只是 32 位 子页的无符号整数页码。 内部 b 树页面上的键数K 几乎总是至少 2并且通常远大于 2。 唯一的例外是第 1 页是内部 b 树页面。 第 1 页的可用存储空间减少了 100 个字节 由于该页面开头存在数据库标头 因此有时很少如果第 1 页是内部 B 树页面它可以 最终只拿着一把钥匙。在所有其他情况下K 为 2 或更多。 K 上的上限是页面上适合的键数。大键 在索引 B 上树被拆分为溢出页因此没有单个键 占用页面上四分之一以上的可用存储空间 因此每个内部页面都能够存储至少 4 个密钥。 表 b 树的整数键永远不够大无法 需要溢出因此键溢出仅发生在索引 B 树上。 定义深度 叶子 B 树的深度为 1任何内部 B 树的深度为 1 超过其任何子项的最大深度。在格式良好的 数据库中内部 B 树的所有子级都具有相同的深度。 在内部 b 树页面中指针和键在逻辑上交替 两端都有一个指针。前一句是要理解的 从概念上讲 - 按键的实际布局和 页面中的指针更复杂将在 续集。同一页面中的所有键都是唯一的并且在逻辑上是 按从左到右的升序排列。同样这个顺序 是合乎逻辑的而不是物理的。键在页面中的实际位置 是任意的。对于任何键 X指向左侧的指针 的 X 是指所有键都小于或等于 X 的 b 树页面。 X 右侧的指针是指所有键所在的页面 大于 X。 在内部 b 树页面中每个键和指向其的指针 紧挨着的左边被组合成一个称为“细胞”的结构。这 最右边的指针是分开的。叶子 b 树页面没有 指针但它仍然使用单元格结构来保存 索引 B 树或表 B 树的键和内容。数据也是 包含在单元格中。 每个 b 树页面最多有一个父 b 树页面。 没有父级的 b 树页面称为根页面。根 b 树页面 连同其子项的闭合一起形成一个完整的 B 树。 有一个完整的 b 树是可能的事实上很常见 它由一个既是叶子又是根的页面组成。 因为有从父母到孩子的指针所以每一页 如果只知道根页则可以找到完整的 B 树。因此 B 树由其根页码标识。 b 树页可以是表 b 树页也可以是索引 b 树页。 每个完整的 b 树中的所有页面都属于同一类型任一表 或索引。数据库文件中有一个表 b 树 对于数据库架构中的每个 RowID 表包括系统表 比如sqlite_schema。有一个索引 b 树 在架构中每个索引的数据库文件中包括隐含索引 由唯一性约束创建。没有与虚拟表关联的 b 树。特定的虚拟表实现可能会使用 用于存储的影子表但这些影子表将具有单独的 数据库架构中的条目。没有 ROWID 表请使用索引 b 树 而不是一个表 b 树所以有一个 在数据库文件中为每个 WITHOUT ROWID 表编制索引 b 树。 与sqlite_schema表对应的 b 树始终是表 b-tree 并且始终具有 1 的根页。 sqlite_schema表包含每隔一个的根页码 数据库文件中的表和索引。 表 b 树中的每个条目都由一个 64 位有符号整数键组成 以及最多 2147483647 字节的任意数据。表 b 树的键 对应于 b 树实现的 SQL 表的 rowid。 内部桌子 b 树只装钥匙和指向儿童的指针。 所有数据都包含在表 b 树叶中。 索引 b 树中的每个条目都由一个任意键 up 组成 长度为 2147483647 字节没有数据。 将单元格的“有效负载”定义为任意长度部分 的细胞。对于索引 b 树键的长度始终是任意的 因此有效载荷是关键。没有任意长度的元素 在内部表 B 树页面的单元格中因此这些单元格没有 有效载荷。表 b 树叶页包含任意长度的内容和 因此对于这些页面上的单元格有效负载是内容。 当单元的有效载荷大小超过某个阈值至 稍后定义则仅有效负载的前几个字节 存储在B树页面余额存储在链表中 的内容溢出页面。 b树页面按以下顺序划分为多个区域 100 字节数据库文件头仅在第 1 页上找到8 或 12 字节的 b 树页眉单元格指针数组未分配的空间单元格内容区域保留区域。 100 字节的数据库文件头仅在第 1 页找到即 始终是表 B 树页面。数据库文件中的所有其他 b 树页 省略此 100 字节标头。 保留区域是每个末尾的未使用空间区域 页面锁定页面除外扩展程序可以使用它来保留每个页面 信息。保留区域的大小由一个字节决定 在数据库文件头的偏移量为 20 处找到的无符号整数。 保留区域的大小通常为零。 对于叶页b 树页眉的大小为 8 个字节而叶页的页眉大小为 12 个字节 内页的字节。页眉中的所有多字节值 是大端的。 b-tree 页眉由以下字段组成 B-tree 页眉格式 偏移大小说明01偏移量为 0 处的单字节标志指示 b 树页面类型。 值 2 0x02 表示该页是内部索引 b 树页。值 5 0x05 表示该页是内部表 b 树页。值 10 0x0a 表示该页是叶索引 b 树页。值 13 0x0d 表示该页是叶表 b 树页。 b 树页面类型的任何其他值都是错误。12偏移量 1 处的双字节整数给出了 页面上的第一个 freeblock如果没有 freeblocks则为零。32偏移量 3 处的双字节整数给出页面上的单元格数。52偏移量 5 处的双字节整数指定单元格内容的开始 面积。此整数的零值被解释为 65536。71偏移量 7 处的一字节整数给出了自由碎片的数量 单元格内容区域中的字节。84偏移量 8 处的四字节页码是最右边的指针。这 value 仅出现在内部 B 树页面的标题中并且从 所有其他页面。 b 树页面的单元格指针数组紧跟在 b 树之后 页眉。设 K 是 btree 上的单元格数。单元格指针 数组由单元格内容的 K 个 2 字节整数偏移量组成。这 单元格指针按键顺序排列最左边的单元格具有 最小的键和最右边的单元格具有最大键的单元格 key最后。 单元格内容存储在 b 树页面的单元格内容区域中。 SQLite努力将单元格放置在b树页面的末尾因为 它可以以便为单元格指针数组的未来增长留出空间。 最后一个单元格指针数组条目和 第一个单元格是未分配的区域。 如果页面不包含单元格仅适用于根页面 不包含行的表则偏移量为 单元格内容区域将等于页面大小减去保留空间的字节数。 如果数据库使用 65536 字节的页面大小并且保留空间为零 保留空间的通常值然后单元格内容偏移量 空页希望为 65536。 但是该整数太大无法存储在 2 字节无符号整数因此在其位置使用值 0。 自由块是一种结构用于识别其中未分配的空间 B 树页面。Freeblocks被组织成一个链。前 2 个字节 freeblock 是一个 big-endian 整数它是 b 树页面中的偏移量 链中的下一个自由区块如果自由区块是最后一个自由区块则为零 链条。每个自由块形式的第三个和第四个字节 一个大端整数其大小为 freeblock 的大小以字节为单位包括 4 字节标头。Freeblocks 始终按顺序连接 增加抵消量。b-tree 页眉的第二个字段是 第一个自由块的偏移量如果 页。在格式良好的 b 树页面中始终至少有一个单元格 在第一个 freeblock 之前。 一个 freeblock 至少需要 4 个字节的空间。如果有一个隔离的 单元格内容区域中 1、2 或 3 个未使用的字节组这些字节 组成一个片段。存储所有片段中的总字节数 在 B 树页眉的第五个字段中。在格式良好的 b 树页面中 片段中的总字节数不得超过 60 个。 b 树页面上的可用空间总量由 未分配的区域加上所有自由块的总大小加上 碎片可用字节数。SQLite可能会不时重组 一个 B 树页面这样就没有 freeblocks 或 fragment 字节所有 未使用的字节包含在未分配的空间区域中并且所有 单元格在页面末尾紧密包装。这叫做 对 B 树页面进行“碎片整理”。 可变长度整数或“varint”是静态霍夫曼编码 的 64 位二进制补码整数为小正数使用更少的空间 值。 变量的长度介于 1 到 9 个字节之间。变量由以下任一部分组成 零个或多个字节其中设置了高阶位后跟一个字节 高阶位为clear或9个字节以较短者为准。 前 8 个字节中每个字节的下 7 位和 第九个字节用于重建 64 位二进制补码整数。 Varint 是 big-endian取自 varint 的较早字节的位 比从后面的字节中获取的位更重要。 单元格的格式取决于单元格的 b 树页面类型 出现在。下表显示了单元格的元素在 出现顺序适用于各种 B 树页面类型。 表 B 树叶单元格标题 0x0d 一个变量它是有效负载的总字节数包括 溢出作为整数键的变量又名“rowid”有效负载的初始部分不会溢出到溢出 页面。一个 4 字节大端整数页码用于 溢出页面列表 - 如果所有有效负载都适合 B 树页面则省略。 表 B 树内部单元格标题 0x05 一个 4 字节的大端页码它是左子指针。作为整数键的变量 索引 B 树叶单元格标题 0x0a 一个变量它是密钥有效负载的总字节数包括 溢出有效负载的初始部分不会溢出到溢出 页面。一个 4 字节大端整数页码用于 溢出页面列表 - 如果所有有效负载都适合 B 树页面则省略。 索引 B 树内部单元格标题 0x02 一个 4 字节的大端页码它是左子指针。一个变量它是密钥有效负载的总字节数包括 溢出有效负载的初始部分不会溢出到溢出 页面。一个 4 字节大端整数页码用于 溢出页面列表 - 如果所有有效负载都适合 B 树页面则省略。 上述信息可以转换为表格格式如下所示 B-tree 单元格格式 数据类型出现在...说明表叶节点类型 0x0d表内部节点类型 0x05索引叶节点类型 0x0a索引内节点类型 0x024 字节整数✔✔左边子项的页码varint✔✔✔有效负载的字节数varint✔✔罗维德字节数组✔✔✔有效载荷4 字节整数✔✔✔第一个溢出页的页码 溢出到溢出页面的有效负载量还取决于 页面类型。对于以下计算设 U 为可用大小 总页面大小减去 每页的末尾。设 P 为有效载荷大小。在下文中 符号 X 表示可直接存储的最大有效载荷量 在 b 树页面上而不会溢出到溢出页面和符号 M 上 表示必须存储在 btree 上的最小有效负载量 允许溢出前的页面。 表 B 树叶单元 设 X 为 U-35。如果有效载荷大小 P 小于或等于 X则 整个有效负载存储在 B-Tree 叶页上。 设 M 为 U-12*32/255-23设 K 为 MP-M%U-4。 如果 P 大于 X 则表b树叶页上存储的字节数为K 如果 K 小于或等于 X 或 M否则。 叶页上存储的字节数永远不会小于 M。 表 B-树内部单元 表 b 树的内页没有有效载荷因此永远不会有 任何要溢出的有效载荷。 索引 B 树叶或内部单元格 设 X 为 U-12*64/255-23。如果有效载荷大小 P 小于 或等于 X则整个有效负载存储在 b 树页面上。 设 M 为 U-12*32/255-23设 K 为 MP-M%U-4。 如果 P 大于 X则 如果 K 小于 或 否则等于 X 或 M。 索引页上存储的字节数永远不会小于 M。 以下是相同计算的替代描述 X 是 U-35用于表 btree 叶页或 U-12*64/255-23 用于索引页。M 始终为 U-12*32/255-23。设 K 为 MP-M%U-4。如果 PX则有效负载的所有 P 字节都直接存储在 没有溢出的 btree 页面。如果 PX 和 KX则 P 的前 K 个字节存储在 btree 页面和剩余的 P-K 字节存储在溢出页面上。如果 PX 和 KX则 P 的前 M 字节存储在 btree 页面和剩余的 P-M 字节存储在溢出页面上。 溢出阈值旨在提供 4 用于索引 b 树并确保足够的有效载荷 位于通常可以访问记录标头的 B 树页面上 无需咨询溢出页面。事后看来设计师 SQLite b-tree 逻辑意识到这些阈值可能是 变得简单多了。但是无法更改计算 而不会导致不兼容的文件格式。和当前的计算 工作得很好即使它们有点复杂。 1.7. 单元格有效负载溢出页面 当 b-tree 单元格的有效负载对于 b 树页面来说太大时 多余的内容会溢出到溢出页面上。溢出页面形成链接 列表。每个溢出页的前四个字节都是一个大端 整数即链中下一页的页码或零 对于链中的最后一页。第五个字节到最后一个可用字节 字节用于保存溢出内容。 1.8. 指针映射或 Ptrmap 页面 指针映射或 ptrmap 页面是插入到数据库中的额外页面 使auto_vacuum和incremental_vacuum模式的操作 效率更高。数据库中的其他页面类型通常具有指针 从父母到孩子。例如内部 b 树页面包含指针 到其子 B 树页面溢出链具有指针 从链条中的早期链接到后期链接。ptrmap 页面包含链接 信息朝着相反的方向发展从子项到父级。 Ptrmap 页面必须存在于任何具有非零的数据库文件中 数据库标头中偏移量为 52 处的最大根 B 树页面值。 如果最大根 b 树页面值为零则数据库不得 包含 ptrmap 页面。 在具有 ptrmap 页面的数据库中第一个 ptrmap 页面是第 2 页。 ptrmap 页面由一个 5 字节条目的数组组成。设 J 为 适合页面可用空间的 5 字节条目数。 换言之JU/5。第一个 ptrmap 页面将包含返回指针 第 3 页到 J2 页的信息含。第二个指针映射 页面将位于 J3 页上该 ptrmap 页面将提供反向指针 J4 至 2*J3含页面的信息。依此类推 整个数据库文件。 在使用 ptrmap 页面的数据库中标识位置的所有页面 通过上一段中的计算必须是 ptrmap 页面而不是 其他页面可能是 PTRmap 页面。除非如果字节锁定页面碰巧 落在与 ptrmap 页面相同的页码上然后移动 ptrmap 到该案例的下一页。 ptrmap 页面上的每个 5 字节条目都提供以下方面的反向链接信息 紧跟在指针映射后面的页面之一。如果页面 B 是 ptrmap页面则B1页面的反向链接信息由以下机构提供 指针映射上的第一个条目。关于页面 B2 的信息是 由第二个条目提供。等等。 每个 5 字节的 ptrmap 条目由一个字节的“页面类型”信息组成 后跟一个 4 字节的 big-endian 页码。可识别五种页面类型 b 树根页。这 页码应为零。自由列表页面。页码应为 零。第一页 单元有效载荷溢出链。页码是 b 树页面 包含内容已溢出的单元格。溢出链中的页面 第一页除外。页码是 溢流链。非根 b 树页面。这 页码是父 B 树页面。 在任何包含 ptrmap 页的数据库文件中所有 b 树根页 必须位于任何非根 B 树页面、单元有效负载溢出页面之前或者 freelist 页面。此限制可确保根页面永远不会 在自动真空或增量真空期间移动。自动吸尘器 逻辑不知道如何更新sqlite_schema的root_page字段 表因此有必要防止根页面被移动 在自动真空期间为了保持 sqlite_schema表。根页面将移动到 数据库文件由 CREATE TABLE、CREATE INDEX、DROP TABLE 和 DROP INDEX 操作。 2. 架构层 上述文本描述了 SQLite 文件的低级方面 格式。b-tree 机制提供了一种强大而高效的 访问大型数据集。本节将介绍如何 低级 B 树层用于实现更高级别的 SQL 能力。 2.1. 记录格式 表 b 树叶页的数据和键 索引 B 树页面的特征如上所述 作为任意字节序列。 前面的讨论提到一个键比另一个键少但是 没有定义“小于”的含义。本节将讨论 这些遗漏。 有效负载表 b 树数据或索引 b 树键 始终采用“记录格式”。 记录格式定义了对应的值序列 添加到表或索引中的列。记录格式指定数字 列数、每列的数据类型以及每列的内容。 记录格式广泛使用上面定义的 64 位有符号整数的可变长度整数或可变表示形式。 记录按此顺序包含标头和正文。 标头以单个变量开头该变量确定总数 的字节数。varint 值是 字节包括 Size varint 本身。以下尺寸变量是 一个或多个附加变量每列一个变量。这些额外的变量 称为“序列号”编号和 根据下图确定每列的数据类型 记录格式的串行类型代码 串行类型内容大小意义00Value 为 NULL。11value 是一个 8 位二进制补码整数。22value 是一个大端 16 位二进制补码整数。33Value 是一个 big-endian 24 位二进制补码整数。44Value 是一个 big-endian 32 位二进制补码整数。56Value 是一个 big-endian 48 位二进制补码整数。68value 是一个 big-endian 64 位二进制补码整数。78值是大端 IEEE 754-2008 64 位浮点数。80值为整数 0。仅适用于架构格式 4 及更高版本。90值是整数 1。仅适用于架构格式 4 及更高版本。10,11变量保留供内部使用。这些序列号类型代码将 永远不会出现在格式正确的数据库文件中但它们 可能在瞬态数据库文件和临时数据库文件中使用 SQLite有时会生成供自己使用。 这些代码的含义可以从一个版本中转移 的 SQLite 到下一个。N≥12 甚至N-12/2值是长度为 N-12/2 字节的 BLOB。N≥13 和奇数N-13/2Value 是文本编码中的字符串长度为 N-13/2 字节。 不存储 nul 终结符。 标头大小变量 串行类型 varint 通常由单个字节组成。这 大型字符串和 BLOB 的串行类型 varint 可能会扩展到两个或三个 字节变量但这是例外而不是规则。 varint 格式在编码记录标头时非常有效。 记录中每列的值紧跟在标题之后。 对于串行类型 0、8、9、12 和 13该值为零字节 长度。如果所有列都属于这些类型则 记录为空。 记录的值可能少于 对应表。例如这可能发生在 ALTER TABLE 之后......ADD COLUMN SQL 语句已增加 表架构中不修改预先存在的行的列数 在表中。 使用表架构中定义的相应列的默认值填充记录末尾的缺失值。 2.2. 记录排序顺序 索引 b 树中键的顺序由 键所表示的记录。记录比较进度列 按列。从左到右检查记录的列。这 第一对不相等的列决定了相对顺序 两条记录。各列的排序顺序如下 遵循 NULL 值序列号类型 0首先排序。数值序列号类型 1 到 9在 NULL 之后排序 并按数字顺序排列。文本值奇数序列类型 13 及更大在数值后排序 按列排序函数确定的顺序排列的值。BLOB 值甚至序列号类型 12 及更大按顺序排在最后 由 memcmp 确定。 为了计算每列的整理函数是必需的 文本字段的顺序。 SQLite定义了三个内置的排序函数 二元的内置的 BINARY 排序规则可逐字节比较字符串 使用 memcmp 函数 来自标准 C 库。NOCASE公司NOCASE 排序规则与 BINARY 类似只是大写 ASCII 字符“A”到“Z” 在运行 比较。只有 ASCII 字符是大小写折叠的。 NOCASE公司 不实现通用的 Unicode 无大小写比较。RTRIM的RTRIM 类似于 BINARY只是在两者的末尾有额外的空格 字符串不会更改结果。换句话说字符串将 只要它们相互比较 区别仅在于末尾的空格数。 可以添加其他特定于应用程序的整理功能 使用 sqlite3_create_collation 接口的 SQLite。 所有字符串的默认排序函数是 BINARY。 可以在 CREATE TABLE 语句中使用列定义上的 COLLATE 子句指定表列的替代排序函数。 为列编制索引时默认情况下CREATE TABLE 语句中指定的相同排序规则函数将用于索引中的列 尽管可以使用 CREATE INDEX 语句中的 COLLATE 子句覆盖此内容。 2.3. SQL表的表示 数据库架构中的每个普通 SQL 表都表示在磁盘上 由表 B 树。表 b 树中的每个条目对应一行 的 SQL 表。SQL 表的 rowid 是 64 位有符号的 表 B 树中每个条目的整数键。 每个 SQL 表行的内容通过以下方式存储在数据库文件中 首先将各列中的值组合成一个字节数组 然后将该字节数组存储为有效负载 表 B 树中的条目。记录中值的顺序为 与 SQL 表定义中的列顺序相同。 当 SQL 表包含 INTEGER PRIMARY KEY 列别名为 rowid时则 列在记录中显示为 NULL 值。SQLite 将始终使用 引用 INTEGER PRIMARY KEY 列时表 b 树键而不是 NULL 值。 如果列的亲和力为 REAL并且该列包含 可以在不丢失信息的情况下转换为整数的值 如果该值不包含小数部分并且不会太大而不能 表示为整数则该列可以存储在记录中 作为整数。SQLite 会将值转换回浮点 从记录中提取它时的点。 2.4. WITHOUT ROWID表的表示 如果使用 “WITHOUT ROWID” 子句创建 SQL 表 在其 CREATE TABLE 语句的末尾则该表是 WITHOUT ROWID 表并使用不同的磁盘表示形式。A 不带 ROWID 表使用索引 B 树而不是表 B 树进行存储。 WITHOUT ROWID b 树中每个条目的键都是一条记录 的列 PRIMARY KEY 后跟 桌子。主键列按其显示顺序显示 在 PRIMARY KEY 子句中声明其余列出现在 它们在 CREATE TABLE 语句中出现的顺序。 因此WITHOUT ROWID 表的内容编码是相同的 作为普通 rowid 表的内容编码除了 重新排列列的顺序以便 PRIMARY KEY 列出现 首先内容用作索引 B 树中的键而不是 而不是作为表 b 树中的数据。 具有 REAL 亲和力的列的特殊编码规则 应用于 WITHOUT ROWID 表的方式与应用于 rowid 表相同。 2.4.1. 禁止 PRIMARY KEY 中的冗余列 的 WITHOUT ROWID 表 如果 WITHOUT ROWID 表的 PRIMARY KEY 使用相同的列 多次使用相同的排序顺序然后是第二个和 该列在 PRIMARY KEY 定义中的后续出现项为 忽视。例如以下 CREATE TABLE 语句都指定 同一个表在磁盘上将具有完全相同的表示形式 CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c)) WITHOUT ROWID; CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c,a,c)) WITHOUT ROWID; CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,A,a,C)) WITHOUT ROWID; CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,a,a,a,c)) WITHOUT ROWID; 上面的第一个示例是表的首选定义 答案是肯定的。所有示例都创建一个 WITHOUT ROWID 表其中包含 两个 PRIMARY KEY 列“a”和“c”按此顺序排列后跟 两个数据列“B”和“D”也按此顺序排列。 2.5. SQL索引的表示 每个 SQL 索引是否通过 CREATE INDEX 语句显式声明 或由 UNIQUE 或 PRIMARY KEY 约束暗示对应于 数据库文件中的索引 B 树。 索引 b 树中的每个条目对应于 关联的 SQL 表。 索引 b 树的关键是 由正在编制索引的列组成的记录后跟 对应表行的键。对于普通表行键为 rowid对于 WITHOUT ROWID 表行键是 PRIMARY KEY。 因为表中的每一行都有一个唯一的行键 索引中的所有键都是唯一的。 在普通索引中行与行之间存在一对一的映射 表以及与该表关联的每个索引中的条目。 但是在部分索引中索引 b 树仅包含条目 对应于表行其中 WHERE 子句表达式在 CREATE INDEX 语句为 true。 索引树和表 b 树中的相应行共享相同的 rowid 或主键值并包含所有索引列的相同值。 2.5.1. 抑制 WITHOUT ROWID 二级索引中的冗余列 在 WITHOUT ROWID 表的索引中如果 PRIMARY KEY 的列 也是索引中的一列并且具有匹配的排序顺序则 索引列在 table-key 后缀中不会重复 索引记录的末尾。例如请考虑以下 SQL CREATE TABLE ex25(a,b,c,d,e,PRIMARY KEY(d,c,a)) WITHOUT rowid; CREATE INDEX ex25ce ON ex25(c,e); CREATE INDEX ex25acde ON ex25(a,c,d,e); CREATE INDEX ex25ae ON ex25(a COLLATE nocase,e); ex25ce 索引中的每一行都是一条记录 使用这些列C、E、D、A。前两列是 要编制索引的列 c 和 e。其余列是主列 对应表行的键。通常主键为 列 d、c 和 a但因为 c 列已经出现在 索引则从键后缀中省略它。 在极端情况下被索引的列覆盖所有列 的 PRIMARY KEY索引将仅包含以下列 索引。上面的 ex25acde 示例演示了这一点。每个条目 EX25ACDE 索引仅包含列 A、C、D 和 E其中 次序。 ex25ae 中的每一行包含五列a、e、d、c、a。“a” 列重复因为第一次出现的“a”具有整理 函数为“nocase”第二个具有“binary”的整理序列。 如果“a”列不重复并且表包含两个或更多 具有相同“e”值的条目其中“a”仅在大小写上有所不同则 所有这些表条目将对应于 索引这将破坏表之间的一对一对应关系 和索引。 禁止显示索引键后缀中的冗余列 条目仅出现在 WITHOUT ROWID 表中。在一个普通的吵闹表中 索引条目始终以 rowid 结尾即使 INTEGER PRIMARY KEY 列是要编制索引的列之一也是如此。 2.6. SQL 数据库架构的存储 数据库文件的第 1 页是表 b 树的根页该 有一张名为“sqlite_schema”的特殊表。这个 b 树是已知的 作为“架构表”因为它存储了完整的 数据库架构。sqlite_schema表的结构如下 如果它是使用以下 SQL 创建的 CREATE TABLE sqlite_schema(type text,name text,tbl_name text,rootpage integer,sql text ); sqlite_schema表包含每个表、索引、视图、 和触发器统称为“对象”在数据库架构中但 不是 sqlite_schema 表本身的条目。sqlite_schema表 除了 application- 之外还包含内部架构对象的条目 和程序员定义的对象。 sqlite_schema.type 列将为 1 以下文本字符串“table”、“index”、“view”或“trigger” 根据定义的对象类型。使用“table”字符串 适用于普通表和虚拟表。 sqlite_schema.name 列将保存对象的名称。表的 UNIQUE 和 PRIMARY KEY 约束导致 SQLite 创建名称形式为“sqlite_autoindex_TABLE_N”的内部索引 其中 TABLE 替换为包含 constraint 和 N 是以 1 开头并递增 1 的整数 在表定义中可以看到的每个约束。 在 WITHOUT ROWID 表中没有 sqlite_schema 条目 PRIMARY KEY但“sqlite_autoindex_TABLE_N”名称被搁置一旁 对于 PRIMARY KEY就好像 sqlite_schema 条目确实存在一样。这 将影响后续 UNIQUE 约束的编号。 “sqlite_autoindex_TABLE_N”名称永远不会分配给 INTEGER PRIMARY KEY无论是在 rowid 表中还是在 WITHOUT ROWID 表中。 sqlite_schema.tbl_name 列保存表或视图的名称 对象与之关联。对于表或视图 tbl_name列是名称列的副本。对于索引tbl_name 是索引的表的名称。对于触发器tbl_name 列存储导致触发的表或视图的名称 开火。 sqlite_schema.rootpage 列存储根目录的页码 表和索引的 B 树页面。对于定义视图、触发器、 和虚拟表rootpage 列为 0 或 NULL。 sqlite_schema.sql 列存储描述 对象。此 SQL 文本是 CREATE TABLE、CREATE VIRTUAL TABLE、CREATE INDEX、CREATE VIEW 或 CREATE TRIGGER 语句如果根据这些语句进行评估 当数据库文件是数据库连接的主数据库时它将重新创建对象。文本通常是原件的副本 语句用于创建对象但应用了规范化 文本符合以下规则 开头的 CREATE、TABLE、VIEW、TRIGGER 和 INDEX 关键字 的语句转换为全部大写字母。如果 TEMP 或 TEMPORARY 关键字出现在 初始 CREATE 关键字。出现在 正在创建的对象将被删除。前导空格被移除。前两个关键字后面的所有空格都转换为单个 空间。 sqlite_schema.sql列中的文本是原件的副本 创建对象的 CREATE 语句文本但规范化为 如上所述并由后续的 ALTER TABLE 语句修改。 对于以下内部索引sqlite_schema.sql为 NULL 由 UNIQUE 或 PRIMARY KEY 约束自动创建。 2.6.1. 模式表的替代名称 名称“sqlite_schema”不会出现在文件格式的任何位置。 该名称只是数据库实现使用的约定。 由于历史和运营方面的考虑 “sqlite_schema”表有时也可以由以下之一调用 以下别名 sqlite_mastersqlite_temp_schemasqlite_temp_master 因为架构表的名称不会出现在 文件格式如果出现以下情况则数据库文件的含义不会改变 应用程序选择通过以下之一来引用架构表 这些替代名称。 2.6.2. 内部模式对象 除了 应用程序和/或开发人员使用 CREATE 语句 SQL、 sqlite_schema表可能包含零个或多个内部架构对象的条目这些条目由 SQLite 为其创建 自己内部使用。内部架构对象的名称 始终以“sqlite_”和任何表、索引、视图或触发器开头 其名称以“sqlite_”开头是一个内部架构对象。 SQLite 禁止应用程序创建名称以 EACH 开头的对象 带有“sqlite_”。 SQLite 使用的内部架构对象可能包括以下内容 名称形式为“sqlite_autoindex_TABLE_N”的索引 用于实现 UNIQUE 和 PRIMARY KEY 约束 普通表。 名称为“sqlite_sequence”的表用于跟踪 表的最大历史整数主键 使用 AUTOINCREMENT。 名称形式为“sqlite_statN”的表其中 N 为整数。 此类表存储由 ANALYZE 命令收集的数据库统计信息并由查询规划器用于帮助确定最佳 用于每个查询的算法。 新的内部架构对象名称始终以“sqlite_”开头 可能会在将来的版本中添加到 SQLite 文件格式中。 2.6.3. sqlite_sequence表 sqlite_sequence表是用于帮助实现 AUTOINCREMENT 的内部表。自动创建sqlite_sequence表 每当任何具有 AUTOINCREMENT 整数主的普通表时 密钥已创建。创建后sqlite_sequence表将存在于 永远sqlite_schema桌子;它不能被丢弃。 sqlite_sequence表的架构为 CREATE TABLE sqlite_sequence(name,seq); sqlite_sequence表中有一个行对应每个普通 使用 AUTOINCREMENT 的表。表的名称如 sqlite_schema.name 位于 sqlite_sequence.name 字段中并且插入该表的最大整数主键为 在 sqlite_sequence.seq 字段中。 自动生成的 AUTOINCREMENT 的新整数主键 表保证大于 sqlite_sequence.seq 字段 那张桌子。 如果 AUTOINCREMENT 表的 sqlite_sequence.seq 字段已位于 然后最大整数值 9223372036854775807 尝试添加新的 具有自动生成的整数主表的行将失败 出现SQLITE_FULL错误。 如果需要sqlite_sequence.seq 字段会在以下情况下自动更新 新条目将插入到 AUTOINCREMENT 表中。 自动删除 AUTOINCREMENT 表的sqlite_sequence行 当表格被丢弃时。 如果 AUTOINCREMENT 表的sqlite_sequence行不存在则在以下情况下 更新 AUTOINCREMENT 表然后创建新的sqlite_sequence行。 如果 AUTOINCREMENT 表的 sqlite_sequence.seq 值是手动的 设置为整数以外的其他内容并且随后尝试 插入 AUTOINCREMENT 表或更新 AUTOINCREMENT 表则行为未定义。 允许应用程序代码修改sqlite_sequence表以添加 新建行删除行或修改现有行。但是应用 如果 sqlite_sequence 表尚不存在则代码无法创建该表。 应用程序代码可以从sqlite_sequence表中删除所有条目 但应用程序代码不能删除sqlite_sequence表。 2.6.4. sqlite_stat1表 sqlite_stat1是由 ANALYZE 命令创建的内部表 并用于保存有关表和索引的补充信息这些信息 查询规划器可用于帮助它找到执行查询的更好方法。 应用程序可以更新、删除、插入或删除sqlite_stat1 表但不能创建或更改sqlite_stat1表。 sqlite_stat1表的架构如下所示 CREATE TABLE sqlite_stat1(tbl,idx,stat); 每个索引通常有一行索引由 sqlite_stat1.idx 列中的 name。sqlite_stat1.tbl 列是 索引所属的表的名称。在每一行中 sqlite_stat.stat 列将是 由整数列表后跟零或多个的字符串组成 参数。其中的第一个整数 list 是索引中的近似行数。数量 索引中的行数与表中的行数相同 部分索引除外。 第二个整数是索引中的近似行数 在索引的第一列中具有相同的值。第三个 integer 是索引中具有 前两列的值相同。第 N 个整数对于 N1 是 对前 N-1 列具有相同值的索引。为 一个 K 列索引则统计列中将有 K1 个整数。如果 索引是唯一的则最后一个整数将为 1。 可以选择跟随统计列中的整数列表 by 参数每个参数都是一系列非空格字符。 所有参数前面都有一个空格。 无法识别的参数将被静默忽略。 如果存在“unordered”参数则查询规划器假定 索引是无序的并且不会将索引用于范围查询 或用于排序。 “szNNN”参数其中 NNN 表示 1 位或更多位的序列 表示表的所有记录的平均行大小或 index 是每行的 NNN 字节数。SQLite 查询规划器可能会使用 “szNNN”令牌提供的估计行大小信息 以帮助它选择需要较少磁盘 I/O 的较小表和索引。 sqlite_stat1.stat 字段上存在“noskipscan”令牌 的索引可防止该索引与跳过扫描优化一起使用。 将来可能会将新的文本标记添加到统计列的末尾 对 SQLite 的增强。为了兼容性末尾有无法识别的令牌 的 stat 列将被静默忽略。 如果 sqlite_stat1.idx 列为 NULL则 sqlite_stat1.stat 列包含一个整数它是 表中由 sqlite_stat1.tbl 标识的行。 如果 sqlite_stat1.idx 列与 sqlite_stat1.tbl 相同 列则该表是 WITHOUT ROWID 表和 sqlite_stat1.stat 字段包含有关实现 没有 ROWID 表。 2.6.5. sqlite_stat2表 仅创建sqlite_stat2并且仅在编译 SQLite 时使用。 如果 SQLITE_ENABLE_STAT2如果 SQLite 版本号介于 3.6.18 2009-09-11 和 3.7.8 2011-09-19。 sqlite_stat2表既不被任何人读取也不写入 3.6.18 之前的 SQLite 版本以及 3.7.8 之后的版本。 sqlite_stat2表包含其他信息 关于索引中键的分布。 sqlite_stat2表的架构如下所示 CREATE TABLE sqlite_stat2(tbl,idx,sampleno,sample); 每个列中的 sqlite_stat2.idx 列和 sqlite_stat2.tbl 列 sqlite_stat2 表的行标识该行描述的索引。 sqlite_stat2中通常有 10 行 每个索引的表。 具有 sqlite_stat2.sampleno 的索引的sqlite_stat2条目 0 和 9含 0 和 9是 索引沿索引均匀分布的点。 设 C 为索引中的行数。 然后采样行由下式给出 行数 i*C*2 C/20 上一个表达式中的变量 i 在 0 和 9 之间变化。 从概念上讲索引空间分为 10 个均匀的桶样品是每个桶的中间一行。 此处记录了sqlite_stat2的格式以供遗留参考。 最新版本的 SQLite 不再支持 sqlite_stat2 和 sqlite_stat2表如果存在将被忽略。 2.6.6. sqlite_stat3表 仅当编译 SQLite 时才使用sqlite_stat3 具有 SQLITE_ENABLE_STAT3 或 SQLITE_ENABLE_STAT4并且 SQLite 版本号为 3.7.9 2011-11-01 或更高版本。 sqlite_stat3表既不被任何人读取也不写入 低于 3.7.9 的 SQLite 版本。 如果使用 SQLITE_ENABLE_STAT4 编译时选项并且 SQLite 版本号为 3.8.1 2013-10-17 或更高版本 然后sqlite_stat3可能会被读取但无法写入。 sqlite_stat3表包含其他信息 关于索引中键的分布该信息 查询规划器可用于设计更好、更快的查询算法。 sqlite_stat3表的架构如下所示 CREATE TABLE sqlite_stat3(tbl,idx,nEq,nLt,nDLt,sample); 每个索引的sqlite_stat3表中通常有多个条目。 sqlite_stat3.sample 列保存 由 sqlite_stat3.idx 和 sqlite_stat3.tbl 标识的索引。 sqlite_stat3.nEq 列包含近似值 索引中最左边列完全匹配的条目数 示例。 sqlite_stat3.nLt 保存 最左边列小于样本的索引。 sqlite_stat3.nDLt 列包含近似值 索引中小于 示例。 每个索引可以有任意数量的sqlite_stat3条目。 ANALYZE 命令通常会生成sqlite_stat3表 包含 10 到 40 个样本分布在 键空间并具有较大的 nEq 值。 在格式良好的sqlite_stat3表中任何单个的样本 索引的显示顺序必须与它们在索引中的出现顺序相同。 换言之如果最左边列 S1 的条目在 索引 b 树比 条目包含最左边的列 S2然后在sqlite_stat3表中 示例 S1 的 rowid 必须小于示例 S2。 2.6.7. sqlite_stat4表 仅创建sqlite_stat4并且仅在编译 SQLite 时使用。 如果 SQLite 版本号为 SQLITE_ENABLE_STAT4则为 3.8.1 2013-10-17 或更高版本。 sqlite_stat4表既不被任何人读取也不写入 3.8.1 之前的 SQLite 版本。 sqlite_stat4表包含其他信息 关于索引中键的分布或 WITHOUT ROWID 表的主键中的键。 查询规划器有时可以使用 sqlite_stat4表用于设计更好、更快的查询算法。 sqlite_stat4表的架构如下所示 CREATE TABLE sqlite_stat4(tbl,idx,nEq,nLt,nDLt,sample); sqlite_stat4表中通常有 10 到 40 个条目 每个可用的统计数据索引但这些限制是 不是硬性界限。 sqlite_stat4表中各列的含义如下 结核病sqlite_stat4.tbl 列包含 该行描述的索引印尼达sqlite_stat4.idx 列包含索引的名称该索引 行描述或者在 WITHOUT ROWID 表的sqlite_stat4条目 表本身的名称。样本sqlite_stat4.sample 列包含 BLOB 以对索引列进行编码的记录格式后跟 rowid 表的 rowid 或主键的列 对于 WITHOUT ROWID 表。 WITHOUT ROWID 表本身的 sqlite_stat4.sample BLOB 仅包含主键的列。 设 sqlite_stat4.sample blob 编码的列数为 N。 对于普通 rowid 表上的索引N 将比数字多 1 索引的列数。 对于 WITHOUT ROWID 表上的索引N 将是列数 indexed 加上主键中的列数。 对于 WITHOUT ROWID 表N 将是 主键。当量sqlite_stat4.nEq 列包含 N 个整数的列表其中 第 K 个整数是索引中条目的近似数 其最左边的 K 列与最左边的 K 列完全匹配 的样本。nLtsqlite_stat4.nLt 列包含 N 个整数的列表其中 第 K 个整数是 其 K 个最左边列的总和 K 个样本最左边的列。nDLtsqlite_stat4.nDLt 列包含 N 个整数的列表其中 第 K 个整数是近似值 索引中在前 K 列中不同的条目数以及 其中最左边的 K 列总小于最左边的 K 列 样品的 K 列。 sqlite_stat4是sqlite_stat3表的概括。这 sqlite_stat3表提供有关 index而 sqlite_stat4 表提供有关所有列的信息 的索引。 每个索引可以有任意数量的sqlite_stat4条目。 ANALYZE 命令通常会生成sqlite_stat4表 包含 10 到 40 个样本分布在 键空间并具有较大的 nEq 值。 在格式良好的sqlite_stat4表中任何单个的样本 索引的显示顺序必须与它们在索引中的出现顺序相同。 换言之如果条目 S1 在索引 b 树中早于 条目 S2则在sqlite_stat4表中示例 S1 必须具有 比样本 S2 小的 rowid。 3. 回滚日志 回滚日志是与每个 SQLite 数据库关联的文件 文件用于将数据库文件还原到其初始 在事务过程中的状态。 回滚日志文件始终位于同一 目录作为数据库 文件与数据库文件同名但字符串 附加“-journal”。只能有一个回滚日志 与给定数据库相关联因此只能有一次写入 一次针对单个数据库打开事务。 如果事务由于应用程序崩溃而中止则操作 系统崩溃或硬件电源故障或崩溃则数据库可能 处于不一致的状态。下次SQLite尝试打开时 数据库文件回滚日志文件的存在将是 检测到日志将自动回放以恢复 数据库设置为未完成事务开始时的状态。 回滚日志仅在存在且 包含有效的标头。因此事务可以在一个中提交 三种方式 可以删除回滚日志文件回滚日志文件可以截断为零长度或者回滚日志的标头可以覆盖 无效的标题文本例如全零。 这三种提交事务的方式对应于 DELETE 分别对journal_mode编译指示进行 TRUNCAT 和 PERSIST 设置。 有效的回滚日志以下列格式的标题开头 回滚日记帐标题格式 抵消大小描述08标头字符串0xd9、0xd5、0x05、0xf9、0x20、0xa1、0x63、0xd784“页数” - 下一段的页数 journal或 -1 至 表示所有内容到文件末尾124校验和的随机随机数164数据库的初始大小以页为单位204写入此内容的进程假定的磁盘扇区的大小 杂志。244此日记中的页面大小。 回滚日志标题用零填充到 单个扇区由偏移量 20 处的扇区大小整数定义。 接头本身位于扇区中因此如果发生断电则 写入扇区标题后面的信息将是 希望完好无损。 在页眉和零填充之后是零个或多个页面记录。每 页面记录存储数据库文件中页面内容的副本 在它被改变之前。同一页面可能不会出现多次 在单个回滚日志中。 要回滚未完成的事务请执行流程 只需从头到尾阅读回滚日志然后 将日志中的页面写回数据库文件中网址为 适当的位置。 设数据库页面大小偏移量为24处的整数值 在日志标题中为 N。 那么页面记录的格式如下 回滚日记页记录格式 抵消大小描述04数据库文件中的页码4N交易开始前页面的原始内容N44校验和 校验和是一个无符号的 32 位整数计算方式如下 将校验和初始化为在 偏移量 12 处的日记帐标题。将索引 X 初始化为 N-200其中 N 是数据库页的大小 以字节为单位。将偏移量 X 处的字节解释为 8 位无符号整数 并将该整数的值添加到校验和中。从 X 中减去 200。如果 X 大于或等于零请返回步骤 3。 校验和值用于防止不完整的写入 电源故障后的日记页记录。不同的随机随机数 每次启动交易时都会使用以最大限度地降低风险 不成文的扇区可能偶然包含来自同一页面的数据 这是以前期刊的一部分。通过更改每个随机数 事务磁盘上的陈旧数据仍将生成不正确的校验和 并且被高概率检测到。校验和仅使用稀疏样本 出于性能原因数据记录中的 32 位字 - 设计研究 在 SQLite 3.0.0 的规划阶段显示 对整个页面进行校验和的性能显著降低。 让日记帐标题中偏移量 8 处的页数值为 M。 如果 M 大于零则在 M 页记录日志文件之后 可能为零填充到扇区大小的下一个倍数和另一个 可以插入日志标题。所有日记帐标题都在同一 日志必须包含相同的数据库页面大小和扇区大小。 如果 M 在初始日记帐标题中为 -1则页数记录 接下来是通过计算将容纳多少页记录来计算的 日志文件其余部分的可用空间。 4. 预写日志 从版本 3.7.0 2010-07-21 开始 SQLite支持新事务 称为“预写日志”或“WAL”的控制机制。 当数据库处于 WAL 模式时与该数据库的所有连接都必须 使用 WAL.特定数据库将使用回滚日志 或 WAL但不能同时使用两者。 WAL 始终与数据库位于同一目录中 文件与数据库文件同名但字符串 附加“-wal”。 4.1. WAL文件格式 WAL 文件由一个标头后跟零个或多个“帧”组成。 每一帧都记录了单页的修订内容 数据库文件。对数据库的所有更改都通过写入来记录 帧进入 WAL。当写入帧时事务提交 包含提交标记。单个 WAL 可以而且通常确实记录 多个事务。定期WAL 的内容是 在名为 “检查点”。 单个 WAL 文件可以多次重复使用。换言之 WAL 可以填满帧然后进行检查点然后是新的 帧可以覆盖旧帧。WAL 总是从一开始就成长 接近尾声。附加到每个帧的校验和和计数器是 用于确定 WAL 中的哪些帧有效以及哪些帧有效 是先前检查站的剩菜。 WAL 标头的大小为 32 个字节由以下 8 个字节组成 big-endian 32 位无符号整数值 WAL 标头格式 抵消大小描述04幻数。0x377f0682或0x377f068344文件格式版本。目前为3007000。84数据库页面大小。示例1024124检查点序列号164Salt-1随机整数随每个检查点递增204Salt-2每个检查点都有不同的随机数244校验和-1标头前 24 个字节的校验和的第一部分284校验和-2标头前 24 个字节的校验和的第二部分 紧跟在 wal-header 之后的是零帧或更多帧。每 Frame 由一个 24 字节的帧头和一个页面大小的字节组成 的页面数据。帧头是 6 个 big-endian 32 位无符号 整数值如下所示 WAL 帧头格式 抵消大小描述04页码44对于提交记录数据库文件的大小以页为单位 提交后。对于所有其他记录为零。84从 WAL 标头复制的 Salt-1124从 WAL 标头复制的 Salt-2164校验和-1累积校验和包括此页204校验和-2累积校验和的后半部分。 当且仅当以下条件为 真 帧头中的 salt-1 和 salt-2 值匹配 wal-header 中的 salt 值 帧标头最后 8 个字节中的校验和值 与连续计算的校验和完全匹配 WAL 标头的前 24 个字节和前 8 个字节以及 所有帧的内容 直到并包括当前帧。 4.2. 校验和算法 校验和是通过将输入解释为 偶数个无符号 32 位整数x0 到 xN。 如果 32 位整数是 big-endian则 WAL 标头的前 4 个字节中的幻数为 0x377f0683并且 如果幻数为 0x377f0682则整数为 little-endian。 校验和值始终存储在帧标头中 big-endian 格式无论使用哪个字节顺序进行计算 校验和。 校验和算法仅适用于 长度为 8 个字节。换句话说如果输入是 x0 到 xN 那么 N 一定是奇数。 校验和算法如下 s0 s1 0 for i from 0 to n-1 step 2:s0 x(i) s1;s1 x(i1) s0; endfor # result in s0 and s1 输出 s0 和 s1 都是使用斐波那契权重的加权校验和 以相反的顺序。最大的斐波那契权重出现在第一个元素上 正在求和的序列。s1 值跨越所有 32 位整数 序列的项而 s0 省略了最终项。 4.3. 检查点算法 在检查点上首先使用 VFS 的 xSync 方法。 然后将 WAL 的有效内容传输到数据库文件中。 最后使用另一个数据库将数据库刷新到持久性存储 xSync 方法调用。 xSync 操作充当写入屏障 - 启动所有写入 在 xSync 必须完成之前在 xSync 开始。 检查点无需运行即可完成。可能是一些 读取器仍在使用包含的数据的旧事务 在数据库文件中。在这种情况下传输较新的内容 从 WAL 文件到数据库的事务将删除内容 从仍在使用旧事务的读者中走出来。为了避免这种情况 只有当所有读者都使用 WAL 中的最后一笔交易。 4.4. WAL复位 在完成检查点后如果事务中没有其他连接 使用 WAL则后续写入事务可以 从头开始覆盖 WAL 文件。这称为“重置 沃尔“。在第一个新的开始 写入事务WAL 标头 salt-1 值递增 并且 SALT-2 值是随机的。盐的这些变化使盐失效 WAL 中已检查但尚未检查的旧帧 覆盖并防止它们再次被检查。 WAL 文件可以选择在重置时被截断但不必如此。 如果 WAL 没有被截断性能通常会好一点因为 文件系统覆盖现有文件的速度通常比它们快 将增长一个文件。 4.5. 阅读器算法 要从数据库中读取页面称为页码 P阅读器 首先检查 WAL 以查看它是否包含页 P。如果是这样那么 页 P 的最后一个有效实例后跟提交帧 或者是提交帧本身成为读取的值。如果 WAL 不包含有效的页面 P 副本并且是提交 frame 或后跟一个提交帧然后从中读取第 P 页 数据库文件。 要启动读取事务读取器记录值的数量 WAL 中的帧作为“mxFrame”。更多详情 读取器使用此记录的 mxFrame 值 对于所有后续读取操作。可以附加新交易 添加到 WAL但只要读取器使用其原始 mxFrame 值 并忽略随后附加的内容读者将看到一个 从单个时间点对数据库进行一致的快照。 此技术允许多个并发读取器查看不同的 同时版本的数据库内容。 前几段中的读取器算法工作正常但是 因为页面 P 的框架可以出现在 WAL 中的任何位置所以 读取器必须扫描整个 WAL 以查找第 P 页帧。如果 WAL 很大通常为数兆字节扫描速度可能很慢 并且读取性能受到影响。为了克服这个问题一个单独的 维护称为 wal-index 的数据结构以加快 搜索特定页面的框架。 4.6. WAL-Index 格式 从概念上讲wal-index 是共享内存尽管当前 VFS 实现使用内存映射文件作为操作系统 可移植性。内存映射 文件与数据库位于同一目录中并具有相同的名称 作为附加了“-shm”后缀的数据库。因为 wal-index 是共享内存当客户端位于不同的机器上时SQLite 不支持网络文件系统上的 journal_modeWAL因为 数据库的所有客户端必须能够共享相同的内存。 wal-index 的目的是快速回答这个问题 给定页码 P 和最大 WAL 帧索引 M 返回不超过 M 的第 P 页的最大 WAL 帧索引 或者如果页面 P 没有不超过 M 的帧则返回 NULL。 上一段中的 M 值是“mxFrame”值 在第 4.4 节中定义在开头阅读 并定义来自 WAL 的最大帧 读者将使用。 wal 指数是瞬态的。崩溃后wal-index 为 从原始 WAL 文件重建。VFS 是必需的 截断或将 wal-index 的标头归零当最后一个 与它的连接关闭。因为wal指数是瞬态的所以它可以 使用特定于体系结构的格式;它不一定是跨平台的。 因此与存储所有值的数据库和 WAL 文件格式不同 作为大端wal-index 将多字节值存储在本机中 主机的字节顺序。 本文档涉及数据库的持久状态 文件并且由于 wal-index 是瞬态结构因此无需进一步 有关 WAL 索引格式的信息将在此处提供。 有关 wal-index 格式的其他详细信息请参见 单独的 WAL 索引文件格式文档。
http://www.pierceye.com/news/188858/

相关文章:

  • 网站建设总体情况网站设计宁波
  • 西宁做网站_君博示范360建筑网会员
  • 做DJ网站违法吗汕头seo网站推广
  • 上海网站建设网站宁波网站模板哪家性价比高
  • 珠海专业做网站制作做网站网站的代理算网站罪吗
  • 建设局网站简介通信建设网站
  • php做网站用什么开发工具大专软件技术工资一般多少
  • 网站建设服务承诺wordpress 博客园
  • seo综合查询站长工具关键词全网营销案例
  • 深圳专业做网站设计政务服务网站建设性建议
  • 做暧免费观看网站哪个网站可以给图片做链接
  • wordpress最好的主题东莞债务优化
  • 全国网站建设大赛网店网站设计
  • 学网站建设需要学多久wordpress火车头插件
  • wordpress 网站实例中国纪检监察报app下载
  • 网站链接dw怎么做营销推广方法
  • 觅知网 大而全的高质量素材站开发手机网站用什么好
  • 建设一个广告联盟的网站医院网站设计与实现
  • 公司网站备案必须是企业信息么网站搭建好有什么内容可以修改
  • 弄网站赚钱吗电影网站怎么做要多少钱
  • 做优化网站能以量取胜么好素材网站
  • wordpress主题网站江苏建设工程教育网
  • 网站制作 客户刁难做宠物网站赚钱吗
  • 网站突然不收录了如何形容一个网站做的好
  • 怎么建网站教程视频做网站跟推广哪家公司好
  • 怎么做网站报告四平网站公司
  • 飞扬动力网站建设支付网站建设要求
  • 达美网站建设廊坊seo扣费
  • 好享购物官方网站购物网页制作与网站开发从入门到精通
  • 坪山网站建设哪家便宜系部网站建设研究方案