-
内连接和外连接有什么区别?内连接和外连接的连接条件能放在on和where吗?
答案: 内连接只返回两张表满足连接条件的交集数据,不满足的直接过滤;外连接分左外、右外、全外,比如左外连接会返回左表所有数据,右表满足条件的匹配,不满足的补 NULL。
连接条件放ON和WHERE有区别:
- 内连接放
ON或WHERE结果一样,因为都是过滤匹配数据; - 外连接必须放
ON!如果放WHERE,会把外连接补的 NULL 数据过滤掉,直接变成内连接的效果。
-
什么是事务?你说一下事务有哪些特性?
答案: 事务就是数据库里一组不可分割的操作集合,要么全部执行成功,要么全部失败回滚,比如转账时扣钱和加钱必须同时成功。
事务有四大特性,简称ACID:
-
原子性:操作要么全成,要么全回滚;
-
一致性:事务执行前后,数据库的完整性约束不变,比如转账前后总金额不变;
-
隔离性:多个事务同时执行,互相隔离不干扰;
-
持久性:事务提交后,数据永久保存在数据库里,不会丢。
-
说一下事务的隔离级别有哪些?分别解决了什么问题?那脏读、不可重复读和幻读分别是什么?mysql和oracle分别是什么隔离级别?既然读已提交和可重复读分别都还有未解决的问题,为什么成熟的商业数据库mysql和oracle还是选择它们作为默认的隔离级别呢?
答案: 事务隔离级别有 4 种,从低到高:
- 读未提交:一个事务能读到另一个事务没提交的数据 → 会出现脏读、不可重复读、幻读;
- 读已提交:只能读到其他事务已提交的数据 → 解决脏读,还会有不可重复读、幻读;
- 可重复读:一个事务内多次读同一数据,结果一样 → 解决脏读、不可重复读,还会有幻读;
- 串行化:事务排队执行,完全隔离 → 解决所有问题,但性能最差。
脏读、不可重复读、幻读的定义:
- 脏读:读到别的事务没提交的、可能会回滚的数据;
- 不可重复读:一个事务内两次读同一数据,结果不一样(被其他事务修改提交了);
- 幻读:一个事务内两次查询同一范围数据,行数不一样(被其他事务增删提交了)。
MySQL 默认可重复读,Oracle 默认读已提交。
为啥选这两个当默认?核心是性能和业务需求的平衡:
- 串行化虽然能解决所有问题,但并发性能极差,实际生产很少用;
- 读未提交问题太多,基本没人用;
- 读已提交和可重复读,既能保证大部分业务场景的正确性,又能提供不错的并发性能。而且剩下的幻读、不可重复读问题,能通过业务代码(比如加锁、乐观锁)或者数据库的行锁、间隙锁来解决,没必要为了极端情况牺牲整体性能。
-
你通常一般具体是怎么学习的?
答案:1. 先解决问题:工作中遇到技术难点,比如优化 SQL 慢查询、排查事务问题,先查官方文档、Stack Overflow,动手写 demo 验证,先把问题解决;
- 再系统补基础:解决完问题后,回头啃底层原理,比如学 MySQL 索引就看《高性能 MySQL》,学事务就看数据库内核相关的文章,把零散的知识点串起来;
- 最后输出沉淀:把学到的东西写成博客或者技术笔记,也会自己搭项目练手,比如写个小的订单系统,把事务、索引这些知识点用进去,这样记得更牢。另外,我也会关注技术社区,比如掘金、GitHub,看看别人的开源项目和经验分享,跟上技术更新。