学习笔记学习心得MySQL学习笔记-基础
LynxFrostMySQL学习笔记
| 名称 |
全称 |
简称 |
| 数据库 |
存储数据的仓库,数据是有组织的进行存储 |
DataBase (DB) |
| 数据库管理系统 |
操纵和管理数据库的大型软件 |
DataBase Management System (DBMS) |
| SQL |
操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准 |
Structured Query Language (SQL) |
net start mysql80 //启动mysql net stop mysql80 //停止mysql
mysql -h ip -P 端口 -u 用户名 -p 密码 //连接mysql
|
SQL
SQL通用语法
- SQL语句可以单行或者多行书写,以分号结尾
- SQL语句可以使用空格/缩进来增强语句的可读性
- MySQL数据的SQl语句不区分大小写,关键词建议用大写
- 注释:
- 单行注释:— 或者#(MySQL独有)
- 多行注释:/ /
SQL分类
| 分类 |
全称 |
说明 |
| DDL |
Data Definition Language |
数据定义语言,用来定义数据库对象(数据库,表,字段) |
| DML |
Data Manipulation Language |
数据操作语言,用来对数据库表中的数据进行增删改 |
| DQL |
Data Query Language |
数据查询语言,用来查询数据库中表的记录 |
| DCL |
Data Control Language |
数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
DDL
数据库操作
查询 查询所有数据库
查询当前数据库
创建
CREATE DATABASE [ IF NOT EXISTS ] 数据库名 [DEFAULT CHARSET 字符集] [COLLATE 排序规则];
|
推荐使用utf8mb4字符集,utf8只有4个字节
删除
DROP DATABASE [ IF EXISTS ] 数据库名;
|
使用
表操作-查询
查询当前数据库的所有表
查询表结构
查询指定表的建表语句
表操作-创建
CREATE TABLE 表名( 字段1 字段1类型 [COMMENT 字段1注释 ], 字段2 字段2类型 [COMMENT 字段2注释 ], 字段3 字段3类型 [COMMENT 字段3注释 ], ...... 字段n 字段n类型 [COMMENT 字段n注释 ] ) [ COMMENT 表注释 ];
|
数值类型
| 分类 |
类型 |
大小 |
有符号 (SIGNED) 范围 |
无符号 (UNSIGNED) 范围 |
描述 |
| 数值类型 |
TINYINT |
1 byte |
(-128, 127) |
(0, 255) |
小整数值 |
| 数值类型 |
SMALLINT |
2 bytes |
(-32768, 32767) |
(0, 65535) |
大整数值 |
| 数值类型 |
MEDIUMINT |
3 bytes |
(-8388608, 8388607) |
(0, 16777215) |
大整数值 |
| 数值类型 |
INT 或 INTEGER |
4 bytes |
(-2147483648, 2147483647) |
(0, 4294967295) |
大整数值 |
| 数值类型 |
BIGINT |
8 bytes |
(-2^63, 2^63-1) |
(0, 2^64-1) |
极大整数值 |
| 数值类型 |
FLOAT |
4 bytes |
(-3.402823466 E+38, 3.402823466351 E+38) |
0 和 (1.175494351 E-38, 3.402823466 E+38) |
单精度浮点数值 |
| 数值类型 |
DOUBLE |
8 bytes |
(-1.7976931348623157 E+308, 1.7976931348623157 E+308) |
0 和 (2.2250738585072014 E-308, 1.7976931348623157 E+308) |
双精度浮点数值 |
| 数值类型 |
DECIMAL |
|
依赖于 M (精度) 和 D (标度) 的值 |
依赖于 M (精度) 和 D (标度) 的值 |
小数值 (精确定点数) |
精度 数字的整体长度,标度 小数部分的长度
字符串类型
| 分类 |
类型 |
大小 |
描述 |
| 字符串类型 |
CHAR |
0-255 bytes |
定长字符串,性能好 |
| 字符串类型 |
VARCHAR |
0-65535 bytes |
变长字符串,性能较差 |
| 字符串类型 |
TINYBLOB |
0-255 bytes |
不超过 255 个字符的二进制数据 |
| 字符串类型 |
TINYTEXT |
0-255 bytes |
短文本字符串 |
| 字符串类型 |
BLOB |
0-65 535 bytes |
二进制形式的长文本数据 |
| 字符串类型 |
TEXT |
0-65 535 bytes |
长文本数据 |
| 字符串类型 |
MEDIUMBLOB |
0-16 777 215 bytes |
二进制形式的中等长度文本数据 |
| 字符串类型 |
MEDIUMTEXT |
0-16 777 215 bytes |
中等长度文本数据 |
| 字符串类型 |
LONGBLOB |
0-4 294 967 295 bytes |
二进制形式的极大文本数据 |
| 字符串类型 |
LONGTEXT |
0-4 294 967 295 bytes |
极大文本数据 |
时间日期类型
| 分类 |
类型 |
大小 |
范围 |
格式 |
描述 |
| 日期类型 |
DATE |
3 |
1000-01-01 至 9999-12-31 |
YYYY-MM-DD |
日期值 |
| 日期类型 |
TIME |
3 |
-838:59:59 至 838:59:59 |
HH:MM:SS |
时间值或持续时间 |
| 日期类型 |
YEAR |
1 |
1901 至 2155 |
YYYY |
年份值 |
| 日期类型 |
DATETIME |
8 |
1000-01-01 00:00:00 至 9999-12-31 23:59:59 |
YYYY-MM-DD HH:MM:SS |
混合日期和时间值 |
| 日期类型 |
TIMESTAMP |
4 |
1970-01-01 00:00:01 至 2038-01-19 03:14:07 |
YYYY-MM-DD HH:MM:SS |
混合日期和时间值,时间戳 |
表操作-修改
添加字段
ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT 注释] [约束];
|
修改数据类型(MODIFY,不改字段名)
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);
|
修改字段名 + 字段类型(CHANGE)
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT 注释] [约束];
|
删除字段
修改表名
ALTER TABLE 表名 RENAME TO 新表名;
|
删除表(IF EXISTS 防止表不存在时报错)
DROP TABLE [IF EXISTS] 表名;
|
清空表内所有数据,表结构保留(底层:删表再重建表)
DML
添加数据(INSERT)
给指定字段添加数据
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...);
|
给全部字段添加数据
INSERT INTO 表名 VALUES (值1, 值2, ...);
|
批量添加数据
INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...); INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, 值2, ...);
|
注意:
- 指定字段顺序必须与值的顺序一一对应
- 字符串和日期型数据要加引号
- 插入数据大小必须在字段规定范围内
更新和删除
更新
UPDATE 表名 SET 字段1=值1,字段2=值2,...[WHERE 条件];
|
删除
DELETE FROM 表名 [WHERE 条件]
|
DQL
SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表 LIMIT 分页参数;
|
执行顺序小提示(很重要,考试常考): FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
- WHERE:分组前过滤原始数据,不能用聚合函数
- HAVING:分组后过滤分组结果,可以使用聚合函数
基本SELECT
SELECT使用
SELECT * FROM 表名; SELECT 字段1, 字段2, 字段3 FROM 表名;
|
别名使用 AS
#as->alias #列的别名可以使用一对""引起来 #AS 可以省略 SELECT 字段名 AS 别名, 字段名 别名, 字段名 "别名", 字段名 * 12 别名 FROM 表名;
|
去除重复行 DISTINCT
#查询员工表一共有哪些部门id SELECT DISTINCT 字段名 FROM 表名
|
空值参与运算
#NULL不等同于0, '', 'null' SELECT * FROM employees; #空值参与运算结果也为NULL SELECT 字段1, 字段2 "月工资", 字段2 * (1 + 字段3) * 12 "年工资" FROM 表;
|
与关键字重名时使用着重号``
SELECT * FROM order;#错误 SELECT * FROM `order`;
|
查询常数,常量列每一行都一样,常用于添加固定标识、标记来源。
SELECT '常量值', 字段1, 字段2 FROM 表名;
|
| ‘ 常量值’ |
字段1 |
字段2 |
| 常量 |
字段1的值 |
字段2的值 |
| 常量 |
字段1的值 |
字段2的值 |
过滤数据WHERE
SELECT 字段列表 FROM 表名 WHERE 条件列表;
|
比较运算符
| 比较运算符 |
功能 |
| > |
大于 |
| >= |
大于等于 |
| < |
小于 |
| <= |
小于等于 |
| = |
等于 |
| <> 或!= |
不等于 |
| BETWEEN … AND … |
在某个范围之内(含最小、最大值) |
| IN(…) |
在 in 之后的列表中的值,多选 |
| LIKE 占位符 |
模糊匹配(_ 匹配单个字符,% 匹配任意个字符) |
| IS NULL |
是 NULL |
逻辑运算符
| 逻辑运算符 |
功能 |
| AND 或 && |
并且(多个条件同时成立) |
| OR 或 \ |
\ |
|
或者(多个条件任意一个成立) |
| NOT 或! |
非,不是 |
聚合函数
聚合函数介绍:将一列数据作为一个整体,进行纵向计算。
| 函数 |
功能 |
| count |
统计数量 |
| max |
最大值 |
| min |
最小值 |
| avg |
平均值 |
| sum |
求和 |
SELECT COUNT(*) FROM 表名; SELECT MAX(字段),MIN(字段),AVG(字段),SUM(字段) FROM 表名;
|
注意:聚合函数忽略 NULL 值
分组查询
SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];
|
WHERE 和 HAVING 的区别
- 执行时机不同:
WHERE:分组之前过滤,不满足 where 条件,不参与分组;HAVING:分组之后对结果进行过滤。
- 判断条件不同:
WHERE 不能对聚合函数进行判断;HAVING 可以使用聚合函数。
一句话记忆:where 先筛数据再分组,having 分组完再筛结果,只有 having 能用聚合函数。
排序查询
SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;
|
注意:多字段排序时,只有第一个字段值相同,才会按第二个字段排序。
分页查询
SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数;
|
注意:
- 起始索引从 0 开始; 公式:起始索引 = (查询页码 - 1) * 每页显示记录数
- 分页属于数据库方言,MySQL 使用
LIMIT,其他数据库语法不一样;
- 查询第 1 页数据时,起始索引可以省略,简写:
limit 10
示例:查询第 2 页,每页 10 条 起始索引 = (2-1)*10 =10
SELECT * FROM 表名 LIMIT 10,10;
|
DCL
数据库控制语言:管理数据库用户、控制数据库的访问权限
管理用户
1. 查询用户 USE mysql; SELECT * FROM user;
2. 创建用户 CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
3. 修改用户密码 ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码';
4. 删除用户 DROP USER '用户名'@'主机名';
|
权限管理
MySQL 常用权限:
| 权限 |
说明 |
| ALL, ALL PRIVILEGES |
所有权限 |
| SELECT |
查询数据 |
| INSERT |
插入数据 |
| UPDATE |
修改数据 |
| DELETE |
删除数据 |
| ALTER |
修改表 |
| DROP |
删除数据库 / 表 / 视图 |
| CREATE |
创建数据库 / 表 |
1. 查询权限 SHOW GRANTS FOR '用户名'@'主机名';
2. 授予权限 GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
3. 撤销权限 REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
|
函数
字符串函数
| 函数 |
功能 |
| CONCAT(S1,S2,…Sn) |
字符串拼接,将 S1,S2,…Sn 拼接成一个字符串 |
| LOWER(str) |
将字符串 str 全部转为小写 |
| UPPER(str) |
将字符串 str 全部转为大写 |
| LPAD(str,n,pad) |
左填充,用字符串 pad 对 str 的左边进行填充,达到 n 个字符串长度 |
| RPAD(str,n,pad) |
右填充,用字符串 pad 对 str 的右边进行填充,达到 n 个字符串长度 |
| TRIM(str) |
去掉字符串头部和尾部的空格 |
| SUBSTRING(str,start,len) |
返回从字符串 str 从 start 位置起的 len 个长度的字符串,索引值从1开始 |
数值函数
| 函数 |
功能 |
| CEIL(x) |
向上取整 |
| FLOOR(x) |
向下取整 |
| MOD(x,y) |
返回 x/y 的模 |
| RAND() |
返回 0~1 内的随机数 |
| ROUND(x,y) |
求参数 x 的四舍五入的值,保留 y 位小数 |
聚合函数
| 函数 |
功能 |
| COUNT |
计算指定列的行数或非空值的数量 |
| SUM |
计算指定列的数值之和 |
| AVG |
计算指定列的数值平均值 |
| MAX |
找出指定列的最大值 |
| MIN |
找出指定列的最小值 |
日期函数
| 函数 |
功能 |
| CURDATE() |
返回当前日期 |
| CURTIME() |
返回当前时间 |
| NOW() |
返回当前日期和时间 |
| YEAR(date) |
获取指定 date 的年份 |
| MONTH(date) |
获取指定 date 的月份 |
| DAY(date) |
获取指定 date 的日期 |
| DATE_ADD(date, INTERVAL expr type) |
返回一个日期 / 时间值加上一个时间间隔 expr 后的时间值 |
| DATEDIFF(date1,date2) |
返回起始时间 date1 和 结束时间 date2 之间的天数 |
流程函数
| 函数 |
功能 |
| IF(value,t,f) |
如果 value 为 true,则返回 t,否则返回 f |
| IFNULL(value1,value2) |
如果 value1 不为空,返回 value1,否则返回 value2 |
| CASE WHEN [val1] THEN [res1] … ELSE [default] END |
如果 val1 为 true,返回 res1,… 否则返回 default 默认值 |
| CASE [expr] WHEN [val1] THEN [res1] … ELSE [default] END |
如果 expr 的值等于 val1,返回 res1,… 否则返回 default 默认值 |
约束
| 约束 |
描述 |
关键字 |
| 非空约束 |
限制该字段的数据不能为 null |
NOT NULL |
| 唯一约束 |
保证该字段的所有数据都是唯一、不重复的 |
UNIQUE |
| 主键约束 |
主键是一行数据的唯一标识,要求非空且唯一 |
PRIMARY KEY |
| 默认约束 |
保存数据时,如果未指定该字段的值,则采用默认值 |
DEFAULT |
| 检查约束 (8.0.16 版本之后) |
保证字段值满足某一个条件 |
CHECK |
| 外键约束 |
用来让两张表的数据之间建立连接,保证数据的一致性和完整性 |
FOREIGN KEY |
NOT NULL 非空约束
CREATE TABLE user( id INT, name VARCHAR(20) NOT NULL );
ALTER TABLE user MODIFY COLUMN name VARCHAR(20) NOT NULL;
ALTER TABLE user MODIFY COLUMN name VARCHAR(20) NULL;
|
UNIQUE 唯一约束
CREATE TABLE user( id INT, phone VARCHAR(11) UNIQUE );
ALTER TABLE user ADD CONSTRAINT uk_phone UNIQUE(phone);
ALTER TABLE user DROP INDEX uk_phone;
|
PRIMARY KEY 主键约束(非空 + 唯一)
CREATE TABLE user( id INT PRIMARY KEY, name VARCHAR(20) );
CREATE TABLE user( id INT, no INT, PRIMARY KEY(id,no) );
ALTER TABLE user ADD PRIMARY KEY(id);
ALTER TABLE user DROP PRIMARY KEY;
|
自增AUTO_INCREMENT
CREATE TABLE user( id INT AUTO_INCREMENT PRIMARY KEY, no INT );
ALTER TABLE user MODIFY COLUMN id INT AUTO_INCREMENT PRIMARY KEY;
CREATE TABLE user( id INT AUTO_INCREMENT PRIMARY KEY, no INT ) AUTO_INCREMENT=100;
ALTER TABLE user MODIFY COLUMN id INT;
|
复合主键场景:不能两个字段都自增!
InnoDB 引擎下,复合主键只能把第一个字段设为自增,第二个字段不能自增
CREATE TABLE user( id INT AUTO_INCREMENT, no INT, PRIMARY KEY(id,no) );
|
错误写法:不能同时给 id 和 no 都加 AUTO_INCREMENT,MySQL 不支持。
AUTO_INCREMENT 只能给整型字段
- 一张表最多 1 个自增列
- 删除数据,自增计数器不会回退(删掉 id=3,下一条还是 4,不会变回 3)
- 复合主键推荐方案:单独加一个自增 id 作为单列主键,业务上用唯一约束保证 id+no 组合唯一(开发最常用)
CREATE TABLE user( id INT AUTO_INCREMENT PRIMARY KEY, no INT, UNIQUE uk_id_no(id,no) );
|
DEFAULT 默认约束
CREATE TABLE user( id INT, gender CHAR(1) DEFAULT '男' );
ALTER TABLE user MODIFY COLUMN gender CHAR(1) DEFAULT '男';
ALTER TABLE user MODIFY COLUMN gender CHAR(1);
|
CHECK 检查约束(MySQL8.0.16 + 才生效)
CREATE TABLE user( id INT, age INT CHECK(age>0) );
ALTER TABLE user ADD CONSTRAINT chk_age CHECK(age>0);
ALTER TABLE user DROP CHECK chk_age;
|
FOREIGN KEY 外键约束(关联两张表)
CREATE TABLE dept( id INT PRIMARY KEY, dept_name VARCHAR(20) );
CREATE TABLE emp( id INT PRIMARY KEY, name VARCHAR(20), dept_id INT, CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id) );
ALTER TABLE emp ADD CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id);
ALTER TABLE emp DROP FOREIGN KEY fk_emp_dept;
|
| 行为 |
说明 |
| NO ACTION |
父表删除 / 更新记录时,检查子表有无关联外键,有则禁止操作。和 RESTRICT 效果一致 |
| RESTRICT |
父表删除 / 更新记录时,检查子表有无关联外键,有则禁止操作。和 NO ACTION 效果一致 |
| CASCADE(级联) |
父表删除 / 更新记录,子表关联记录同步删除 / 更新 |
| SET NULL |
父表删除记录,子表对应的外键字段置为 NULL;前提:外键字段允许为 NULL |
| SET DEFAULT |
父表变更,子表外键设为默认值;InnoDB 引擎不支持 |
CREATE TABLE emp( id INT PRIMARY KEY, name VARCHAR(20), dept_id INT, CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id) ON UPDATE CASCADE ON DELETE CASCADE; );
CREATE TABLE emp( id INT PRIMARY KEY, name VARCHAR(20), dept_id INT, CONSTRAINT fk_emp_dept FOREIGN KEY(dept_id) REFERENCES dept(id) ON DELETE SET NULL );
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名(主表字段名) ON UPDATE CASCADE ON DELETE CASCADE;
|
多表查询
多表关系
- 一对多(多对一) 在多的一方建立外键,指向一的一方主键
- 多对多 建立中间表,中间表至少包含两个外键,分别关联两方主键
- 一对一 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一
内连接
隐式内连接
SELECT 字段列表 FROM 表 1 , 表 2 WHERE 条件 ... ;
|
显式内连接
SELECT 字段列表 FROM 表 1 [INNER] JOIN 表 2 ON 连接条件 ... ;
|
内连接查询的是两张表交集的部分
外连接
左外连接
SELECT 字段列表 FROM 表 1 LEFT [OUTER] JOIN 表 2 ON 条件 ... ;
|
相当于查询表 1 (左表) 的所有数据 包含 表 1 和表 2 交集部分的数据
右外连接
SELECT 字段列表 FROM 表 1 RIGHT [OUTER] JOIN 表 2 ON 条件 ... ;
|
相当于查询表 2 (右表) 的所有数据 包含 表 1 和表 2 交集部分的数据
自连接
SELECT 字段列表 FROM 表 A 别名 A JOIN 表 A 别名 B ON 条件 ... ;
|
自连接查询,可以是内连接查询,也可以是外连接查询。
联合查询
对于 union 查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
SELECT 字段列表 FROM 表 A ... UNION [ALL] SELECT 字段列表 FROM 表 B ...;
|
对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重。
子查询
概念:SQL 语句中嵌套 SELECT 语句,称为嵌套查询,又称子查询。
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
|
子查询外部的语句可以是INSERT / UPDATE / DELETE / SELECT的任何一个。
根据子查询结果不同,分为:
- 标量子查询:子查询结果为单个值
- 列子查询:子查询结果为一列
- 行子查询:子查询结果为一行
- 表子查询:子查询结果为多行多列
根据子查询位置,分为:
WHERE 之后、FROM 之后、SELECT 之后。
标量子查询
子查询的结果是一个单元格
列子查询
返回的结果是一列或多行。
常用操作符:
| 操作符 |
描述 |
| IN |
在指定的集合范围内,多选一 |
| NOT IN |
不在指定的集合范围内 |
| ANY |
子查询返回列表中,有任意一个满足即可 |
| SOME |
与ANY等同,使用SOME的地方都可以使用ANY |
| ALL |
子查询返回列表的所有值都必须满足 |
| EXISTS |
如果存在则返回结果 |
| NOT EXISTS |
用于查找不满足存在条件的记录 |
行子查询
返回的结果是一行(可以是多列) 常用操作符:=, <, >, IN, NOT IN
表子查询
返回的结果是多行多列,需要别名 常用操作符:IN
相关子查询
如果子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表,并进行了条件关联,因此每执行一次外部查询,子查询都要重新计算一次,这样的子查询就称之为关联子查询。
相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。
事务
事务是一组操作的集合,事务会把所有操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。
事务操作
# 方式一 #查看事务提交方式 SELECT @@AUTOCOMMIT; #设置事务提交方式,1为自动提交,0为手动提交,该设置只对当前会话有效 SET @@AUTOCOMMIT = 0; #此时为手动提交
#提交事务 COMMIT; #一开始没执行提交时是没有反应的,执行了提交,才会有下一步
#一旦出错 #回滚事务 ROLLBACK;
|
# 方式二
# 开启事务
START TRANSACTION 或 BEGIN TRANSACTION;
# 提交事务
COMMIT;
# 回滚事务
ROLLBACK;
|
事务四大特性(ACID)
- 原子性(Atomicity):事务是不可分割的最小操作但愿,要么全部成功,要么全部失败
- 一致性(Consistency):事务完成时,必须使所有数据都保持一致状态
- 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
- 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
并发事务问题
| 问题 |
描述 |
| 脏读 |
一个事务读到另一个事务还没提交的数据 |
| 不可重复读 |
一个事务先后读取同一条记录,但两次读取的数据不同 |
| 幻读 |
一个事务按照条件查询数据时,没有对应的数据行,但是再插入数据时,又发现这行数据已经存在 |
事务的隔离级别
| 隔离级别 |
脏读 |
不可重复读 |
幻读 |
| Read uncommitted(读未提交) |
√ |
√ |
√ |
| Read committed(读已提交) |
× |
√ |
√ |
| Repeatable Read(默认; 可重复读) |
× |
× |
√ |
| Serializable(可串行化) |
× |
× |
× |
- √ 表示在当前隔离级别下该问题会出现
- Serializable 性能最低;Read uncommitted 性能最高,数据安全性最差
- 事务隔离级别越高,数据越安全,但是性能越低
SELECT @@TRANSACTION_ISOLATION;
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE };
|