网络编程5-数据库、sqlite3数据库
一、基本概念
1、信息:
是指对现实世界存在方式或运动状态的反映
2、数据:
存储于某一媒体、可被识别的物理符号”,范畴不仅包含字符构成的文本数据,还涵盖了音频、视频等其他类型的数据
3、信息与数据的关系:
信息与数据是相互依赖存在的,数据是信息的载体,信息是数据的内涵
4、数据库:
本质:"数据模型"(如表格、文档、图结构)对数据进行规范化组织,确保数据的关联性、一致性和可管理性。
核心价值:相比本地文件(如 Excel、TXT),数据库能支持多用户同时访问、复杂条件查询(如 “筛选近 30 天某地区的订单”)、数据备份与恢复,且能避免数据重复或冲突
数据->集合起来->整理归纳->形成的数据仓库
5、数据库管理系统
- 实际是个软件
- 数据库管理员
- 数据库应用软件
- 操作系统
- 数据库模型分类
- 关系数据库--常用
- 管理数据——管理一张张表类excel表
- 非关系数据库
- 关系数据库--常用
- 常见的数据库
- ORACLE(适用于大型、中型和微型计算机)
Mysql(开放源码的小型关系型)
- SQL server(微软 Microsoft 出品,客户机/服务器体系结构)
- Access(微软,一种桌面数据库,只适合数据量少的应用)
- Sybase
- SQLite(一个开源的、内嵌式、微型数据库)
二、SQLite3数据库
1、基础操作
(1)终端进入命令:
sqlite3 //进入数据库中(l临时数据库)
(2)sqlite3 的命令
以“.”开头(执行此些命令不能省略“.”)
帮助
.help //查看各种sqlite3 的命令
显示/查看
.databases //显示当前在操作哪个数据库文件
.tables //可以看到表的名字
.schema //可以看到表的 字段(定义的表头).mode //输出模式的选择(查询表时的显示设置)
查询时
.headers on //打开表头
.mode column //指定查询的输出格式 以列对齐的方式退出
.quit
.exit
eg:.databases
eg:查看表头
eg:
(3)创建数据库
sqlite3 xxx.db //数据库文件后缀 “.db” -->创建/打开xxx.db数据库
2、sql 语句
(1)创建一张表
普通创建
create table stu (name,sex,age,score);
有类型的创建
create table stu1 (name text,sex text,age int,score real);create table user1(id int,name char,age int,dt datetime);
自动增长列的创建
create table user3(id INTEGER PRIMARY KEY ASC,name char,age int,dt datetime);
//id这列插入是的值为NULL,便可以实现自动增长
(2)向表插入数据
创建好的表://(name,sex,age,score);
插入数据的语法
insert into 表名 values ("tom","male",19,99.5);
全部列都给到
insert into stu values ("tom","male",19,99.5);
给部分列插入数据insert into stu (name,sex) values ("jack","male");
向表中插入时间列
unicode
CREATE TABLE user1(id int,name char,age int,dt datetime);
eg:
insert into user1 values (2,'张三',23,datetime('now','+8 hours'));
(3)删除表/表中数据
删除表中满足指定条件的部分记录(行)没懂
delete from 表名 where 条件;
eg:delete from students where age < 18 删除students表中所有年龄小于 18 岁的学生记录
完全删除整个表
drop table 表名称;
(4)修改表/表中数据
修改表的名称 或者 向表中添加新的字段(表头内容)(aql大小写不区分)
ALTER TABLE database_name.table_name RENAME TO new_table_name;
alter table database_name.table_name RENAME TO new_table_name;
向表中添加
alter table 表名 add 列名;修改表中的数据:
update 表名 set 列1=值1 [, 列2 = 值2, ...] [匹配条件];eg:sqlite> select * from user;
id|name|age
1|s|1修改内容
update user set name = 'name_abc',age = 20 where id = 1;
(5)查询表/表中数据
限制查询条件的语句
条件语句:
where 字句
where 列名 操作符 列值
where age > 10查询语句
select 列名1,列名2,... from 表名;
具体查询方式
1.查询部分字段
select name from stu where score>80;
2.in语句
select * from stu where age in(18,19);
3.and语句 //多个条件
select * from stu where age > 18 and score > 80;
4.or语句
select * from stu where age > 18 or score > 80;
5. 范围 between ... and ...
select * from stu where age between 19 and 20;
6. like
select * from stu where name like "tom";
select * from stu where name like "%tom%"; //% 表示匹配任意多个字符
select * from stu where name like "_tom_"; //_ 表示匹配任意一个字符
7. order by
select * from user where age >= 18 order by age;
select * from user where age >= 18 order by age limit 2;
条件语句的条件:
eg:
(6)注意事项
- 编译时 要链接库文件 :gcc test_sqlite3.c -lsqlite3
- 关系型数据库 ---管理数据---管理的是一张张的表
3、相关函数接口
(1)sqlite3_open 打开数据库
函数原型:int sqlite3_open(char *db_name,sqlite3 **db);
功能: 打开数据库
参数:
db_name: 数据库文件名,若文件名包含 ASCII 码表范围的之外的字符,则其必需是(UTF-8)编码。
db:数据库标识,此结构体为数据库操作句柄。通过此句柄可对数据库文件进行相应操作。返回值:
成功返回 SQLITE_OK,
失败返回 非SQLITE_OK打印错误信息:printf("%s\n", errmsg
例:
sqlite3 *db;
int ret = sqlite3_open("stu.db",&db);
if (ret != SQLITE_OK)
{printf("sqlite3_get_table fail:%s\n", errmsg);
return -1;
}
(2)sqlite3_exec 执行相关的sql语句
功能介绍:
- 可以执行各种类型的 SQL 语句,包括查询(SELECT)、插入(INSERT)、更新(UPDATE)、删除(DELETE)等
- 对于查询语句,它能通过回调函数处理返回的结果集
- 对于非查询语句,它直接执行并返回执行结果状态
sqlite3_exec
函数原型:int sqlite3_exec( sqlite3 *db,
const char *sql,
exechandler_t callback,
void *arg,
char **errmsg
);功能:执行 sql 指向的 SQL 语句,
若结果集不为空,函数会调用函数指针 callback 所指向的函数
参数:
db:数据库的连接句柄,数据库的标识
sql:SQL 语句(一条或多条),以’;’结尾
callback:是回调函数指针,当这条语句执行后,sqlite3 会去调用你写好的函数
arg:当执行 sqlite3_exec 的时候传递给回调函数的参数
errmsg:存放错误信息的地址,执行失败后可以查阅这个指针
返回值:
成功返回 SQLITE_OK,
失败返回 非SQLITE_OK
回调函数指针:
typedef int (*exechandler_t)(void *para,
int n_column,
char **column_value,
char **column_name
);功能:此函数由用户定义,当 sqlite3_exec 函数执行 sql 查询语句后
结果集不为空(NULL代表空的意思,与c语言中指针的NULL意思不同)时
sqlite3_exec 函数会自动调用此函数,每次调用此函数时会把结果集的一行信息传给此函数
参数:
para: sqlite3_exec 传给此函数的参数,para 为任意数据类型的地址
n_column: 结果集的列数
column_value: 指针数组的地址,其存放一行信息中各个列值的首地址
column_name:指针数组的地址,其存放一行信息中各个列值对应列名的首地址
返回值:回调函数返回 0 表示继续处理下一行,返回非 0 表示中止查询
int (*sqlite3_callback)(
void *arg, /* 由sqlite3_exec传递的用户数据 */
int column_count, /* 列数 */
char **column_values, /* 列值数组 */
char **column_names /* 列名数组 */
);
示例:
简单插入函数实现
sqlite3 *db;
char *err_msg = 0;
int rc = sqlite3_open("test.db", &db);
if (rc != SQLITE_OK) {// 处理错误
}char *sql = "INSERT INTO users(name, age) VALUES('John', 30);";
rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK) {// 处理错误sqlite3_free(err_msg);
}sqlite3_close(db)
(3)sqlite3_close 关闭数据库
函数原型: int sqlite3_close(sqlite3 *db);
功能: 关闭数据库、释放打开数据库时申请的资源
参数: db:数据库的标识
返回值:
成功返回 SQLITE_OK,
失败返回 非SQLITE_OK
(4)get_table 执行相关的sql语句
get_table sqlite3_excl区别
维度 | sqlite3_get_table | sqlite3_exec |
---|---|---|
适用 SQL 类型 | 仅查询语句(SELECT ) | 所有 SQL 语句(查询、插入、更新等) |
结果处理方式 | 自动存储为二维数组,直接访问 | 通过回调函数手动处理每一行结果 |
灵活性 | 低(固定数组格式) | 高(可自定义解析逻辑) |
易用性 | 简单(无需写回调) | 稍复杂(需手动实现回调函数) |
内存管理 | 需调用 sqlite3_free_table 释放 | 结果通过回调处理,无需额外释放 |
(5)sqlite3_free_table 关闭数据库
三、练习
录入单词进入数据库
main.c
#include <stdio.h>
#include <sqlite3.h>
#include <string.h>int main(void)
{sqlite3 *db = NULL;int ret = sqlite3_open("dict.db",&db);if (ret != SQLITE_OK){printf("sqlite3_open fail");return -1; }char *errmsg = NULL;ret = sqlite3_exec(db,"create table dict(id INTEGER PRIMARY KEY ASC,world char,explain char)",NULL,NULL,&errmsg);if (ret != SQLITE_OK){printf("sqlite3_exec fail:%s\n", errmsg);return -1;}FILE *fp = NULL;fp = fopen("dict.txt","r");if (NULL == fp ){perror("fail to fopen");return -1;}char srcbuf[1024] = {0};char *world = NULL;char *explain = NULL;char *ptmp = NULL; char *pret = NULL;while (1){memset(srcbuf,0,sizeof(srcbuf));pret = fgets(srcbuf,sizeof(srcbuf),fp);if (NULL == pret){break;}world = strtok_r(srcbuf," ",&ptmp);while (*ptmp == ' ' || *ptmp == '\0'){ptmp++;}explain = ptmp;explain[strlen(explain)] = '\0';char sql[1024] = {0};sprintf(sql,"insert into dict values(NULL,\"%s\",\"%s\")",world,explain);ret = sqlite3_exec(db,sql,NULL,NULL,&errmsg);if (ret != SQLITE_OK){printf("sqlite3_excl fail:%s\n",errmsg);return -1;}}sqlite3_close(db);return 0;
}