数据库

嵌入式数据库

 

11.1 嵌入式数据库概述

1.  嵌入式数据库介绍

    随着电子技术的飞速发展,嵌入式系统中的存储器容量和性能也在迅速提高,这为扩

大嵌入式的应用领域提供了必要的物理基础。展望未来,嵌入式系统正在向网络化、智能化

等高端应用方向发展。在这个发展过程中,嵌入式系统内的数据量会急剧膨胀。因此,嵌入

式数据库的作用将会变得越来越重要。

    由于嵌入式平台和应用领域的多样化,所以嵌入式数据库的体系结构与运行模式和企

业级数据库有很大的区别。嵌入式数据库的主要特性如下:

(1)嵌入性

    嵌入性是嵌入式数据库的根本特性。嵌入式数据库不但可以嵌入到各种软件中,也能嵌入到硬件中。

(2)可移植性

    可移植性是嵌入性的基本保证。嵌入式数据库必须能够支持各种硬件平台。

(3)实时性

    在嵌入式领域,实时性是一个重要的指标。所以嵌入式数据库也需要具有较高的实时性

能。

(4)伸缩性

    伸缩性使嵌入式数据库能够满足各种应用需要,提高嵌入式系统的性能。

(5)可移动性

    随着嵌入式系统的网络化发展,可移动性也正变得越来越重要。所以嵌入式数据库需要

满足可移动性的要求。

    为了更好的满足嵌入式应用的需求,嵌入式数据库本身需要具有企业级数据库的基本

功能(比如一致性、安全性等)。此外,嵌入式数据库也必须提供一套完整的 SQL 接口,以满足应用开发的需要。

    总而言之,嵌入式数据库的应用环境是非常苛刻的。嵌入式数据库需要在满足应用要

求的前提下保证高效的运行性能。

 

  根据应用方式的不同,嵌入式数据库可以大致分为以下几类:

(1)C/S 嵌入式数据库

    C/S嵌入式数据库可以看成是企业级数据库的一个精简版,一般运用在对实时性要求不

高的系统中。

(2)面向软件嵌入式数据库  

    面向软件嵌入式数据库以组件的形式嵌入到软件中,一般运用在对运行速度和安全性要

求较高的系统中。

(3)面向硬件嵌入式数据库

   面向硬件嵌入式数据库直接嵌入到硬件设备中,一般运用在对实时性和稳定性要求较高

的系统中。

(4)内存嵌入式数据库

   内存嵌入式数据库直接运行在内存中,所以运行性能非常高。但数据无法永久保存。

2. SQLite 介绍

  SQLite 是一款轻量级的开源嵌入式数据库,由 D.Richard Hipp在2000年发布。SQLite

使用方便,性能出众,广泛应用于消费电子、医疗、工业控制、军事等各种领域。QLite

主要具有以下特点:

(1)性能:SQLite 对数据库的访问性能很高,其运行速度比 MySQL、Postgre SQL 等开源数 据库要快很多。

(2)体积:SQLite的体积非常小巧,最低只需要几百K的内存就可以运行。

(3)可移植性:SQLite 的能支持各种 32 位和 64 位体系的硬件平台,也能在 Windows、

LinuxBSD、Mac OS、Solaries 等软件平台中运行。

(4)稳定性:SQLite 支持事务的 ACID 特性,既原子性、一致性、隔离性、持久性

(5)SQL 支持:SQLite支持 ANSI SQL92 中的大多数标准,提供了对子查询、视图、触发

 器等机制的支持。

(6)接口:SQLite 为 C、Java、PHPPython、Tcl等多种语言提供了 API 接口。SQLite 总体采用了模块化设计,其结构如图 11-1 所示。

 

 (1)接口。接口由 SQLite  C  API 函数组成。所有的应用程序都必须通过接口访问

SQLite数据库。

 (2)编译器。编译器由词法分析、语法分析和中间代码生成三个模块组成。其中,词法分

析模块和语法分析模块负责检查 SQL 语句的语法,然后把生成的语法树传递给中间代码生

