北京JAVA基础面试30天打卡09
1.MySQL存储引擎及区别
特性 | MyISAM | Memory | InnoDB |
---|---|---|---|
B+ 树索引 | ✅ Yes | ✅ Yes | ✅ Yes |
备份 / 按时间点恢复 | ✅ Yes | ✅ Yes | ✅ Yes |
集群数据库支持 | ❌ No | ❌ No | ❌ No |
聚簇索引 | ❌ No | ❌ No | ✅ Yes |
压缩数据 | ✅ Yes | ❌ No | ✅ Yes |
数据缓存 | ❌ No | N/A | ✅ Yes |
加密数据 | ✅ Yes | ✅ Yes | ✅ Yes |
外键支持 | ❌ No | ❌ No | ✅ Yes |
全文检索 | ✅ Yes | ❌ No | ✅ Yes |
地理空间数据类型支持 | ✅ Yes | ❌ No | ✅ Yes |
地理空间索引支持 | ✅ Yes | ❌ No | ✅ Yes |
哈希索引 | ❌ No | ✅ Yes | ❌ No |
索引缓存 | ✅ Yes | N/A | ✅ Yes |
锁的粒度 | Table | Table | Row |
MVCC | ❌ No | ❌ No | ✅ Yes |
复制支持 | ✅ Yes | Limited | ✅ Yes |
存储限制 | 256 TB | RAM | 64 TB |
T-tree 索引 | ❌ No | ❌ No | ❌ No |
事务 | ❌ No | ❌ No | ✅ Yes |
存储引擎 | 特点 | 事务支持 | 锁粒度 | 适用场景 | |
---|---|---|---|---|---|
InnoDB | MySQL 8.0 默认引擎,支持 ACID 事务,行级锁,支持外键,支持崩溃恢复 | ✅ | 行锁 | 高并发 OLTP 系统 | |
MyISAM | 不支持事务,只有表级锁,读取速度快,占用空间小,支持全文索引 | ❌ | 表锁 | 以读为主、日志、归档类系统 | |
Memory | 数据存储在内存中,速度极快,但数据易丢失(重启清空),支持哈希索引 | ❌ | 表锁 | 临时表、缓存计算 | |
CSV | 数据存储为 CSV 文件,方便与外部程序交换数据,不支持索引 | ❌ | 表锁 | 数据导入导出 |
2.Mysql的InnoDB引擎中的聚簇索引和非聚簇索引有什么区别?
聚簇索引的非叶子节点存储的是索引值,叶子节点存储的是完整的数据记录,一个表只能有一个聚簇索引,一般是表的主键,主要用于范围查询和排序。非聚簇索引的非叶子节点存储的也是索引值,但是叶子节点存储的是数据行的主键和对应的索引列,一个表可以有多个非聚簇索引,非聚簇索引又称为助索引,二级索引等,主要用于快速定位 要查找的列。
补充回答
聚簇索引简单理解就是把索引和数据记录放在一起了,通过索引就可以直接找到数据行了,而非聚簇索引,还需要通过回表找到相应的数据记录。扩展回答 (引导思路及面试假想)
扩展回答
1:为什么聚簇索引查询速度快?
在lnnoDB中,聚簇索引指的是按照每张表的主键构建的一种索引方式,它是将表数据按照主键的顺序存储在磁盘上的一种方式。这种索引方式保证了行的物理存储顺序与主键的逻辑顺序相同,因此查找聚簇索引的速度非常快。
2:没有创建主键怎么办?
其实数据库记录中除了我们自己定义的字段外,还会添加一些隐藏字段,比如db_row_id,如果我们没有创建主键,会默认选择一个唯一索引作为聚簇索引,如果唯一索引也没有,默认就选择隐藏主键db_row_id作为聚簇索引l。
3:上面提到的回表是什么意思?
通常我们使用聚簇索就可以直接查找到数据记录,但是非聚簇索引由于它的叶子节点只存储主键值和索引值,这种情况下我们使用非聚簇索引查询相应的数据记录,需要先查到对应的叶子节点的主键值,然后再用主键值进行一次查询才能获得我们需要的数据记录,这个过程称为回表。
4:为什么主键查询效率快?
从上面的回答可以看出,主键索引查询数据记录不需要回表,减少了查询步骤,相应也提升的查询效率。
5:我们应该如何提升查询效率呢?
前面我们说到回表会降低查询效率,所以我们应该通过优化索引结构,添加相应的索引以及优化sql语句,减少回表的次数以提升查询的效率,同时我们也可以依赖覆盖索引、索引下推等技术。
6:既然你提到了索引下推,和索引覆盖,能否具体讲一下?
索引覆盖就是在索引中就包含了我们需要查询的数据列,比如我想查询column2,此时有一个索引记录(columnl,column2),那我们通过索引columnl进行查询 select column2 from table where column1='test’,上面的情况就是覆盖索引的例子,这种情况就不需要回表进行查询了。接下来讲下索引下推,这个也很好理解,首先我们需要了解,存储引擎只能根据索引例的值来定位到对应勺主键值,然后回表获取完整的记录行。如果查询条中还有其他未在索引中使用的筛选条件,那么这些条件只能在回表获取完整行之后在服务器层进行判斤。这就导致了很多不满足条件的记录也进行了回表桑作,增加了回表的次数。为了减少回表次数,我们可以利用索引下推技术在存储引擎层使用索引中的列来进行额外的筛选操作,而不仅仅是使用索引来定位已录的主键值。总结来说就是,索引下推就是联合索在本身数据就有的情况下,直接通过联合索引再进行一次数据的过滤,而不是通过回表返回到server层行数据的过滤。
3. MySQL 索引类型
按数据结构分类:
- B+Tree 索引(最常用,支持范围查询、排序)
- Hash 索引(Memory 引擎支持,等值查询快,不支持范围查询)
- R-Tree 索引(空间索引,MyISAM 的 GIS 数据)
- Fulltext 索引(全文搜索,MyISAM/InnoDB 支持)
按功能分类:
- 主键索引(Primary Key)
- 唯一索引(Unique Key)
- 普通索引(Index)
- 全文索引(Fulltext)
- 空间索引(Spatial)
按物理存储分类:
- 聚簇索引(Clustered Index)
- 非聚簇索引(Secondary Index / 非主键索引)
- 覆盖索引(Covering Index,索引包含查询所需的所有列,无需回表)
- 组合索引(Composite Index,多列联合索引)
- 前缀索引(Prefix Index,对字符串前 N 个字符建索引)
拓展:
1.InnoDB为什么使用B+树实现索引?
1.B+树是一棵平衡树,每个叶子节点到根节点的路径长度相同,查询效率高
2.所有关键字都在叶子节点上,因此范围查询时只需要谣历一遍叶子节点即可。
3.叶子节点都按照关键字的大小顺序存放,因此可以快速的根据关键字大小进行排序。
4.非叶子节点不存储实际数据,因此可以存储更多的索引数据
5.非叶子节点适用指针链接叶子节点,因此可以快速的支持范国查询和倒序查询。
6.叶子节点之间通过 双向链表链接,方便进行范国查询。
所以可以总结得出,使用B+树有以下有几点,支持范围查询、支持排序、可以存储更多的索引数据、因为叶子节点大小固定,节点分裂和合并时,IO操作少,同时因为大小固定,还有利于磁盘预读,因为非叶子节点只存储指向子节点的指针,而不存储据,所以可以缓存更多的索引数据,有利于缓存。
2.B+树索引l和Hash索引有什么区别?
1.因为B+树索引将索引列的值按照大小排序存储,所以更适合于范围查询,而哈希索引是基于Hash表的结构,所以哈希索引更适合等值查询,但不适合范围查询和排序操作。
2.如果B+树索引插入数据和删除数据时需要调整索引结构,可能涉及到页分裂和页合并等操作(无序插入),维护成本较高,而哈希索引在插入和删除数据只需要计算哈希值并插入或者删除相应的记录。
3.B+树索引在磁盘上是有序存储的,而哈希索引是无序存储的
3.唯一索引和主键索引的区别?
两者都具有唯一性,但是主键索引不能为null,唯一索引可以,主键索引每表只能有一个,唯一索引可以创建多个,在innoDB中,主键索引就是聚簇索引,但唯一索引通常是非聚簇索引(除了特殊情况,就是在没有创建主键索引的情况下,MySQL会默认选择一个唯一的非空索引I作为聚簇索引),同时主键索引一定不需要回表,但是唯一索引查询通常是需要回表的,主键可以被其他表引用为外键,而唯一索引不可以。
4.MySQL如何保证唯一索引I的唯一性?
在支持事务的存储引擎中(例如lnnoDB)中,事务机制和锁定协议帮助维护索引的唯一性,当个事务正在修改索引引列时,其他事务对相同键值的修改会被适当的阻塞,直到第一个事务提交或回滚,确保了数据的一致性和唯一性,并且在实际的写入数据到磁盘之前,MySQL也会执行约束检查,确保不会违反唯一性约束。相应的因为唯一索引保证了指定列的值唯一,会让唯一性索引查询比非唯一性查询根块,因为能够快速的匹配到唯一的记录,但是也是因为要保证索引列的唯一性,因此在插入的时候需要检查是否存在相同的索引值,会对插入性能产生一定的影响。