1.1. 数据库概念(属于C/S结构)
数据库 :是存放数据的仓库,它是一个按数据结构来存储和管理数据的计算机软件系统。
数据库管理系统 : 是数据库系统的核心组成部分,主要完成对数据库的操作与管理功能,例如实现数据 的存储,查询,修改,删除,及数据库用户的管理,权限管理等。
RDBMS : 关系数据库管理系统(Relational Database Management System)。
SQL : 结构化查询语言(Structured Query Language). mysql数据库是一种C/S模型(即客户端和服务端模型),客户单通过用户名,密码登录连接服务器。连 接成功后才可以进行数据库的操作(增删改查)。
数据库是一个C/S结构,包含服务器端和客户端,我们在安装的时候(apt install mysql-server)安装的是服务器端,其实它自己默认也会安装客户端,目前的数据库都是CS结构,数据库的服务器端和客户端是通过tcp连接的,mysql的端口是3306。(面试问题)IP地址根据部署来决定。如下图所示:

C/S结构概述
C/S结构(Client/Server Structure)是一种分布式计算架构,将任务分解为客户端(Client)和服务器端(Server)两部分。客户端负责用户交互和界面展示,服务器端处理核心逻辑与数据存储。两者通过网络协议(如HTTP、TCP/IP)通信,实现资源共享与功能协同。
1.2MySql的安装及设置
在ubuntu发行版本上使用apt命令安装mysql可以使用apt工具安装:
apt install mysql-server

1.3查看数据库的状态
sql
service mysql status
1.4查看数据库的端口
sql
netstat -natp

二.使用MYSQL
1.登录
sql
mysql -uroot -p+密码

注意;如果是第一次登录直接使用可以直接回车
进入数据库可以修改自己的密码
sql
ALTER user 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '自己更改的密码';
在数据库中可以按照我们所学的sql语法来进行使用
2.数据库语法
查看数据库
sql
show databases;

显示数据库版本号
sql
select version();

显示时间
sql
select now();

创建数据库
sql
create database 数据库名
选择数据库
sql
use 数据库名
数据库内部操作
查看数据库中的所有表
sql
show table(字段 类型 约束,
字段 类型 约束 );
创建表
创建表时,需要指定各个字段的类型,常见类型如下:
数值类型(部分)

字符串,部分类型如下:

char(N) 是定长,无论存多少字符,都占 N 个字符的存储空间(不足补空格);varchar(N) 是变长,实际存多少字符就占多少空间(额外加 1-2 字节记录长度)。
日期类型

约束
主键 primary key : 物理上存储的顺序
非空 not null : 此字段不允许填写空值
唯一unique: 此字段的值不允许重复
默认default: 当不填写此值时,会使用默认值。如果填写时,以填写的值为准
外键foreign key : 对关系字段进行约束,当为关系字段填写值时,会到关联的表中查询此值是否存在,如果存在则写成功,如果不存在则写失败。 虽然外键约束可以保证数据的有效性,但是在进行 数据的crud(增加,修改,删除,查询)时,都会降低数据库的性能。
auto_increment 表示自动增长。
现在让我们利用我们所学的知识创建一个数据库,并向其添加学生信息的表,


查看表
sql
select * from 表名

desc+表名可以查看表的结构也就是各个字段的信息

修改表名字
修改表的名字,使用 alter table 原表名 rename [to] 新表名; 其中to可以省略

修改表字段信息
修改表--添加字段
alter table 原表名 add 列名 类型;
修改字段-- 重新命名
alter table 原表名 change 原字段名 新字段名 类型;
修改字段-- 不改名字
alter table 表名 modify 列名 类型 约束
插入数据
sql
insert into 表名 values (...);

更新数据

删除数据

