MySQL
MySQL
一、数据库概述
1 基础
数据库(DataBase):DB,存储数据的仓库,数据是有组织的进行存储。
数据库管理系统(DataBase Management System):DBMS,操纵和管理数据库的大型软件。
SQL(Structured Quer Language) :SQL语句。操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准
Mysql有商业版和免费版,商业版官方会提供技术支持。
关系型数据库(RDBMS):建立在关系模型基础上,由多张相互连接的二维表组成的数据库。Mysql是关系型数据库。
关系型数据库特点:
- 使用表存储数据,格式统一,便于维护。
- 使用SQL语言操作,标准统一,使用方便。
工作流程:Client链接DBMS,利用DBMS操作DB。
2 下载和管理
official::MySQL Community Downloads
安装:
- Type and Networking:next
- Authentication Method:next
- Accounts and Roles:设置root的用户密码。
- Windows Service:next
- Apply Configuration:next
服务管理:
win + R
——services.msc
——MySQL80
(Windows Service设置的名字)命令:
- 启动:
net start mysql80
- 停止:
net stop mysql80
连接:
- 工具:开始菜单——MySQL 8.0 Command Line Client - Unicode)——输入密码。
- 命令:
mysql [-h 127.0.0.1] [-P 3306] -u root -p
(IP和PORT不指定就是默认127.0.0.1:3306
)配置环境变量:环境变量——系统变量——
Path
——...\Mysql\Mysql Server 8.0\bin\
3 图形化界面
navicat
:official::Download Navicat
datagrip
:official::Download DataGrip
二、SQL语句
1 概念
SQL通用语法:
- SQL语句可以单行或多行书写,以分号结尾。
- SQL语句可以使用空格 / 缩进来增强语句的可读性。
- MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
- 注释:
- 单行注释:
-- 注释内容
或# 注释内容(MySQL特有)
(符号和注释间要有空格)- 多行注释:
/*注释内容*/
SQL分类:
- DDL(Data Definition Language):数据定义语言,用来定义数据库对象(数据库,表,字)。
- DML(Data Manipulation Language):数据操作语言,用来对数据库表中的数据进行增删改。
- DQL(Data Query Language):数据查询语言,用来查询数据库中表的记录。
- DCL(Data Control Language):数据控制语言,用来创建数据库用户、控制数据库的访问权限。
2 DDL
2.1 库操作
IF NOT EXISTS
用来对数据库是否存在进行判断,加上的话会自己判断,不加的话如果库存在再创建则会报错,IF EXISTS
同理。指定字符集合时,最好不要用
utf8
,而是使用utf8mb4
。因为utf8
默认每个字符3个字节,而有的特殊字符是4个字节,所以要用utf8mb4
。
utf8mb4_unicode_ci
:是针对utf8mb4
字符集的一个特定的排序规则,它提供了较为通用且对非英语字符友好的排序和比较,通常被认为是较为包容和准确的选择。
/* 基础语法 */ |
/* 案例 */ |
2.2 表操作
字段类型:MySQL 数据类型 | 菜鸟教程 (runoob.com)
常用类型:
TINYINT
:1字节(-128 - 127)。TINYINT UNSIGNED
:1字节(0 - 255)。UNSIGNED
表示无符号。INT
:4字节。DECIMAL(M, D)
:小数值。M(精度)表示整个数长度,D(标度)是小数部分。CHAR(n)
:定长字符串,长度n。假设n=10,即使只存了一个字符,此时存储长度也是10。性能好但是需要额外消耗空间。VARCHAR(n)
:变长字符串,长度n。假设n=10,如果存了一个字符,此时存储长度就是1。性能差但省空间。DATE
:年月日。DATETIME
:年月日时分秒。TIMESTAMP
:时间戳,只能到2038年。
/* 基础语法 */ |
/* 案例 */ |
3 DML
3.1 增删改
插入数据注意:
- 插入数据时,指定的字段顺序需要与值的顺序是一一对应的。
- 字符串和日期型数据应该包含在引号中。
- 插入的数据大小,应该在字段的规定范围内。
修改数据注意:修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据。
删除数据注意:
- DELETE语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据。
- DELETE语句不能删除某一个字段的值(可以使用UPDATE将某一字段设置为
null
)。
/* 基础语法 */ |
/* 案例 */ |
4 DQL
4.1 基本查询
查询语法的执行的顺序:
FROM
、WHERE
、GROUP BY
、HAVING
、SELECT
、ORDER BY
、LIMIT
/* 基础语法 */ |
/* 案例 */ |
4.2 条件查询
复杂条件查询:
<>
:就是!=
,表示不等于BETWEEN A AND B
:在A-B个范围(含最大和最小值)IN (...)
:在列表中的值,多选一,列表可以是查询结果(也就是嵌套select
)LIKE 占位符
:模糊匹配(_
匹配单个字符,%
匹配任意字符)IS NULL
:空。
/* 基础语法 */ |
/* 案例 */ |
4.3 聚合函数
常用聚合函数:
count、max、min、avg、sum
。注意:所有的
null
不参与聚合函数的运算。
/* 基础语法 */ |
/* 案例 */ |
4.4 分组查询
where
与having
区别:
- 执行时机不同:
where
是分组之前进行过滤,不满足where
条件,不参与分组;而having
是分组之后对结果进行过滤。- 判断条件不同:
where
不能对聚合函数进行判断,而having
可以。注意:
- 执行顺序:
where
> 聚合函数 >having
。- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。
/* 基础语法 */ |
/* 案例 */ |
4.5 排序查询
排序方式:
ASC
:升序(默认值)DESC
:降序注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。
/* 基础语法 */ |
/* 案例 */ |
4.6 分页查询
注意:
- 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT。
- 如果查询的索引是0,直接简写为limit 10。
/* 基础语法 */ |
/* 案例 */ |
5 DCL
5.1 用户设置
用户信息都存在系统user表中。
User表:
- Host:可以访问的主机地址,localhost表示只能本机访问,不能远程访问。设置任意主机访问填
%
- User:用户
/* 基础语法 */ |
/* 案例 */ |
5.2 权限控制
数据操作权限:
ALL, ALL PRIVILEGES
:授予用户对特定对象(如数据库、表等)的所有权限。
SELECT
:SELECT
权限允许用户执行SELECT
语句,即查询指定表中的数据。
INSERT
:允许用户向表中插入新的数据行。UPDATE
:允许用户修改表中已存在的数据。DELETE
:允许用户删除表中的数据行。结构操作权限:
CREATE
:允许用户创建新的数据库、表、索引、视图、触发器、存储过程等数据库对象。ALTER
:允许用户更改现有数据库对象的结构,如添加或删除列、修改列属性、重命名表等。DROP
:允许用户删除数据库对象,如删除表、索引、视图等。管理权限:
GRANT OPTION
:允许用户将自己拥有的权限进一步授予其他用户。REFERENCES
:允许用户在创建外键约束时引用其他表的键。INDEX
:允许用户创建或删除表上的索引。TRIGGER
:允许用户创建或删除触发器。EXECUTE
:允许用户执行存储过程和函数。特殊权限:
CREATE TEMPORARY TABLES
:允许用户创建临时表。LOCK TABLES
:允许用户锁定表,以便进行并发控制或备份操作。SHOW VIEW
:允许用户查看视图的定义。EVENT
:允许用户管理事件调度器中的事件。FILE
:允许用户读取、写入或删除服务器上的文件(可能有安全风险,通常不推荐使用)。系统权限:
SUPER
:提供高级管理权限,如关闭服务器、更改全局系统变量、执行KILL
命令等。PROCESS
:允许用户查看服务器中正在运行的线程和进程信息。RELOAD
:允许用户执行FLUSH
命令,如刷新表缓存、重载授权表等。SHUTDOWN
: 允许用户关闭 MySQL 服务器。注意:
- 多个权限之间,使用逗号分隔。
- 授权时,数据库名和表名可以使用*进行通配,代表所有。
/* 基础语法 */ |
/* 案例 */ |
6 约束
6.1 概念
定义:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
目的:保证数据库中数据的正确、有效性和完整性。
注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。
分类:
- 非空约束(NOT NULL):限制该字段的数据不能为null
- 唯一约束(UNIQUE):保证该字段的所有数据都是唯一、不重复的
- 主键约束(PRIMARY KEY):主键是一行数据的唯一标识,要求非空且唯一
- 默认约束(DEFAULT):保存数据时,如果未指定该字段的值,则采用默认值
- 检查约束(CHECK,8.0.16版本之后):保证字段值满足某一个条件
- 外键约束(FOREIGN KEY):用来让两张表的数据之间建立连接,保证数据的一致性和完整性
其他设置:
- 自增(AUTO_INCREMENT):每次增加字段时数值是当前字段的最大值加一,从1开始。
/* 案例 */ |
6.2 外键
外键约束:
NO ACTION
:默认。当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与RESTRCT
一致)RESTRICT
:当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与NO ACTION
一致)CASCADE
:当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。SET NULL
:当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求该外键允许取null)。SET DEFAULT
:父表有变更时,子表将外键列设置成一个默认的值(Innodb
不支持)
/* 基础语法 */ |
/* 案例 */ |
7 多表查询
7.1 多表关系
一对多:
- 案例:部门与员工的关系
- 关系:一个部门对应多个员工,一个员工对应一个部门
- 实现:在多的一方建立外键,指向一的一方的主键
多对多:
- 案例:学生与课程的关系
- 关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择
- 实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
多对一:
- 案例:用户与用户详情的关系
- 关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率
- 实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)
/* 案例 */ |
7.2 内联查询
概述:指从多张表中查询两张表相交的数据。
笛卡尔积:笛卡尔乘积是指在数学中,两个集合,A集合和B集合的所有组合情况。(在多表查询时,需要消除无效的笛卡尔积)
/* 语法 */ |
/* 案例 */ |
7.3 外连接查询
外连接:
- 左外连接:查询左表所有数据,以及两张表交集部分数据。
- 右外连接:查询右表所有数据,以及两张表交集部分数据。
外连接也要除无效的笛卡尔积。
/* 语法 */ |
/* 案例 */ |
7.4 自连接查询
自连接:当前表与自身的连接查询,自连接必须使用表别名。
/* 案例 */ |
7.5 联合查询
对于union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
union all
会将全部的数据直接合并在一起,union
会对合并之后的数据去重。
/* 语法 */ |
/* 案例 */ |
7.6 子查询
概念:SQL语句中嵌套
SELECT
语句,称为嵌套查询,又称子查询。子查询外部的语句可以是
INSERT / UPDATE/ DELETE/ SELECT
的任何一个。根据子查询结果不同,分为:
- 标量子查询:子查询结果为单个值,常用
=, <>, >
等操作符操作数据。- 列子查询:子查询结果为一列,常用
IN, NOT IN, ANY, SOME, ALL
等对数据做操作。ANY
和SOME
意思相同,都是有一个满足即可。ALL
则是要满足子查询所有数据。- 行子查询:子查询结果为一行,常用
=, <>, >
等操作符操作数据。- 表子查询:子查询结果为多行多列。常用
IN
对数据做操作。
/* 语法 */ |
/* 案例 */ |
三、函数
1 字符串函数
/* 基础语法 */ |
/* 案例 */ |
2 数值函数
/* 基础语法 */ |
3 日期函数
/* 基础语法 */ |
/* 案例 */ |
4 流程控制函数
/* 基础语法 */ |
/* 案例 */ |
四、事务
1 概述
事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。
事务特性(ACID):
- 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
- 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
- 隔离性(lsolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
/* 基础语法 */ |
/* 案例 */ |
2 并发事务
问题:
- 脏读:一个事务读到另外一个事务还没有提交的数据。
- 不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。
- 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了”幻影”。
/* 案例 */ |
3 事务隔离级别
分类:
- Read uncommitted:可读未提交。事务可以读取其他未提交事务所做的修改。因此可能会出现脏读和不可重复读的问题。这种隔离级别的优点是读取数据的性能较高,但缺点是可能会导致一定程度的数据不一致。
- Read committed:读已提交。事务只能读取已经提交的数据,无法读取未提交的数据。这种隔离级别可以避免脏读,但仍可能出现不可重复读和幻读的问题。
- Repeatable Read:可重复读。事务在读取数据时会保持一致性,因此在同一个事务内多次读取相同数据,结果都是一样的。这种隔离级别可以避免脏读和不可重复读,但仍可能出现幻读的问题。
- Serializable:串行化。事务彼此之间完全隔离,每个事务运行时都像是在系统中独自运行一样。这种隔离级别保证了数据的一致性,避免了脏读、不可重复读和幻读的问题。但串行化的隔离级别会降低数据库的并发性能,因为事务需要按顺序依次执行。
从上向下,性能越来越差,数据越来越安全。
隔离级别 \ | 会出现的问题 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|
Read uncommitted | √ | √ | √ | |
Read committed(Oracle默认) | x | √ | √ | |
Repeatable Read(Mysql默认) | x | x | √ | |
Serializable | x | x | x |
/* 基础语法 */ |
/* 案例 */ |
五、存储引擎
1 概述
MySQL体系结构:
- 连接层:最上层是一些客户端和链接服务,主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。包括:认证授权、线程管理、连接数限制、检查内存等。
- 服务层:第二层架构主要完成大多数的核心服务功能。提供SQL接口、解析器、查询优化器、缓存等。所有跨存储引擎的功能也在这一层实现,如过程、函数等。
- 引擎层:存储引擎真正的负责了MySQL中数据的存储和提取,提供可插拔的存储引擎,服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能,可以使用不同的存储引擎来存储数据。索引是在存储引擎层实现的。
- 存储层:主要是将数据存储在文件系统之上,并完成与存储引擎的交互。包括系统文件、文件和日志等。
存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。
存储引擎是MySQL特有的。
存储引擎是基于表的,而不是基于库的,一个库下面的不同的表可以选择不同的存储引擎。所以存储引擎也可被称为表类型。
2 使用存储引擎
在创建表时候可以选择存储引擎,如果不指定默认是
InnoDB
/* 基础语法 */ |
/* 案例 */ |
3 InnoDB
定义:
InnoDB
是一种兼顾高可靠性和高性能的通用存储引擎,在MySQL 5.5
之后,InnoDB
是默认的MySQL
存储引擎。特点:
- 事务:
DML
操作遵循ACID
模型,支持事务。- 行级锁:行级锁,提高并发访问性能。
- 外键:支持外键
FOREIGN KEY
约束,保证数据的完整性和正确性。文件:
xxx.ibd
:xx
代表的是表名,innoDB
引擎的每张表都会对应这样一个表空间文件,存储该表的表结构(frm、sdi
)、数据和索引。参数:innodb_file_per_table
。8.0
以前表结构存储在frm
中,8.0
以后存储在sdi
这个数据字典中。查看数据:首先找到MySQL8.0——Data——库名,然后在该路径下打开
cmd
,输入ibd2sdi xxx.ibd
,表示将idb
显示为sdi
,就可以看到里面的数据了。直接打开看到的是二进制。逻辑存储结构:
- Tablespece:表空间,表空间下有若干个段。
- Segment:段,段空间下有若干个区。
- Extent:区,区空间下有若干个页。大小固定,1M,最多包含64个页。
- Page:页,页空间下有若干个行。磁盘操作的最小单元。大小固定,16K。
- Row:行。包括
Trx id
(最后一次操作事务的id
),Roll pointer
(指针),若干个col
(字段)
/* 基础语法 */ |
4 MyISAM
介绍:MyISAM是MySQL早期的默认存储引擎。
特点:
- 不支持事务,不支持外键。
- 支持表锁,不支持行锁。
- 访问速度快。
相关文件:
MYD
:存放数据。MYI
:存放所索引。sdi
:存放表结构的信息。可以直接查看,JSON格式。
5 Memory
介绍:Memory引擎的表数据时存储在内存中的,由于受到硬件问题、或断电问题的影响,只能将这些表作为临时表或缓存使用。
特点:
- 内存存放
- hash索引(默认)
文件:
xxx.sdi
,存储表结构信息。
6 存储引擎选择
在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合:
InnoDB
:是Mysql的默认存储引擎,支持事务、外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询之外,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。MyISAM
:如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。MEMORY
:将所有数据保存在内存中,访问速度快,通常用于临时表及缓存。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,而且无法保障数据的安全性。但是实际上
MySQL
几乎只会使用InnoDB
存储引擎,MyISAM
引擎的作用现在常用MongoDB
数据库替代,MEMORY
引擎的作用现在常用Redis
数据库替代。
六、索引
1 定义
定义:是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
简述:索引是一种数据结构,用于高效地获取数据。
案例:
select * from user where age = 45
:
- 无索引:全表扫描,从上到下依次匹配。时间:
O(n)
- 有索引:可以建立一个二叉搜索树(只是案例,实际上不是二叉搜索树),时间:
O(logn)
优点:
- 提高数据检索的效率,降低数据库的IO成本。
- 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。
缺点:
- 索引列也是要占用空间的。(实际上现在空间问题几乎可以忽略)
- 索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE时,效率降低。(实际上一个正常的系统大多数查,增删改比例较少)
2 索引结构
MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的结构。
B+Tree索引:MySQL索引数据结构对经典的B+Tree进行了优化。在原B+Tree的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的B+Tree,提高区间访问的性能。其中,每一个B+Tree结点(包括叶子节点)都是一个页。
简单来说MySQL的B+Tree索引就是:原来的B+Tree是单向链表,MySQL改成了双向循环链表。
在MySQL中,支持hash索引的是Memory引擎,而InnoDB中具有自适应hash功能,hash索引是存储引擎根据B+Tree索引在指定条件下自动构建的。
为什么使用B+tree索引结构:
- 相对于二叉树,层级更少,搜索效率高。
- 对于BTree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低。
- 同时B+Tree的链表可以用于范围查找。
索引结构 | 描述 | InnoDB | MyISAM | Memory |
---|---|---|---|---|
B+Tree索引 | 最常见的索引类型,大部分引擎都支持B+树索引。使用较多。 | √ | √ | √ |
Hash索引 | 底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询 | x | x | √ |
R-tree(空间索引) | 空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少 | x | √ | x |
Full-text(全文索引) | 是一种通过建立倒排索引,快速匹配文档的方式。类似于Lucene,Solr,ES,通常使用较少 | 5.6版本后支持 | √ | x |
3 索引分类
普通索引分类 | 含义 | 特点 | 关键字 |
---|---|---|---|
主键索引 | 针对于表中主键创建的索引 | 默认自动创建,只能有一个 | PRIMARY |
唯一索引 | 避免同一个表中某数据列中的值重复 | 可以有多个 | UNIQUE |
常规索引 | 快速定位特定数据 | 可以有多个 | |
全文索引 | 全文索引查找的是文本中的关键词,而不是比较索引中的值 | 可以有多个 | FULLTEXT |
在InnoDB存储引擎中,根据索引的存储形式,分成:
- 聚集索引(Clustered Index):将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据。必须有,而且只有一个。简单来说就是B+Tree的叶子节点,key是主键值,value是那一行的数据。
- 二级索引(Secondary Index):将数据与索引分开存储(像B+Tree),索引结构的叶子节点关联的是对应的主键。可以有多个。简单来说就是B+Tree的叶子节点,key是对应值,value是主键值。
聚集索引选取规则:
- 如果存在主键,主键索引就是聚集索引。
- 如果不存在主键,将使用第一个唯一索引(UNIQUE)作为聚集索引。
- 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。
案例
select * from user where name="Arm"
:先通过二级索引name,找到Arm对应的主键值(id),再用id到聚集索引id中,定位到id对应的行数据,然后返回那一行的数据。该过程的专业术语为回表查询。