欢迎光临
我们一直在努力

Linux应用层开发 --- 数据库

数据库:专业的数据管理方式

数据库文件与普通文件区别:

  • 普通文件对数据管理(增删改查)效率低

  • 数据库对数据管理效率高,使用方便

一、常用数据库

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;
}

赞(0)
未经允许不得转载:171主机测评 » Linux应用层开发 --- 数据库
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址