SQLite 使用介绍

1. SQLite Introduction

SQLite是目前最流行的开源嵌入式数据库,和很多其他嵌入式存储引擎相比(NoSQL),如BerkeleyDB、MemBASE等,SQLite可以很好的支持关系型数据库所具备的一些基本特征,如标准SQL语法、事务、数据表和索引等。事实上,尽管SQLite拥有诸多关系型数据库的基本特征,然而由于应用场景的不同,它们之间并没有更多的可比性。下面我们将列举一下SQLite的主要特征:

  1. 管理简单,甚至可以认为无需管理。
  2. 操作方便,SQLite生成的数据库文件可以在各个平台无缝移植。
  3. 可以非常方便的以多种形式嵌入到其他应用程序中,如静态库、动态库等。
  4. 易于维护。

综上所述,SQLite的主要优势在于灵巧、快速和可靠性高。SQLite的设计者们为了达到这一目标,在功能上作出了很多关键性的取舍,与此同时,也失去了一些对RDBMS关键性功能的支持,如高并发、细粒度访问控制(如行级锁)、丰富的内置函数、存储过程和复杂的SQL语句等。正是因为这些功能的牺牲才换来了简单,而简单又换来了高效性和高可靠性。

2. 工作中选择SQLite 的理由

1.授权协议(License)

SQLite使用的是Public Domain协议,这是最爽一种,可以放心大胆地用。

2.用户的普及程度

最近这几年,使用SQLite的人越来越多(从Google Trends可以反应出来)。包括一些大公司也开始把它整合到产品中(比如Google的Gears、Apple的Safari、Adobe的AIR)。这说明它的健壮性、稳定性等方面不会有太大问题。

3.开发的活跃程度

如果到SQLite的Change Log上大致了解一下,可以看出最近5年基本上每1-2个月都会有更新。说明开发的活跃度还是非常高的。

从上述几个非技术因素来看,SQLite用于商业公司的软件项目还是非常靠谱的。

3. SQLite 优缺点

(1).SQLite技术上的优点和特性

 SQLite是一个轻量级、跨平台的关系型数据库。既然号称关系型数据库,支持SQL92标准中常用的玩意儿(比如视图、事务、触发器等)就是理所当然的了,咱今天就不细说了。今天主要聊聊一些有点特色的玩意儿。

1.轻量级

  先说它的第一个特色:轻量级。想必SQLite的作者很看重这个特性,连它的Logo都是用的“羽毛”,来显摆它的轻飘飘。

SQLite和C/S模式的数据库软件不同,它是进程内的数据库引擎,因此不存在数据库的客户端和服务器。使用SQLite一般只需要带上它的一个动态库,就可以享受它的全部功能。而且那个动态库的尺寸也挺小,3.6.27版本也就几百K

2.绿色软件

SQLite的另外一个特点是绿色:它的核心引擎本身不依赖第三方的软件,使用它也不需要“安装环境”(如:Oledb等)。所以在部署的时候能够省去不少麻烦。

3.单一文件

所谓的“单一文件”,就是数据库中所有的信息(比如表、视图、触发器、等)都包含在一个文件内。这个文件可以copy到其它目录或其它机器上,也照用不误。

4.跨平台/可移植性

  如果光支持主流操作系统(Windows,Linux),那就没啥好吹嘘的了。除了主流操作系统,SQLite还支持了很多小型嵌入式系统,比如Android、Windows Mobile、Symbin、Palm、VxWorks等,也就是说iPhone,Android等手机上都可以用。

  

5.内存数据库(in-memory database)

这年头,内存越来越便宜,很多普通PC都开始以GB为单位来衡量内存(服务器就更甭提了)。这时候,SQLite的内存数据库特性就越发显得好用。SQLite的API不区分当前操作的数据库是在内存还是在文件(对于存储介质是透明的)。所以如果你觉得磁盘I/O有可能成为瓶颈的话,可以考虑切换为内存方式。切换的时候,操作SQLite的代码基本不用大改,只要在开始时把文件Load到内存,结束时把内存的数据库Dump回文件就OK了。

(2). 技术上的缺点和不足

 前面光聊了特性和优点,为了避免枪手写软文的嫌疑,再来说说SQLite的一些缺点。列位看官将来如果想用它,这些缺点要权衡一下。

1.并发访问的锁机制

SQLite在并发(包括多进程和多线程)读写方面的性能一直不太理想。数据库可能会被写操作独占,从而导致其它读写操作阻塞或出错。

