MySQL存储引擎&事务
- 一、MySQL 存储引擎
- 1、怎么查看/添加“存储引擎”?
- 2、常用存储引擎简介
- 二、MySQL 事务
- 1、什么是事务?
- 2、事务是怎么做到多条DML语句同时成功和同时失败的呢?
- 3、事务四大特性 ACID
- 4、四个隔离级别
一、MySQL 存储引擎
存储引擎:实际上存储引擎是一个表存储/组织数据的方式。不同的存储引擎,表存储数据的方式不同。
1、怎么查看/添加“存储引擎”?
使用语句 show create table t_student
可以查看表结构:
在建表的时候可以在最后小括号的")"的右边使用:ENGINE
来指定存储引擎。CHARSET
来指定这张表的字符编码方式。
CREATE TABLE `t_student` (
`no` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`cno` int(11) DEFAULT NULL,
PRIMARY KEY (`no`),
KEY `cno` (`cno`),
CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`classno`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
create table t_product(
id int primary key,
name varchar(255)
)engine=InnoDB default charset=gbk;
可使用如下语句查看当前服务器支持哪些存储引擎:
show engines \G
2、常用存储引擎简介
MyISAM 存储引擎:MyISAM 表最适合于大量的数据读而少量数据更新的混合操作。MyISAM 表的另一种适用情形是使用压缩的只读表。
InnoDB 存储引擎:如果查询中包含较多的数据更新操作,应使用 InnoDB。其行级锁机制和多版本的支持为数据读取和更新的混合操作提供了良好的并发机制。
MEMORY 存储引擎:可使用 MEMORY 存储引擎来存储非永久需要的数据,或者是能够从基于磁盘的表中重新生成的数据。
二、MySQL 事务
1、什么是事务?
一个事务 transaction 其实就是一个完整的业务逻辑。是一个最小的工作单元。不可再分。
这里举个例子:假设转账,从A账户向B账户中转账10000。将A账户的钱减去10000(update语句),将B账户的钱加上10000(update语句)这就是一个完整的业务逻辑。
update account set balance = balance-10000 where id = 'A';
update account set balance = balance+10000 where id ='B';
以上的操作是一个最小的工作单元,要么同时成功,要么同时失败,不可再分,这样才能保证钱是正确的。。事务就是为了解决类似于转账僵硬的问题。事务的本质就是把多个sql语句给打包成一个整体,要么全都执行,要么就一个都不执行,而不会出现“执行一半”这样的中间状态。
注:只有 DML 语句(i
nsert、delete、update
)才会有事务这一说,其它SQL语句和事务无关。主要是因为因为 只有以上的三个语句是数据库表中数据进行增、删、改的。只要你的操作一旦涉及到数据的增、删、改,那么就一定要考虑安全问题。因此需要事务保证数据的完整性。
2、事务是怎么做到多条DML语句同时成功和同时失败的呢?
MySQL 事务都是指在 InnoDB 引擎下,在InnoDB存储引擎中,提供一组用来记录事务性活动的日志文件。在事务的执行过程中,每一条DML的操作都会记录到“事务性活动的日志文件”中。在事务的执行过程中,我们可以提交事务,也可以回滚事务。
开启事务:start transaction;
mysql默认情况下是支持自动提交事务的。也就是说每执行一条DML语句,则提交一次!这种自动提交实际上是不符合我们的开发习惯,因为一个业务通常是需要多条DML语句共同执行才能完成的,为了保证数据的完整性,必须要求同时成功之后再提交,所以不能执行一条就提交一条。此时我们可以使用命令 set autocommit = OFF;或set autocommit = ON;来取消/开启自动提交,或者手动开启一个事务:start transaction;
提交事务:commit;
语句
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。提交事务标志着,事务的结束。并且是一种全部成功的结束。
回滚事务:rollback;
语句
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件。回滚事务标志着,事务的结束。并且是一种全部失败的结束。
注意:回滚永远都是只能回滚到上一次的提交点!
回滚事务演示:
提交事务演示:
3、事务四大特性 ACID
- 原子性(Atomicity) 整个事务中的所有操作,必须作为一个单元全部完成(或全部取消)。
- 一致性(Consistency) 在事务开始之前与结束之后,数据库都保持一致状态。即在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。
- 持久性(Durability) 在事务完成以后,该事务对数据库所作的更改将持久地保存在数据库之中,并不会被回滚。
- 隔离性(Isolation) 一个事务不会影响其他事务的运行,一般存在于多个事务“并发”执行。例如教室A和教室B之间有一道墙,这道墙就是隔离性。
当多个客户端并发
地访问同一个表时,可能出现下面的一致性问题:
- 脏读取(Dirty Read) 一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交,这就出现了脏读取。此时的读操作就称为脏读,读到的数据也称为脏数据(无效数据)。
- 不可重复读(Non-repeatable Read) 在同一个事务中,同一个读操作对同一个数据的前后两次读取产生了不同的结果,这就是不可重复读。例如在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条,导致两次读取数据不一致,称为不可重复读取。
- 幻像读(Phantom Read) 每一次读取到的数据都是幻象。不够真实!例如早晨9点开始开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样!读到的是假象。不够绝对的真实。
4、四个隔离级别
为了解决上述并发访问时可能会出现的问题,InnoDB 实现了四个隔离级别:
- 读未提交:read uncommitted—
没有提交就读到了
事务A可以读取到事务B未提交的数据。最低的隔离级别,效率最高。
说明:这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是二级起步
- 读已提交:read committed—
提交之后才能读到
事务A只能读取到事务B提交之后的数据。
说明:解决了脏读的现象。oracle数据库默认的隔离级别是:read committed
- 可重复读:repeatable read—
提交之后也读不到,永远读取的都是刚开启事务时的数据
事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变,这就是可重复读。
说明:解决了不可重复读取数据。mysql中默认的事务隔离级别就是这个
- 序列化/串行化:serializable
将一个事务与其他事务完全地隔离,每一次读取到的数据都是最真实的。隔离级别最高,由于不能并发,所以效率最低。这种隔离级别解决了以上所有的问题。
总结:隔离级别与一致性问题
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 可能 | 可能 | 可能 |
读已提交 | 不可能 | 可能 | 可能 |
可重复读 | 不可能 | 不可能 | 可能 |
串行化 | 不可能 | 不可能 | 不可能 |
拓展:
- 查看隔离级别可使用命令
select @@tx_isolation;
- 设置全局隔离级别 set global transaction isolation level 隔离级别;