MySQL简介
常见面试知识点:
- 用过MySQL吗?事务讲下。
- MySQL有几个隔离级别(最好这个问题不要等被问,而在问上个的时候主动说这个)
- MySQL是怎么确保事务的正常执行的(日志,这个问得好像不多,但是可以作为一个亮点)
- MySQL有哪些存储引擎,各自的特点
因为这篇文章不想写索引,索引必问的索引优化没提到。后面再复习
1. MySQL是什么
MySQL是比较常用的数据库,同样的还有MS SQL以及Oracle DB。都是一个类型的产品。后面两种都是商业产品,比较昂贵。MS SQL是微软的,一般用 .net的都用这个,绑定在微软的战车上。还有是Oracle的数据库,传统行业一般都用这个,老牌行业大佬了。这两种商业的,收费比较昂贵,都是提供服务支持(其实就是除了问题能找到人背锅)。相对来说MySQL可以免费使用(虽然想在也是Orale下面的)。但是出问题。那我们就又变强了点(其实是头发少了点)。但是对小企业来说。MySQL用的比较多,毕竟节省成本。而且这三个都是关系型数据库。其中某一个用的比较好。其他两种都能很快上手(我之前两家公司,一个用Oracle 11g,一个是MS SQL2008 。但是我学习都是看的MySQL的相关书籍。并不影响我使用)
1.1 MySQL是什么
- MySQL是一款关系型数据库管理系统,有社区版。(关系型数据库可以联想下Excel的表格结构)
- 管理磁盘上的数据
- 支持多个存储引擎
- 支持事务(依赖存储引擎)
- 崩溃恢复(依赖存储引擎)
1.2 范式
第一范式: 每个列都是最小单元,具有原子性,不可再分割
第二范式: 所有的非主键都直接依赖于主键。就是说可以通过主键直接决定其他的信息。例如知道 小李的身份证号可以直接知道,小李名字,家庭地址,性别。都是和身份证号(主键)直接关联
第三范式: 所有的非主键都不依赖与非主键。性别和家庭地址是没有依赖关系的
范式的好处: 没有冗余,每次更新需要更新的数据少
范式的缺点: 很多时候需要查询多方面的信息,例如通过小李的身份证,我希望查到小李的信息,希望能得到其父亲(紧急联系人)的部分信息。如果没有冗余表示我需要连表查询。连表查询的效率又比单表查询慢好多。一般对于查询量大,但是很少更新的数据表一般都会设计的不符合范式
2. MySQL逻辑架构
MySQL是三层架构,客户端,服务层,存储引擎层(物理文件在磁盘,有存储引擎直接操作)
其中处理语句的都在都在中间这一层
如下图(图片来源于网络):
- 客户端连接服务器后,服务器先对客户端进行身份检验,判定其可以查询哪个表,可以做什么操作。
- 每个客户端都连接都有一个线程来处理,该连接的查询都由这个线程来处理。服务器有线程缓存,不需要每次都新建和销毁线程
- SQL语句执行查询的时候,会先看看缓存是否有对应数据,如果有直接返回结果。否则解析SQL,优化后,调用存储引擎的接口进行查询
- 存储引擎有多种(后面会介绍)
3. MySQL并发控制
按照是否共享可以分为共享锁与排它锁(服务层)。按照锁粒度可以分为表锁与行级锁(存储引擎,比较这个直接和数据交互)
3.1 共享锁与排他锁
- 共享锁(读锁):资源可以被多个线程获取,能提供更大的并发
- 排他锁(写锁):资源被一个线程获取,需要该线程释放锁后才可以被其他线程获取
3.2 表锁与行级锁
- 表级锁 :锁整张表,锁开销小,但是支持的并发度小
- 行级索(InnoDB存储引擎),能支持较大并发,但是锁开销大(加锁,检查锁状态,释放锁都需要开销)
4. MySQL事务
InnoDB才支持事务,MyISAM不支持事务,由于之前MySQL5.1之前都是默认用的MyISAM存储引擎,导致很多人认为MySQL不支持事务。
4.1 事务特点
- 原子性(Atomicity):事务里面的操作要么全部执行,要么都不执行
- 一致性(Consistency):事务开始,到事务提交结束。数据库是从一个正确状态到另一个正确状态。数据库的数据完整性没有被破坏,例如外键约束,或者其他业务上的约束(执行的过程中可能会破坏数据完整性,这说明原子性,是一致性的基本保障。没有原子性,一致性也很难维持)
- 隔离性(Isolation):避免多个事务对一个资源同时操作导致数据不一致(用Java讲就是多线程安全)事务有4个不同隔离级别(见4.2)
- 持久性(Durability):事务执行成功后,对数据的修改是永久性的,即使数据故障也不会丢失
4.2 事务隔离级别
- 未提交读(Read uncommitted)
- 提交读(read committed)
- 可重复读(repeatable read):MySQL默认的事务隔离级别
- 串行化(Serializable)
其实是根据解决的问题命名的
隔离级别 | 问题 |
---|---|
未提交读 | 脏读,重复读,幻读 |
提交读 | 重复读,幻读 |
可重复读 | 幻读 |
串行化 |
隔离级别越高,能够支持的并发越有限(鱼和熊掌不可兼得。又想开发的快,又想不出bug,工资还不想给。程序员也太难了o(╥﹏╥)o)
- 脏读: 事务能够读取到其他事务还没有提交的数据。我读取到其他事务没有提交的数据,如果那个事务最终回滚了。那么我依赖那个数据所做的操作不就有问题了。 数据库怎么避免的:先写在副本里,提交时候更新到磁盘中(类似CopyOnWrite(COW)机制,很多地方用到例如 JUC包里面的写操作都是这种方式)
- 重复读: 在一个事务里面两次读取的数据前后不一致 eg:A事务查询小明账户余额为500,结果另外有个B事务执行且提交了,将改成200。A事务发出取款500的操作。A事务前后两次读取的余额不一致。可重复读级别数据库是怎么处理的:不让AB两个事务同时执行就好了,可以给AB事务排序,也可以对小明账户余额加排他锁。获取到锁的事务才能执行操作。
- 幻读: 事务两次读取的事务行数不一致。这个和重复读不一样,重复指的是某一行的数据不一致(update导致的),加行级锁,幻读指的是数据表的行数,是指多行数据(insert,delete导致),这个得表锁。或者事务都串行化执行
4.2 日志简介
声明:这篇仅介绍日志,仅介绍,而且主要介绍事务相关的日志。具体可以去专门找日志相关的文章
- MySQL是如何确保原子性,一致性,隔离性与持久性的?
- 原子性简单说就是全执行或全不执行,但是如果事务执行到一半,系统出故障,或者其他原因(例如余额不够)导致系统无法执行。这个时候就需要回滚,依赖什么回滚? 是 undo log,当事务执行语句时,会在undo log记录想法的操作语句,例子执行
insert
语句,undo log会记录对应的delete
,对应的undolog记录了才会真的执行语句(先留好了退路哈), 回滚的时候就会就执行undo log语句。 - 一致性依赖原子性和隔离性来确保
- 隔离性依靠锁和MMVC机制(多版本并发控制),简单点就是乐观锁,来确保
- 持久性。CPU操作数据都在内存上(其实是在内存与CPU之间的缓存区Cache,或者寄存器),但是这有个缺点:断电就没了。只有保存到磁盘中,才能永久保存(当然磁盘也会坏)。我们当然不会直接操作磁盘,那这样频繁从磁盘取数据,插入数据,那得多慢。MySQL是在内中操作,操作前会将操作(SQL脚本语句)记录到 redo log。redo log放到磁盘中,才会将事务提交(先日志,再操作)。即使事务为提交,或过程崩溃了,MySQL启动时还是会根据redo log去做这件事。redo log好处在于记录语句,比直接操作数据对IO消耗小,同时redo log是记录到一起的,相对于事务做的IO是随机IO,顺序IO肯定更快
5. MySQL存储引擎
5.1 InnoDB存储引擎
5.2 MyISAM存储引擎
6. 小结
- 数据库逻辑架构
- 数据库锁(读写锁/表锁与行级锁)
- 事务特性ACID
- 事务隔离级别(4中隔离级别)
- 事务日志
- 博文已经太长了,存储引擎先不管了
还有很多没提,可以看考看看,事务的2PC,3PC。日志的奔溃恢复,日志在复制过程的作用(这里是 bin log),MySQL事务的语句【开始:START TRANSACTION ;提交:Commit;回滚:Rollback】
转载:https://blog.csdn.net/m0_37628958/article/details/105296508