2.SQL标准支持不全

在它的官方网站上,具体列举了不支持哪些SQL92标准。我个人感觉比较不爽的是不支持外键约束。

3.网络文件系统(以下简称NFS)

有时候需要访问其它机器上的SQLite数据库文件,就会把数据库文件放置到网络共享目录上。这时候你就要小心了。当SQLite文件放置于NFS时,在并发读写的情况下可能会出问题(比如数据损坏)。原因据说是由于某些NFS的文件锁实现上有Bug。

4. 各种编程语言接口

SQLite支持很多种语言的编程接口。这对于我这种喜欢混用多种编程语言的人来说,是很爽的。下面我大概介绍一下。

(1)C/C++

由于SQLite本身是C写的,它自带的API也是C接口的。所以C/C++用起来最直接了。假如你不喜欢面向过程的C API风格,可以另外找个C++的包装库。想重新发明轮子的同学,也可以自己包装一个。

(2)Java

如果要用Java访问SQLite,可以通过SQLite的JDBC驱动,或者通过专门的SQLite包装库。我个人建议走JDBC方式,万一将来要换数据库,代码就不用大改。

(3)Python

pysqlite是Python操作SQLite的首选。从Python 2.5开始,它已经被整合到Python的标准库中。看来Python社区还是蛮喜欢SQLite嘛。

(4).net

对于喜欢.net的同学,可以通过System.Data.SQLite来访问。

(5)Ruby

Ruby可以通过SQLite-Ruby操作SQLite数据库,不过我没用过。

(6)Perl

在CPAN上有DBD::SQLite,不过我也没用过。

5. C语言编程接口

下面详细介绍C/C++接口,毕竟其他语言库的接口都是基于C实现的,了解了下面的接口之后对于学习相关框架很有帮助。

5.1 Basic

在SQLite提供的C/C++接口中,其中5个APIs属于核心接口。在这篇博客中我们将主要介绍它们的用法,以及它们所涉及到的核心SQLite对象,如database_connection和prepared_statement。相比于其它数据库引擎提供的APIs,如OCI、MySQL API等,SQLite提供的接口还是非常易于理解和掌握的。

5.2 核心对象和接口

(1) 核心对象:

在SQLite中最主要的两个对象是:database_connectionprepared_statement, database_connection对象是由sqlite3_open()接口函数创建并返回的,在应用程序使用任何其他SQLite接口函数之前,必须先调用该函数以便获得database_connnection对象,在随后的其他APIs调用中,都需要该对象作为输入参数以完成相应的工作。

至于prepare_statement,我们可以简单的将它视为编译后的SQL语句,因此,所有和SQL语句执行相关的函数也都需要该对象作为输入参数以完成指定的SQL操作。

(2). 核心接口:

$1. sqlite3_open

上面已经提到过这个函数了,它是操作SQLite数据库的入口函数。该函数返回的database_connection对象是很多其他SQLite APIs的句柄参数。注意,我们通过该函数既可以打开已经存在的数据库文件,也可以创建新的数据库文件。对于该函数返回的database_connection对象,我们可以在多个线程之间共享该对象的指针,以便完成和数据库相关的任意操作。然而在多线程情况下,我们更为推荐的使用方式是,为每个线程创建独立的database_connection对象。对于该函数还有一点也需要额外说明,我们没有必要为了访问多个数据库而创建多个数据库连接对象,因为通过SQLite自带的ATTACH命令可以在一个连接中方便的访问多个数据库。

$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

该函数用于获取当前行指定列的数据,然而严格意义上讲,此函数在SQLite的接口函数中并不存在,而是由一组相关的接口函数来完成该功能,其中每个函数都返回不同类型的数据,如:

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函数用于获取当前结果集中的字段数据。下面是使用sqlite3_step和sqlite3_column函数迭代结果集中每行数据的伪代码,注意这里作为示例代码简化了对字段类型的判断:

int fieldCount = sqlite3_column_count(...);
while (sqlite3_step(...) <> EOF)
{
    for (int i = 0; i < fieldCount; ++i)
    {
        int v = sqlite3_column_int(...,i);
    }
}

$5. sqlite3_finalize

该函数用于销毁prepared statement对象,否则将会造成内存泄露。

$6. sqlite3_close

该函数用于关闭之前打开的database_connection对象,其中所有和该对象相关的prepared_statements对象都必须在此之前先被销毁。

(3)参数绑定:

