我是Sqlite的新手,实际上是整个SQL概念的新手,我对这些数据表如何存储在数据库中感到困惑,让我试着展示我的想法:
我想这个:
Database Database_name
{
Table table_name;
Table another_table_name;
/*and the table creation continues like this*/
}
但我知道Dataset,所以我想知道它是否存储如下:
Database Database_name
{
Dataset dataset_name
{
Table table_name;
Table another_table_name;
}
Dataset dataset_name2
{
Table table_name2;
Table another_table_name2;
}
}
所以它存储的实际方式是什么,使用数据库数据集和表更好地解释它,正如我演示的那样
答案 0 :(得分:4)
tl; dr :每个SQLite数据库都是一组文件,一个用于数据库,另一个用于事务。在数据库文件中,每个表都是B-tree,每个节点有一行。节点的键是rowid,值是每列的类型和大小,加上该行的每列的值。
B树的每个节点都是数据库文件中的一个页面。每个页面大小相同。如果某行对于某个页面来说太大,它可能会溢出到另一个页面。
SQLite database file format is documented。有两个文件,数据库文件和回滚日志。回滚日志包含事务所需的信息。
数据库文件以一个标题开头,该标题包含有关数据库的信息,如其编码,其余部分分为"pages"个固定大小的磁盘空间块。这允许SQLite快速查找文件中的特定内容而无需阅读整个内容,它知道每个页面在文件中的起始位置,并且可以快速seek
到该位置。
他们可以......
你关心最后一个,即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)
得到的id
为12345.这将使用密钥12345存储在b树中。该值以描述列中内容的标题开头
0, 35, 4
0代表integer primary key
。 0表示它为空。由于它是关键,因此不需要再次存储在值中。
35表示下一个字段是文本,长度为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,他们很棒。