成模块。中间代码生成模块负责生成 SQLite 引擎可以识别的中间代码。

 (3)数据库引擎。数据库引擎是 SQLite 的核心,负责运行中间代码,指挥数据库的具体操作。

 (4)后台。台由 B 树、页缓存和系统调用三个模块组成。其中,B 树负责维护索引,页缓存负责页面数据的传送,系统调用负责和操作系统交互,最终实现数据库的访问。

 

 

11.2 SQLite3 的使用

11.2.1 SQLite3 的命令

  SQLite3 是目前最新的 SQLite 版本。可以从 http://www.sqlite.org/download.html 网站上下载 SQLite3 的源代码(本书使用的版本是 sqlite-3.6.12.tar.gz)。

  解压缩后进入 sqlite-3.6.12 的根目录,首先命令“./configure”生成 Makefile 文件,接着运行命令“make”对源代码进行编译,最后运行命令“make install”安装 SQLite3。安装完毕后,可以运行命令 sqlite3 查看 SQLite3 是否能正常运行,如下所示:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [root@localhost ~]# sqlite3  
  2. SQLite version 3.6.12  
  3. Enter ".help" for instructions  
  4. Enter SQL statements terminated with a ";"  
  5. sqlite>  


  可以看到,SQLite3 启动后会停留在提示符 sqlite>处,等待用户输入 SQL 语句。

  在使用 SQLite3 前需要先了解下 SQLite3 支持的数据类型。SQLite3 支持的基本数据类型主要有以下几类:

(1)NULL  

(2)NUMERIC

(3)INTEGER  

(4)REAL

(5)TEXT

SQLite3 会自动把其他数据类型转换成以上 5 类基本数据类型,转换规则如下所示:

(1)char、clob、test、varchar—> TEXT

(2)integer—>INTEGER

(3)real、double、float—> REAL l  

(4)blob—>NULL l  

(5)其余数据类型都转变成 NUMERIC

 

下面通过一个实例来演示 SQLite3 的使用方法。

(1)新建一个数据库

     新建数据库 test.db(使用.db 后缀是为了标识数据库文件)。在 test.db 中新建一个表test_table,该表具有 name,、sex、age 三列。SQLite3 的具体操作如下所示:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1.  [root@localhost home]# sqlite3 test.db  
  2. SQLite version 3.6.12  
  3. Enter ".help" for instructions  
  4. Enter SQL statements terminated with a ";"  
  5. sqlite> create table test_table(name, sex, age);  


    如果数据库 test.db 已经存在,则命令“sqlite3 test.db”会在当前目录下打开 test.db。如果数据库 test.db 不存在,则命令“sqlite3 test.db”会在当前目录下新建数据库 test.db。为了提高效率,SQLite3 并不会马上创建 test.db,而是等到第一个表创建完成后才会在物理上创建数据库。

    由于 SQLite3 能根据插入数据的实际类型动态改变列的类型,所以在 create 语句中并不要求给出列的类型。

(2)创建索引

     为了加快表的查询速度,往往在主键上添加索引。如下所示的是在 name 列上添加索引的过程。

sqlite> create index test_index on test_table(name);

(3)操作数据

   如下所示的是在 test_table 中进行数据的插入、更新、删除操作:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. sqlite> insert into test_table values ('xiaoming', 'male', 20);  
  2. sqlite> insert into test_table values ('xiaohong', 'female', 18);  
  3. sqlite> select * from test_table;  
  4. xiaoming|male|20  
  5. xiaohong|female|18  
  6. sqlite> update test_table set age=19 where name = 'xiaohong';  
  7. sqlite> select * from test_table; 258  
  8. xiaoming|male|20  
  9. xiaohong|female|19  
  10. sqlite> delete from test_table where name = 'xiaoming';  
  11. sqlite> select * from test_table;  
  12. xiaohong|female|19  


 

(4)批量操作数据库

