数据库:专业的数据管理方式
数据库文件与普通文件区别:
-
普通文件对数据管理(增删改查)效率低
-
数据库对数据管理效率高,使用方便
一、常用数据库
1. 关系型数据库
核心思想:把复杂数据抽象简化成多张二维表格 一张表 = 行 + 列
- 行(记录):一条完整的数据
- 列(字段):数据的属性
- 表与表之间可以通过主键、外键建立关联关系,这就是 “关系” 的来源
- 使用标准化语言:SQL 结构化查询语言,通用增删改查
特点
(1)结构化:建表就要预先定义字段名称、字段类型(INTEGER、TEXT、REAL等),表结构固定
(2)支持事务 ACID:保证数据操作原子性、一致性、隔离性、持久性。转账、订单场景,要么全部成功,要么全部失败,不会出现数据半更新
(3)通过主键、外键做多表关联查询,支持多表 join
(4)数据存放在磁盘,持久化保存
常见产品
| 大型商用数据库 | Oracle、DB2 | 企业级,性能强、高并发,价格昂贵;银行、电信核心业务。 |
| 中型数据库 | MySQL、SQL Server | MySQL 开源免费,互联网项目最常用;SQLServer 微软产品,多用于 Windows 企业项目。 |
| 小型嵌入式数据库 | SQLite | 无独立服务进程,整个数据库就是一个文件,零配置;适合移动端、嵌入式、课程作业;本课程写词典用的就是 SQLite。 |
2. 非关系型数据库
不再严格遵循二维表格,结构不固定,没有统一 SQL 语法;数据存储模型多种多样
适用场景:海量数据、高并发、数据格式经常变化
主要四大类:键值数据库、文档数据库、列族数据库、图数据库
重点掌握两个:Redis(键值对)、MongoDB(文档型 JSON)
(1)键‑值数据库 Key‑Value
以 key(键) → value(值) 的键值对形式存储,结构不固定。 代表:Redis
Redis 知识点扩充
1)绝大部分数据放在内存,读写速度极快;可以持久化落磁盘
2)value 支持多种数据类型:字符串 string、哈希 hash、列表 list、集合 set、有序集合 zset
3)典型用途:
缓存:网站热点数据,减轻数据库压力;
计数器、排行榜、session 会话、分布式锁。
4)缺点:内存成本高,复杂多条件查询能力弱,不适合做复杂多表关联
(2)文档型数据库 Document
存储单元是文档,格式类似 JSON,一个文档相当于关系数据库的一行记录。 代表:MongoDB
文档结构不固定,不同文档可以拥有完全不一样的字段,不需要预先定义表结构。
对比关系库:关系库建表必须提前写死字段;MongoDB 可以一条记录多几个字段,另一条少几个字段。
二、嵌入式数据库
sqlite3:
特点:
(1)开源免费,C语言开发
(2)代码量少,一万行左右,总大小10M以内
(3)文件型数据库,可以移动
(4)数据容量最大2T
1. sqlite3的安装
在线安装
sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev
2. sqlite3相关命令
创建数据库:sqlite3 xxx.db
.help 查看所有支持命令
.tables 查看数据库中的表名
.headers on/off 显示/关闭表头
.mode column 设置表左对齐
.quuit 退出数据库
3. sqlite3提供的SQL语句
<<不区分大小写>>
sqlite数据类型:
NULL:空类型
INTEGER:整数类型
REAL:浮点型
TEXT:字符串类型(文本)
BLOB:根据输入确定

