数据库索引原理

一、什么时数据库索引

数据库索引是数据库管理系统中一个排序的数据结构,将原本无规则一行一行排列的原始数据按照特定的数据结构排列起来而形成一个新的排序+原始数据的结构。这种数据结构主要以「平衡树」(非二叉),也就是b tree或者 b+ tree为主,当然有的数据库也使用哈希桶作用索引的数据结构。

二、数据库索引的作用

  1. 快速的查找数据。如果没有索引,通常会全表扫描数据,如果表的数据非常大的话,一条一条的去匹配的话,最坏的情况下需要匹配O(n)最坏时间复杂度;而通过索引的话,不需要全表扫描,一般只需要O(logn)次就可以定位到具体的数据,大大减少了查询速度。
  2. 管理数据库约束。索引通常还会用于数据库约束,例如:UNIQUE,PRIMARY KEY,FOREIG KEY,当一个索引被定义成UNIQUE时,数据库同时创建一个隐式的约束。

三、索引的优缺点

优点:

  • 减少I/O次数,加快检索速度;
  • 根据索引分组和排序,可以加快分组和排序。

缺点:

  • 创建索引和维护索引耗时,时间随着数据的增加而增加,成正比;
  • 索引需要占物理空间,除了数据表占数据空间外,每一个索引还要占一定的物理空间,如果建立聚簇索引,占得物理空间会更大;
  • 索引会降低数据表的修改操作(删除,添加,修改)的效率,因为在修改数据表的同时还需要修改索引表;

四、索引的创建与分类

索引可以按照与数据之间的物理存储顺序的关系分为两位类:

  1. 聚集索引/聚簇索引:聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。一个表只能有一个聚簇索引。
  2. 非聚集索引/非聚簇索引:非聚簇索引的顺序与数据物理排列顺序无关,他们是分开的,非聚簇索引结构的叶子节点都不存放具体的物理数据而是存放的指向具体物理数据对应行的指针。

索引的创建方式:

--1、主键索引:即根据主键pk_clolum(length)建立索引,不允许重复;
ALTER TABLE table_name ADD PRIMARY KEY index_name(id);

--2、唯一索引:用来建立索引的列的值必须是唯一的,允许空值;
ALTER TABLE table_name ADD UNIQUE index_name(col1(10));

--3、普通索引:用表中的普通列构建的索引,没有任何限制;
ALTER TABLE table_name ADD INDEX index_name(col2(20);

--4、全文索引:用大文本对象的列构建的索引;
ALTER TABLE table_name ADD FULLTEXT INDEX index_name(col3(255));

--5、组合索引:用多个列组合构建的索引;
ALTER TABLE table_name ADD INDEX index_name(col1,col2,col3);

--删除索引
ALTER  TABLE  company  DROP  INDEX  index_name;

联合索引最左侧原则:
例如: ALTER TABLE person ADD INDEX idx_age_name_sex(age,name,sex);

A:select * from person where age = 16 and sex= '男'
B:select * from person where name = '小明' and age = 16
C:select * from person where name = '小明' and sex= '男'
D:select * from person where age = 18 and name = '小明' and sex = '男' 
D:select * from person where age > 20 and name = '小明'
E:select * from person where age != 15 and name = '小明'
F:select * from person where age = 15 and name != '小明'

上次这些查询除了C不走索引,其他都会走索引,也就是说只要查询条件中包含创建索引时最左边的那个字段,并且全部使用and连接起来,那么这个联合索引就生效。如果条件中包含or时,这个联合索引也不生效。

五、索引的底层数据结构

索引常用的数据结构主要有B-tree(平衡树)、B+tree、Hashes(哈希)。

B+tree与B-tree的主要区别在于:

  1. B+Tree中的非叶子结点不存储数据,只存储键值;
  2. B+Tree的叶子结点没有指针,所有键值都会出现在叶子结点上,且key存储的键值对应data数据的物理地址;
  3. B+Tree的每个非叶子节点由n个键值key和n个指针point组成;

B+Tree对比BTree的优点:

  1. 磁盘读写代价更低:因为B+Tree的非叶节点中不存储data,就可以存储更多的key,每个节点中的key个数越多,那么树的高度越小,需要I/O的次数越少,而提升查找速度的关键就在于尽可能少的磁盘I/O,因此一般来说B+Tree比BTree更快。
  2. 查询速度更稳定:由于B+Tree非叶子节点不存储数据(data),因此所有的数据都要查询至叶子节点,而叶子节点的高度都是相同的,因此所有数据的查询速度都是一样的。
InnoDB索引实现:

InnoDB引擎使用B+Tree作为索引实现,在InnoDB引擎中主键索引为聚集索引,其他辅助索引都为非聚集索引。在InnoDB引擎中通过主键索引也就是聚集索引可以直接获取到具体的数据;而通过辅助索引在叶子节点只能拿到获取具体数据的主键id,然后再通过主键去查找主键索引,最终找到具体的数据。下面借用网上的图片作为参考:
InnoDB的主键索引图:数据库索引原理_第1张图片
InnoDB的辅助索引图:数据库索引原理_第2张图片

MyISM索引实现:

MyISM引擎也是使用B+Tree作为索引实现,并且所有的索引都是非聚集索引。在MyISM引擎中都是先通过索引找到指向具体数据的指针,再通过指针找到具体的数据。下面同样借用网上的图片来体现下:
MyISM的主键索引:数据库索引原理_第3张图片
MyISM的辅助索引:数据库索引原理_第4张图片

联合索引

数据库索引原理_第5张图片
创建联合索引:CREATE INDEX IDX_XXX ON TABLE(COL3, COL2);
数据库索引原理_第6张图片

联合索引在查找的时候,比如要找 Alice,34 这条记录 WHERE COL3 = ‘Alice’ AND COL2 = 34

  1. 先根据col3 查找 Alice ,找到了2条记录,
  2. 在根据col2 查找这2条记录等于34的主键id,然后获取到主键 15 ,在根据主键查找主索引。

你可能感兴趣的:(数据库,数据库)