如下所示的是在 test_table 中连续插入两条记录:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. sqlite> begin;  
  2. sqlite> insert into test_table values ('xiaoxue', 'female', 18);  
  3. sqlite> insert into test_table values ('xiaoliu', 'male', 20);  
  4. sqlite> commit;  
  5. sqlite> select * from test_table;  
  6. xiaohong|female|19  
  7. xiaoxue|male|18  
  8. xiaoliu|male|20  


运行命令 commit 后,才会把插入的数据写入数据库中。

 

(5)数据库的导入导出

 如下所示的是把 test.db 导出到 sql 文件中:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [root@localhost home]# sqlite3 test.db ".dump" > test.sql;  
  2. test.sql 文件的内容如下所示:  
  3. BEGIN TRANSACTION;  
  4. CREATE TABLE test_table(name, sex, age);  
  5. INSERT INTO "test_table" VALUES('xiaohong','female',19);  
  6. CREATE INDEX test_index on test_table(name);  
  7. COMMIT;  


如下所示的是导入 test.sql 文件(导入前删除原有的 test.db):

[root@localhost home]# sqlite3 test.db < test.sql;

通过对 test.sql 文件的导入导出,可以实现数据库文件的备份。

 

11.2.2 SQLite3 的 C 接口

 以上介绍的是 SQLite3 数据库的命令操作方式。在实际使用中,一般都是应用程序需要对数据库进行访问。为此,SQLite3 提供了各种编程语言的使用接口(本书介绍 C 语言接口)。SQLite3 具有几十个 C 接口,下面介绍一些常用的 C 接口。

(1)sqlite_open

作用:打开 SQLite3 数据库

原型:int sqlite3_open(const char *dbname, sqlite3 **db)

参数: dbname:数据库的名称;

           db:数据库的句柄;

 

(2)sqlite_colse

作用:关闭 SQLite3 数据库

原型:int sqlite_close(sqlite3 *db)

例如: test.c:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <sqlite3.h>  
  3. static      sqlite3 *db=NULL;  
  4.    
  5. int main()  
  6. {  
  7.      int rc;  
  8.      rcsqlite3_open("test.db", &db);  
  9.        
  10.      if(rc)  
  11.      {  
  12.         printf("can't open database!\n");  
  13.      }  
  14.      else 260  
  15.      {  
  16.         printf("open database success!\n");  
  17.      }  
  18.    
  19.      sqlite3_close(db);  
  20.      return 0;  
  21. }  


运行命令“gcc –o test test.c –lsqlite3”进行编译,运行 test 的结果如下所示:

[root@localhost home]# open database success!

(3) sqlite_exec

作用:执行 SQL 语句

原型:int sqlite3_exec(sqlite3 *db, const char *sql, int (*callback)(void*,int,char**,char**),

      void *, char **errmsg)

参数: db:数据库;

       sql:SQL 语句;

   callback:回滚;

   errmsg :错误信息

   

例如:test.c:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <sqlite3.h>  
  3.    
  4. static   sqlite3 *db=NULL;  
  5. static char *errmsg=NULL;  
  6.    
  7. int main()  
  8. {  
  9.      int rc;  
  10.    
  11.      rc = sqlite3_open("test.db", &db);  
  12.      rc = sqlite3_exec(db,"insert into test_table values('daobao', 'male', 24)", 0, 0, &errmsg);  
  13.    
  14.      if(rc)  
  15.      {  
  16.         printf("exec fail!\n");  
  17.      }  
  18.      else  
  19.      {  
  20.         printf("exec success!\n");  
  21.      }  
  22.    
  23.      sqlite3_close(db);  
  24.      return 0; 261  
  25. }  


编译完成后,运行 test 的结果如下所示:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [root@localhost home]# ./test  
  2. exec success!  
  3. [root@localhost home]# sqlite3 test.db  
  4. SQLite version 3.6.11  
  5. Enter ".help" for instructions  
  6. Enter SQL statements terminated with a ";"  
  7. sqlite> select * from test_table;  
  8. daobao|male|24  


(4)sqlite3_get_table

作用:执行 SQL 查询

原型:int sqlite3_get_table(sqlite3 *db,  const char *z Sql, char ***paz Result,  int  *pn Row,              int *pn Column, char **pz Errmsg)