和大多数关系型数据库一样,SQLite的SQL文本也支持变量绑定,以便减少SQL语句被动态解析的次数,从而提高数据查询和数据操作的效率。要完成该操作,我们需要使用SQLite提供的另外两个接口APIs,sqlite3_reset和sqlite3_bind。

见如下示例:

void test_parameter_binding()
{
//1. 不带参数绑定的情况下插入多条数据。char strSQL[128];
    for (int i = 0; i < MAX_ROWS; ++i)
    {
        sprintf(strSQL,"insert into testtable  values(%d)",i);sqlite3_prepare_v2(..., strSQL);sqlite3_step(prepared_stmt);sqlite3_finalize(prepared_stmt);
    }

//2. 参数绑定的情况下插入多条数据。
string strSQLWithParameter = "insert into testtable values(?)";
sqlite3_prepare_v2(..., strSQL);

    for (int i = 0; i < MAX_ROWS; ++i)
    {
        sqlite3_bind(...,i);
        sqlite3_step(prepared_stmt);
        sqlite3_reset(prepared_stmt);
    }

sqlite3_finalize(prepared_stmt);
}

这里首先需要说明的是,SQL语句”insert into testtable values(?)”中的问号(?)表示参数变量的占位符,该规则在很多关系型数据库中都是一致的,因此这对于数据库移植操作还是比较方便的。通过上面的示例代码可以显而易见的看出,参数绑定写法的执行效率要高于每次生成不同的SQL语句的写法,即2)在效率上要明显优于1),下面是针对这两种写法的具体比较:

  1. 单单从程序表面来看,前者在for循环中执行了更多的任务,比如字符串的填充、SQL语句的prepare,以及prepared_statement对象的释放。
  2. 在SQLite的官方文档中明确的指出,sqlite3_prepare_v2的执行效率往往要低于sqlite3_step的效率。
  3. 当插入的数据量较大时,后者带来的效率提升还是相当可观的。

6. SQL常用函数:

//1.打开数据库
int sqlite3_open(
    const char *filename,   // 数据库的文件路径
    sqlite3 **ppDb          // 数据库实例
);

//2.执行任何SQL语句
int sqlite3_exec(
    sqlite3*,                                  // 一个打开的数据库实例
    const char *sql,                           // 需要执行的SQL语句
    int (*callback)(void*,int,char**,char**),  // SQL语句执行完毕后的回调
    void *,                                    // 回调函数的第1个参数
    char **errmsg                              // 错误信息
);

//3.检查SQL语句的合法性(查询前的准备)
int sqlite3_prepare_v2(
    sqlite3 *db,            // 数据库实例
    const char *zSql,       // 需要检查的SQL语句
    int nByte,              // SQL语句的最大字节长度
    sqlite3_stmt **ppStmt,  // sqlite3_stmt实例,用来获得数据库数据
    const char **pzTail
);

//4.查询一行数据
int sqlite3_step(sqlite3_stmt*); // 如果查询到一行数据,就会返回SQLITE_ROW

//5.利用stmt获得某一字段的值(字段的下标从0开始)
double sqlite3_column_double(sqlite3_stmt*, int iCol);  // 浮点数据

int sqlite3_column_int(sqlite3_stmt*, int iCol); // 整型数据

sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); // 长整型数据

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); // 二进制文本数据

const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);  // 字符串数据

6. 其他资源

SQLite的官方主页:

http://www.sqlite.org/

SQLite中文站:

http://www.sqlite.com.cn/

System.Data.SQLite:

http://sqlite.phxsoftware.com/

sql学习笔记之 嵌入式数据库(sqlite,firebird)

http://www.cnblogs.com/ljzforever/archive/2010/03/09/1681453.html

sql 学习笔记,博主写的很详细

http://www.cnblogs.com/stephen-liu74/category/348367.html

SQLite GUI图形管理工具(推荐):

Navicat for SQLite(导入,导出功能强大,功能实用,操作直观):

http://www.navicat.com/en/download/download.html

时间: 2024-09-29 18:14:20

SQLite 使用介绍的相关文章

iOS开发数据库篇—SQLite简单介绍

转自:http://www.cnblogs.com/wendingding/p/3868893.html 一.离线缓存 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等. 说明:离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式 (1)归档:NSCodeing.NSKeyedArchiver (2)偏好设置:NSUserDefaults (3)Plist存储:writeToFile 提示:上述三种方法都有一个致命的缺点,那就是都无法存储大批量的数据,有性能的问题.

