🌷 1.索引
⭐️ 1.1 定义
索引:为了提高查询效率而使用一种数据结构把数据组织起来。可以把索引理解在书的⽬录或字典的检索表(拼⾳检索)。
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现
。
⭐️ 1.2 为什么要用索引
为了提⾼查询效率。
这是⼀个是典型的以空间换时间
的操作,刚才说了,创建索引也要占⼀定的空间,⽽且在数据新增和删除的时间开销还是⽐较⼤的,因为不但要更新数据⾏,还是更新索引
⽐如,⼀书本在修订的时候增加或删除了⼀部分内容,那么后⾯的内容对应的⻚码全都改变了,所以⽬录也要做相应的调整。
如果没有索引,那么查找时可能需要全整的遍历整个数据集,时间复杂度最坏就是O(N)
有了索引之后,就可以通过⻚码,快速定位⼀个范围,然后再这个⼩范围内去找,这时的时间复杂度就⼤⼤降低了。
⭐️ 1.3 作用
- 数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。
- 索引所起的作用类似书籍目录,可用于快速定位、检索数据。
- 索引对于提高数据库的性能有很大的帮助。
⭐️ 1.4 使用场景
要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
数据量较大
,且经常对这些列进行条件查询。- 该数据库表的
插入
操作,及对这些列的修改
操作频率较低
。- 索引会
占用额外的磁盘空间
。
满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率
。
反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。索引一般创建在频繁查询的列上,且这个列中的值重复较少。
⭐️ 1.5 使用
🍁 1.5.1 查看索引
show index from 表名;
案例:查看学生表已有的索引
show index from student;
🍁 1.5.2 创建索引
对于非主键、非唯一约束、非外键的字段,可以创建普通索引(字段名可以有多个,用逗号隔开,一个索引包含多个字段就叫组合索引)
create index 索引名 on 表名(字段名);
create index 索引名 on 表名(字段名1,字段名2...);
案例:创建班级表中,name字段的索引
create index idx_classes_name on classes(name);
🍁 1.5.3 删除索引
drop index 索引名 on 表名;
案例:删除班级表中name字段的索引
drop index idx_classes_name on classes;
⭐️ 1.6 创建索引的⽅式
- 创建
主键约束
(PRIMARY KEY)、唯一约束
(UNIQUE)、外键约束
(FOREIGN KEY)时,会自动创建对应列的索引。 - ⼿动创建,业务中我想对学⽣的身份证号建⽴⼀个索引:
create index idx_student_idcard on student(idcard); - ⼀张表⾥⾄少会有⼀个索引
a. 如果⼀张表⾥没有主键,MySql会为每⼀⾏⽣成⼀个唯⼀的字段,并⽤这个字段当前做索引
b. 如果⼀张表⾥有主键,那么主键必然是索引,主键索引也叫聚簇索引
, ⽽且⼀直存在这也是我们绝⼤部分情况下的使⽤场景
c. 如果⾃⼰⼿动创建索引,那会会为这个列或是列的组合(多个列)创建单独的索引,⾮聚簇索引
- 分类:
a. 按使⽤场景分:普通索引,主键索引,唯⼀索引,全⽂索引
b. 按数据组织⽅式分:聚簇索引,⾮聚索引
c. 还有⼀种数据查找过程中出现的现象叫索引覆盖
⭐️ 1.7 选择索引的数据结构(面试常问)
题外话:推荐一个做数据结构图的链接(非常好用!!!):
Data Structure Visualizations
🍁 1.7.1 HASH
查询和插⼊的时间复杂度是O(1).
Hash这种数据结构快是快,但是他不适合做数据库的索引,为什么叫呢?因为他不⽀持做范围查询,⼤于号⼩于号 between and 这种操作,是不⽀持的。
不清楚为什么不支持范围查询的朋友可以看一下这篇:哈希表
🍁 1.7.2 ⼆叉搜索树
⼆叉搜索树的时间复杂度是多少,O(logN), O(N)
红⿊树是O(logN),因为红⿊树可以动态调整树⾼,不会出现单边树的情况.
那红⿊适合不适合做索引底层的数据结构呢?
答:不适合, 为什么呢? ⼆叉搜索树的中序遍历是⼀个有序数组。
它没有办法控制树的⾼度,树的⾼度决定了磁盘的访问次数,咱们先这么理解,每向孩⼦节点访问⼀级,就发⽣了些磁盘IO,⽽在⼀个系统中,对性能影响最⼤的就是磁盘IO,所以就要有⼀种数据结构能有效控制树的⾼度。
🍁 1.7.3 N叉搜索树,B 树
可以规定每⼀个节点可以存多少个元素,当节点中达到了规定的元素个数时,才去调整,B树就可以解决树⾼的问题&#