八股文骚套路之mysql
关系型数据库和非关系型数据库的区别
关系型数据库:
- 用表存储数据,表表之间存在外键联系,存在一对一、一对多、多对多的联系
- 支持ACID事务,确保数据的一致性
- 用SQL语言进行查询和操作
- 存在数据冗余,还会用索引来提高检索速度,占用空间较大
非关系型数据库:
- 存储数据的方式多种多样,键值型、文档型、图形型等等
- 性能强大,适合高并发场景
- 数据冗余较少,相比关系型数据库节省内存空间
ORDER BY、LIMIT、GROUP BY、HAVING 这些关键字的作用
- order by:排序
- limit: 限制查询返回的行数
- group by:根据一个或多个列对查询结果分组
- having: 用于过滤分组后的数据
- 相比较where:HAVING 在分组后应用条件,而 WHERE 在分组前应用条件
左链接和右链接的区别
一个以左边的表为基础,确保左表中的行都出现在结果中,反之亦然
InnoDB(mysql数据库管理系统的一个存储引擎)相关
索引的本质是一种排序好的数据结构
InnoDB 和 MyISAM 的区别是什么
- InnoDB 支持行级锁,MyISAM只有表级锁
- MyISAM 不提供事务支持。
- InnoDB 提供事务支持,MyISAM不支持。
- MyISAM 不支持外键,而 InnoDB 支持。
- MyISAM 不支持 MVCC,而 InnoDB 支持。
- 虽然 MyISAM 引擎和 InnoDB 引擎都是使用 B+Tree 作为索引结构,但是两者的实现方式不太一样。
- MyISAM 不支持数据库异常崩溃后的安全恢复,而 InnoDB 支持。
- InnoDB 的性能比 MyISAM 更强大
整个数据库,提高检索效率
索引相关
介绍一下索引的原理
索引是一种用于快速查询和检索的数据结构,本质可以看作一种排序好的数据结构
索引的作用相当于书的目录,使得在检索数据库的时候不需要遍历
索引是基于某个或多个列的值创建的数据结构。它通过使用一种特定的算法和数据结构,将数据的键值与其物理存储位置进行映射
索引所采用的数据结构,以及为什么要这样设计
常见的索引结构有:
- hash表 不支持顺序和范围查询
- 红黑树
- B树
- B+树
- 节点存放key,叶子存放key和data
- 叶子节点有一条引用鲢指向与他相邻的叶子节点
- 任何查找都是从根节点到叶子节点的过程,检索效率稳定
- B+树的范围查找只需要对叶子节点作范围查询
- 二叉查找树(左小右大)
- 平衡二叉树(优化的二叉查找树 左右子树高度之差不超过 1)
BTree 索引和 Hash 索引的适用范围
InnoDB数据库和MyISM数据库默认使用BTree索引
- hash索引适用于等值查询,尤其是在内存密集的环境中;
- 不适用于范围查询、排序和处理大量哈希冲突的情况
SQL优化问题
索引的应用场景
数据库查询的几个常见函数:
- 排序
- 连接
- 唯一性约束
- 聚集函数
- 范围查询
索引在哪些情况会失效
- 不能对索引列进行查询和函数操作
- 数据分布不均匀
- 数据量很大
- 频繁更新的列
- 索引列参与复杂的表达式或者条件
事务四大特性,并解释这四大特性的含义
ACID
- 原子性 事务是最小执行单位,不允许分割
- 一致性 执行事务前后 数据保持一致
- 隔离性 并发访问数据库时,一个用户的事务不被其他事务所干扰
- 持久性 事务提交之后对数据库的影响是永久的
只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障。也就是说 A、I、D 是手段,C 是目的!
并发事务处理会带来哪些问题?
- 脏读 a读到了b修改未提交的数据
- 幻读 a多次读同一个数据,但是期间其他事务对数据进行了修改
- 丢失修改 a读一个数据,b也访问该数据,第一个事务修改数据之后,b也修改了这个数据,导致a的修改结果丢失
事务隔离级别
- 读未提交 读取尚未提交的数据变更 会导致脏读 不可重读 幻读
- 读已提交 允许读取并发事务已经提交的数据 会导致不可重读 幻读
- 可重读 对同一字段的多次读取结果是一致的 会导致幻读
- 可串行化 满足acid
InnoDB 行锁实现方式
共享锁(s)(读锁)和排它锁(x)(写锁)
MVCC(多版本并发控制)MVCC可以在读取数据时不加锁,同时保证事务的一致性。每个事务在开始时都会生成一个唯一的事务ID,每行数据也会保存这个事务ID的版本信息。这样,即使其他事务在修改数据,当前事务也可以读取到之前版本的数据。
MVCC(多版本并发控制) 是一种并发控制机制,通过在每个数据行上维护多个版本的数据,当一个事务要对数据库中的数据进行修改的时候,MVCC会为该事务创建一个数据快照,而不是直接修改实际的数据行,用于在多个并发事务同时读写数据库时保持数据的一致性和隔离性
读操作使用旧版本数据的快照,写操作创建新版本,并确保原始版本仍然可用
你了解 Next-key 锁吗?
Next-Key锁是一种特殊类型的锁,通常在实现范围查询时用于避免幻读(Phantom Read)问题。
Next-Key锁结合了行锁(Row Lock)和间隙锁(Gap Lock)的特性,用于确保范围查询的一致性。
- 普通select读取的时候读取mvcc的快照
- 使用当前读的时候读取最新数据,并且防止其他事务在查询范围内插入数据
如何避免 InnoDB 中的死锁
- 尽量使用索引
- 使用事务的隔离级别
- 减少并发
- 合理设计事务
死锁的类型
死锁是指多个事务在相互持有资源的情况下,同时等待对方释放资源
简单死锁
涉及两个事务,互相等待递归死锁
多个事务,循环等待资源不足死锁
资源紧张的情况下,多个事务由于资源不足进入等待
如何优化数据库?
- 索引
- 分库分表: 就是将数据库中的数据分散到不同的数据库上,是对单表的数据进行拆分。
- 读写分离:将对数据库的读写操作分散到不同的数据库节点
- 数据冷热分离:根据数据的访问频率和业务重要性,将数据分为冷数据和热数据,冷数据一般存储在存储在低成本、低性能的介质中,热数据存放在高性能存储介质中。
数据库中的乐观锁和悲观锁,以及适用场景?
悲观锁:假设并发访问会导致冲突,因此在访问数据之前获取锁,以防止别的事务对数据进行修改,适用于频繁写的场景。(例如数据库中的行级锁和表级锁)
乐观锁:假设并发访问不会导致冲突,因此在访问数据时不会立即获取锁,在更新数据时检查数据是否被其他事务修改过,如果没有则进行更新,否则会进行回滚或者重试。适用于读操作多,写操作少的场景
数据库响应慢可能有什么原因
- 查询复杂性:复杂的查询语句、多表连接、大量的数据过滤和排序等操作会增加数据库的负载。
- 索引缺失或失效:数据库需要进行全表扫描,导致响应时间变慢。
- 数据量过大
- 硬件资源不足
- 网络延迟:数据库服务器与应用服务器之间的网络延迟会影响数据库的响应时间。
- 锁竞争:并发访问数据库时,如果多个事务需要同时修改同一行数据或同一数据页,可能会出现锁竞争,导致等待时间增加,响应变慢。
- 数据库配置不当:数据库的配置参数(如缓冲池大小、并发连接数等)设置不合理,未充分利用硬件资源,导致性能下降。
如何删除大表中的所有数据
- 每次删除限定一定数量,然后分批次循环删除
- 直接按照需求删除指定分区表
- 拷贝表结构,生成临时表,删除原表,升级临时表为正式表
- 直接删除物理文件
数据库主从
用于数据库的读写分离,主库写,从库读,可以提高读的性能,应对数据库读并发问题
视图有什么作用
- 可以看到表结构,隐藏一些敏感信息
- 可以用来筛选数据表