(1)创建数据库中的表
create table 表名(列名1 数据类型1, 列名2 数据类型2, 列名3 数据类型3);
CREATE TABLE 表名(列名1 数据类型1, 列名2 数据类型2, 列名3 数据类型3);
示例:
sqlite> create table class1(id INTEGER, name TEXT, score REAL);
sqlite> .tables
class1
(2)插入数据库数据
insert into 表名 values(值1, 值2, 值3);
TEXT类型的数据,插入时需要用" "或' '引起来
示例:
sqlite> insert into class1 values(1, "zhangsan", 90.5);
sqlite> insert into class1 values(2, "lisi", 88.8);
sqlite> insert into class1 VALUES(3, "wangwu", 92);
(3)查找数据库数据
select * from 表名; //查找表中所有数据
示例:
sqlite> select * from class1;
1|zhangsan|90.5
2|lisi|88.8
3|wangwu|92.0
设置表头显示、表左对齐效果:
sqlite> .headers on
sqlite> .mode column
sqlite> select * from class1;
id name score
———- ———- ———-
1 zhangsan 90.5
2 lisi 88.8
3 wangwu 92.0
补充:
1)查找指定列数据
select 列1, 列2 from 表名;
示例:
sqlite> select name, score from class1;
name score
———- ———-
zhangsan 90.5
lisi 88.8
wangwu 92.0
2)条件查找
select * from 表名 where 条件;
select * from where 列名 关系运算符 值;
关系运算符:= < > <= >= !=
连接多个条件:and or
示例:
sqlite> select * from class1 where id=1;
id name score
———- ———- ———-
1 zhangsan 90.5
sqlite> select * from class1 where id>1;
id name score
———- ———- ———-
2 lisi 88.8
3 wangwu 92.0
sqlite> select * from class1 where id!=1;
id name score
———- ———- ———-
2 lisi 88.8
3 wangwu 92.0
sqlite> select * from class1 where score>=80 and score<=90;
id name score
———- ———- ———-
2 lisi 88.8
sqlite> select * from class1 where score>=90 or score<60;
id name score
———- ———- ———-
1 zhangsan 90.5
3 wangwu 92.0
3)模糊查找
select * from 表名 where 条件 like XXX
% :模糊匹配若干个字符
_ :模糊匹配一个字符
示例:
sqlite> select * from class1 where name like "纪%"; //或单引号
id name score
———- ———- ———-
4 纪三四五 56.0
sqlite> select * from class1 where name like "%五";
id name score
———- ———- ———-
4 纪三四五 56.0
sqlite> select * from class1 where name like "___五";
id name score
———- ———- ———-
4 纪三四五 56.0
4)有序查找
select * from 表名 order by 列名 ASC; //升序显示
select * from 表名 order by 列名 DESC; //降序显示
示例:
sqlite> select * from class1 order by score DESC;
id name score
———- ———- ———-
3 wangwu 92.0
1 zhangsan 90.5
2 lisi 88.8
4 纪三四五 56.0
sqlite> select * from class1 order by name ASC;
id name score
———- ———- ———-
2 lisi 88.8
3 wangwu 92.0
1 zhangsan 90.5
4 纪三四五 56.0
(4)删除数据库数据
delete from 表名 where 条件; //条件表述与查找一致
示例:
sqlite> delete from class1 where id=4;
sqlite> select * from class1;
id name score
———- ———- ———-
1 zhangsan 90.5
2 lisi 88.8
3 wangwu 92.0
(5)修改数据库数据
updata 表名 set 列名=新值 where 条件;
示例:
sqlite> update class1 set score=99 where name="wangwu";
sqlite> select * from class1;
id name score
———- ———- ———-
1 zhangsan 90.5
2 lisi 88.8
3 wangwu 99.0
(6)删除数据库中的表
drop table 表名
示例:
drop table class1;
(7)主键值自动增长列
create table 表名(列名 INTEGER PRIMARY KEY AUTOINCREMENT, 列名 数据类型);
示例:
sqlite> create table class2(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, score REAL);
sqlite> insert into class2 values(NULL, "zhangsan", 88);
sqlite> insert into class2 values(NULL, "lisi", 85);
sqlite> insert into class2 values(NULL, "wangwu", 92);
sqlite> insert into class2 values(NULL, "wanglu", 96);
sqlite> select * from class2;
id name score
———- ———- ———-
1 zhangsan 88.0
2 lisi 85.0
3 wangwu 92.0
4 wanglu 96.0
(8)时间相关函数
示例:
sqlite> create table info(id INTEGER PRIMARY KEY AUTOINCREMENT, temp REAL, hum REAL, time TEXT);
sqlite> select date();
date()
———-
2026-09-05
sqlite> select datetime();
datetime()
——————-
2026-09-05 06:17:48
sqlite> select datetime("now", "+8 hours"); //矫正时间误差
datetime("now", "+8 hours")
—————————
2026-09-05 14:18:41
sqlite> insert into info values(NULL, 32.5, 50, datetime("now", "+8 hours"));
sqlite> insert into info values(NULL, 31.7, 53, datetime("now", "+8 hours"));
sqlite> insert into info values(NULL, 31.2, 52, datetime("now", "+8 hours"));
sqlite> insert into info values(NULL, 29.9, 51, datetime("now", "+8 hours"));
sqlite> select * from info;
id temp hum time
———- ———- ———- ——————-
1 32.5 50.0 2026-09-05 14:19:34
2 31.7 53.0 2026-09-05 14:20:00
3 31.2 52.0 2026-09-05 14:20:16
4 29.9 51.0 2026-09-05 14:20:29
(9)数据库的可视化工具
安装:sudo apt-get install sqlitebrowser
打开:sqlitebroswer xxx.db
NavicatSqlite3 —> Windows数据库可视化工具
4.sqlite3提供的C/C++ API接口
(1)sqlite3_open
int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
功能:打开一个数据库文件
参数:
filename:数据库名称
ppDb:保存数据库句柄的指针sqlite3 *
返回值:
成功:SQLITE_OK
失败:错误码
(2)sqlite3_errmsg
const char *sqlite3_errmsg(sqlite3* pdb);
功能:获取当前数据库错误码对应的错误信息
参数:
pdb:数据库句柄
返回值:错误信息字符串
(3)sqlite3-exec
int sqlite3_exec(
sqlite3*, /* 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 */
);
功能:执行SQL语句
参数:
pdb:数据库句柄
sql:要执行的SQL语句
callback:回调函数,当select查询时,若查询到数据,会触发回调函数执行
arg:传递给callback的参数(实参)
errmsg:保存出错信息
返回值:
成功:SQLITE_OK
失败:错误码
int (*callback)(void *arg, int n, char **value, char **name);
功能:select查询到数据时执行的回调函数
参数:
arg:由sqlite3_exec的第4个参数传递的参数值(形参)
n:select查询到的数据的列数
value:查找到的数据的每一列的值,本质为char *value[]
name:查找到的数据列的表头,本质为char *name[]
返回值:
成功:0
失败:!0
回顾:二级指针使用场景
1)被调函数中修改主调函数中的指针变量
2)指针数组的数组名(此处用这个)
注意:
1)callback必须要有返回值,返回0表示正常
2)当select查询数据时,每找到一条数据,callback就会被触发一次
3)数据库中的数据,通过select查询出时,统一按照字符串处理
(4)sqlite3_close
int sqlite3_close(sqlite3*);
该例程关闭之前调用 sqlite3_open() 打开的数据库连接。所有与连接相关的语句都应在连接关闭之前完成。
如果还有查询没有完成,sqlite3_close() 将返回 SQLITE_BUSY 禁止关闭的错误消息。
示例1:创建数据库、增添数据
#include<stdio.h>
#include<string.h>
#include<sqlite3.h>
int main(void)
{
sqlite3 *pdb;
int ret = sqlite3_open("./stu.db", &pdb);
if(ret != SQLITE_OK)
{
fprintf(stderr, "sqlite3_open error : %s\\n", sqlite3_errmsg(pdb));
return -1;
}
char *psql = "create table if not exists class3(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, score REAL);";
ret = sqlite3_exec(pdb, psql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
fprintf(stderr, "sqlite3_exec error : %s\\n", sqlite3_errmsg(pdb));
return -1;
}
psql = "insert into class3 values(NULL, \\"wangwu\\", 99);";
ret = sqlite3_exec(pdb, psql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
fprintf(stderr, "sqlite3_exec error : %s\\n", sqlite3_errmsg(pdb));
return -1;
}
char buff[512] = {0};
char sql[1024] = {0};
fgets(buff, sizeof(buff), stdin);
buff[strlen(buff)-1] = '\\0';
sprintf(sql, "insert into class3 values(NULL, \\"%s\\", 100);", buff);
ret = sqlite3_exec(pdb, sql, NULL, NULL, NULL);
if(ret != SQLITE_OK)
{
fprintf(stderr, "sqlite3_exec error : %s\\n", sqlite3_errmsg(pdb));
return -1;
}
sqlite3_close(pdb);
return 0;
}
终端输入姓名:wanglu,会填入设定位置

示例2:查找数据
#include<stdio.h>
#include<string.h>
#include<sqlite3.h>
int flag = 0;
int callback(void *arg, int n, char **value, char **name)
{
if(0 == flag)
{
printf("n = %d\\n", n);
for(int i=0; i<n; ++i)
{
printf("%s ", name[i]);
}
printf("\\n");
flag = 1;
}
for(int i=0; i<n; ++i)
{
printf("%s ", value[i]);
}
printf("\\n");
return 0;
}
//printf("%s %s %s\\n",value[0], value[1], value[2]); 禁止,段错误
int main(void)
{
sqlite3 *pdb;
int ret = sqlite3_open("./stu.db", &pdb);
if(ret != SQLITE_OK)
{
fprintf(stderr, "sqlite3_open error : %s\\n", sqlite3_errmsg(pdb));
return -1;
}
char *psql = "select * from class1;";
ret = sqlite3_exec(pdb, psql, callback, NULL, NULL);
if(ret != SQLITE_OK)
{
fprintf(stderr, "sqlite3_exec error : %s\\n", sqlite3_errmsg(pdb));
return -1;
}
sqlite3_close(pdb);
return 0;
}






