MySQL
数据库
数据库:DataBase(DB),是存储和管理数据的仓库
数据库管理系统:DataBase Management System(DBMS),操纵和管理数据库的大型软件
SQL:Structured Query Language,操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准
MySQL
- 将数据库软件压缩包解压
- 将软件文件夹中的bin文件添加到环境变量中

- 以管理员身份打开CMD,并依次输入以下命令:
1 | mysqld --initialize-insecure |
- 登录参数:
1 | mysql -u用户名 -p密码 -h要连接的mysql服务器的ip地址(默认127.0.0.1) -P端口号(默认3306) |
MySQL数据模型
- 关系型数据库:建立在关系模型基础上,由多张相互连接的二维表组成的数据库
- 特点:
- 使用表存储数据,格式统一,便于维护
- 使用SQL语言操作,标准统一,使用方便,可用于复杂查询
创建数据库命令:
1 | create database xxxx; |
SQL
- SQL:一门操作关系型数据库的编程语言,定义操作所有关系型数据库的统一标准
- 分类:
分类 | 全称 | 说明 |
---|---|---|
DDL | Data Definition Language | 数据定义语言,用来定义数据库对象(数据库,表,字段) |
DML | Data Manipulation Language | 数据操作语言,用来对数据库表中的数据进行增删改 |
DQL | Data Query Language | 数据查询语言,用来查询数据库表的记录 |
DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
DDL
库操作
- 操作语法
1 | --查询所有数据库(注意复数形式) |
表操作
- 创建表的语法:
1 | create table tablename( |
案例说明:
1 | create table user( |
最终结构如下:
id | username | name | age | gender |
---|---|---|---|---|
… | … | … | … | … |
约束
- 约束:约束时作用于表中字段上的规则,用于限制存储在表中的数据
- 目的:保证数据库中数据的正确性、有效性和完整性
常见约束如下:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段值不能为null | not null |
唯一约束 | 保证字段的所有数据都是唯一、不重复的 | unique |
主键约束 | 主键是一行数据的唯一表示,要求非空且唯一 | primary key |
默认约束 | 保存数据时,如果未指定该字段值,则采用默认值 | default |
外键约束 | 让两张表的数据建立连接,保证数据的一致性和完整性 | foreign key |
将之前的案例进行优化:
1 | create table user( |
想要让主键自动增长,输入auto_increment
即可
1 | id int primary key auto_increment comment 'ID,唯一标识' |
数据类型
数值类型
数据类型 | 描述 |
---|---|
TINYINT |
非常小的整数(-128 到 127) |
SMALLINT |
小整数(-32,768 到 32,767) |
MEDIUMINT |
中等大小的整数(-8,388,608 到 8,388,607) |
INT |
普通整数(-2,147,483,648 到 2,147,483,647) |
BIGINT |
大整数(-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807) |
FLOAT |
单精度浮点数 |
DOUBLE |
双精度浮点数 |
DECIMAL |
固定小数点数 |
字符串类型
数据类型 | 描述 |
---|---|
CHAR |
定长字符串 |
VARCHAR |
变长字符串 |
TINYTEXT |
非常小的文本 |
TEXT |
小文本 |
MEDIUMTEXT |
中等大小的文本 |
LONGTEXT |
大文本 |
BINARY |
定长二进制数据 |
VARBINARY |
变长二进制数据 |
TINYBLOB |
非常小的BLOB数据 |
BLOB |
小BLOB数据 |
MEDIUMBLOB |
中等大小的BLOB数据 |
LONGBLOB |
大BLOB数据 |
ENUM |
枚举类型 |
SET |
集合类型 |
日期和时间类型
数据类型 | 描述 |
---|---|
DATE |
日期值(YYYY-MM-DD) |
TIME |
时间值(HH:MM:SS) |
DATETIME |
日期和时间值(YYYY-MM-DD HH:MM:SS) |
TIMESTAMP |
时间戳(YYYY-MM-DD HH:MM:SS),存储从1970年1月1日以来的秒数 |
YEAR |
年份值(YYYY) |
空间数据类型(Spatial Data Types)
数据类型 | 描述 |
---|---|
GEOMETRY |
几何数据的通用类型 |
POINT |
一个点 |
LINESTRING |
一条线 |
POLYGON |
多边形 |
MULTIPOINT |
多个点 |
MULTILINESTRING |
多条线 |
MULTIPOLYGON |
多个多边形 |
GEOMETRYCOLLECTION |
几何数据集合 |
查询、修改、删除表
- 表结构的查询、修改、删除相关语法如下:
1 | show tables; -- 查询当前数据库的所有表 |
DML
- DML英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增、删、改操作
- 添加数据(INSERT)
- 修改数据(UPDATE)
- 删除数据(DELETE)
添加数据——Insert
1 | -- 指定字段添加数据 |
修改数据——update
1 | -- 修改数据 |
注意:修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据
删除数据——delete
1 | -- 删除数据 |
注意:
- DELETE 语句的条件可以有,也可以没有,如果没有条件,则删除整张表的所有数据
- DELETE 语句不能删除某一个字段的值(如果要操作,可以使用update,将该字段值设为NULL)
DQL
- DQL英文全称是Data Query Language(数据查询语言),用来查询数据库表中的记录
- 关键字:Select
完整的DQL语句语法:
1 | select |
- 基本查询:
select ... from ...
- 条件查询:
where
- 分组查询:
group by
- 排序查询:
order by
- 分页查询:
limit
基本查询
1 | -- 查询多个字段 |
条件查询
1 | -- 条件查询 |
条件列表中可以使用比较运算符和逻辑运算符
比较运算符 | 功能 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
= | 等于 |
<> 或 != | 不等于 |
between … and … | 在某个范围之内(含最小值,最大值) |
in(…) | 在in之后的列表中的值,多选一 |
like 占位符 | 模糊匹配(_匹配单个字符, %匹配任意个字符) |
is null | 是null值(非空值 is not null) |
逻辑运算符 | 功能 |
---|---|
and 或 && | 并且(多个条件同时成立) |
or 或 || | 或者(多个条件任意一个成立) |
not 或 ! | 非 , 不是 |
举例:
1 | SELECT * FROM xxx WHERE 字段名 = xxx; |
分组查询
聚合函数:将一列数据作为一个整体,进行纵向计算
函数 | 功能 |
---|---|
count | 统计数量(NULL值不统计) |
max | 最大值 |
min | 最小值 |
avg | 平均值 |
sum | 求和 |
1 | SELECT COUNT(*) FROM 表名; |
1 | --分组查询 |
- where与having的区别:
- 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤
- 判断条件不同:where不能对聚合函数进行判断,而having可以
单独使用group by:
1 | SELECT 字段名, COUNT(*) FROM 表名 GROUP BY 字段名; |
结合having使用:
1 | SELECT 字段名, COUNT(*) FROM 表名 GROUP BY 字段名 HAVING COUNT(*) > 1; |
实际案例:
1 | select gender, count(*) from emp group by gender; |
结果:
gender | count(*) |
---|---|
Male | 45 |
Female | 35 |
Other | 5 |
解释:
SELECT gender, count(*): 选择
gender
列,并计算每个性别的员工数量。FROM emp: 数据来源于
emp
表。GROUP BY gender: 按照
gender
列对数据进行分组。
排序查询
1 | -- 排序查询 |
- 排序方式:升序(asc),降序(desc);默认为升序asc,也就是可以不写采用默认方式
举例:
假设表为:
department | total_employees |
---|---|
Sales | 5 |
IT | 5 |
Marketing | 3 |
HR | 2 |
Finance | 2 |
1 | SELECT department, COUNT(*) AS total_employees |
结果:
department | total_employees |
---|---|
Sales | 15 |
Marketing | 12 |
IT | 10 |
HR | 5 |
Finance | 3 |
说明:
SELECT department, COUNT(*) AS total_employees: 选择
department
列,并计算每个部门的员工数量,结果列名为total_employees
。FROM employees: 数据来源于
employees
表。GROUP BY department: 按照
department
列对数据进行分组。HAVING COUNT(*) > 1: 过滤分组后的结果,只保留员工总数大于1的部门。
ORDER BY total_employees DESC: 按照
total_employees
列进行降序排列
分页查询
1 | -- 排序查询 |
说明:
- 起始索引从0开始
- 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT
- 如果起始索引为0,起始索引可以省略,直接简写为
limit 10
举例:
假设表为:
id | name | department |
---|---|---|
1 | Alice | Sales |
2 | Bob | Sales |
3 | Charlie | Marketing |
4 | David | Marketing |
5 | Eva | IT |
6 | Frank | IT |
7 | Grace | IT |
8 | Hannah | HR |
9 | Ivy | HR |
10 | Jack | Finance |
11 | Kevin | Finance |
12 | Liam | Sales |
13 | Mia | Sales |
14 | Nina | Marketing |
15 | Oliver | IT |
1 | SELECT department, COUNT(*) AS total_employees |
结果:
department | total_employees |
---|---|
Sales | 4 |
IT | 4 |
Marketing | 3 |
解释:
- SELECT department, COUNT(*) AS total_employees:选择
department
列,并计算每个部门的员工总数,结果列名为total_employees
。 - FROM employees:数据来源于
employees
表。 - WHERE department IS NOT NULL:条件是部门不为空。
- GROUP BY department:按照
department
列对数据进行分组。 - HAVING COUNT(*) > 1:过滤分组后的结果,只保留员工总数大于1的部门。
- ORDER BY total_employees DESC:按照员工总数降序排列。
- LIMIT 0, 3:限制查询结果的起始索引为0,并显示前3个记录。
多表关系
- 项目开发中,在进行数据库表结构设计时,会根据业务需求以及业务模块之间的关系,分析并设计表结构。由于业务之间相互关联,所以各个表结构之间也存在着各种联系
- 多表关系分为三种:
- 一对多(多对一)
- 一对一
- 多对多
一对多(多对一)
场景:部门与员工的关系(一个部门下有多个员工)
实现思路:在数据库表中
多
的一方(子表),添加字段,来关联一的一方的主键
多表问题
- 问题:当父表删除某个数据后,子表依旧会关联父表被删除的数据,导致数据不完整、不一致
- 原因:虽然逻辑上,父表与子表关联,但在数据库层面,并未直接建立关联,所以是无法保证数据的一致性和完整性
- 解决方案:外键约束
外键约束
- 可以在创建时或表结构创建完成后,为字段添加外键约束
1 | -- 创建表时指定 |
1 | -- 建完表后,添加外键 |
dept:
id | name | create_time | update_time |
---|---|---|---|
1 | 学工部 | 2023-09-25 09:47:40 | 2023-09-25 09:47:40 |
2 | 教研部 | 2023-09-25 09:47:40 | 2023-10-09 15:17:04 |
3 | 咨询部2 | 2023-09-25 09:47:40 | 2023-11-30 21:26:24 |
4 | 就业部 | 2023-09-25 09:47:40 | 2023-09-25 09:47:40 |
5 | 人事部 | 2023-09-25 09:47:40 | 2023-09-25 09:47:40 |
15 | 行政部 | 2023-11-30 20:56:37 | 2023-11-30 20:56:37 |
emp:
id | username | password | name | gender | phone | job | salary | image | entry_date | dept_id(外键) | create_time | update_time |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | shinaian | 123456 | 施耐庵 | 1 | 13309090001 | 4 | 15000 | 5.png | 2000-01-01 | 2 | 2023-10-20 16:35:33 | 2023-11-16 16:11:26 |
2 | songjiang | 123456 | 宋江 | 1 | 13309090002 | 2 | 8600 | 01.png | 2015-01-01 | 2 | 2023-10-20 16:35:33 | 2023-10-20 16:35:37 |
3 | lujunyi | 123456 | 卢俊义 | 1 | 13309090003 | 2 | 8900 | 01.png | 2008-05-01 | 1 | 2023-10-20 16:35:33 | 2023-10-20 16:35:39 |
4 | wuyong | 123456 | 吴用 | 1 | 13309090004 | 2 | 9200 | 01.png | 2007-01-01 | 1 | 2023-10-20 16:35:33 | 2023-10-20 16:35:41 |
5 | gongsunsheng | 123456 | 公孙胜 | 1 | 13309090005 | 2 | 9500 | 01.png | 2012-12-05 | 2 | 2023-10-20 16:35:33 | 2023-10-20 16:35:43 |
查看表之间关系
物理外键
- 概念:使用
foreign key
定义外键关联另一张表 - 缺点:
- 影响增删改的效率(需要检查外键关系)
- 仅用于单节点数据库,不适用于分布式、集群场景
- 容易引发数据库的死锁问题,消耗性能
一对一
案例:用户与身份证信息的关系
关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他字段放在另一张表中,以提升操作效率
实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
tb_user:
id | name | gender | phone | degree |
---|---|---|---|---|
1 | 白眉鹰王 | 1 | 18812340001 | 初中 |
2 | 青翼蝠王 | 1 | 18812340002 | 大专 |
3 | 金毛狮王 | 1 | 18812340003 | 初中 |
4 | 紫衫龙王 | 2 | 18812340004 | 硕士 |
tb_user_card:
id | nationality | birthday | idcard | issued | expire_begin | expire_end | user_id |
---|---|---|---|---|---|---|---|
1 | 汉 | 1960-11-06 | 100000100000100001 | 朝阳区公安局 | 2000-06-10 | NULL | 1 |
2 | 汉 | 1971-11-06 | 100000100000100002 | 静安区公安局 | 2005-06-10 | 2025-06-10 | 2 |
3 | 汉 | 1963-11-06 | 100000100000100003 | 昌平区公安局 | 2006-06-10 | NULL | 3 |
4 | 回 | 1980-11-06 | 100000100000100004 | 海淀区公安局 | 2008-06-10 | 2028-06-10 | 4 |
多对多
- 案例:学生与课程的关系
- 关系:一个学生可以选秀多门课程,一门课程也可以供多个学生选择
- 实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
tb_student:
id | name | no |
---|---|---|
1 | 张三 | 200100101 |
2 | 李四 | 200100102 |
3 | 王五 | 200100103 |
4 | 赵六 | 200100104 |
tb_course:
id | name |
---|---|
1 | Java |
2 | PHP |
3 | MySQL |
4 | Hadoop |
tb_student_course:
id | studentid | courseid |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 1 | 3 |
4 | 2 | 1 |
5 | 2 | 4 |
多表设计案例
- 需求:
emp(1)➡emp_expr(n)
emp_expr:
1 | -- 表:dept(1)➡emp(n) || emp(1)➡emp_expr(n) |
多表查询
- 多表查询:指从多张表中查询数据
数据准备
dept:
id | name | create_time | update_time |
---|---|---|---|
1 | 学工部 | current_timestamp | current_timestamp |
2 | 教研部 | current_timestamp | current_timestamp |
3 | 咨询部 | current_timestamp | current_timestamp |
4 | 就业部 | current_timestamp | current_timestamp |
5 | 人事部 | current_timestamp | current_timestamp |
emp:
id | username | password | name | gender | phone | job | salary | image | entry_date | dept_id | create_time | update_time |
---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | shinaian | 123456 | 施耐庵 | 男 (1) | 13309090001 | 4 | 15000 | http://…… | 2000-01-01 | 2 | 2024-10-27 16:35:33 | 2024-10-27 16:35:35 |
2 | songjiang | 123456 | 宋江 | 男 (1) | 13309090002 | 2 | 8600 | http://…… | 2015-01-01 | 2 | 2024-10-27 16:35:33 | 2024-10-27 16:35:37 |
3 | lujunyi | 123456 | 卢俊义 | 男 (1) | 13309090003 | 2 | 8900 | http://…… | 2008-05-01 | 2 | 2024-10-27 16:35:33 | 2024-10-27 16:35:39 |
4 | wuyong | 123456 | 吴用 | 男 (1) | 13309090004 | 2 | 9200 | http://…… | 2007-01-01 | 2 | 2024-10-27 16:35:33 | 2024-10-27 16:35:41 |
5 | gongsunsheng | 123456 | 公孙胜 | 男 (1) | 13309090005 | 2 | 9500 | http://…… | 2012-12-05 | 2 | 2024-10-27 16:35:33 | 2024-10-27 16:35:43 |
6 | huosanniang | 123456 | 扈三娘 | 女 (2) | 13309090006 | 3 | 6500 | http://…… | 2013-09-05 | 1 | 2024-10-27 16:35:33 | 2024-10-27 16:35:45 |
多表查询基本SQL语句
1 | select * from emp, dept; |
如果直接使用以上SQL语句查询,会出现很多无效数据
为了避免出现上述问题,在查询时要附带条件查询
1 | select * from emp, dept where emp.dept_id = dept.id; |
连接查询
- 内连接:相当于查询A、B交集部分数据
- 外连接:
- 左外连接:查询左表所有数据(包括两张表交集部分数据)
- 右外连接:查询右表所有数据(包括两张表交集部分数据)

内连接
内连接查询的是两张表交集部分的数据。具体语法为:
1 | -- 1. 隐式内连接(常见) |
案例:
1 | -- ============================= 内连接 ========================== |
外连接
- 外连接分为左外连接和右外连接。具体语法为:
1 | -- 1. 左外连接(常见) |
案例:
1 | -- =============================== 外连接 ============================ |
子查询
- 介绍:SQL语句中嵌套select语句,称为嵌套查询,又称子查询
- 形式:
select * from t1 where column1 = (select column1 from t2 ...);
- 说明:子查询外部的语句可以是
insert
/update
/delete
/select
的任何一个,最常见的是select
- 分类:
- 标量子查询:子查询返回的结果为单个值
- 列子查询:子查询返回的结果为一列
- 行子查询:子查询返回的结果为一行
- 表子查询:子查询返回的结果为多行多列
- 要点:子查询的要点是,先对需求做拆分,明确具体步骤,再逐步编写SQL语句
案例:
1 | -- ========================= 子查询 ================================ |
综合案例
1 | -- 需求: |
MySQL图形化工具
- 介绍:DataGrip是JetBrains旗下的一款数据库管理工具,是管理和开发MySQL、Oracle、PostgreSQL的理想解决方案
- 官网:https://www.jetbrains.com/zh-cn/datagrip/
- 安装以及使用文档:DataGrip安装文档 - 飞书云文档