https://blog.csdn.net/itguangit/article/details/82145322
https://www.cnblogs.com/happyflyingpig/p/7662881.html
一个没有主键的表,在数据无序的存储在磁盘上;
一个表加了主键,这个表在磁盘上的存储结构就转变为树状结构,即平衡树结构,同时也是索引;
此时整个表变为一个索引,即 聚集索引
聚集索引:
也称为 主键索引
表中的数据按照索引的顺序存储,即索引存储着数据, 检索效率比非聚集索引高,但是对数据更新影响大,因为修改数据会改变平衡树各个节点的内容;破坏树得到结构;
聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的记录数据。
聚集索引的叶子节点称为数据页,聚集索引的这个特性决定了索引组织表中的数据也是索引的一部分。
非聚集索引:
也称为 辅助索引(二级索引)
和聚集索引一样,采用平衡树作为索引的数据结构。索引树结构中各节点的值来自于表中的索引字段, 假如给user表的name字段加上索引 , 那么索引就是由name字段中的值构成,在数据改变时, DBMS需要一直维护索引结构的正确性。如果给表中多个字段加上索引 , 那么就会出现多个独立的索引结构,每个索引(非聚集索引)互相之间不存在关联。
非主键索引,叶子节点=键值+书签。Innodb存储引擎的书签就是相应行数据的主键索引值
每次给字段建一个新索引, 字段中的数据就会被复制一份出来, 用于生成索引。 因此, 给表添加索引,会增加表的体积, 占用磁盘存储空间。
//建立索引 create index index_birthday on user_info(birthday); //查询生日在1991年11月1日出生用户的用户名 select user_name from user_info where birthday = '1991-11-1'
SQL语句的执行过程如下:
先通过非聚集索引 index_birthday 查找 birthday 为 1991-11-1 的所有记录的主键ID值。
然后,通过得到的主键ID值执行聚集索引查找,找到主键ID值对的真实数据(数据行)存储的位置。
最后,从得到的真实数据中取得 user_name 字段的值返回。
非聚集索引和聚集索引:
区别在于, 通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据,如下图
覆盖索引:
就是平时所说的复合索引或者多字段索引查询。 文章上面的内容已经指出, 当为字段建立索引以后, 字段中的内容会被同步到索引之中, 如果为一个索引指定两个字段, 那么这个两个字段的内容都会被同步至索引之中。
就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫 做覆盖索引。
是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也即,索引包含了查询正在查找的所有数据)
把 birthday 字段上的索引改成双字段的覆盖索引
create index index_birthday_and_user_name on user_info(birthday, user_name);
SQL语句的执行过程就会变为:
通过非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的叶节点的内容,然而, 叶节点中除了有user_name表主键ID的值以外, user_name字段的值也在里面, 因此不需要通过主键ID值的查找数据行的真实所在, 直接取得叶节点中user_name的值返回即可。