数据库命名约定
sqlite3_open()API用到数据库的文件名,可以是相对当前工作目录的相对路径名,也可以是从系统根文件树开始的完整路径名。任何被本地文件系统接受的正规文件名都是好的。
如果文件名是C语言中的NULL指针(即,0),SQlite创建并打开一个临时文件。如果文件名是内存地址,SQLite创建一个内存数据库。在这两种情况中,当应用程序关闭数据库时,数据库都会被消灭,即数据库不是持久的。SQLite随机选择临时文件名(以sqlite_开头,后跟16位字母数字随机串)。文件尝试在以下目录存储,(1) /var/tmp, (2) /usr/tmp, (3) /tmp, (4) 当前工作目录。不管是什么方式打开的数据库(文件数据库,临时数据库,内存数据库),在SQLite内部都被命名为主数据库(main database)。
在内部,数据库文件名不是数据库名。他们是相关但是不同的概念。用attach命令,可以把一个数据库文件以不同的数据库别名关联到一个数据库连接上。可以通过这些别名访问数据库文件。
当应用程序用sqlite3_open()打开数据库时,SQLite会为每一个连接维护一个单独的临时数据库。临时数据库存储临时对象(表及其索引)。应用程序可以在其查询中用这两个名称(main和temp),例select * from temp.table1返回在临时数据库中表1的所有行,而不是主数据库中的。临时数据库的catalog名是sqlite_temp_master。临时对象只在相同的数据库连接内才是可见的,在对相同数据库的不同的连接是不可见的,即使是同一个线程,进程或是程序。SQlite把临时数据库存储在一个与主数据库文件不同的单独的临时文件中。当应用程序关闭到主数据库的连接时,会删除这个临时文件。
数据库文件系统
除了内存数据库,SQLite存储一整个数据库(main或temp)在一个单独的页中。
页:为了方便空间按管理,SQLite把数据库(包括内存数据库)划分成固定大小的区域,称为数据库的页(页大小为2的幂次方,从512到32768,默认1024。上界是由在代码中或在外部存储中的2字节的有符号整数确定的)。数据库是由页的数组(可扩大或缩小)组成的,数组的下标称为是页号,下标从1开始直到231 -1结束(上界由本地文件系统的最大文件长度确定)。第0页被作为没有此页或不是个页对待,总之是物理上不存在的页。第1页以及以后的页都是依次从数据库文件偏移量为0的位置开始排列。
一旦创建了数据库文件,SQLite采用默认的也大小,但是在创建第一个表之前,也可通过编译命令改变页大小。SQlite把页大小作为元数据的一部分来存储。将会用这个值代替默认的页大小(编译命令用来改变数据库的行为特性)。
页类型:有四种页:叶子页,内部页,溢出叶,自由页。自由页是无效(当前未被使用),其他的都是活跃的页。
B+树内部页有搜索导航信息,叶子页存储实际的数据(表中的行),如果一行信息量太大不能放入一个页中,则部分数据存入叶子页中,剩余的存在溢出页中。
B树有内部页有搜索信息和数据。
文件头:SQLite可以把任何页类型用于任何数据库页,除了第1页,它总是B+树的内部页。在该页0偏移地址处存储了100字节的文件头记录,文件头记录描述了数据库文件的数据结构。SQLite在建立一个数据库文件时初始化文件头。
Offset Size Description
0 16 Header string This is the 16 byte string: "SQLite format 3."
16 2 Page size in bytes
18 1 File format write version
19 1 File format read version
20 1 Bytes reserved at the end of each page
21 1 Max embedded payload fraction
22 1 Min embedded payload fraction
23 1 Min leaf payload fraction
24 4 File change counter
28 4 Reserved for future use
32 4 First freelist page
36 4 Number of freelist pages
40 60 15 4-byte meta values