一、存储引擎
是啥?有啥用?
存储引擎是MySQL中特有的术语,实际上存储引擎是一个表存储/组织数据的方式,不同的存储引擎,表存储/组织数据的方式不同。
怎么给表指定存储引擎?
// 展现当时创建这张表的SQL语句
show create table emp;
drop table if exists t_user;
CREATE TABLE `t_user` (
`id` int(11) DEFAULT NULL,
`name` varchar(32) DEFAULT NULL,
`birth` date DEFAULT NULL,
`creat_time` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
**ENGINE
指定存储引擎,CHARSET
**指字符编码方式
结论:MySQL默认存储引擎:InnoDB,字符编码方式utf8
—MySQL支持哪些存储引擎?
# 查看MySQL支持哪些存储引擎
show engines \G
----MySQL常用的存储引擎:
1. MyISAM 存储引擎
优势:可以被转换为压缩、只读表来节省空间
2. InnoDB存储引擎
这是MySQL默认的存储引擎,也是一个重量级的存储引擎。
InnoDB支持事务,支持数据库崩溃后自动恢复机制。
非常安全
支持事务
3. Memory存储引擎
数据和索引存在内存当中,查询“快”
内存和硬盘的区别:
内存是直接取,光速!从硬盘上取,硬盘有磁针,哒哒哒的取,机械性的。
二、事务(必须掌握、必须精通)
2.1 什么是事务?
一个事务就是一个完整的业务逻辑?
(完成一件事)
假设转账,从A账户向B账户中转账10000,
从A账户减去10000,
将B账户的钱加上10000.
以上操作是一个最小的工作单元,要么同时成功,要么同时失败,不可再分。这两个update语句要求必须同时成功
或者同时失败
,这样才能保证钱是正确的。
2.2 只有DML语句才会有事务这一说,其他语句和事务无关。
insert
delete
update
只有以上三个语句和事务有关系,其他都没关系,因为这仨是增删改,一旦涉及增删改,就一定要保证数据安全。
2.3 假设所有的业务,只要一条DML语句就能完成,还有存在事务机制的必要吗?----不需要了。
正是因为做某件事的时候需要多条DML语句才能完成,所以需要事务来完成。
事务:
本质上,一个事务就是多条DML语句同时成功,或者同时失败
2.4 事务是怎么做到多条DML语句同时成功和同时失败的?
InnoDB:提供了一组用来记录事务性活动
的日志
文件
在事务的执行过程中,每一条DML语句操作都会记录到**事务性活动文件
中。在事务的执行过程中,我们可以提交
事务,也可以回滚
**事务。
提交事务:
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。标志着事务的结束,并且是一种胜利的结束。(完事了)
回滚事务:
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件,回滚事务标志着事务的结束,是一种失败的结束。(全部撤销)
2.5 事务怎么提交和回滚?
----回滚到上一次的提交点
transaction
提交事务:commit; 语句
回滚事务:rollback;语句 : 回滚到上一次的提交点
MySQL默认情况下是支持自动提交
事务的。
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id | name | birth | creat_time |
+------+----------+------------+---------------------+
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
+------+----------+------------+---------------------+
5 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id | name | birth | creat_time |
+------+----------+------------+---------------------+
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
+------+----------+------------+---------------------+
5 rows in set (0.00 sec)
咋关闭自动提交呢?
start transaction # 关闭自动提交机制
来了!!!
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id | name | birth | creat_time |
+------+----------+------------+---------------------+
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
+------+----------+------------+---------------------+
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from t_user where id = 1;
Query OK, 5 rows affected (0.00 sec)
mysql> select * from t_user;
Empty set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id | name | birth | creat_time |
+------+----------+------------+---------------------+
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
+------+----------+------------+---------------------+
关上重启,又自动提交了
mysql> select * from t_user;
+------+----------+------------+---------------------+
| id | name | birth | creat_time |
+------+----------+------------+---------------------+
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
| 1 | zhangsan | 1990-10-01 | 2023-07-05 20:06:15 |
+------+----------+------------+---------------------+
5 rows in set (0.00 sec)
mysql> delete from t_user where id = 1;
Query OK, 5 rows affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user;
Empty set (0.00 sec)
这种自动提交方式不好,因为一个业务通常是需要多条DML语句共同执行才能完成的,为了保证数据的安全,必须要求同时成功之后再提交,所以不能这样玩
commit // 提交事务,滚不回去喽
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | creat_time |
+------+------+------------+---------------------+
| 1 | lisi | 1009-11-24 | 2023-07-13 20:12:32 |
| 1 | lisi | 1009-11-24 | 2023-07-13 20:12:47 |
| 1 | lisi | 1009-11-24 | 2023-07-13 20:12:54 |
+------+------+------------+---------------------+
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_user;
+------+------+------------+---------------------+
| id | name | birth | creat_time |
+------+------+------------+---------------------+
| 1 | lisi | 1009-11-24 | 2023-07-13 20:12:32 |
| 1 | lisi | 1009-11-24 | 2023-07-13 20:12:47 |
| 1 | lisi | 1009-11-24 | 2023-07-13 20:12:54 |
+------+------+------------+---------------------+
2.6 事务包括四个特性
A
原子性:事务是最小的工作单元,不可再分
C
一致性:在同一个事务当中,所有操作必须同时成功或同时失败
I
隔离性:A事务和B事务具有一定的隔离。
A教室和B教室之间有一道墙,这道墙就是隔离性
多线程并发访问同一张表
D:
持久性:事务最终结束的一个保障。事务提交,就相当于将没有保存到硬盘上的数据保存在硬盘上。
2.7 隔离性 — 隔离级别
数据库事务的隔离级别有4种,由低到高分别为Read uncommitted(读未提交) 、Read committed (读已提交)、Repeatable read (重复读)、Serializable (序列化)。 1到4档,二档起步
-
读未提交(Read Uncommitted)— 最低的《没提交也能读到》:
- 在这个级别下,事务A可以读取到事务B未提交的事务。
- 存在的问题是**“脏读”现象,即读到了脏数据(对方没有提交的数据)**
- 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。用户A查询库存时,由于读未提交的特性,可能读到用户B购买尚未提交的库存减少的操作,导致用户A看到的库存数量不准确。
-
读已提交(Read Committed)《提交之后才能读到》:
-
事务A只能读取到事务B已提交的数据。
-
解决的脏读现象,问题:不可重复读取数据
-
因为事务B一直在提交,所以A每次读到的都不一样
- 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。用户A查询库存时,由于读已提交的特性,只能读取到已提交的库存数量,不会看到用户B尚未提交的修改。
-
可重复读(Repeatable Read)《提交之后也读不到》:
-
事务A开启后,不管多久,每一次在事务A中读取到的数据都是一致的,即使事务B将数据修改了、提交了,事务A读取到的数据还是没有发生改变。
-
案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。用户A在查询库存后,多次查询同一个库存时,由于可重复读的特性,每次查询的库存数量都保持一致,不受用户B尚未提交的修改影响。
-
-
序列化 / 可串行化(Serializable)— 最高的:
- 在这个级别下,事务之间的操作完全串行执行,确保数据的严格一致性。
- 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。由于可串行化的特性,用户A和用户B的购买操作必须串行执行,即先完成用户A的购买,再进行用户B的购买,以确保数据的一致性
update library set name=name, ISBN = ISBN where id =
外链图片转存中…(img-68ULk5A9-1689737153614)]
-
序列化 / 可串行化(Serializable)— 最高的:
- 在这个级别下,事务之间的操作完全串行执行,确保数据的严格一致性。
- 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。由于可串行化的特性,用户A和用户B的购买操作必须串行执行,即先完成用户A的购买,再进行用户B的购买,以确保数据的一致性