tl; dr:每个SQLite数据库都是一组文件,一个用于数据库,另一个用于事务,如事务。在数据库文件中,每个表是一个B-tree,每个节点一行。节点的键是rowid,值是每列的类型和大小,以及该行每列的值。
B树的每个节点都是数据库文件中的页面。每一页都是相同的大小。如果一行对于一个页面来说太大,它可能会溢出到另一页面。
该SQLite database file format is documented。有两个文件,数据库文件和回滚日志。回滚日志包含事务所需的信息。
数据库文件以包含关于数据库的信息(如其编码的信息)的头开始,其余部分分割为固定大小的磁盘空间块"pages"。这允许SQLite快速查找文件中的特定内容,而不必读取整个文件,它知道每个页面在文件中的起始位置,并且可以快速地将seek
移动到该位置。
他们可以...
- 将锁定字节(这是针对Windows强制性文件锁定的事情)。
- 可用页面的链接列表,如已删除并准备好可重复使用的行。
- 如果一行中的数据对于一页太大,则溢出。
- 使吸尘效率更高的指针图。
- B-Tree中的页面包含表格和索引以及所有这些页面。
你在乎的是最后一个,B树。 B树允许您存储快速查找单个对的键/值对,快速按顺序读取整个列表,快速插入,快速删除和高效的空间。
每个表格都是以页为单位散布在文件周围的B树。树中的每个条目都有一个键,即64位rowid,值是行。该行表示为一个标题,该标题描述了每个字段在该行中的大小,以及所有列的字节数组按其声明的顺序排列。
因此,让我们说你有:
create table user (
id integer primary key,
name text,
age integer
);
你insert into user (name, age) values ("Yarrow Hock", 41)
它获取的12345的id
将被存储在B树中,关键12345的值与头开始描述什么是在该列。
0, 35, 4
0代表integer primary key
。 0表示它是空的。由于它是关键,所以不需要再次存储该值。如果下一个字段是文本,并且长度为11(假设你使用的是UTF-8,那么你可能就是这样)。怎么样?这是(length * 2) + 13
或(11 * 2) + 13
。它是这样做的,以确保该领域始终是奇怪的,它已经超过了12个。即使是超过12的字段也是二元的。 12以下的任何东西都是整数或浮点数或固定宽度的东西。
而4表示最后一个字段是一个32位整数。
最后,所有列的数据放在一起组成一个字节数组。这是它在十六进制中的样子。
59 61 72 72 6f 77 20 48 6f 63 6b 00 00 00 29
使用头,SQLite知道名称字段从data[0]
开始,是11个字节长。这是59 61 72 72 6f 77 20 48 6f 63 6b
的一部分。年龄字段开始于data[11]
并且是4个字节,这是00 00 00 29
部分。
所有表,索引,触发器和视图完整的数据库架构存储在一个特殊的表名为sqlite_master
看起来像这样。
create table sqlite_master(
type text,
name text,
tbl_name text,
rootpage integer,
sql text
);
它像常规表一样存储,每个表,索引,触发器或视图都是一行。
还有很多其他的东西在里面,你可以read the docs to learn more,但是这是如何存储SQLite的信息基础。我建议你看看B-trees,他们很棒。
对不起,它不能解释为你演示,因为它与SQLite如何存储的东西没有关系。 – Schwern