SQLite

来源:互联网 发布:安卓 服务器软件 编辑:程序博客网 时间:2024/06/02 01:34

目前封装的比较好的框架是FMDB

简介:

1). 管理简单,甚至可以认为无需管理。

2). 操作方便,SQLite生成的数据库文件可以在各个平台无缝移植。

3). 可以非常方便的以多种形式嵌入到其他应用程序中,如静态库、动态库等。

4). 易于维护。

5). 支持索引。建立索引的优缺点

优势:

1. 一致性的文件格式:
    在SQLite的官方文档中是这样解释的,我们不要将SQLite与Oracle或PostgreSQL去比较,而是应该将它看做fopen和fwrite。与我们自定义格式的数据文件相比,SQLite不仅提供了很好的移植性,如大端小端、32/64位等平台相关问题,而且还提供了数据访问的高效性,如基于某些信息建立索引,从而提高访问或排序该类数据的性能,SQLite提供的事务功能,也是在操作普通文件时无法有效保证的。
    
    2. 在嵌入式或移动设备上的应用:
    由于SQLite在运行时占用的资源较少,而且无需任何管理开销,因此对于PDA、智能手机等移动设备来说,SQLite的优势毋庸置疑。
    
    3. 内部数据库:
    在有些应用场景中,我们需要为插入到数据库服务器中的数据进行数据过滤或数据清理,以保证最终插入到数据库服务器中的数据有效性。

有的时候,数据是否有效,不能通过单一一条记录来进行判断,而是需要和之前一小段时间的历史数据进行特殊的计算,再通过计算的结果判断当前的数据是否合法。在这种应用中,我们可以用SQLite缓冲这部分历史数据。

还有一种简单的场景也适用于SQLite,即统计数据的预计算。比如我们正在运行数据实时采集的服务程序,我们可能需要将每10秒的数据汇总后,形成每小时的统计数据,该统计数据可以极大的减少用户查询时的数据量,从而大幅提高前端程序的查询效率。在这种应用中,我们可以将1小时内的采集数据均缓存在SQLite中,在达到整点时,计算缓存数据后清空该数据。
    
    4. 数据分析:
    可以充分利用SQLite提供SQL特征,完成简单的数据统计分析的功能。这一点是CSV文件无法比拟的。
    
    5. 产品Demo和测试:
    在需要给客户进行Demo时,可以使用SQLite作为我们的后台数据库,和其他关系型数据库相比,使用SQLite减少了大量的系统部署时间。对于产品的功能性测试而言,SQLite也可以起到相同的作用

劣势:

1. C/S应用:
    如果你有多个客户端需要同时访问数据库中的数据,特别是他们之间的数据操作是需要通过网络传输来完成的。在这种情况下,不应该选择SQLite。由于SQLite的数据管理机制更多的依赖于OS的文件系统,因此在这种操作下其效率较低。
    
    2. 数据量较大:
    受限于操作系统的文件系统,在处理大数据量时,其效率较低。对于超大数据量的存储,甚至不能提供支持。
    
    3. 高并发:
    由于SQLite仅仅提供了粒度很粗的数据锁,如读写锁,因此在每次加锁操作中都会有大量的数据被锁住,即使仅有极小部分的数据会被访问。换句话说,我们可以认为SQLite只是提供了表级锁,没有提供行级锁。在这种同步机制下,并发性能很难高效。


