-----------------------
为什么要使用数据库呢?
-----------------------
我个人的理由就是:我喜欢用简单统一的SQL语句实现复杂的数据处理。
回顾计算机发展的历史,数据处理经历了:人工管理、文件管理和数据库管理三个阶段。早期的数据和程序不具有独立性,一组数据对应一组程序,如果数据存储发生了一些变化,就必须修改程序,而且各种程序中的数据会有大量重复。现代的数据库系统比文件系统更加先进:1、数据是结构化的,相互之间存在关联,冗余度小,从而更能适应大量数据管理的客观需要;2、数据可以由多个用户共享,数据库保证其完整性、安全性和并发性;3、数据具有独立性,当存储结构改变时,逻辑结构可以不变,进而,对应的应用程序也不必修改。这使得应用程序的维护工作大大简化。
数据库比普通文件更适合于表达数据量大,且在数据之间存在着复杂联系的应用系统。一般,关系数据库常用非过程化的命令或语言,不仅使应用程序的长度较传统的应用系统大为缩短,而且明显提高了应用程序的开发效率。
使用数据库肯定会带来很多好处,尤其是应用程序的开发速度大大提高了,稳定性也好,不过,嵌入式系统内存和性能受限,不能直接使用桌面系统上现成的大型数据库,因此,现在出现了很多轻量级,速度很快的嵌入式数据库,sqlite就是其中一个不错的选择。
------------
sqlite简介
------------
SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎。它是完全独立的,不具有外部依赖性。它是作为PHP V4.3中的一个选项引入的,构建在PHP V5中。SQLite支持多数SQL92标准,可以在所有主要的操作系统上运行,并且支持大多数计算机语言。SQLite还非常健壮。其创建者保守地估计SQLite可以处理每天负担多达10000次点击率的Web站点,并且SQLite有时候可以处理10倍于上述数字的负载。
在功能上,SQLite对SQL92标准的支持包括索引、限制、触发和查看。SQLite不支持外键限制,但支持原子的、一致的、独立和持久 (ACID) 的事务。SQLite支持大小高达2TB的数据库,每个数据库完全存储在单个磁盘文件中。这些磁盘文件可以在不同字节顺序的计算机之间移动。这些数据以B+树(B+tree)数据结构的形式存储在磁盘上。SQLite 根据该文件系统获得其数据库权限。
----------------
sqlite使用手册
----------------
数据库的大量操作一般是对数据的存储、查询、检索、修改以及安全保护等等,SQL语言抽象了这些处理请求为非过程化的命令或语言,使得数据处理过程变得简单统一。
建立数据库档案
用sqlite3建立数据库的方法很简单,只要在shell下键入(以下$符号为shell提示号,请勿键入):
$ sqlite3 foo.db
如果目录下没有foo.db,sqlite3就会建立这个数据库。sqlite3并没有强制数据库档名要怎么取,因此如果你喜欢,也可以取个例如foo.icannameitwhateverilike的档名。
在sqlite3提示列下操作
进入了sqlite3之后,会看到以下文字:
SQLite version 3.1.3Enter ".help" for instructionssqlite>
这时如果使用.help可以取得求助,.quit则是离开(请注意:不是quit)
SQL的指令格式
所以的SQL指令都是以分号(;)结尾的。如果遇到两个减号(--)则代表注解,sqlite3会略过去。
建立资料表
假设我们要建一个名叫film的资料表,只要键入以下指令就可以了:
create table film(title, length, year, starring);
这样我们就建立了一个名叫film的资料表,里面有name、length、year、starring四个字段。
这个create table指令的语法为:
create table table_name(field1, field2, field3, ...);
table_name是资料表的名称,fieldx则是字段的名字。sqlite3与许多SQL数据库软件不同的是,它不在乎字段属于哪一种资料型态:sqlite3的字段可以储存任何东西:文字、数字、大量文字(blub),它会在适时自动转换。
建立索引
如果资料表有相当多的资料,我们便会建立索引来加快速度。好比说:
create index film_title_index on film(title);
意思是针对film资料表的name字段,建立一个名叫film_name_index的索引。这个指令的语法为
create index index_name on table_name(field_to_be_indexed);
一旦建立了索引,sqlite3会在针对该字段作查询时,自动使用该索引。这一切的操作都是在幕后自动发生的,无须使用者特别指令。
加入一笔资料
接下来我们要加入资料了,加入的方法为使用insert into指令,语法为:
insert into table_name values(data1, data2, data3, ...);
例如我们可以加入
insert into film values ('Silence of the Lambs, The', 118, 1991, 'Jodie Foster');insert into film values ('Contact', 153, 1997, 'Jodie Foster');insert into film values ('Crouching Tiger, Hidden Dragon', 120, 2000, 'Yun-Fat Chow');insert into film values ('Hours, The', 114, 2002, 'Nicole Kidman');
如果该字段没有资料,我们可以填NULL。
查询资料
讲到这里,我们终于要开始介绍SQL最强大的select指令了。我们首先简单介绍select的基本句型:
select columns from table_name where expression;
最常见的用法,当然是倒出所有数据库的内容:
select * from film;
如果资料太多了,我们或许会想限制笔数:
select * from film limit 10;
或是照着电影年份来排列:
select * from film order by year limit 10;
或是年份比较近的电影先列出来:
select * from film order by year desc limit 10;
或是我们只想看电影名称跟年份:
select title, year from film order by year desc limit 10;
查所有茱蒂佛斯特演过的电影:
select * from film where starring='Jodie Foster';
查所有演员名字开头叫茱蒂的电影('%' 符号便是 SQL 的万用字符):
select * from film where starring like 'Jodie%';
查所有演员名字以茱蒂开头、年份晚于1985年、年份晚的优先列出、最多十笔,只列出电影名称和年份:
select title, year from film where starring like 'Jodie%' and year >= 1985 order by year desc limit 10;
有时候我们只想知道数据库一共有多少笔资料:
select count(*) from film;
有时候我们只想知道1985年以后的电影有几部:
select count(*) from film where year >= 1985;
(进一步的各种组合,要去看SQL专书,不过你大概已经知道SQL为什么这么流行了:这种语言允许你将各种查询条件组合在一起──而我们还没提到「跨数据库的联合查询」呢!)
如何更改或删除资料
了解select的用法非常重要,因为要在sqlite更改或删除一笔资料,也是靠同样的语法。
例如有一笔资料的名字打错了:
update film set starring='Jodie Foster' where starring='Jodee Foster';
就会把主角字段里,被打成'Jodee Foster'的那笔(或多笔)资料,改回成Jodie Foster。
delete from film where year < 1970;
就会删除所有年代早于1970年(不含)的电影了。
其他sqlite的特别用法
sqlite可以在shell底下直接执行命令:
sqlite3 film.db "select * from film;"
输出 HTML 表格:
sqlite3 -html film.db "select * from film;"
将数据库「倒出来」:
sqlite3 film.db ".dump" > output.sql
利用输出的资料,建立一个一模一样的数据库(加上以上指令,就是标准的SQL数据库备份了):
sqlite3 film.db < output.sql
在大量插入资料时,你可能会需要先打这个指令:
begin;
插入完资料后要记得打这个指令,资料才会写进数据库中:
commit;
----------
应用范例
----------
下面是一个简单范例,用于说明如何用C/C++和sqlite函数库接口。
#include
#include
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
int i;
for(i=0; i printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
int main(int argc, char **argv){
sqlite3 *db;
char *zErrMsg = 0;
int rc;
if( argc!=3 ){
fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
exit(1);
}
rc = sqlite3_open(argv[1], &db);
if( rc ){
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
sqlite3_close(db);
return 0;
}
注解:
sqlite3_open()打开数据库“/home/testdb.db”;
sqlite3_exec()执行针对该数据库的SQL命令;
sqlite3_close()关闭数据库连接。
运行make编译测试程序,生成的程序大小约300KB:
接着将测试程序下载到目标板,测试运行结果如下:
# /home/sqlitetest /home/testdb.db "CREATE TABLE my_table(id int, name varchar(20))"
# /home/sqlitetest /home/testdb.db "INSERT INTO my_table values(1, 'jianglj')"
# /home/sqlitetest /home/testdb.db "INSERT INTO my_table values(2, 'Hily Jiang')"
# /home/sqlitetest /home/testdb.db "SELECT * FROM my_table"
id = 1
name = jianglj
id = 2
name = Hily Jiang
#
----------
论坛实例
----------
论坛数据库的建立可以使用DOS下的命令行接口数据库管理工具。
例如:
1、创建新的数据库和表
c:\t>sqlite3 c:\t\yy.db
SQLite version 3.2.1
Enter ".help" for instructions
sqlite> create table mytable(name varchar(40), age smallint);
sqlite> insert into mytable values('Nils-Erik',23);
sqlite> select * from mytable;
Nils-Erik|23
sqlite>
然后,可以再次打开该数据库,列出它的表和架构,并继续进行插入和删除值的操作。
2、列出表和架构
c:\t>sqlite3 c:\t\yy.db
SQLite version 3.2.1
Enter ".help" for instructions
sqlite> .tables
mytable
sqlite> select * from mytable;
Nils-Erik|23
sqlite> .schema
CREATE TABLE mytable(name varchar(40), age smallint);
sqlite>
图1、图2、图3是通过GUI图形数据库管理工具查看yy.db的效果。
通过命令行/GUI数据库管理工具,我们可以在PC机上创建一个论坛数据库,就象创建access数据库那样,把表格构造好,这样一个空白的数据库bbs.db就做好了,然后将其保存在CF/SD卡上,在CGI程序里使用sqlite的C/C++接口操作此数据库,就可以把论坛移植到EASYARM2200/SMARTARM2200开发板上了。本站论坛的数据关系不在此详细列出,感兴趣的朋友可以参照上的论坛自行实现,或者参照开源的ASP代码做个留言板也不错。