0.数据库大纲
数据库是什么 ? 如何在在命令行使用SQL语句操作数据库 ?
如何在C/C++程序中操作数据库
1.数据库和数据库管理系统及数据库系统
数据库是一个存储数据(电子化表格)的仓库.
数据库, 简单来说可以看做是一个电子化的文件柜,—> 存储电子文件的工具,
用户可文件中的数据进行 , 增 , 删 , 改 , 查等操作.
其实我们常说的"数据库" 值的是 “数据管理系统”.
数据库(DataBase) :存储数据(电子化表格)的仓库.
数据库管理系统(DBMS DataBase Management System) : 数据库对外操作数据的接口.
数据库系统(DBS DataBase System) : 带有数据库的计算机系统, 一般由数据库,数据库管理系统
(及其开发工具),相关的硬件,软件和各类人员组成.
数据库系统 包含 数据库 和 数据库管理系统.
数据库管理系统(DBMS)是为数据库设计的计算机软件,一般都是可以对数据进行, 增 , 删 , 改 , 查等操作.
我们数据库(DB) 和 数据库管理系统(DBMS) 之间的关系和现实中 :
excel中学生表(多个表) 和 excel关系.
1.关系型数据库(Relational Database)
关系型数据库是创建在关系模型(E-R模型)基础上的数据库(数据和数据是存在关系的)关系 ? 表格
表 是行和列的形式组织起来的数据的集合;
关系型数据库是由多个表组成的数据库.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yACgTkaP-1667307229748)(…/3-pic/image-20221101093019425.png)]
行 : 一条完整的记录 , 包含多个不同的属性.
列 : 具有相同属性的数据集合 .
表中的每一行称为一条记录 , 一列称为一个字段(属性), 每一列的标题称为字段名.
如果给关系型数据库中的每一个关系取一个名字 , 则一个有n个字段的关系表可以表示为 :
关系表名(字段1 , 字段2 , 字段3 , … , 字段n);
如 : 学生信息表(学号 , 姓名 , 地址 , 班级)
常用的关系型数据库(数据库管理系统有很多)
Oracle
Mysql
Sqlite3 轻量级的开源的关系型数据库 , 很适合在嵌入式设备上使用
SQL server
DB2
关系型表格如何创建 ?
E-R模型(可以描述现实生活中的关系模型)
实体-关系模型
实体-关系模型图 ,由三个部分组成 :
实体 : 客观存在的事物, 用矩形表示 , 如 : 学生 ,成绩
联系 : 实体之间的联系, 用菱形表示 , 如 : 考试
属性 : 实体所具有的某一个属性 ,用椭圆表示 ,如 : 学号, 姓名
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ij9jBgZd-1667307229751)(…/3-pic/image-20221101095015125.png)]
一般来说 ,一个实体就会对应一个表格 ,实体的属性就是对应表格中的字段 ,多个表格可以通过 主键 和 外键相互联系
主键
关系型数据库中一条记录中有若干个属性 ,若一个属性能唯一的标识一条记录.
该属性就可以设置成一个主键.
如 :
学生信息表(学号 ,姓名 ,地址 ,班级)
其中每一个学生的学号是唯一的, 学号就是学生表中的一个主键.
课程表(课程编号 ,任课老师 ,开课时间)
其中的课程编号是唯一的,课程编号就是课程表中的一个主键
成绩表中单一的一个属性无法唯一标识一条记录 , 学号 和 科目的组合可以 唯一标识一条记录 , 主键可以是属性的集合. 外键
在当前表中不是主键 ,但是在其他表中是主键.
成绩表中的学号不是成绩表的主键 ,但是他和学号表中的学号是对应的,
并且学生表中的学号是学生表的主键 ,则把成绩表中的学号叫做学生表的外键.
主键 和 外键主要是维护关系数据的完整性.
a . 主键能在当前表中唯一标识一条一条记录.
b.外键是用于和另外一张表的关联.
2.关系型数据库语言 SQL语言
SQL (Structtured Query Language)结构化的查询语言 ;
是一种通用的功能强大的关系型数据库语言 .
结构化的查询语言包含六个部分 :
数据查询语言 DQL Data Quary Language 从数据库中获取/查询数据(SELECT)
数据库的操作语言 DML Data Manipulation Language 用来操作数据库中的用户数据 ,包括增加数据(INSERT) ,删除数据(DELETE) , 修改数据(UPDATE)
事物处理语句 确保DML语句的作业及时的更新到数据库中;
数据控制语言 DCL 数据定义语言 DDL Data Define Language 用来操作数据库中的元数据 包括创建一个表 ,删除一个表 , 修改一个表中的字段.
指针控制语言
数据查询语言 DQL Data Quary Language
从数据库中获取/查询数据(SELECT)
数据库的操作语言 DML Data Manipulation Language
用来操作数据库中的用户数据 ,包括增加数据(INSERT) ,删除数据(DELETE) ,
修改数据(UPDATE)
数据定义语言 DDL Data Define Language
用来操作数据库中的元数据
包括创建一个表 ,删除一个表 , 修改一个表中的字段.
所有的SQL语句都是在命令行中执行的
执行sqlite3命令就要进入sqlite3命令行
sqlite3
.help
.quit
.exit 退出sqlite3的程序
(1) 创建一个sqlite数据库(里面没有数据)对象
终端 :
sqlite3 数据库对象名字 //打开或创建一个数据库
如 : sqlite3 test.db
通过SQL语句操作数据库都是在sqlite3的命令行程序中 :
注意 :
a.在sqlite3命令下面 ,SQL语句以分号(" ; ")结束
b.SQL语句支持大小写 ,但是在实际使用中建议使用大写 ;
因为所有的语句在执行的时候 ,都是先转换为大写的形式.
(2) 在数据库对象(test.db)中创建一个表
CREATE TABLE : 用来创建一个关系表
语法 :
CREATE TABLE 表名(
列名1 数据类型 "约束",
列名2 数据类型 "约束",
列名3 数据类型 "约束",
...
列名n 数据类型 "约束"
);
表名 : 数据库中关系表的名字
列名 : 关系表中的字段名
数据类型 : 说明字段中的数据的类型
integer(size) 此字段必须为整数 size规定数字的最大的位数
int(size)
smallint(size)
...
decimal(size,d)
容纳带小数的数字,size规定数字的最大位数,d表示小数点右侧的最大位数
float
double
real
char(size) 固定从长度的字符串 ,size规定字符串的长度
varchar(size) 可变长度的字符串,size规定字符串的最大长度
text
data 日期
2022/11/1
2022-11-1
约束 :
NOT NULL 此字段不能为空
UNIQUE 此字段唯一(不能重复)
PRIMARY KEY 主键 ,主键必须是 NOT NULL AND UNIQUE
FOREGIN KEY 外键 ,这一列在其他表中是主键,在自己的表中不是主键
CHECK 用于限制数据的范围
CHECK SCORE>=0 AND SCORE<=100
例子 : 在test.db中创建一个学生表
STUINFO(学号 ,名字 ,地址 ,分数)
CREATE TABLE STUINFO(
NUM int(4) PRIMARY KEY,
NAME varchar(255) NOT NULL,
ADDR varchar(255) NOT NULL,
SCORE real(4) CHECK(SCORE>=0 AND SCORE<=100)
);
CREATE TABLE STUINFO(NUM int(4) PRIMARY KEY,NAME varchar(255) NOT NULL,ADDR varchar(255) NOT NULL,SCORE real(4) CHECK(SCORE>=0 AND SCORE<=100));
CREATE TABLE STU(NUM int(4) PRIMARY KEY,NAME varchar(255) NOT NULL,ADDR varchar(255) NOT NULL,SCORE real(4) CHECK(SCORE>=0 AND SCORE<=100));
查询数据库中的表格
.table
查看表格的结构
.schema
删除数据库中的一个表
语法 :
DROP TABLE 表名;
如 : DROP TABLE STUTEST;
修改表的结构 :
a . 修改表名
ALTER TABLE 表名 RENAME TO 新名字;
如 : ALTER TABLE STU RENAME TO STUINFO;
b . 增加字段
ALTER TABLE 表名 ADD 字段名 字段类型;
如 : ALTER TABLE STUINFO ADD TEL INT;//在STUINFO中增加一个新的字段
(3) 向表中插入新行(一条新的记录)
INSERT INFO : 用于向表格插入新行
语法 :
INSERT INFO 表名 VALUES(值1,值2,...,值n);
INSERT INFO 表名(字段1,字段2,...) VALUES(值1,值2,...,值n);
如 :
INSERT INTO STUINFO VALUES(1,"zhangsan","cs",88,10086);
INSERT INTO STUINFO(NUM,NAME,ADDR,SCORE) VALUES(2,"lisi","cs",89);
(4) SELECT用于从表中选取数据 ,把结果列举出来
语法 :
SELECT 列名1,列名2... FROM 表名 WHERE 列 运算符 值;
SELECT * FROM 表名;//查看表中所有的信息
如 : SELECT * FROM STUINFO;
INSERT INTO STUINFO VALUES(3,"wangwu","bj",68,10000);
INSERT INTO STUINFO VALUES(4,"zhaoliu","jx",99,119);
运算符 :
= 等于
<> 不等于
> 大于
< 小于
BETWEEN AND
SELECT * FROM STUINFO WHERE NUM=1;//查看学号为1的学生信息
SELECT * FROM STUINFO WHERE NUM<>1;//查看学号不为1的学生信息
SELECT * FROM STUINFO WHERE NUM>3;//查看学号大于3的学生信息
//查看学生表中学号为2-4之间的学生信息
SELECT * FROM STUINFO WHERE NUM BETWEEN 2 AND 4;
WHERE 表示条件查询
如果有多个条件 :
AND 并且
OR 或者
//查看学号为2或者电话为10086的学生信息
SELECT * FROM STUINFO WHERE NUM=2 OR TEL=10086;
限定 + 排序
SELECT * FROM 表名 ORDER BY 字段 ASC/DESC
//查看学生表中根据分数降序排序的前三条记录
SELECT * FROM STUINFO ORDER BY SCORE DESC LIMIT 3;
查找模糊值(like)
//查找姓zhang的学生信息
SELECT NAME,NUM,TEL FROM STUINFO WHERE NAME LIKE 'zhang%';
SELECT NAME,NUM,TEL FROM STUINFO WHERE NAME LIKE '%i%';
(5) 多表查询–多表连接
CREATE TABLE KCB(NUM INT,KCH INT PRIMARY KEY,NAME VARCHAR,SCORE REAL);
INSERT INTO KCB VALUES(1,1,"yuwen",89);
INSERT INTO KCB VALUES(1,2,"shuxue",68);
INSERT INTO KCB VALUES(1,3,"yingyu",70);
语法 :
SELECT 表名.列名1,表名.列名2... FROM 表名1,表名2 WHERE 列 运算符 值;
如果在多表查询中不指定连接条件,就会自动的连接,导致将一个表中所有的行
都连接到另一个表中所有的行上面 --- 卡迪尔积
如果第一个表中有50行,第二个表中有10行,得到的结果就有500
多表查询的时候,实际上是从产生的"卡迪尔积"的结果中得到满足条件的记录.
SELECT STUINFO.NUM,STUINFO.NAME,STUINFO.ADDR,KCB.NUM,KCB.KCH,KCB.SCORE FROM STUINFO,KCB;
SELECT STUINFO.NUM,STUINFO.NAME,STUINFO.ADDR,KCB.NUM,KCB.KCH,KCB.SCORE FROM STUINFO,KCB WHERE STUINFO.NUM=KCB.NUM;
.header on //列举结果的时候,会显示表头
.mode colum //按照列的方式显示结果
这样看起来会顺眼一些
SQL语句 ,需要掌握的有 :
创建一个表
CREATE TABLE
删除一个表
DROP TABLE
修改一个表的元数据
ALTTER TABLE
查询数据
SELECT
增加表中的用户数据
INSERT INTO
删除表中的用户数据
DELETE FROM
修改表中的用户数据
UPDATE
4.数据库对C/C++的API接口
通过C/C++程序去操作数据库
如何通过API函数接口 ,执行SQL语句
Sqlite3的API函数接口的核心部分 :
两大对象 和 八大函数
两大对象
数据库连接对象(The Database Connection Object)
数据库连接句柄/数据库自己的文件描述符 ,表示一个已经打开的数据库
sqlite3 * 代表你打开的那一个sqlite3的数据库文件(test.db);
后续对数据库的所有操作都需要通过这个连接对象.
SQL语句对象(The prepare Statement Object)
sqlite3_stmt
就是一条准备好的SQL语句.
操作数据库的标准语言就是SQL语句 ,在这里 ,使用准备好的SQL语句对象
表示的SQL语句去操作数据连接对象表示的数据库.
利用SQL语句操作数据库的流程(八大函数)
1.建立连接
2.打开/创建一个数据
sqlite3_open();//打开或创建一个sqlite3的数据库连接对象
3.利用SQL语句对象操作数据库
sqlite3_prepare_v2();//准备一个SQL语句对象
sqlite3_bind_*();//绑定参数
sqlite3_step();//执行sql语句
sqlite3_column();//输出查询到的数据库的数据
sqlite3_finalize();//释放资源,销毁SQL语句对象
sqlite3_exec();
4.关闭数据库
sqlite3_close();//关闭一个数据库连接对象
5.具体的API函数的使用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hipXwlnD-1667980048382)(…/3-pic/image-20221102102404172.png)]
(1) 打开数据
sqlite3_open
sqlite3 * 代表你打开的那一个sqlite3的数据库文件(test.db) ,
后续对数据的所有操作都需要通过这个连接对象.
SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
filename : 要打开的sqlite3的数据库名字(带路径)
ppDb : 二级指针,用来保存打开的数据库的连接对象(连接句柄)
ppdb指向的内存是用来保存打开的数据库对象的地址.
返回值 :
成功 返回SQLITE_OK
失败 返回其他值
(2) 关闭一个sqlite3数据库连接对象
sqlite3_close
SQLITE_API int sqlite3_close(sqlite3*);
参数为你要关闭的数据库指针
(3) 关于SQL语句对象的API函数(准备)
sqlite3_stmt 这个结构体来描述一个SQL语句对象
我们的应用程序都是通过SQL语句对象去发送SQL语句的.
sqlite3_stmt * stmt;//SQL语句对象的指针
sqlite3_prepare_v2();//准备一个SQL语句
SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, //数据库连接对象,语句作用在哪一个数据库上
const char *zSql, //要执行的原始的sql语句的字符串形式
int nByte, //原始sql语句的长度
sqlite3_stmt **ppStmt, //OUT: 用来保存解析后的SQL语句对象
const char **pzTail //OUT: 指向原始的sql语句中未使用的部分
);
nByte : 原始sql语句的长度(原始语句可以包含多条SQL语句)
<0 :编译到zSql指向的sql语句的第一个'\0'为止.
>0 :编译到zSql指向的sql语句的nByte指定的字节为止.
=0 :什么都不编译.
ppStmt : 二级指针,用来保存解析后的SQL语句对象的地址
要改变指针变量的值,指针不在作用范围内,只能间接访问,把指针变量的地址
传入函数,在函数的内部就可以改变指针变量的值.
在函数内部,可能会让指针变量指向一个准备好的SQL语句对象.
pzTail :二级指针,用来指向原始的SQL语句总未使用的部分(如果不需要,也就是
说zSql指向的字符串中只有一条SQL语句,则可以指定为NULL);
可以实现一个字符串中写多条SQL语句,准备一条语句后,指针指向的位置为未使用的部分.
sqlite3_stmt * stmt;//SQL语句对象的指针
const char *p = NULL;
sqlite3_prepare_v2(test.db,str,-1,&stmt,&p);
在函数执行完毕后,stmt指向准备好的SQL语句对象
p指向str中未使用的部分.
返回值 :
成功 返回SQLITE_OK
失败 返回其他值
(4) 执行一条准备好的SQL语句(SQL语句对象)
sqlite3_step
SQLITE_API int sqlite3_step(sqlite3_stmt*);
stmt : 指针,指向你准备好的SQL语句对象,也是你要执行的SQL语句对象
返回值 :
成功 返回SQLITE_DONE
失败 返回其他值
(5) 释放资源
sqlite3_finalize
SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
在prepare的时候,很有可能让stmt指针指向了动态分配的内存空间,通过函数释放所有的资源.
<1> pzTail :二级指针,用来指向原始的SQL语句总未使用的部分(如果不需要,也就是 说zSql指向的字符串中只有一条SQL语句,则可以指定为NULL); <2> 从标准输入往数据库中添加数据 <3> 读取文件数据并添加到数据库中 <4> 通过绑定索引值往数据库中添加数据
(6) 一步查询的执行操作(sqlite3_exec)
sqlite3_exec()接口[sqlite3_prepare_v2 , sqlite3_step , sqlite3_finalize ]集合,他可以
让应用程序运行多个SQL语句 ,而不必使用大量的C语言代码.
SQLITE_API int sqlite3_exec(
sqlite3*, //数据库连接对象
const char *sql, //是一条你要执行的SQL语句
int (*callback)(void*,int,char**,char**), //回调函数,只有在SELECT的时候才有用
void *, //回调函数的第一个参数
char **errmsg //出错信息的指针
);
int (*callback)(void*,int,char**,char**)
函数指针,执行你要执行的函数,函数的返回值为int,有四个参数
当调用sqlite3_exec 去执行SELECT语句的时候,就会执行这个回调函数,
主要作用是处理SELECT的结果信息.
int (*callback)(void*,int,char**,char**)
回调函数参数的详细信息 :
第一个参数是指针,可以传入用户自己的数据
第二个参数是执行SELECT语句后,查询到结果的列数
第三个参数是一个指向字符串的指针数组,就是结果数据的每一列信息
第四个参数是一个指向字符串的指针数组,就是结果数据每一列的表头信息
sqlite3_exec参数详解 :
第一个参数是你要操作的数据连接对象
第二个参数是以分号分隔的SQL的原始语句
第三个参数如果为空,表示没有回到函数,如果不为空,在执行SELECT语句的时候
会调用回调函数,回调函数主要是处理SELECT查询到的结果
第三四个参数作为回调函数的第个参数(作用用户自定义)
第五个参数不为NULL,则将错误信息写入[sqlite3_nalloc]分配内存中,
并且让第五个参数指向的分配的内存,为了避免内存泄漏,应用程序在处理完
错误信息后,通过sqlite3_free释放第五个参数指向的内存.
只有在执行SELECT语句的时候,才需要回调函数
SELECT有多少条记录,就会执行多少次回调函数
好文阅读
发表评论