特性:

    1. 零配置:
    SQLite本身并不需要任何初始化配置文件,也没有安装和卸载的过程。当然也不存在服务器实例的启动和停止。在使用的过程中,也无需创建用户和划分权限。在系统出现灾难时,如电源问题、主机问题等,对于SQLite而言,不需要做任何操作。
    
    2. 没有独立的服务器:
    和其他关系型数据库不同的是,SQLite没有单独的服务器进程,以供客户端程序访问并提供相关的服务。SQLite作为一种嵌入式数据库,其运行环境与主程序位于同一进程空间,因此它们之间的通信完全是进程内通信,而相比于进程间通信,其效率更高。然而需要特别指出的是,该种结构在实际运行时确实存在保护性较差的问题,比如此时,应用程序出现问题导致进程崩溃,由于SQLite与其所依赖的进程位于同一进程空间,那么此时SQLite也将随之退出。但是对于独立的服务器进程,则不会有此问题,它们将在密闭性更好的环境下完成它们的工作。
    
    3. 单一磁盘文件:
    SQLite的数据库被存放在文件系统的单一磁盘文件内,只要有权限便可随意访问和拷贝,这样带来的主要好处是便于携带和共享。其他的数据库引擎,基本都会将数据库存放在一个磁盘目录下,然后由该目录下的一组文件构成该数据库的数据文件。尽管我们可以直接访问这些文件,但是我们的程序却无法操作它们,只有数据库实例进程才可以做到。这样的好处是带来了更高的安全性和更好的性能,但是也付出了安装和维护复杂的代价。
    
    4. 平台无关性:
    这一点在前面已经解释过了。和SQLite相比,很多数据库引擎在备份数据时不能通过该方式直接备份,只能通过数据库系统提供的各种dump和restore工具,将数据库中的数据先导出到本地文件中,之后在load到目标数据库中。这种方式存在显而易见的效率问题,首先需要导出到另外一个文件,如果数据量较大,导出的过程将会比较耗时。然而这只是该操作的一小部分,因为数据导入往往需要更多的时间。数据在导入时需要很多的验证过程,在存储时,也并非简简单单的顺序存储,而是需要按照一定的数据结构、算法和策略存放在不同的文件位置。因此和直接拷贝数据库文件相比,其性能是非常拙劣的。
    
    5. 弱类型:
    和大多数支持静态类型的数据库不同的是,SQLite中的数据类型被视为数值的一个属性。因此对于一个数据表列而言,即便在声明该表时给出了该列的类型,我们在插入数据时仍然可以插入任意类型,比如Integer的列被存入字符串'hello'。针对该特征唯一的例外是整型的主键列,对于此种情况,我们只能在该列中存储整型数据。
    
    6. SQL语句编译成虚拟机代码:
    很多数据库产品会将SQL语句解析成复杂的,相互嵌套的数据结构,之后再交予执行器遍历该数据结构完成指定的操作。相比于此,SQLite会将SQL语句先编译成字节码,之后再交由其自带的虚拟机去执行。该方式提供了更好的性能和更出色的调试能力。



API

1. 核心对象:
在SQLite中最主要的两个对象是,database_connectionprepared_statement

在应用程序使用任何其他SQLite接口函数之前,必须先调用该函数以便获得database_connnection对象,在随后的其他APIs调用中,都需要该对象作为输入参数以完成相应的工作。

prepare_statement,所有和SQL语句执行相关的函数也都需要该对象作为输入参数以完成指定的SQL操作。
    
    2. 核心接口:
    1). sqlite3_open
   它是操作SQLite数据库的入口函数。该函数返回的database_connection对象是很多其他SQLite APIs的句柄参数。注意,我们通过该函数既可以打开已经存在的数据库文件,也可以创建新的数据库文件。

对于该函数返回的database_connection对象,我们可以在多个线程之间共享该对象的指针,以便完成和数据库相关的任意操作。

然而在多线程情况下,我们更为推荐的使用方式是,为每个线程创建独立的database_connection对象。
        
    2). sqlite3_prepare
    该函数将SQL文本转换为prepared_statement对象,并在函数执行后返回该对象的指针。事实上,该函数并不会评估参数指定SQL语句,它仅仅是将SQL文本初始化为待执行的状态。最后需要指出的,对于新的应用程序我们可以使用sqlite3_prepare_v2接口函数来替代该函数以完成相同的工作。
    
    3). sqlite3_step
    该函数用于评估sqlite3_prepare函数返回的prepared_statement对象,在执行完该函数之后,prepared_statement对象的内部指针将指向其返回的结果集的第一行。

如果打算进一步迭代其后的数据行,就需要不断的调用该函数,直到所有的数据行都遍历完毕。

然而对于INSERT、UPDATE和DELETE等DML语句,该函数执行一次即可完成。
    
    4). 数据检索
    sqlite3_column_blob
    sqlite3_column_bytes
    sqlite3_column_bytes16
    sqlite3_column_double
    sqlite3_column_int
    sqlite3_column_int64
    sqlite3_column_text
    sqlite3_column_text16
    sqlite3_column_type
    sqlite3_column_value
    sqlite3_column_count
    其中sqlite3_column_count函数用于获取当前结果集中的字段数据。

    5). sqlite3_finalize

    该函数用于销毁prepared statement对象,否则将会造成内存泄露。
    
    6). sqlite3_close
    该函数用于关闭之前打开的database_connection对象,其中所有和该对象相关的prepared_statements对象都必须在此之前先被销毁。

