MySQL学习笔记
登录登出
-- 登录数据库服务器
$ mysql -uroot -p1234
-- 登出数据库服务器
exit;
基本语法
-- 显示所有数据库
show databases;
-- 创建数据库
CREATE DATABASE databaseName;
-- 切换数据库
USE databaseName;
-- 删除数据库
DROP DATABASE databaseName;
-- 显示数据库中的所有表
show tables;
-- 创建表
CREATE TABLE pet (
name VARCHAR(20),
owner VARCHAR(20),
species VARCHAR(20),
gender CHAR(1),
birth DATE,
death DATE
);
-- 删除表
DROP TABLE pet;
-- 查看表结构
DESC pet;
-- 插入数据 - 增
INSERT INTO pet VALUES ("jiaomei","lily","dog","male","2025-01-01","2035-01-01");
INSERT INTO pet (name,owner) VALUES ("jiaomei","lily");
-- 删除数据 - 删
DELETE FROM pet WHERE owner="lily";
-- 修改数据 - 改
UPDATE pet SET name="gouzi" WHERE owner="lily";
-- 查询表 - 查
SELECT * FROM pet;
数据类型
- 数值 : INT , FLOAT , DOUBLE .. ;
- 日期/时间 : DATE , DATETIME .. ;
- 字符串 : CHAR , VARCHAR .. .
建表约束
- 主键约束
在表中定义一个主键以唯一确定表中每一行数据的标识符 .
只要 联合的主键值不完全相同 且 联合的主键值中的任何一个字段不为空 即可 .
-- 主键约束
-- 在表中定义一个主键以唯一确定表中每一行数据的标识符
-- 定义为主键的字段不重复且不为空 以确保表内所有数据的唯一性
CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(20)
);
-- 联合主键
-- 联合主键中的每个字段不为空 且加起来不能和已设置的联合主键重复
CREATE TABLE user (
id INT,
name VARCHAR(20),
passwd VARCHAR(20),
PRIMARY KEY (id, name)
);
-- 添加主键约束
-- 如果在建表时未设置主键 可通过SQL语句设置(两种方式)
ALTER TABLE user ADD PRIMARY KEY (id);
ALTER TABLE user MODIFY id INT PRIMARY KEY;
-- 删除主键约束
ALTER TABLE user DROP PRIMARY KEY;
- 自增约束
同主键约束搭配使用 .
-- 自增约束和主键约束搭配使用 且自增约束的主键由系统自动递增分配
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);
- 唯一约束
保证一个字段或一组字段里的数据与表中其它行数据相比是唯一的 .
- 主键约束 - 值不为空
- 唯一约束 - 值可为空
-- 唯一约束
CREATE TABLE user (
id INT,
name VARCHAR(20),
UNIQUE (name)
);
-- 添加唯一约束
-- 如果在建表时未设置唯一键 可通过SQL语句设置(两种方式)
ALTER TABLE user ADD UNIQUE (name);
ALTER TABLE user MODIFY name VARCHAR(20) UNIQUE;
-- 删除唯一约束
ALTER TABLE user DROP INDEX name;
- 非空约束
保证某个字段不能为空 .
-- 建表时设置非空约束 约束某个字段不能为空
CREATE TABLE user (
id INT,
name VARCHAR(20) NOT NULL
);
-- 删除非空约束
ALTER TABLE user MODIFY name VARCHAR(20);
- 默认约束
保证某个字段有默认值 .
-- 建表时设置默认约束 约束某个字段的默认值
CREATE TABLE user (
id INT,
name VARCHAR(20),
age INT DEFAULT 20
);
-- 删除默认约束
ALTER TABLE user MODIFY age INT;
- 外键约束
涉及到两个表 : 父表(主表) - 子表(副表) .
主表中没有的数据值 , 在副表中是不可以使用的 ;
主表中的记录被副表使用 , 是不可以被删除的 .
-- 创建班级表
CREATE TABLE classes (
id INT PRIMARY KEY,
name VARCHAR(20)
);
-- 创建学生表
CREATE TABLE students (
id INT PRIMARY KEY,
name VARCHAR(20),
class_id INT,
FOREIGN KEY (class_id) REFERENCES classes (id)
);
三大范式
1. 第一范式
数据表中的所有字段都是不可分割的原子值 .
只要字段值还可以继续拆分 , 就不满足第一范式 .
范式设计得越详细 , 对于某些实际操作可能更好 , 但是也不一定都是好处 .
以实际开发的便捷性确定 .
2. 第二范式
在满足第一范式的前提下 , 第二范式要求 :
除主键外的每一列都必须完全依赖于主键 , 如果出现不完全依赖 , 只可能发生在联合主键的情况下 .
CREATE TABLE myorder (
product_id INT,
consumer_id INT,
product_name VARCHAR(20),
consumer_name VARCHAR(20),
PRIMARY KEY (product_id, consumer_id)
);
-- 拆表重新设计
-- ====================>
CREATE TABLE myorder (
order_id INT PRIMARY KEY,
product_id INT,
consumer_id INT,
);
CREATE TABLE product (
id INT PRIMARY KEY,
name VARCHAR(20),
);
CREATE TABLE consumer (
id INT PRIMARY KEY,
name VARCHAR(20),
);
3. 第三范式
在满足第二范式的前提下 , 第三范式要求 :
除主键外的其它列不能有传递依赖关系 .
CREATE TABLE myorder (
order_id INT PRIMARY KEY,
product_id INT,
consumer_id INT,
consumer_phone VARCHAR(11)
);
-- 拆表重新设计
-- ======================>
CREATE TABLE myorder (
order_id INT PRIMARY KEY,
product_id INT,
consumer_id INT
);
CREATE TABLE consumer (
id INT PRIMARY KEY,
phone VARCHAR(11)
);
查询练习
数据准备
1. 建库并选择该库
CREATE DATABASE selectTest;
USE selectTest;
2. 建表
-- 创建学生表
CREATE TABLE student (
no VARCHAR(20) PRIMARY KEY,
name VARCHAR(20) NOT NULL,
gender VARCHAR(10) NOT NULL,
birthday DATE,
class VARCHAR(20)
);
-- 创建教师表
CREATE TABLE teacher (
no VARCHAR(20) PRIMARY KEY,
name VARCHAR(20) NOT NULL,
gender VARCHAR(10) NOT NULL,
birthday DATE,
prof VARCHAR(20) NOT NULL,
dept VARCHAR(20) NOT NULL
);
-- 创建课程表
CREATE TABLE course (
no VARCHAR(20) PRIMARY KEY,
name VARCHAR(20) NOT NULL,
t_no VARCHAR(20) NOT NULL,
FOREIGN KEY (t_no) REFERENCES teacher (no)
);
-- 创建成绩表
CREATE TABLE score (
s_no VARCHAR(20) NOT NULL,
c_no VARCHAR(20) NOT NULL,
degree DECIMAL,
FOREIGN KEY (s_no) REFERENCES student (no),
FOREIGN KEY (c_no) REFERENCES course (no),
PRIMARY KEY (s_no,c_no)
);
-- 创建等地表
CREATE TABLE grade (
low INT(3),
upp INT(3),
grade CHAR(1)
);
3. 向表中添加数据
-- 添加学生表数据
INSERT INTO student VALUES ('101','曾华','男','1977-09-01','95033');
INSERT INTO student VALUES ('102','匡明','男','1975-10-02','95031');
INSERT INTO student VALUES ('103','王丽','女','1976-01-23','95033');
INSERT INTO student VALUES ('104','李军','男','1976-02-20','95033');
INSERT INTO student VALUES ('105','王芳','女','1975-02-10','95031');
INSERT INTO student VALUES ('106','陆军','男','1974-06-03','95031');
INSERT INTO student VALUES ('107','王尼玛','男','1976-02-20','95033');
INSERT INTO student VALUES ('108','张全蛋','男','1975-02-10','95031');
INSERT INTO student VALUES ('109','赵铁柱','男','1974-06-03','95031');
-- 添加教师表数据
INSERT INTO teacher VALUES ('804','李诚','男','1958-12-02','副教授','计算机系');
INSERT INTO teacher VALUES ('856','张旭','男','1969-03-12','讲师','电子工程系');
INSERT INTO teacher VALUES ('825','王萍','女','1972-05-05','助教','计算机系');
INSERT INTO teacher VALUES ('831','刘冰','女','1977-08-14','助教','电子工程系');
-- 添加课程表数据
INSERT INTO course VALUES ('3-105','计算机导论','825');
INSERT INTO course VALUES ('3-245','操作系统','804');
INSERT INTO course VALUES ('6-166','数字电路','856');
INSERT INTO course VALUES ('9-888','高等数学','831');
-- 添加成绩表数据
INSERT INTO score VALUES ('103','3-245','86');
INSERT INTO score VALUES ('105','3-245','75');
INSERT INTO score VALUES ('109','3-245','68');
INSERT INTO score VALUES ('103','3-105','92');
INSERT INTO score VALUES ('105','3-105','88');
INSERT INTO score VALUES ('109','3-105','76');
INSERT INTO score VALUES ('103','6-166','85');
INSERT INTO score VALUES ('105','6-166','79');
INSERT INTO score VALUES ('109','6-166','81');
-- 添加等地表数据
INSERT INTO grade VALUES (90,100,'A');
INSERT INTO grade VALUES (80,89,'B');
INSERT INTO grade VALUES (70,79,'C');
INSERT INTO grade VALUES (60,69,'D');
INSERT INTO grade VALUES (0,59,'E');
五张表的数据展示
1. 学生表
+-----+--------+--------+------------+-------+
| no | name | gender | birthday | class |
+-----+--------+--------+------------+-------+
| 101 | 曾华 | 男 | 1977-09-01 | 95033 |
| 102 | 匡明 | 男 | 1975-10-02 | 95031 |
| 103 | 王丽 | 女 | 1976-01-23 | 95033 |
| 104 | 李军 | 男 | 1976-02-20 | 95033 |
| 105 | 王芳 | 女 | 1975-02-10 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 | 95031 |
| 107 | 王尼玛 | 男 | 1976-02-20 | 95033 |
| 108 | 张全蛋 | 男 | 1975-02-10 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 | 95031 |
+-----+--------+--------+------------+-------+
2. 教师表
+-----+------+--------+------------+--------+------------+
| no | name | gender | birthday | prof | dept |
+-----+------+--------+------------+--------+------------+
| 804 | 李诚 | 男 | 1958-12-02 | 副教授 | 计算机系 |
| 825 | 王萍 | 女 | 1972-05-05 | 助教 | 计算机系 |
| 831 | 刘冰 | 女 | 1977-08-14 | 助教 | 电子工程系 |
| 856 | 张旭 | 男 | 1969-03-12 | 讲师 | 电子工程系 |
+-----+------+--------+------------+--------+------------+
3. 课程表
+-------+------------+------+
| no | name | t_no |
+-------+------------+------+
| 3-105 | 计算机导论 | 825 |
| 3-245 | 操作系统 | 804 |
| 6-166 | 数字电路 | 856 |
| 9-888 | 高等数学 | 831 |
+-------+------------+------+
4. 成绩表
+------+-------+--------+
| s_no | c_no | degree |
+------+-------+--------+
| 103 | 3-105 | 92 |
| 103 | 3-245 | 86 |
| 103 | 6-166 | 85 |
| 105 | 3-105 | 88 |
| 105 | 3-245 | 75 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 109 | 3-245 | 68 |
| 109 | 6-166 | 81 |
+------+-------+--------+
5. 等地表
+------+------+-------+
| low | upp | grade |
+------+------+-------+
| 90 | 100 | A |
| 80 | 89 | B |
| 70 | 79 | C |
| 60 | 69 | D |
| 0 | 59 | E |
+------+------+-------+
测试练习
- 查询student表中的所有记录
SELECT * FROM student;
- 查询student表中所有记录的name,gender,class
SELECT name, gender, class FROM student;
- 查询teacher表中的所有单位 - DISTINCT 去重
SELECT DISTINCT dept FROM teacher;
- 查询score表中成绩在60-80之间的所有记录 - BETWEEN AND 范围
SELECT * FROM score WHERE degree BETWEEN 60 AND 80;
- 查询score表中成绩为85,86或88的记录 - IN 或者
SELECT * FROM score WHERE degree IN (85,86,88);
- 查询student表中"95031"班或性别为"女"的同学记录 - AND 交集
SELECT * FROM student WHERE class="95031" OR gender="女";
- 以class降序查询student表中的所有记录 - ORDER BY DESC 排序
SELECT * FROM student ORDER BY class DESC;
- 以c_no升序 degree降序查询score表中的所有记录 - ORDER BY DESC 排序
SELECT * FROM score ORDER BY c_no, degree DESC;
- 查询"95031"班的学生人数 - COUNT 统计
SELECT COUNT(*) FROM student WHERE class="95031";
- 查询每门课的平均成绩 - GROUP BY 分组 AVG 均值
SELECT c_no, AVG(degree) FROM score GROUP BY c_no;
- 查询score表中至少有2名学生选修且以3开头的课程的平均分数 - 均值 AVG 分组 GROUP BY 条件 HAVING 统计 COUNT 模糊匹配 LIKE
SELECT c_no, AVG(degree) FROM score GROUP BY c_no HAVING COUNT(*) >= 2 AND c_no LIKE "3%";
- 查询"计算机系" "电子工程系"不同职称的教师的姓名和职称 - 求并集
SELECT name, prof FROM teacher WHERE dept = "计算机系" AND prof NOT IN (SELECT prof FROM teacher WHERE dept = "电子工程系")
UNION
SELECT name, prof FROM teacher WHERE dept = "电子工程系" AND prof NOT IN (SELECT prof FROM teacher WHERE dept = "计算机系");
- 查询所有"女"教师和"女"同学的姓名,性别,生日 - 求并集
SELECT name, gender, birthday FROM student WHERE gender = "女"
UNION
SELECT name, gender, birthday FROM teacher WHERE gender = "女";
- 查询student表中最大最小的birthday日期值
SELECT MAX(birthday) AS "maxValue", MIN(birthday) AS "minValue" FROM student;
- 查询选修编号"3-105"且成绩至少高于选修编号"3-245"的同学的学号,课程号,分数,并按degree从高到低排序.
SELECT s_no, c_no, degree FROM score WHERE c_no = "3-105" AND degree > ANY (SELECT degree FROM score WHERE c_no = "3-245") ORDER BY degree DESC;
- 查询选修编号"3-105"且成绩高于选修编号"3-245"的同学的学号,课程号,分数
SELECT s_no, c_no, degree FROM score WHERE c_no = "3-105" AND degree > ALL (SELECT degree FROM score WHERE c_no = "3-245") ORDER BY degree DESC;
- 查询score表中最高分的学生学号和课程号 - 子查询
SELECT s_no, c_no FROM score WHERE degree = (SELECT MAX(degree) FROM score);
- 查询成绩高于学号"109"课程号"3-105"的成绩的所有记录 - 子查询
SELECT * FROM score WHERE degree > (SELECT degree FROM score WHERE s_no = "109" AND c_no = "3-105");
- 查询和学号"101""108"的同学同年出生的所有学生的学号,姓名,生日 - 子查询 YEAR()
SELECT no, name, birthday FROM student WHERE YEAR(birthday) IN (SELECT YEAR(birthday) FROM student WHERE no IN ("101", "108"));
- 查询"张旭"教师任课的学生成绩 - 子查询
SELECT * FROM score WHERE c_no IN (SELECT no FROM course WHERE t_no = (SELECT no FROM teacher WHERE name = "张旭"));
- 查询选修某课程的同学人数多于3人的教师姓名 - 子查询
SELECT name FROM teacher WHERE no IN (SELECT t_no FROM course WHERE no IN (SELECT c_no FROM score GROUP BY c_no HAVING COUNT(*) >= 3));
- 查询"计算机系"教师所教课程的成绩表 - 子查询
SELECT * FROM score WHERE c_no IN (SELECT no FROM course WHERE t_no IN (SELECT no FROM teacher WHERE dept = "计算机系"));
- 查询所有任课教师的姓名和单位 - 子查询
SELECT name, dept FROM teacher WHERE no IN (SELECT t_no FROM course WHERE no IN (SELECT DISTINCT c_no FROM score));
- 查询男教师所上的课程 - 子查询
SELECT * FROM course WHERE t_no IN (SELECT no FROM teacher WHERE gender = "男");
- 查询最高分同学的学号,课程号,分数 - 子查询
SELECT * FROM score WHERE degree = (SELECT MAX(degree) FROM score);
- 查询和"李军"同性别的所有学生的姓名 - 子查询
SELECT name FROM student WHERE gender = (SELECT gender FROM student WHERE name = "李军");
- 查询和"李军"同性别且同班的所有同学的姓名 - 子查询
SELECT name FROM student WHERE gender = (SELECT gender FROM student WHERE name = "李军") AND class = (SELECT class FROM student WHERE name = "李军");
- 查询所有选秀"计算机导论"课程的"男"同学的成绩表 - 子查询
SELECT * FROM score WHERE c_no IN (SELECT no FROM course WHERE name = "计算机导论") AND s_no IN (SELECT no FROM student WHERE gender = "男");
- 查询选修"3-105"课程的成绩高于"109"号同学"3-105"成绩的所有同学的记录 - 子查询 HARD
SELECT * FROM student WHERE no IN (SELECT DISTINCT s_no FROM score WHERE c_no = "3-105" AND degree > (SELECT degree FROM score WHERE s_no = "109" AND c_no = "3-105"));
- 查询所有学生的姓名,课程号,分数 - 多表查询
SELECT name, c_no, degree FROM student, score WHERE student.no = score.s_no;
- 查询所有学生的学号,课程名,分数 - 多表查询
SELECT s_no, name, degree FROM course, score WHERE course.no = score.c_no;
- 查询所有学生的姓名,课程名,分数 - 多表查询
SELECT student.name, course.name, degree FROM student, course, score WHERE student.no = score.s_no AND course.no = score.c_no;
- 查询 "95031"班学生每门课的课程名称和平均分 - 多表查询 子查询 分组
SELECT c_no, name, AVG(degree) FROM course, score WHERE course.no = score.c_no AND s_no IN (SELECT no FROM student WHERE class = "95031") GROUP BY c_no;
- 查询所有同学的学号,课程号,等地 - 按等地查询 多表查询
SELECT s_no, c_no, grade FROM score, grade WHERE degree BETWEEN low AND upp;
SELECT s_no, student.name, c_no, course.name, grade FROM score, grade, student, course WHERE (degree BETWEEN low AND upp) AND (student.no = score.s_no) AND (course.no = score.c_no);
- 查询成绩比该课程平均成绩低的同学的成绩表 - 复制表数据做条件查询 HARD
两层的嵌套循环 如 外层循环到"3-105"时 则内层过一遍所有的"3-105"并求均值
SELECT * FROM score a WHERE degree < (SELECT AVG(degree) FROM score b WHERE a.c_no = b.c_no);
- 查询至少有4名男生的班号 - HARD
SELECT class FROM student WHERE gender = "男" GROUP BY class HAVING COUNT(*) >= 4;
连接查询
数据准备
1. 建库并选择该库
CREATE DATABASE testJoin;
USE testJoin;
2. 建表
CREATE TABLE person (
id INT,
name VARCHAR(20),
cardId INT
);
CREATE TABLE card (
id INT,
name VARCHAR(20)
);
3. 向表中添加数据
INSERT INTO person VALUES (1, '张三', 1), (2, '李四', 3), (3, '王五', 6);
INSERT INTO card VALUES (1, '饭卡'), (2, '建行卡'), (3, '农行卡'), (4, '工商卡'), (5, '邮政卡');
两张表的数据展现
1. 用户表
+------+------+--------+
| id | name | cardId |
+------+------+--------+
| 1 | 张三 | 1 |
| 2 | 李四 | 3 |
| 3 | 王五 | 6 |
+------+------+--------+
2. 卡表
+------+--------+
| id | name |
+------+--------+
| 1 | 饭卡 |
| 2 | 建行卡 |
| 3 | 农行卡 |
| 4 | 工商卡 |
| 5 | 邮政卡 |
+------+--------+
1. 内连接 - INNER JOIN
查询两张表的交集
SELECT * FROM person INNER JOIN card ON person.cardId = card.id;
查询结果
+------+------+--------+------+--------+
| id | name | cardId | id | name |
+------+------+--------+------+--------+
| 1 | 张三 | 1 | 1 | 饭卡 |
| 2 | 李四 | 3 | 3 | 农行卡 |
+------+------+--------+------+--------+
2. 左外连接 - LEFT OUTER JOIN
完整显示左边的表 右边的表如果符合条件就显示 不符合条件就补NULL
SELECT * FROM person LEFT OUTER JOIN card ON person.cardId = card.id;
查询结果
+------+------+--------+------+--------+
| id | name | cardId | id | name |
+------+------+--------+------+--------+
| 1 | 张三 | 1 | 1 | 饭卡 |
| 2 | 李四 | 3 | 3 | 农行卡 |
| 3 | 王五 | 6 | NULL | NULL |
+------+------+--------+------+--------+
3. 右外连接 - RIGHT OUTER JOIN
完整显示右边的表 左边的表如果符合条件就显示 不符合条件就补NULL
SELECT * FROM person RIGHT OUTER JOIN card ON person.cardId = card.id;
查询结果
+------+------+--------+------+--------+
| id | name | cardId | id | name |
+------+------+--------+------+--------+
| 1 | 张三 | 1 | 1 | 饭卡 |
| 2 | 李四 | 3 | 3 | 农行卡 |
| NULL | NULL | NULL | 2 | 建行卡 |
| NULL | NULL | NULL | 4 | 工商卡 |
| NULL | NULL | NULL | 5 | 邮政卡 |
+------+------+--------+------+--------+
4. 完全外连接 - FULL OUTER JOIN
查询两张表的并集 MySQL不支持该语法
SELECT * FROM person LEFT OUTER JOIN card ON person.cardId = card.id
UNION
SELECT * FROM person RIGHT OUTER JOIN card ON person.cardId = card.id;
查询结果
+------+------+--------+------+--------+
| id | name | cardId | id | name |
+------+------+--------+------+--------+
| 1 | 张三 | 1 | 1 | 饭卡 |
| 2 | 李四 | 3 | 3 | 农行卡 |
| 3 | 王五 | 6 | NULL | NULL |
| NULL | NULL | NULL | 2 | 建行卡 |
| NULL | NULL | NULL | 4 | 工商卡 |
| NULL | NULL | NULL | 5 | 邮政卡 |
+------+------+--------+------+--------+
事务
如何控制事务
在MySQL中 , 事务默认开启自动提交 .
自动提交 : 当我们执行一条SQL语句时 , 其产生的效果会立即体现 , 且不能回滚 .
- 自动提交
- 查看自动提交状态 :
SELECT @@AUTOCOMMIT;
;- 设置自动提交状态 :
SET AUTOCOMMIT=0;
.- 手动提交
@@AUTOCOMMIT=0
时 , 使用COMMIT
命令提交事务 ;- 事务回滚 : 撤销SQL语句执行效果
@@AUTOCOMMIT=0
时 , 使用ROLLBACK
命令回滚事务 .
手动开启事务
事务的自动提交被默认开启之后 , 此时就不能使用事务回滚了 . 但我们可以手动开启一个事务 , 使其可以发生回滚 .
当autocommit=1时, 加 BEGIN 或者 START TRANSACTION 手动开启事务, 可回滚 .
事务的四大特征 - ACID
- A(原子性) : 一个事务中的所有操作, 要么全部完成, 要么全部不完成, 不会结束在中间某个环节 ;
- C(一致性) : 在事务开始之前和事务结束之后, 数据库的完整性没有被破坏 ;
- I(隔离性) : 多个用户并发访问数据库时, 数据库为每一个用户开启的事务, 不能被其它事务的操作所干扰, 多个并发事务之间相互隔离 ;
- D(持久性) : 一个事务一旦被提交, 它对数据库中数据的修改是永久的, 即便系统故障也不会丢失 .
事务的隔离性(性能从高到低)
- READ-UNCOMMITTED(读未提交的-脏读)
一个事务读取了另外一个事务未提交的数据 . 事务A对数据进行了修改 , 但是还未提交 , 另一个事务B可以读到A尚未提交的数据 , 当事务A进行回滚时 , 事务B读到的数据就是脏数据 .- 举个栗子 : 小明在淘宝店买了一双鞋 , 付完款之后 , 淘宝店发现钱已到账 , 小明执行ROLLBACK , 数据恢复原样 , 这是脏读-读取未提交的 . 如果执行COMMIT , 则不可ROLLBACK .
- READ-COMMITTED(读已经提交的-不可重复读)
同一个事务在事务过程中 , 对同一个数据进行读取操作 , 读取到的结果不同 . 事务B在事务A的更新操作前读到的数据 , 与事务A提交此更新操作后读到的数据 , 可能不同 . 要避免不可重复读 , 需要将事务所操作的记录都加上锁 , 不允许其它事务对此纪录进行写操作 .- 举个栗子 : 小明在淘宝店买了一双鞋 , 付完款之后未提交 , 在本地看发现钱已到账 , 淘宝店远程连接 , 发现钱未到账 , 即远程连接查询到的数据只能是已经提交过的 .
- REPEATABLE-READ(可以重复读-幻读)
事务A和事务B同时操作一张表 , 事务A提交的数据 , 不能被事务B读到 , 就会造成幻读 .
举个栗子 : 小张和小王同时操作一张表 , 两人同时各自开启一个新的事务 , 小张添加了一条数据 , 无论他是否COMMIT , 小王都无法看到小张的事务记录 , 会出现 幻读 , 即一个事务提交的数据 , 另一个事务不能读取到 .
- 串行化(SERIALIZABLE)
事务序列化 , 前一个事务执行完 , 后面的事务才可以执行, 即同时只能执行一个事务的写入操作 . 因此 , 会导致大量的超时 , 性能差 .
隔离级别越高 , 性能越差 , MySQL默认隔离级别是REPEATABLE-READ .
网友评论