赞
踩
mysql官方对索引的定义为:索引(index)是帮助Mysql高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种放肆引用(指向数据),这样就可以在这些数据结构上实现高级的查找算法,这种数据结构就是索引。如下的示意图所示
左边是数据表,一共有两列七条数据,最左边的是数据记录的物理地址 如“0x07”就是物理地址。(逻辑上相邻的两条数据在磁盘上不一定就是相邻的)。为了加快Col2列的查找,可以维护一个如右图所示的二叉查找数<–这边是打个比喻。每个节点分别包含索引键值和一个指向对应的数据记录物理地址值的指针,这样就库运用二叉查找快速的获取对应的数据。
注意:一般来说索引本身也很大,不可能全部存储到内存中,因此索引往往以索引文件的形式存储到磁盘上。索引是数据库中用来提高性能的最佳工具。
1.实际上索引也是一张表,该表中保存了主键与索引字段,并指向实体类的记录,所以索引列也是要占空间的。
2.虽然索引大大的提高了查询效率,同时也降低了更新表的速度,如对表进行Inster、uodate、delete。因为更新表时,Mysql不仅要保存数据,还要保存索引文件每次更新添加了索引列的字段,都会调整因为更新带来的键值变化的索引信息。
索引的设计可以遵循一些已有的原则,创建索引的时候请尽量考虑符合这些原则,便于提升索引的使用效率,更高效的使用索引。
索引实在Mysql的存储引擎中实现的,而不是在服务器层实现的。所以每种存储引擎的索引都是不一定相同到额,也不是所有的存储引擎都支持所有的索引类型的。Mysql目前提供了一下四种索引:
MyISAM、InnoDB、Memory三种存储引擎对各种索引类型的支持
我们平常所说的索引,如果没有特别指明,都是指B+树(多路搜索树,并不一定是二叉的)结构组织的索引。其中聚集索引、复合索引、前缀索引、唯一索引默认都是使用 B+tree 索引,统称为 索引。
引擎是基于表实现的
在数据库中可视化也是可以看的,这边我使用的是NAV,打开一个数据库–>打开表–>右击–>设计表–>索引就可以查看此表的索引。也可以在–>选项中查看引擎类型
这边以以下库为例:
创建名为 demo_01的库,在库中创建 city、country两张表。
create database demo_01 default charset=utf8mb4; use demo_01; CREATE TABLE `city` ( `city_id` int(11) NOT NULL AUTO_INCREMENT, `city_name` varchar(50) NOT NULL, `country_id` int(11) NOT NULL, PRIMARY KEY (`city_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `country` ( `country_id` int(11) NOT NULL AUTO_INCREMENT, `country_name` varchar(100) NOT NULL, PRIMARY KEY (`country_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `city` (`city_id`, `city_name`, `country_id`) values(1,'西安',1); insert into `city` (`city_id`, `city_name`, `country_id`) values(2,'NewYork',2); insert into `city` (`city_id`, `city_name`, `country_id`) values(3,'北京',1); insert into `city` (`city_id`, `city_name`, `country_id`) values(4,'上海',1); insert into `country` (`country_id`, `country_name`) values(1,'China'); insert into `country` (`country_id`, `country_name`) values(2,'America'); insert into `country` (`country_id`, `country_name`) values(3,'Japan'); insert into `country` (`country_id`, `country_name`) values(4,'UK');
**创建索引语句 :
create index<create index: 创建索引> index_city_name<index_city_name : 索引名> on <on 在哪里创建> city(city_name)<city(city_name) 为city表中的city_name字段创建>**
1)单值索引:即一个索引只包含单个列,一个表可以有多个单列索引 :这里为city的city_name字段创建名为index_city_name单值索引
create index index_city_name on city(city_name)
2)唯一索引:索引列的值必须唯一A(就像表中的主键,自动就为主见列创建唯一索引),但是可以有空值
3)复合索引:即一个索引包含多个列 。 这里为city的city_id和city_name字段创建名为index_city_id_name的复合索引。
create index index_city_id_name on city(city_id,city_name)
就相当于
对city_id创建索引 ;
对city_id, city_name创建了索引 ;
这里值得注意的就是 我们定义的如果是复合索引 ,那么我们在查找的时候就要遵循我们定义索引的顺序,要不然会失效。
在上边语句中,我们定义的顺序是 先city_id 在city_name 就像是上楼一样, city_id是第一层楼, 我们只能先上c了ity_id这第一层楼才能去尝试上第二层楼city_name。
查看city表中的所有索引
show index from city<表名>
删除city表中的名为 index_city_name的索引。
drop index index_city_name on city ;
在前文我们说过,Mysql默认就是采用InnoDB引擎,默认采用B+TREE数据结构存储。那么B+TREE到底是什么呢?
B+TREE是一种特殊的B-TREE(B 杠 TREE ,可以不是 B 减 树哦)。
所以在这里我们要先介绍一下B-TREE
BTree又叫多路平衡搜索树
一颗m叉(就是一个节点下有几个分支)的BTREE的特征如下。
看的懵逼,很正常,下面我们举一个案例看一下
以3叉BTree为例,key的数量:公式推导[ceil(m/2)-1] <= n <= m-1。所以 1 <= n <=2 。当n>2时,中间节点分裂到父节点,两边节点分裂。
插入1-5这5个数据。在树中,比根节点大的去右边,小的去左边
我这边有个网站,测试B-TREE的新增等变化
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
一个m阶的B+树具有如下几个特征:
1.有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
2.所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3.所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。
B+Tree为BTree的变种,B+Tree与BTree的区别为:
1). n叉B+Tree最多含有n个key,而BTree最多含有n-1个key。
2). B+Tree的叶子节点保存所有的key信息,依key大小顺序排列。
3). 所有的非叶子节点都可以看作是key的索引部分。
是不是好繁琐的样子,不急,我们来慢慢看哦
由于B+Tree只有叶子节点保存key信息,查询任何key都要从root走到叶子。所以B+Tree的查询效率更加稳定。
B+TREE转载自:https://zhuanlan.zhihu.com/p/54102723
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。