一二章请点击:网络编程_1(网络基础+跨主机传输)
三四章请点击:网络编程_2(网络属性+UDP(UDP模型+广播组播))
第五章请点击:网络编程_3(TCP)
第六章请点击:网络编程_4(IO模型)
七八九十章请点击:网络编程_5(超时检测+UNIX域套接字+抓包工具+包头分析)
十一、数据库
1、数据库基本概念
1.1数据(Data)
能够输入计算机并能被计算机程序识别和处理的信息集合
1.2数据库 (Database)
数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合
1.3常用的数据库
1)大型数据库
Oracle公司是最早开发关系数据库的厂商之一,其产品支持最广泛的操作系统平台。目前Oracle关系数据库产品的市场占有率名列前茅。
IBM 的DB2是第一个具备网上功能的多媒体关系数据库管理系统,支持包Linux在内的一系列平台。
中型数据库
Server是微软开发的数据库产品,主要支持windows平台。
2)小型数据库
mySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司,2008年被Sun公司收购,开放源码。
3)基于嵌入式的数据库
基于嵌入式Linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB
Firebird是关系型数据库,功能强大,支持存储过程、SQL兼容等
SQLite关系型数据库,体积小,支持ACID事务
Berkeley DB中并没有数据库服务器的概念,它的程序库直接链接到应用程序中
eXtremeDB是内存数据库,运行效率高
1.4SQLite基础
www.sqlite.org
SQLite的源代码是C,其源代码完全开放。SQLite第一个Alpha版本诞生于2000年5月。 他是一个轻量级的嵌入式数据库。
SQLite有以下特性:
零配置一无需安装和管理配置;
储存在单一磁盘文件中的一个完整的数据库;
数据库文件可以在不同字节顺序的机器间自由共享;
支持数据库大小至2TB;
足够小,全部源码大致3万行c代码,250KB;
比目前流行的大多数数据库对数据的操作要快;
安装方式
本地安装数据库方法:
1.将“数据库Linux安装文件”中的三个安装包拷贝到虚拟机中
2.在放置三个安装包的位置,运行 sudo dpkg -i * .deb在线安装方式:
1.确保虚拟机能联网
2.更新更新源
sudo apt-get update
3、安装软件及开发环境
apt-get install sqlite3 —>sqlite3数据库软件
apt-get install libsqlite3-dev —>sqlite3数据库开发支持库
apt-get install libsqlite3-doc —>sqlite3数据库说明文档 /usr/share/doc/sqlite3 或 /usr/share/doc/sqlite3-doc
apt-get install sqlitebrowser —>sqlite3数据库操作软件
安装成功后,终端输入以下指令,判断是否安装成功:
linux@linux:~$ sqlite3 出现下列语句,标识安装成功 SQLite version 3.7.2 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> 输入 .quit退出数据库 linux@linux:~$ sqlite3 SQLite version 3.7.2 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .quit linux@linux:~$
2.sqlite3命令语句
SQLITE3不区分大小写;
1.sqlite创建数据库
$ sqlite3 sq.db
如果sq.db存在就是打开,如果不存在则会创建sq.db;
显示下面的内容则说明创建成功
SQLite version 3.7.2
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
2.系统命令
.命令不需要以‘;’结尾
都是以点开头,也叫做点命令
.header on //显示表头; .header off
.mode column //对齐
.timer on //显示时间 .timer off
.help 显示帮助信息,获取所有的系统命令
.quit 退出数据库
.exit 退出数据库
.table 查看当前数据库下的所有表格
.databases 显示当前打开的数据库文件
.schema 查看表的结构
.schema test
3.sql语句
注意:sql语句都是以分号结尾的;
1)创建表格
create table 表名(字段 类型,字段 类型);
create table if not exists 表名(字段 类型,字段 类型);
例子:
sqlite> create table test(id int, name char, sex char, score float);
sqlite> create table if not exists test(id int, name char, sex char, score float);
注意:不支持严格的类型检查,数据类型写错了,也能创建成功,不会有错误提示。
2)删除表格
drop table 表名;
sqlite> drop table test2;
删除表格后,表中的数据也会一并删除。
3)插入记录
1)全字段插入;
insert into 表名 values (数据1,数据2,数据3,数据4);
sqlite> insert into test values(1, "zhangsan", 'F', 90);
sqlite> select * from test; //查看
注意:
1.数据的顺序需要与创建表格时候的字段顺序一致;
2.字符串可以使用单引号也可使用双引号;
2)部分字段插入;
insert into 表名(字段1, 字段2)values(数据1,数据2);
sqlite> insert into test(name, sex) values('lisi', 'M');
注意:
1.数据的顺序要与前面的(字段1, 字段2)一致;
4)查看记录
1)查看所有记录
select * from 表名;
sqlite> select * from test;
2)按条件筛选:(查看某几行)
select * from 表名 where 限制条件;
sqlite> select * from test where score>80;
and or
sqlite> select * from test where score<90 and score>60;
sqlite> select * from test where score>=90 or score<70;
sqlite> select * from test where name='zhangsan' and score=90;
3)查询指定字段:(查看某几列)
select 字段1,字段2 from 表名;
select 字段1,字段2 from 表名 where 限制条件;
sqlite> select name, sex from test;
sqlite> select name, sex from test where score>60 and score<90;
5)更新记录
update 表名 set 字段=数值 where 字段=数值;
sqlite> UPDATE test set score=85 where name='lisi';
sqlite> UPDATE test SET id=2 where name='lisi' and score=85;
6)删除行
delete from 表名 where 字段=数值;
sqlite> delete from test where id=2 and name='lisi';
删除表中所有记录;
sqlite> delete from test;
7)增加列
alter table 表名 add column 字段名 类型;
sqlite> alter table test add column age int;
8)修改表名
alter table 老表名 rename to 新表名;
sqlite> alter table test rename to stu; //将test修改成stu
9)修改列名(字段名)
不支持直接修改列名
1.将表重新命名(a改成b)
alter table a rename to b;
2.新建修改字段后的表(新建一个a)
create table a (id1 int, name char, sex char, score float, age int);
3.从旧表b中取出数据,插入到新表a中;
insert into a select * from b;
sqlite> alter table stu rename to stuinfo;
sqlite> create table stu(id1 int, name char, sex char, score float, age int);
sqlite> insert into stu select * from stuinfo;
10)删除列
不支持直接删除列;
1.创建一个新表b,并复制旧表a需要保留的字段信息;
create table b as select id1, name, score from a;
2.删除旧表a
drop table a;
3.修改新表b的名字a
alter table b rename to a;
sqlite> create table stu1 as select id1, name, score from stu;
sqlite> drop table stu;
sqlite> alter table stu1 rename to stu;
11)主键(primary key)
primary key //主键;
create table 表名(字段名 类型 primary key, 字段名 类型);
primary key 主键:唯一标识表格中的每一条记录;
例如id字段为主键,当表格中有id==1的记录时,不允许再插入id为1的记录了;
注意:主键的值必须唯一,每一个表格应该都设置一个主键,而且只能设置一个;
12)附加指令
i)排序
select * from 表名 order by 列名 asc; //升序 asc可以忽略;
select * from 表名 order by 列名 desc; //降序
ii)求和
select sum(列名) as sumvalue from 表名;
iii)求平均值
select avg(列名) as avgvalue from 表名;
iv)求最大/最小值
select max(列名) as maxvalue from 表名;
select min(列名) as minvalue from 表名;
3.sqlite3 APIs
头文件:
#include <sqlite3.h>
编译时候需要加上 -lsqlite3
gcc .c文件 -lsqlite3
1. sqlite3_open
功能:打开或创建数据库;
原型:
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
参数:
char *filename:数据库的路径+数据库名;
sqlite3 **ppDb:sqlite句柄指针,存储打开的数据库地址;
返回值:
成功,返回0/SQLITE_OK;
失败,返回错误码(非0值);
例子:
sqlite3 * db = NULL;
int ret = sqlite3_open("./sq.db", &db);
2. sqlite3_close
功能:关闭数据库;
原型:
int sqlite3_close(sqlite3* db);
参数:
sqlite3* db:指定要关闭的数据库句柄;
返回值:
成功,返回0,SQLITE_OK;
失败,返回错误码(非0值);
例子:
sqlite3_close(db);
3. sqlite3_errmsg
功能:通过错误码获取错误信息,一般放在打开数据库失败后;
原型:
const char *sqlite3_errmsg(sqlite3*db);
参数:
sqlite3*db:句柄指针,存储打开失败的数据库地址;
返回值:
返回错误码对应的错误信息;
例子:
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
4. sqlite3_exec
功能:执行一条sql语句;
原型:
int sqlite3_exec(
sqlite3* db, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *arg, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
参数:
sqlite3* db:数据库句柄指针,要操作的数据库;
const char *sql:sql语句;
int (*callback)(void*,int,char**,char**):回调函数,可以指向 int func(void*, int, char**, char**);
注意:只有在查询sql语句时候使用;
void *arg:传入给回调函数的参数;
char **errmsg:错误信息;
返回值:
成功,返回0;SQLITE_OK;
失败,返回错误码,非0参数;
回调函数
回调函数:只有在查询的时候使用;
int callback(void* arg,int f_num, char** f_value,char** f_name);
功能:每找到一条记录就会自动执行一次该函数;
参数:
void* arg:传递给回调函数的参数;
int f_num:查询结果的列数(字段数);
char** f_value:该指针指向存储查询结果的指针数组;
例子: id name score;
f_value[0] = "1" //id
f_value[1] = "zhangsan" //name
f_value[2] = "90.0" ; //score;
for(i=0; i<f_num; i++)
{
printf("%s ",f_value[i]);
}
char** f_name:该指针指向存储字段名的指针数组;
例子: id name score;
f_name[0] = "id";
f_name[1] = "name";
f_name[2] = "score";
#include <sqlite3.h>
#include <stdio.h>
#include <string.h>
int callback(void* arg, int f_num, char** f_value, char** f_name);
int main(int argc, const char *argv[])
{
//创建并打开数据库
sqlite3 * db = NULL;
int ret = sqlite3_open("./sq.db", &db);
if(ret != 0)
{
fprintf(stderr, "数据库打开失败\n");
//打印错误信息
fprintf(stderr, "%s\n", sqlite3_errmsg(db));
return -1;
}
printf("数据库打开成功\n");
char sql[256] = "";
char *errmsg = NULL;
//创建表
bzero(sql, sizeof(sql));
// sprintf(sql, "create table if not exists stu(id int primary key, name char, score float )");
sprintf(sql, "create table if not exists stu(id int, name char, score float )");
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg)!=0)
{
fprintf(stderr, "sqlite3_exec:%s\n", errmsg);
goto END;
}
printf("创建表格成功\n");
//插入数据
int i = 0;
for(i=1; i<4; i++)
{
bzero(sql, sizeof(sql));
sprintf(sql, "insert into stu values(%d, \"zs\", 90)", i);
if(sqlite3_exec(db, sql, NULL, NULL, &errmsg)!=0)
{
fprintf(stderr, "sqlite3_exec:%s\n", errmsg);
goto END;
}
}
printf("插入数据成功\n");
//查询数据
bzero(sql, sizeof(sql));
sprintf(sql, "select * from stu");
int flag = 1;
if(sqlite3_exec(db, sql, callback, &flag, &errmsg) !=0)
{
fprintf(stderr, "sqlite3_exec:%s\n", errmsg);
goto END;
}
printf("查询数据成功\n");
END:
//关闭数据库
if(sqlite3_close(db) != 0)
{
fprintf(stderr, "数据库关闭失败\n");
return -1;
}
return 0;
}
//回调函数
int callback(void* arg, int f_num, char** f_value, char** f_name)
{
int i = 0;
if(1 == *(int*)arg) //防止表头重复打印
{
for(i=0 ;i<f_num; i++)
{
printf("%-10s", f_name[i]); //打印字段名
}
putchar(10);
*(int*)arg = 0; //通过指针的方式间接访问 修改flag
}
for(i=0; i<f_num; i++)
{
printf("%-10s", f_value[i]); //打印查到的数据
}
putchar(10);
return 0;
}
5. sqlite3_get_table
功能:查询数据,获取表格数据;
原型:
int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
int *pnRow, /* Number of result rows written here */
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
参数:
sqlite3 *db:句柄指针,存储打开的数据库
const char *zSql:sql语句,**只能填写查询相关的sql语句**;
char *** pResult:用来指向sql执行结果的指针,包括表头的数据,需要手动释放。
由函数将查询到的结果放到指针数组
指针数组保存结果字符串首地址,包括表头;
int *pnRow:满足条件的记录条数(行数);
int *pnColumn:满足条件的字段数(列数);
char **pzErrmsg:错误信息;
返回值:
成功,返回0,SQLITE_OK;
失败,返回错误码,非0参数;
释放空间:
void sqlite3_free_table(char **result);