深入浅出MySQL

1. 数据库事务ACID四大特性

MySQL主要通过日志及锁实现事务的ACID特性。

A-atomicity 原子性,也称不可分割性

数据库依赖 redo / undo 日志实现事务的原子性。

简单来说,redo 日志记录事务后的修改数据, undo 日志记录事务前的原始数据。在恢复时,数据库先检查事务中断在什么阶段:如果事务中断在 commit 阶段,则重放 redo 日志;如果中断在 prepare 阶段,则利用 undo 日志进行回滚。

数据库用 检查点(check-point)确定事务的恢复位点。检查点代表:在这一点之前提交的事务所修改的数据已经全部写回磁盘。因此,数据库故障后只要找到最近一次检查点,就可以从这个位置开始处理 redo / undo 日志。

C-consistency 一致性

用类型检查、唯一索引、外键约束和级联更新保护数据的完整性

I-isolation 隔离性,又称独立性

实现事务隔离的主要手段是锁。另外一个关键技术是 MVCC (Multi-version Concurrency Control), 它可以在一些场景避免加锁, 实现同时读写(详见下文【数据库事务的隔离级别】)

D-durability 持久性

数据库的持久化依赖磁盘和数据复制机制

2. 数据库事务的隔离级别

Read uncommitted - 读未提交。读不需要加锁,写仅仅需要加行锁。

会出现脏读问题:在一个事务处理过程中读取了另一个未提交的事务中的数据

Read committed - 读已提交。需要加写锁,读必须等待写事务结束。

会存在不可重复读问题:对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。

不可重复读和脏读的区别是,脏读是某一事务读取了另一个事务未提交的脏数据,而不可重复读则是读取了前一事务提交的数据。

在某些情况下,不可重复读并不是问题,比如我们多次查询某个数据当然以最后查询得到的结果为主。

Repeatable reads - 可重复读。需要加读锁,当有事务在读一行记录,其他写同一行的事务都会阻塞,就是在开始读数据(事务开启)时,不再允许修复操作。

不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

Serializable - 串行化。需要加范围锁,当有事务 SELECT 某个范围的数据时,其他访问同一范围的事务都会阻塞。

序列化是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用

大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle

Oracle数据库中,只支持Serializable (串行化)级别和Read committed (读已提交)这两种级别,其中默认的为Read committed级别

MySQL的默认隔离级别是Repeatable read。

四种隔离级别对应可以避免的问题(不过级别越高,执行效率就越低):

① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。

② Repeatable read (可重复读):可避免脏读、不可重复读的发生。

③ Read committed (读已提交):可避免脏读的发生。

④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。

3. 数据库表结构设计三范式(Normal Form)

◆ 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。

◆ 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。不符合 2NF 的设计容易产生冗余数据。

◆ 第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。

第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,

2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;

3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。

4. 数据库系统检查

##查询数据库隔离级别SELECT @@tx_isolation;
##查询数据库是否自动提交事务:1-是SELECT @@autocommit;##查询数据库进程SHOW PROCESSLIST;##查杀死锁进程SELECT * FROM information_schema.innodb_trx;KILL 123; ## trx_id##EXPLAIN 检查SQL执行计划##使用explain可以查看该SQL语句有没有使用索引,有没有做全表扫描EXPLAIN  select * from user;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值