数据库-存储引擎、事务、三大范式、锁

1. MySQL常见存储引擎:MYISAM,INNODB

数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能
1)myisam与inodb的区别:
(1)缓存
每个MyISAM在磁盘上存储成三个文件。分别为:表定义文件、数据文件、索引文件。
myisam仅仅缓存索引,不会缓存数据表中的数据,它会将这个工作交给OS级别的文件系统缓存。
InnoDB有自己的缓存,不仅仅可以缓存索引,还能缓存数据表
(2)事务,外键
myisam不支持事务,InnoDB支持事务,也支持主外键
(3)
myisam 只支持表锁,innoDB支持行级锁、页面锁,粒度更小的锁定级别
所以如果执行大量的SELECT,MyISAM是更好的选择。若执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。
(4)表的总行数
MyISAM: 保存有表的总行数,如果select count() from table;会直接取出出该值。
InnoDB: 没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相 当大
在MySQL 5.1 及之前的版本,MyISAM是默认引擎。
2)MyISAM 和 InnoDB 两种引擎所使用的索引的数据结构都是B+树
索引是为了加速对表中数据行的检索而创建的一种分散存储的数据结构。
索引部分见另一篇博客数据库索引

2.事务的四大特征(ACID)Q

(3)原子性:事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败
(2)一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
举例子:张三向李四转100元,转账前和转账后的数据是正确的状态,这就叫一致性,如果出现张三转出100元,李四账号没有增加100元这就出现了数据错误,就没有达到一致性。
(3)隔离性:隔离性的体现,多个并发事务之间是隔离的。
举例子:张三给李四转账,如果事务没有提交的话,那么在另外一个session中并不能查看另外一个session未提交的数据。
(4)持久性:一个事务一旦被提交,它对数据库中数据的改变就是永久性的

3.事务的4种隔离级别

在这里插入图片描述
(1)读未提交(RU):一个事务可以读取另一个未提交事务的数据。
可能引起 脏读,不可重复读,幻读。
(2)读已提交(RC):一个事务要等另一个事务提交后才能读取数据
可能引起 不可重复读,幻读。
(3)可重复读(RR):在开始读取数据(事务开启)时,不再允许修改操作
可能引起 幻读。
(4)串行:事务串行化顺序执行。
可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
多数数据库默认的事务隔离级别是读已提交,比如Sql Server , Oracle。Mysql的默认隔离级别是可重复读。
脏读:如果你正在读数据库内容,而我现在修改了数据库内容还没有提交,接着我修改后的内容没有提交的情况下被你读到了,就叫脏读.
具体点:数据库有某一个数据A值为25,有事务1要将A改成30,A的值变成30,但事务1并未提交。
与此同时,事务2对A进行读取,读到的是30。若事务1,修改失败,发生了回滚,那么此时数据库中A的值并未发生变化,仍然为25,但事务2读取到的值确实30。

不可重复读:比如你正在读数据库内容,而我update数据库后提交了,你又读了一次数据库内容,这时出现两个内容不同的结果,这叫不可重复读.

幻读:比如你正在读数据库内容,而我insert数据库后提交了,你又读了一次数据库内容,这时你看到内容出现了多一条数据,这叫幻读.

4. 三大范式

(1)第一范式(确保每列保持原子性):数据表中的每一列,必须是不可拆分的最小单元,也就是确保每一列的原子性,而不是集合。
(2)第二范式(确保表中的每列都和主键相关):满足1NF的基础上,要求:表中的所有列,都必需依赖于主键,而不能有任何一列与主键没有关系。第二范式消除表的无关数据。
(3)第三范式(确保每列都和主键列直接相关,而不是间接相关):满足2NF的基础上,任何非主属性不依赖于其它非主属性.

5.数据库的乐观锁和悲观锁

悲观锁:认为每当修改数据时,会有其他线程也会同时修改该数据。所以读取数据之后就加锁,这样别的线程读取该数据的时候就需要等待当前线程释放锁,获得到锁的线程才能获得该数据的读写权限。从而保证了并发修改数据错误的问题。但是由于阻塞原因,所以导致吞吐量不高。悲观锁更适用于多写少读的情况。
乐观锁:只有在更新数据的时候才会检查这条数据是否被其他线程更新了。如果更新数据时,发现这条数据被其他线程更新了,则此次更新失败。如果数据未被其他线程更新,则更新成功。由于乐观锁没有了锁等待,提高了吞吐量,所以乐观锁适合多读少写的场景。、
简单总结:
悲观锁:读取时加锁,更新完释放锁,再此过程中会造成其他线程阻塞,导致吞吐量低,适用于多写场景。
乐观锁:不加锁,只有在更新时验证数据是否被其他线程更新,吞吐量较高,适用于多读场景。

发布了59 篇原创文章 · 获赞 12 · 访问量 2256

猜你喜欢

转载自blog.csdn.net/qq_41219586/article/details/104294225