[安卓基础]011存储数据(中)——sqlite语法介绍

*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; text-decoration: none; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: poin

SQLite数据库介绍

SQLite是一个文件数据库,不像Mysql,Oracle等数据库有很多进程,被很多语言bullet-in成了自己的模块,python.php.ruby都支持,作为一个小app或者更大软件不需要连接网络上数据库是一个很好的选择,一些linux主机还会初始安装sqlite. 下面给出一个最简单的示例代码: import sqlite3 conn = sqlite3.connect('test.db') cur = conn.cursor() cur.execute('select count(*)

SQLite 基础介绍

1.什么是SQLite ? -> SQLite简介 SQLite 是一个进程内的库,是一种轻量级的.自给自足的.无服务器的.无需配置的,事务性的SQL数据库引擎.和他其他的数据库一样,SQLite引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接.SQLite可以直接访问其存储文件. SQLite 是一个开源的嵌入式关系数据库. 其特点是高度便携.使用方便.结构紧凑.高效.可靠. 与其他数据库管理系统不同,SQLite 的安装和运行非常简单,在大多数情况下 - 只要确保SQLite的二

【转】 iOS开发数据库篇—SQLite简单介绍

开始学SQLite啦, 原文: http://www.cnblogs.com/wendingding/p/3868893.html iOS开发数据库篇—SQLite简单介绍 一.离线缓存 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等. 说明:离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式 (1)归档:NSCodeing.NSKeyedArchiver (2)偏好设置:NSUserDefaults (3)Plist存储:writeToFile 提示:上述三种方

SQLite简单介绍

一.离线缓存 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等. 说明:离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式 (1)归档:NSCodeing.NSKeyedArchiver (2)偏好设置:NSUserDefaults (3)Plist存储:writeToFile 提示:上述三种方法都有一个致命的缺点,那就是都无法存储大批量的数据,有性能的问题. 举例:使用归档 两个问题: (1)数据的存取都必须是完整的,要求写入的时候要一次性写入,读取的时候要一次性

Android的SQLite使用介绍

Android的SQLite使用介绍 一.SQLite的简介 Android当中内置SQLite数据库,那个SQLite有什么特点呢? SQLite 是一个开源的嵌入式关系数据库,实现自包容.零配置.支持事务的SQL数据库引擎. 其特点是高度便携.使用方便.结构紧凑.高效.可靠. 与其他数据库管理系统不同,SQLite 的安装和运行非常简单,在大多数情况下 - 只要确保SQLite的二进制文件存在即可开始创建.连接和使用数据库.在于个人使用SQLite的体验中,SQLite最大的优点就是高度便携

Android SQLite 的介绍和使用(二)

上一节简单介绍了一下SQLite,这一节我们开始SQLite在Android中的应用. Android提供了一个数据库的帮助类 SQLiteOpenHelper,用于管理数据库的创建和版本管理.我们可以继承这个类,实现它的 onCreate和 onUpgrade方法.我们可以在这里设置数据库的版本,数据库名称,创建数据库表等.下面看代码: public class DBHelper extends SQLiteOpenHelper { //数据库的版本号必须要大于1 public final s

Android探索之数据存储Sqlite的介绍及使用

前言: 本来没有打算整理有关Sqlite数据库文章的,最近一直在研究ContentProvider的使用,所有觉得还是先对Sqlite进行一个简单的回顾,也方便研究会学习ContentProvider. Sqlite简介: Sqlite数据库是一种轻量级数据库,它具备跨平台,多语言操作等优点,它广泛用于包括浏览器.IOS,Android以及一些便携需求的小型web应用系统.它具备占用资源低,处理速度快等优点. 接下来具体介绍一下如何 使用? 如何创建一个数据库? public class DBH

C# 中 SQLite 使用介绍

关于SQLite SQLite是一款轻型的嵌入式的遵守ACID的关系型数据库管理系统,诞生已有15个年头了.随着移动互联的发展,现在得到了更广泛的使用. 在使用SQLite之前,我们势必要先了解它一些“个性”的地方.下面是它的一些特点: 1.  自包含.SQLite很大层度上是独立的,他只需要非常小的外部库支持.任何程序能够访问磁盘就可以使用SQLite数据库.这使它适用于嵌入式设备,缺乏桌面计算机支持的基础设施.这也使得SQLite适用于不作任何修改就可运行在不同配置电脑上的程序. 2.  无