SQLite的SQL文本也支持变量绑定,以便减少SQL语句被动态解析的次数,从而提高数据查询和数据操作的效率


关于最新的API列表请参照官网:

官网 SQLite API 

官网API Result Code



用法

一、存储种类和数据类型:

    SQLite将数据值的存储划分为以下几种存储类型:
     NULL: 表示该值为NULL值。
     INTEGER: 无符号整型值。
     REAL: 浮点值。
     TEXT: 文本字符串,存储使用的编码方式为UTF-8、UTF-16BE、UTF-16LE。
     BLOB: 存储Blob数据,该类型数据和输入数据完全相同。

    由于SQLite采用的是动态数据类型,而其他传统的关系型数据库使用的是静态数据类型,即字段可以存储的数据类型是在表声明时即以确定的,因此它们之间在数据存储方面还是存在着很大的差异。在SQLite中,存储分类和数据类型也有一定的差别,如INTEGER存储类别可以包含6种不同长度的Integer数据类型,然而这些INTEGER数据一旦被读入到内存后,SQLite会将其全部视为占用8个字节无符号整型。因此对于SQLite而言,即使在表声明中明确了字段类型,我们仍然可以在该字段中存储其它类型的数据。然而需要特别说明的是,尽管SQLite为我们提供了这种方便,但是一旦考虑到数据库平台的可移植性问题,我们在实际的开发中还是应该尽可能的保证数据类型的存储和声明的一致性。除非你有极为充分的理由,同时又不再考虑数据库平台的移植问题,在此种情况下确实可以使用SQLite提供的此种特征。
   1. 布尔数据类型:
    SQLite并没有提供专门的布尔存储类型,取而代之的是存储整型1表示true,0表示false。

   2. 日期和时间数据类型:
    和布尔类型一样,SQLite也同样没有提供专门的日期时间存储类型,而是以TEXT、REAL和INTEGER类型分别不同的格式表示该类型,如:
    TEXT: "YYYY-MM-DD HH:MM:SS.SSS"
    REAL: 以Julian日期格式存储
    INTEGER: 以Unix时间形式保存数据值,即从1970-01-01 00:00:00到当前时间所流经的秒数。


二、表达式:
常用表达式
    和大多数关系型数据库一样,SQLite能够很好的支持SQL标准中提供的表达式,其函数也与SQL标准保持一致,如:
    ||
    *    /    %
    +    -
    <<   >>   &    |
    <    <=   >    >=
    =    ==   !=   <>   IS   IS NOT   IN   LIKE 
    AND   
    OR
    ~    NOT

    在上面的表达式中,唯一需要说明的是"||",该表达式主要用于两个字符串之间的连接,其返回值为连接后的字符串,即便该操作符两边的操作数为非字符串类型,在执行该表达式之前都需要被提前转换为字符串类型,之后再进行连接


条件表达式:

    该表达式的语法规则如下:
    1). CASE x WHEN w1 THEN r1 WHEN w2 THEN r2 ELSE r3 END
    2). CASE WHEN x=w1 THEN r1 WHEN x=w2 THEN r2 ELSE r3 END
    对于第一种情况,条件表达式x只需计算一次,然后分别和WHEN关键字后的条件逐一进行比较,直到找到相等的条件,其比较规则等价于等号(=)表达式。如果找到匹配的条件,则返回其后THEN关键字所指向的值,如果没有找到任何匹配,则返回ELSE关键字之后的值,如果不存在ELSE分支,则返回NULL。对于第二种情况,和第一种情况相比,唯一的差别就是表达式x可能被多次执行,比如第一个WHEN条件不匹配,则继续计算后面的WHEN条件,其它规则均与第一种完全相同。最后需要说明的是,以上两种形式的CASE表达式均遵守短路原则,即第一个表达式的条件一旦匹配,其后所有的WHEN表达式均不会再被执行或比较。

转换表达式:

    该表达式的语法规则如下:
    CAST(expr AS target_type)
    该表达式会将参数expr转换为target_type类型


更为详细的请参照SQLite学习手册

更为专业的请参照SQLite 官网


0 0