7.13_SQL存储引擎与事务

一、存储引擎

是啥?有啥用?

存储引擎是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 (序列化)。		14档,二档起步
  1. 读未提交(Read Uncommitted)— 最低的《没提交也能读到》:

    • 在这个级别下,事务A可以读取到事务B未提交的事务。
    • 存在的问题是**“脏读”现象,即读到了脏数据(对方没有提交的数据)**
    • 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。用户A查询库存时,由于读未提交的特性,可能读到用户B购买尚未提交的库存减少的操作,导致用户A看到的库存数量不准确。
  2. 读已提交(Read Committed)《提交之后才能读到》:

    • 事务A只能读取到事务B已提交的数据。

    • 解决的脏读现象,问题:不可重复读取数据

在这里插入图片描述

 因为事务B一直在提交,所以A每次读到的都不一样
  • 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。用户A查询库存时,由于读已提交的特性,只能读取到已提交的库存数量,不会看到用户B尚未提交的修改。
  1. 可重复读(Repeatable Read)《提交之后也读不到》:

    • 事务A开启后,不管多久,每一次在事务A中读取到的数据都是一致的,即使事务B将数据修改了、提交了,事务A读取到的数据还是没有发生改变。
      在这里插入图片描述

    • 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。用户A在查询库存后,多次查询同一个库存时,由于可重复读的特性,每次查询的库存数量都保持一致,不受用户B尚未提交的修改影响。
      在这里插入图片描述

  2. 序列化 / 可串行化(Serializable)— 最高的:

    • 在这个级别下,事务之间的操作完全串行执行,确保数据的严格一致性。
    • 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。由于可串行化的特性,用户A和用户B的购买操作必须串行执行,即先完成用户A的购买,再进行用户B的购买,以确保数据的一致性
update library set name=name, ISBN = ISBN where id = 

外链图片转存中…(img-68ULk5A9-1689737153614)]

  1. 序列化 / 可串行化(Serializable)— 最高的:

    • 在这个级别下,事务之间的操作完全串行执行,确保数据的严格一致性。
    • 案例:用户A想要购买商品X,而商品X的库存为10。用户B同时也要购买商品X,并且正在支付过程中。由于可串行化的特性,用户A和用户B的购买操作必须串行执行,即先完成用户A的购买,再进行用户B的购买,以确保数据的一致性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值