MySQL面试(基础知识+隔离级别和幻读的问题)

数据库三大范式?
什么是关系型数据库?

答:是一种建立在关系模型基础上的数据库,关系模型表明了数据库中数据之间的联系(一对多、一对一、多对多等)。关系型数据库中数据被放在了各种表中,表中的每一行就标识一条数据。

大部分关系型数据库都使用SQL语句来操作数据库,并且基本都支持四大特性(ACID)

A:原子性:事务中的操作要么全做要么全不做;C:一致性,事务开始和结束时,数据库保持一致性,比如转账前后的总金额一致;I:隔离性:事务之间相互隔离,不会互相打扰。D:持久性,事务一旦提交就是永久性的。其中A和I是为了实现C和D。

char和varchar之间的区别是什么?

char是定长字符串,varchar是可变长字符串。char规定了长度之后会进行填充达到指定的长度,varchar只是指定了最大存储的长度,但存储的时候只会存数据大小的长度,并且记录数据的长度。varchar(100)和 varchar(10)都是变长类型,只是支持的最大长度不一样。

decimal和double的区别

decimal是定点数,可以存精确的小数,double只能存小数的近似值。和金钱相关的用decimal。

null和‘ ’之间的区别:

null表示确实或者不确定的值,而“”是空的字符串。

使用聚合函数时,null会被忽略,而count(*)时,又会被包含在里面。

在进行比较时,null只能用 is null 和is not null来判断,因为它不是一个具体的数据类型,而“”可以用等于或者不等于来判断。

SQL语句在MySQL中的执行过程

MySQL的基础架构主要包括server层和存储引擎层,存储引擎层主要负责对数据的存储和读取。server层包括连接器、查询缓存、分析器、优化器和执行器。

一条SQL开始执行时,首先会经过连接器验证用户的权限,如果具备权限的话建立连接,会查询缓存,缓存存在则直接返回结果,否则进行词法、句法分析,判断有无语法错误,然后经过优化器,选择合适的执行方案,比如利用什么索引,确定好执行方案之后,通过存储引擎执行对数据的操作。

MySQL的存储引擎,innodb与myisam之间的区别

默认的是innodb,5.5版本之前是myisam。它们两者之间的区别主要在于innodb支持事务,能够支持提交和事务回滚,myisam不支持。innodb支持行级锁和MVCC,而myisam不支持MVCC且只支持表级锁,因此性能没有innodb好。并且innodb崩溃后重启可以恢复到崩溃前的数据,myisam不支持。innodb支持外键,myisam也不支持。innodb使用聚簇索引,myisam使用非聚簇索引,即索引文件和数据文件是分开的。

总的来说就是:事务、MVCC、行级锁、外键、数据崩溃恢复、是否使用聚簇索引。

因此想要数据更稳定,支持数据崩溃恢复的话,innodb无疑是更好的。

事务有哪些特性:ACID 原子性、一致性 、隔离性、持久性

并行事务会发生哪些问题:

脏读:一个事务B读到了未提交事务A中的数据,如果事务A发生回滚,那就产生了脏读。

不可重复读:一个事务读取数据时得到的结果不一样,可能是在两次读取期间有别的事务作出修改并提交了。

幻读:一个事务中两次查询的结果集不一样,有可能是别的事物insert或者delete了数据。

MySQL中的隔离级别

MySQL中有四种不同的隔离级别,分别是读未提交:事务未提交时,做出的变更就能被看到;读已提交:事务提交之后,做出的变更才能被看到;可重复读:事务提交前能够读取的数据跟开启时的数据是一致的;串行化:通过加读写锁来控制对数据的访问和修改,强制任务串行执行。如果多个事务访问冲突,必须等前一个事务执行完成才能执行,隔离级别最高,可以完全解决幻读,但效率显然降低。

是否能解决读未提交读已提交可重复读串行化
提交之后才能看到变化事务执行过程中的数据跟开启事务时的数据是一致的对记录加上读写锁
脏读×
不可重复读××
幻读×××

innodb的默认隔离级别是可重复读,通过MVCC多版本控制和记录锁和间隙锁来解决大部分幻读问题。

针对快照读(select语句),用MVCC多版本控制来解决幻读。可重复读在事务开启之前会生成一个快照read_view,包含了几个字段,比如创建该快照的事务ID create_trix_id,当前事务开启时活跃的事务ID列表trix_ids,当前活跃事务的最小ID min_trix_id,和当前事务对应的下一个事务ID  max_trix_id。此外数据行里面除了数据之外,还有两个额外的字段分别是,最后一次对数据作出修改的事务ID和指向该数据旧版本的指针地址。因此创建快照之后,我们可以根据快照的trix_id划分为,已提交的事务,正在活跃的事务,和尚未开启的事务。一个事务去访问数据的时候:

如果数据行的trix_id<min_trix_id,则记录可以访问;

如果trix_id>max_trix_id,说明记录是在开启该事务之后修改的,不可见,需要访问旧版本;

如果min_trix_id<trix_id<max_trix_id,去检查是否在trix_ids列表中,如果在的话,说明事务仍然活跃,数据不可见,需要通过指针查询旧版本数据,如果不在,说明已经提交了,可以访问该数据。

通过多个版本的控制来决定当前事务访问的都是开启事务时的数据,解决幻读问题。

chat的回答更好:

利用MVCC解决幻读,幻读是什么;MVCC为每行数据维护了多个版本;事务开始时会生成快照,快照中有几个字段;根据这个字段个数据行的事务ID来判断数据是否对当前事务可见。保证了在事务内部查询数据时总能保持一致的结果。

针对当前读(select for update、insert、delete、update等),是通过next_key lock(间隙锁+记录锁)解决幻读,执行当前读时会加上该锁,在这个范围内插入数据时会被阻塞,无法插入成功,这就很好地避免了幻读。

RR隔离级别没有解决幻读,只是在很大程度上避免了幻读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值