删除表
sql
drop table +表名
排序
sql
-- 按年龄升序排列
SELECT * FROM student ORDER BY age;
-- 按年龄降序排列
SELECT * FROM student ORDER BY age DESC;
-- 多字段排序:年龄升序,身高降序
SELECT * FROM student
WHERE age BETWEEN 18 AND 24
ORDER BY age ASC, height DESC;
聚合函数
- 常用函数
COUNT(),MAX(),MIN(),SUM(),AVG()
sql
-- 统计男生人数(修正原示例中的错误写法)
SELECT COUNT(*) FROM student WHERE gender = '男';
-- 计算平均年龄并保留两位小数
SELECT ROUND(AVG(age), 2) FROM student;
条件查询
比较运算符
>, <, >=, <=, =, !=
sql
-- 查询年龄大于18岁的学生
SELECT * FROM student WHERE age > 18;
-- 查询年龄等于18岁的学生
SELECT * FROM student WHERE age = 18;
逻辑运算符
AND, OR, NOT
sql
-- 18到24岁之间的学生
SELECT * FROM student WHERE age > 18 AND age < 24;
-- 18岁以上或身高180及以上
SELECT * FROM student WHERE age > 18 OR height >= 180;
-- 非18岁以上的男生
SELECT * FROM student WHERE NOT (age > 18 AND gender = '男');
模糊查询(LIKE)
%(匹配任意字符),_(匹配单个字符)
sql
-- 查询姓名以"小"开头
SELECT name FROM student WHERE name LIKE '小%';
-- 查询姓名包含"小"字(修正原示例中的笔误)
SELECT name FROM student WHERE name LIKE '%小%';
-- 查询两个字符的名字
SELECT name FROM student WHERE name LIKE '__';
范围查询
sql
-- 不连续范围(IN)
SELECT name FROM student WHERE age IN (18, 20, 24);
-- 连续范围(BETWEEN)
SELECT name FROM student WHERE age BETWEEN 18 AND 24;
-- 空值判断
SELECT * FROM student WHERE addr IS NULL;
分组查询(GROUP BY)
- 基本分组与聚合
sql
-- 按性别分组统计人数
SELECT gender, COUNT(*) FROM student GROUP BY gender;
-- 按性别分组显示组内人名
SELECT gender, GROUP_CONCAT(name) FROM student GROUP BY gender;
分页(LIMIT与OFFSET)
sql
-- 每页10条数据,查询第3页(跳过前20条)
SELECT * FROM student LIMIT 10 OFFSET 20;
-- 简写方式
SELECT * FROM student LIMIT 20, 10;
连接查询(JOIN)
- 内连接(INNER JOIN)
sql
-- 查询学生及其班级信息
SELECT s.name, c.class_name
FROM student s
INNER JOIN class c ON s.cls_id = c.id;
- 左连接
sql
-- 查询所有学生及班级信息(包含无班级的学生)
SELECT s.name, c.class_name
FROM student s
LEFT JOIN class c ON s.cls_id = c.id;
左连接:以左边的信息为主,返回左表的全部记录,右表无匹配时补NULL
子查询
标量子查询
sql
-- 查询年龄大于平均年龄的学生
SELECT * FROM student
WHERE age > (SELECT AVG(age) FROM student);
IN子查询
sql
-- 查询在班级1或2的学生
SELECT * FROM student
WHERE cls_id IN (SELECT id FROM class WHERE id IN (1, 2));
三.C/C++链接数据库
在连接之前需要确保已经安装了c/c++开发库如果没有安装可以在管理员模式下输入:
apt install libmysqlclient-dev
链接数据库的头文件如下
cpp
#include<mysql/mysql.h>
当使用了一些访问mysql有关的接口在需要链接的时候需要指定库名及在编译后加 -lmysqlclient
3.1初始化链接
cpp
MYSQL *mysql_init(MYSQL* mysql);
该方法用来初始化一个连接句柄,如果参数为空,则返回一个指向新分配的连接句柄的指针。如果传递一个已有的结构,它将被重新初始化,出错时返回为NULL。
3.2链接数据库
cpp
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
const char *user, const char *passwd,
const char *db, unsigned int port,
const char *unix_socket,
unsigned long clientflag);
参数介绍:
mysql:是上一步mysql_init方法初始化后返回的指针。
host:是主机名,或者连接的服务器 IP 地址,也可以使用"localhost",或"127.0.0.1"或"" ,或NULL 。
user:是用户名,数据库中添加的用户,管理员是"root" 。
passwd:是用户的密码。
db:是数据库的名字。
port:默认是3306,也可直接写 0,意味着使用 mysql 默认端口。
unix_socket:一般为NULL,表示不使用 unix 套接字或者管道。
clientflag:标志位,一般给 0 。
返回值:失败为NULL,成功与第一个参数值相同。
3.3关闭链接
cpp
void mysql_close(MYSQL* mysql);
3.4执行sql语句
cpp
int mysql_query(MYSQL* mysql,const char* p);
3.5提取结果集
cpp
MYSQL_RES *mysql_store_result(MYSQL *mysql); // 一次性提取所有数据
//MYSQL_RES *mysql_use_result(MYSQL *mysql); // 一次提取一行数据
3.6获取结果集中有多少行
cpp
uint64_t mysql_num_rows(MYSQL_RES *res);
只有执行了mysql_store_result()之后,才可以调用该方法,获取结果集中的行数。如果没有返回行,则为 0 。
3.7取出结果集中的一行记录
cpp
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
释放内存
cpp
void mysql_free_result(MYSQL_RES *result);
小练习
cpp
int main()
{
MYSQL my;
MYSQL *use = mysql_init(NULL);
if (NULL == use)
{
exit(1);
}
if (mysql_real_connect(use, "127.0.0.1", "root",
"111111", "sq_2414", 3306, NULL, 0) == NULL)
{
printf("connect ERROR");
printf("%s",mysql_error(use));
exit(1);
}
printf("succeed\n");
char sql[128] = {0};
//
for(int i=0;i<10000;i++){
sprintf(sql,"insert into stu values (3,'XIAO',%d)",i);
if (mysql_query(use, sql) != 0)
{
mysql_ping(use);
printf("QERROR\n");
printf("%s", mysql_error(use));
// printf("%s",mysql_error(use));
}
}
exit(1);
}
// mysql_close(use);