SQLite

安装

sudo apt-get install sqlite3 

sudo apt-get install libsqlite3-dev

运行

gcc main.c -lsqlite3

SQLite API

SQLite是一个嵌在程序中的调用级的接口库。用C语言实现了所有的API函数。所有的API函数名的前缀为sqlite3_,其在sqlite3.h中声明。还有常量助记符也在.h中声明。

SQLite源文件和应用程序都应该用相同的编译器编译

sqlite3_open()打开或者创建数据库。调用其他API之前必须先用这个函数。此函数比较偷懒,直到读写文件时才会被真正执行。

sqlite3_prepare()把SQL语句转化为“预备语句”(或者说是字节码文件),在虚拟机或者解释器上运行。这个准备语句句柄的作用像一个游标,用于获取由select语句返回所得到的行的集合,每次处理一个。

sqlite3_step()执行字节码程序,直到一个断点(返回SQLITE_ROW),或者直到停止(返回SQLITE_DONE)。最初游标在所有应输出的行的集合之前,此函数使得游标每次向前移动一个位置,而且游标只能向后移动。

sqlite3_column_*()是检索sqlite3_step()函数所返回的SQLITE_ROW,可以见所各列的值(属性或字段)。

sqlite3_finalize()破坏准备语句(即清除字节码程序),所有的准备语句必须被释放以防止内存泄露。

sqlite3_close()关闭数据库连接,并释放所有分配给连接的资源。

sqlite3_bind_*()是把SQL中的字符串用SQL参数标记来代替?

sqlite3_reset()貌似是把原先的准备语句换成空的准备语句?

所有API返回0或正整数。SQLite建议用助记符检查返回值。

SQLITE_OK表示成功。

SQLITE_ROW表示sqlite_step返回了行的集合中的一个新的行。

SQLITE_DONE表示该语句执行完毕。

还有另一种直接操作数据库的方式:打开数据库文件,应用sqlite3_exec API函数,最后关闭数据库文件。此API有两个参数(数据库文件名,SQL语句)。如果语句产生输出,则exec()函数应该为每一个行调用回调函数。读者应该具有对文件的读权限,视情况要有写权限。

每个线程都应该有自己的SQLite句柄,不建议共享。在UNIX,LINUX中不应在持有一个连接时fork出一个子进程。多线程共享一个连接是可以的,当一个线程不持有该连接上的任何本地文件锁时,可把连接切换到下一个线程。即没有锁,没有未完成事务(或者被重置或者被完成)。总之线程在相互排斥的情况下是可以共用一个连接的。

master catalog 是主目录可以查询 select * from sqlite_master,但是不能修改master catalog,所有内部保留的都是以sqlite_开头的,不能以这个前缀(大写,小写,大小写混合)建(表,视图,索引,触发器)。

SQLite以一个单一的本地文件存储整个数据库,这个文件也可以被放在本地的任何其他目录下。

SQLite的attach命令用于同时访问多个数据库的事务处理。

SQLIte体系结构

前端接收从应用程序来的SQL语句和SQLite命令,解析,优化,生成后台可以直接执行的内部字节码程序

标记生成器:分割输入语句为标记。

解析器:分析标记生成解析树,重组解析树。

代码生成器:遍历解析树,生成字节码。

在前端实现sqlite3_prepare()。

后端是解释字节码程序的引擎,该引擎负责实际的数据库处理工作。

虚拟机:是内部字节码程序的解释器,执行字节码。操作数据库中的数据,把数据库视为表和索引的集合,把表和索引视为元组或记录的集合。

B/B+树:把每个元组组织成有序的树形结构。表和索引在不同的树中。负责帮助虚拟机搜索,增加,删除在树中的元组,也负责建立新树,删除旧树。

页操作模块:在本地文件系统基础上实现面向页的数据库文件的抽象。管理内存中的缓存(数据库页,B/B+树用)。管理锁和日志来实现事务的ACID特性。

操作系统界面:为不同的系统提供统一的接口。

在后端实现sqlite3_bind_*(),sqlite3_step(),sqlite3_column_*(),sqlite3_reset(),sqlite3_finalize()等API。

SQLite局限性

未支持全部SQL-92功能。

低并发:只支持扁平事务[不能嵌套事务(子事务),保存点(允许事务回滚到以前已经稳定的状态)]。也不能支持高度的事务的并发,允许并发读事务,只允许一个独占的的写事务。即有读事务,其他写事务都禁止;有写事务,其他任何事务都禁止。SQLite只提供数据库级的并发事务处理,及前面提到的都是数据库级独占。

应用限制:SQLite只适合于小规模事务并发。但是有些应用,尤其是写密集型的,需要更多的事务并发(表级或行级),SQLite并不适合。

网络文件系统:SQLite使用本地文件的锁原语控制事务的并发性。但是如果数据库文件在其他网络中,由于网络文件系统的文件锁的实现的bug,可能会导致多个程序去修改数据库,SQLite对此无解。由于网络延迟使得网络文件系统性能不好,可能客户-服务器模型的DBMS会比SQLite更有效。

数据库规模:理论上数据库文件可达241字节。但是日志的内存开销与数据库大小成正比。对于每个写事务,SQLite都要对内存中的每个页面维护1位,无论事物是否读写该页面。因此如果有上百万页的话,内存开销可能是SQLite最严重的瓶颈。

对象的数目和类型:一个表或者索引最多有264-1个条目(这是不可能的,因为内存才有241字节)。目前SQLite实现了单个条目可保存230字节数据(底层文件格式支持单行262字节数据)。在打开一个数据库文件时,SQLite读取并预处理所有主目录的条目,并在内存中创建许多目录对象。为了保持性能,最好保持表,索引,视图,触发器的数目在一个较低水平。虽然表中列的数目没有限制,也不要太多,只可能会对前31列做某些优化。也可以随意把很多列加到一个索引上,但是有30列以上的索引是不会被用作查询优化的。

主机变量引用:在某些其他嵌入式DBMS中,SQL语句可以直接引用主机变量(来自程序空间的变量),但是SQLite不能。SQLite绑定主机输入参数用sqlite3_bind_*()API函数,但不能绑定到输出参数。这方法比直接访问要好,因为直接访问还需要再把SQL语句进行特殊预处理转换成特殊的API调用。

存储过程:许多别的DBMS可以创建和保存存储过程,但SQLite没有。存储过程是一组可形成一个逻辑工作单元或执行特定功能的SQL语句的集合。

原文地址:https://www.cnblogs.com/amdb/p/4028893.html