写在前面:sqlite作为嵌入式数据库,通常针对的应用的数据量相对于通常DBMS的数据量是较小的。所以它的存储模型设计得非常简单,总的来说,sqlite把一个数据文件分成若干大小相等的页面,然后以B树的形式来组织这些页面。而对于大型的数据库管理系统,比如Oracle,或者DM ,存储模型要复杂得多。就拿Oracle来说吧,它对数据文件不仅从物理进行分块,而且从逻辑上进行分段,盘区和页的一个层次划分,DM也一样。不管怎么说,数据库文件要存储大量的数据,为了更好管理,查询和操作数据文件,DBMS不得不从物理上、逻辑上对数据文件的数据进行复杂的组织。本节主要讨论文件格式,下节讨论页面格式。
1、文件格式
1.1、数据库名称应用程序通过sqlite3_open API来打开数据库,该函数的一个参数为数据库文件的名称。sqlite内部命名为main数据库(除了临时数据库和内存数据库)。sqlite对每一个数据库都创建一个独立的文件。
在sqlite内部,数据文件名不是数据库名。sqlite对应用程序的每一个连接都维护着一个单独的临时数据库(temp数据库),临时数据库存临时对象,例如:表以及相应的索引。这些临时对象仅仅对同一个连接可见(对同一个线程,进程的其它连接是不可见的),sqlite存储临时数据库到一个单独的临时文件中,当应用程序关闭对main数据库的连接时,就删除临时文件。
1.2、数据库文件结构
除了内存数据库,sqlite把一个数据库(main和temp)都存储到一个单独的文件。
1.2.1、页面(page)
为了更好的管理和读/写数据库,sqlite把一个数据库(包括内存数据库)分成一个个固定大小的页面。页面大小的范围从512-32768(两者都包含),页面默认大小为1024个字节(1KB),实际上,页面的上限由2个字节的有符号整数决定。整个数据库可以看成这些页面的数组,页面数组的下标为页面的编号(page number),page number从1开始,一直到2,147,483,647 (2^31– 1)。实际上,数组上界还受文件系统允许的最大文件大小决定。0号页面视为空页面(NULL page),物理上不存在,1号页面从文件的0偏移处开始,一个页面接着下一个页面。
注:一旦数据库创建,sqlite使用编译时确定的默认的页面大小。当然,在创建第一个表之前,可以通过pragma命令改变页面大小。sqlite把该值作为元数据的一部分存储在文件中。
1.2.2、页面类型
页面(page)分四种类型:叶子页面(leaf),内部页面(internal),溢出页面(overflow)和空闲页面(free)。内部页面包含查询时的导航信息,叶子页面存储数据,例如元组。如果一个元组的数据太大,一个页面容纳不下,则一些数据存储在B树的页面中,余下的存储在溢出页面中。
1.2.3、文件头(file header)
作为文件开始的1号页面比较特殊,它包括100个字节的文件头。当sqlite创建文件时例初始化文件头,文件头的格式如下:
Structure of database file header |
||
Offset |
Size | Description |
0 |
16 | Header string |
2 | Page size in bytes | |
18 | 1 | File format write version |
19 | File format read version | |
20 | Bytes reserved at the end of each page | |
21 | Max embedded payload fraction | |
22 | Min embedded payload fraction | |
23 | Min leaf payload fraction | |
24 | 4 | File change counter |
28 | Reserved for future use | |
32 | First freelist page | |
36 | Number of freelist pages | |
40 | 60 | 15 4-byte Meta values |
53 51 4C 69 74 65 20 66sqlite f 6F 72 6D 61 74 20 33 00ormat 3. 04 00 01 01 00 40 20 20.....@ 00 00 00 11 00 00 00 00........ 00 00 00 00 00 00 00 00........ 00 00 00 01 00 00 00 01........ 00 00 00 01 00 00 00 00........ 00 00 00 00 |
** Meta values are as follows: **Meta[0] Schema cookie.Changes with each schema change. **Meta[1] File format of schema layer. **Meta[2] Size of the page cache. **Meta[3] Use freelist if 0.Autovacuum if greater than zero. **Meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE **Meta[5] The user cookie. Used by the application. **Meta[6] **Meta[7] **Meta[8] **Meta[9] |