网络编程(数据库)
一、概述
1、什么是数据库
数据库是按特定结构 组织、存储、管理 数据的集合,支持高效率的 探索、更新、管理,数据库的功能和文件IO,标准IO类似,都是用来记录存储数据的,相关操作有 增删改查。
特点:
1. 存储:数据可以长期存储,在重新运行后依然存在,掉电丢失
2. 结构:通过文档、表单、字段 定义数据关系
3. 共享:可多用户同时访问
4. 安全:提供权限控制和数据加密机制
2、常见的数据库
sqlite3:一个本地轻量级数据库,方便整合到各种工具中,十分适合嵌入式编程
mysql:一个带有远程服务功能的数据库,吞吐量大,早期是一个免费开源的数据库,所以很多电商平台早期都是使用mysql存储数据的
3、数据库的结构
1)数据库的底层结构
2)数据库的使用结构
第一层:数据库文件
数据库文件,我们可以理解为 excel文件
第二层:数据库中的表单
不同的表单,可以记录的意义不同,结构不同的数据
第三层:字段
一个表单可以存放多条数据
每条数据都由多个字段构成
每个字段都有独特的意义,多个字段就能够完整描述一条记录的数据
二、指令操作数据库
1、数据库的准备工作
sudo apt install sqlite3 安装数据库
sqlite3 -version 确认是否安装成功
sudo apt install libsqlite3-dev 安装sqkure3数据库相关函数库
ls /usr/include/sqlite3.h 检查安装的头文件是否存在
2、打开数据库
sqlite3 数据库名.db
3、操作数据库的指令
在数据库中,大小写模糊:不论是指令还是语句,不论大小写,最终都为会被转为大写执行
数据库相关的指令分为两种:
1. 针对数据库本身的操作指令,例如 查询表单,设置显示结构 等等,一般以 . 开头
2. 针对数据库中表单的操作指令,例如 增、删、改、查,一般以 ;结尾
1). 开头的指令
1. 显示数据库中的所有表单(.table)
2. 退出当前数据库(.quit)
3. 输出指定表单的字段结构(.schema)
4. 打开字段名显示(.headers on)
打开字段名显示前
打开字段名显示后
5. 使输出列表列对齐(.mode column)
有ascii column csv html insert line list quote tabs tcl 等等很多对其方式
这里只讲一种 .mode colume 以字段为分割进行对齐
如果记不起对齐的关键字可以输入 .mode 后连按tab键,或 输入.mode xxx(故意输错),会进行提示
2);结尾的指令
1. 在当前数据库创建表单
create table if not exists 表单名(字段名1 数据类型 约束类型,字段名2 数据类型 约束类型,字段名3 数据类型 约束类型,字段名4 数据类型 约束类型
);
(1)字段名
表示存放的数据的具体含义
(2)数据类型
常用的数据类型
整型:int
字符串:test
浮点型:real
日期类型:date
注意:数据库内只有字符串类型,没有字符类型
SQLite3数据库的数据类型很多可以上网址查找(SQLite 数据类型表)
(3)约束类型
一个字段允许被多个约束条件约束
1、主键约束 primary key
将该字段设置成当前表单的 "键" 键:用来决定数据存放的位置,不能重复,不能修改,primary key 只能修饰 int 类型修饰属性:autoincrement 一般用于修饰 "键" 也就是 primary key 修饰的字段 被 autoincrement 修饰的对象,如果在新添加数据时,没有填充值,那么数据库会自动补全补全方式:找到最后一次添加的该值,+1 后补全如图:我在添加参数时,并没有输入"键"ID的值,但是由于自动补全,自动添加了值
2、非空约束 not null
在添加新数据时,必须填写该值,不填写就无法新添数据
3、默认约束 default 默认值
使用格式:default 默认值 设置为默认值后,如果在添加数据时,没有添加该值,数据库会直接填入默认值
4、检查约束 check(检查条件)
使用格式:check(检查条件) 在添加新数据时,会根据"检查条件"判断被检查被约束的字段,填充的值,是否满足条件 满足则添加成功,不满足则添加失败
2. insert into(往表单中添加数据)
insert into 表单名(字段1,字段2,···字段n) value(数据1,数据2,···数据n)
3. select ··· from ··· (查看表单中的数据)
select 字段1,字段2,···,字段n from 表单名
功能:查看指定表单中字段 1~n的所有数据select * from 表单名
功能:输出表单名中所有数据(若不写表单名,则会输出所有表单的数据)
4. insert + select(拷贝其他表单中的数据到当前表单)
insert into 粘贴的表单名(粘贴的字段名) select (复制的字段名) from 复制的表单
功能:将一个表单中的字段复制到另一个表单中,"复制" "粘贴" 的目标的数量及数据类型,必须一致
5. where(查询表单中数据)(子句)
where 条件select * from 表单名 where 条件;
功能:查询表单中符合条件的数据,可以用 and 和 or 连接多个条件例如:select * from students where name = "XXX";
6. like | grop(模糊查询)(子句)
字段名 like 参数 ( = 表示精准查找 like 表示模糊查找)
使用like语句可以使用占位符 _ 和 %
_ : 表示 1 个字符的占位
% : 表示 0 ~ n 个字符的占位select * from 表单名 where 字段名 like 参数
功能:模糊查找指定表单中符合条件的数据举例:select * from students where name like "X_";功能:查找表单students 字段name 中第一个字符为 "X" 且总共只有两个字符的数据select * from students where name like "X_%";功能:查找表单students 字段name 中第一个字符为 "X" 且总共至少有两个字符的数据select * from students where name like "%X%";功能:查找表单students 字段name 中包含 "X" 这个字符的数据
7. update(修改表单中的数据)
update 表单名 set 字段名 = 新数据 where 条件
功能:修改指定 表单 中符合条件的指定 字段 的数据为新数据
8. delete(删除表单中的数据)
delete from 表单名 where 条件
功能:删除表单中符合条件的数据delete from 表单名
功能:删除表单中所有数据,如果没有写表单名,会删除数据库中所有数据(但不会删除表单)
一般来说删除数据,不会直接使用delete,而是使用一种叫做软删除的方式
软删除:为要删除的数据做标记,在数据库维护的时候统一删除,或者定期统一删除
如何标记:在创建表单的时(或者后续) 添加一个字段 is_delete将要删除的数据的该字段修改为True,不删除的则为false统一删除表单名种所有软删除的数据:
delete from 表单名 where is_delete == True;
9. drop table(删除指定的表单)
drop table 表单名
功能:删除指定的表单,不添加表单名,会删除所有表单
10. order by(排序显示数据)(子句)
order by 字段名select from 表单名 order by 字段名
功能:以字段名 升序 排序,并输出,默认时升序排序
select from 表单名 order by 字段名 desc
功能:以字段名 降序 排序,并输出(语句最后添加desc,更改为降序)
11. limit offset(显示有限数据)(子句)
limit 下标 offset 个数 select from 表单名 limit 下标 offset 个数
功能:指定表单中,从指定下标开始输出,输出指定个数的数据
12. alter table ··· add colum ···(为表单添加新的字段)
alter table 表单名 add colum 新字段 数据类型 约束类型
13. alter table ··· rename to ···(重命名表单)
alter table 表单名 rename to 新表单名
14. 重命名字段名
sqlite3数据库中,不存在直接修改字段名的操作
假设想要重命名的字段为 stu:name -> stu:姓名
1:将表单stu重命名 -> temp
2:重新创建一个stu表单,字段格式和temp表单一致,唯独需要重命名的字段,用新的字段名 姓名
3:使用insert + select 语句,将temp表单里面的所有数据,拷贝给 stu表单
4:删除temp表单
15. 删除表单中指定字段
sqlite3数据库中,不存在直接删除字段的操作
假设想要删除的字段为 stu:name
1:将表单stu重命名 -> temp
2:重新创建一个stu表单,字段格式和temp表单一致,唯独去掉需要删除的字段 name
3:使用insert + select 语句,将temp表单里面的所有数据(除了 name),拷贝给 stu表单
4:删除temp表单
三、函数操作数据库(SQLite3接口)
1、操作数据库的流程
整个对数据库的操作流程和对文件IO的操作流程一致
1. 打开数据库
2. 操作数据库
3. 关闭数据库
2、操作数据库的函数
注:SQLite3 是一个动态库,编译的时候需要加上 -lsqlite3
1)sqlite3_open(打开数据库)
#include <sqlite3.h>
int sqlite3_open(const char *dbname,sqlites3 **db);
功能:打开数据库
参数 dbname:要打开的数据库的路径
参数 db:文件描述符(传入二级指针,将一级指针指向 数据库的文件描述符)
返回值:成功返回 SQLITE_OK 失败返回SQLITE_错误码
2)sqlite3_close(关闭数据库)
#include <sqlite3.h>
int sqlite3_close(sqlites3 *db);
功能:关闭打开的数据库
参数 db:文件描述符
3)sqlite3_exec(操作数据库)
#include <sqlite3.h>
int sqlite3_exec(sqlites3 *db,sonst char *sql,int (*callback)(void *,int,char **,char **),void *arg,char **errmsg);
功能:用于执行数据库的语句
参数 db:文件描述符
参数 sql:想要执行的数据库语句 : select,insert,alter
参数 callback:是int (void *,int,char **,char **)类型的函数指针callback 函数 只有执行 select 语句的时候才用,其他时候可以填 NULLcallback 函数会第一时间接收查询出来的数据,具体怎么操作,要看用户怎么编写
参数 arg:用于给 callback 函数向外传递接收到的数据
参数 errmsg:会返回数据库中的报错提示
返回值:成功返回 SQLITE_OK 失败返回SQLITE_错误码