参数:db:数据库;

      z Sql:SQL 语句;

      paz Result:查询结果集;

      pn Row:结果集的行数;

      pn Column:结果集的列数;

      errmsg:错误信息;

 

(5)sqlite3_free_table

作用:注销结果集

 

原型:void sqlite3_free_table(char **result)

参数:result:结果集;

例如: test.c:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <sqlite3.h>  
  3.    
  4. static   sqlite3 *db=NULL;  
  5. static char **Result=NULL;  
  6. static char *errmsg=NULL;  
  7.    
  8. int main()  
  9. {  
  10.     int rc, i, j;  
  11.     int nrow;  
  12.     int ncolumn;  
  13.    
  14.     rcsqlite3_open("test.db", &db);  
  15.     rcsqlite3_get_table(db, "select * from test_table", &Result, &nrow, &ncolumn,    
  16. &errmsg);  262  
  17.    
  18.      if(rc)  
  19.      {  
  20.         printf("query fail!\n");  
  21.      }  
  22.      else  
  23.      {  
  24.         printf("query success!\n");  
  25.         for(i = 1; i <= nrow; i++)  
  26.         {  
  27.            for(j = 0; j < ncolumn; j++)  
  28.            {  
  29.               printf("%s | ", Result[i * ncolumn + j]);  
  30.            }  
  31.            printf("\n");  
  32.         }  
  33.      }  
  34.    
  35.      sqlite3_free_table(Result);  
  36.      sqlite3_close(db);  
  37.      return 0;  
  38. }  


编译完成后,运行 test 的结果如下所示:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [root@localhost home]# ./test  
  2. query success!  
  3. xiaohong | female | 19 |  
  4. xiaoxue | female | 18 |  
  5. xiaoliu | male | 20 |  
  6. daobao | male | 24 |  


(6)sqlite3_prepare

作用:把 SQL 语句编译成字节码,由后面的执行函数去执行

原型:int sqlite3_prepare(sqlite3 *db, const char *z Sql, int n Byte, sqlite3_stmt **stmt, const

char **p Tail)

参数:db:数据库;

      z Sql:SQL 语句;

      n Byte:SQL 语句的最大字节数;

      stmt:Statement 句柄;

      p Tail:SQL 语句无用部分的指针;

 

(7)sqlite3_step

作用:步步执行 SQL 语句字节码

原型:int sqlite3_step (sqlite3_stmt *)

例如: test.c:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <sqlite3.h>  
  3.    
  4. static   sqlite3 *db=NULL;  
  5. static   sqlite3_stmt *stmt=NULL;  
  6.    
  7. int main()  
  8. {  
  9.      int rc, i, j;  
  10.      int ncolumn;  
  11.    
  12.      rcsqlite3_open("test.db", &db);  
  13.      rc=sqlite3_prepare(db,"select * from test_table",-1,&stmt,0);  
  14.    
  15.      if(rc)  
  16.      {  
  17.         printf("query fail!\n");  
  18.      }  
  19.      else  
  20.      {  
  21.         printf("query success!\n");  
  22.         rc=sqlite3_step(stmt);  
  23.         ncolumn=sqlite3_column_count(stmt);  
  24.         while(rc==SQLITE_ROW)  
  25.         {  
  26.            for(i=0; i<2; i++)  
  27.            {  
  28.                printf("%s | ", sqlite3_column_text(stmt,i));  
  29.            }  
  30.            printf("\n");  
  31.            rc=sqlite3_step(stmt);  
  32.         }  
  33.      }  
  34.    
  35.      sqlite3_finalize(stmt);  
  36.      sqlite3_close(db);  
  37.      return 0;  
  38. }  


编译完成后,运行 test 的结果如下所示:

[html]   view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [root@localhost home]# ./test  
  2. query success!  
  3. xiaohong | female | 19 |  
  4. xiaoxue | female | 18 |  
  5. xiaoliu | male | 20 |  


在程序中访问 SQLite3 数据库时,要注意 C API 的接口定义和数据类型是否正确,否则会得到错误的访问结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值