MySQL_MySQL索引详解(重要)

引入:

       在上一篇文章中,我们对索引有了一个比较基础的认识,那么接下来,我们一起来深入探讨一下索引的其他方面需要注意的知识。

常见的索引类型以及相关注意事项:

我们通过创建学生表(student)以及对应的相关操作来实现我们需要的测试。

1.单列索引

    (1).当列索引的创建

   <1>.在创建数据库表的时候创建。

    ①:创建普通索引,学生姓名上建立索引            

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `st_name` varchar(50) DEFAULT NULL,
  `st_age` int(10) DEFAULT NULL,
  `st_sex` varchar(10) DEFAULT NULL,
  `st_num` varchar(50) DEFAULT NULL,
  `st_major` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  INDEX st_name_index(st_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

查看索引是否建立: 

  ②:创建唯一索引,在学生学号上建立索引

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `st_name` varchar(50) DEFAULT NULL,
  `st_age` int(10) DEFAULT NULL,
  `st_sex` varchar(10) DEFAULT NULL,
  `st_num` varchar(50) DEFAULT NULL,
  `st_major` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX st_num_idx(st_num)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 查看索引是否建立: 

   ③:创建主键索引,在记录的编号id上建立,其实只要我们指定主键即可

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `st_name` varchar(50) DEFAULT NULL,
  `st_age` int(10) DEFAULT NULL,
  `st_sex` varchar(10) DEFAULT NULL,
  `st_num` varchar(50) DEFAULT NULL,
  `st_major` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

查看索引是否建立: 

 <2>.在已有数据表的基础上创建索引。

创建数据库表student

 ①:创建普通索引,在学生名字上创建索引

create index st_name_idx on student(st_name(50)); 

  ②:创建唯一索引

create unique index st_num_idx on student(st_num(50)); 

  ③:创建主键索引

    由于主键索引在创建数据库表的时候就已经创建好,则不再继续创建。

 查看student表上锁创建好的索引

 (2).单列索引的使用

 <1>.普通索引使用,通过学生名字查询,查看是否使用了索引

 <2>.唯一索引使用,通过查询学生编号,查看是否是否使用了索引

 <3>.主键索引使用,通过记录编号id来进行数据的查询

explain关键查询结果说明:

Explain关键字执行SQL语句结果说明:

id:select的查询序列号,标识在查询语句中select出现的频次。

select_type:所使用的select查询类型。

table:数据库表名称,如果涉及多张数据库表,那么他就会,按照先后顺序进行加载。

type : 指定本数据表和其他数据表之间的关联关系,该表中所有符合检索值的记录都会被取出来和从上一个表中
       取出来的记录作联合。也就是显示的contact。

possible_keys:进行数据查询的时候可以使用的索引。

key : 实际在查询的时候使用的索引。

key_len:所使用的索引的长度

ref:关联关系中另一个数据表中数据列的名字。如果没有,那么它将给出的是常量(const)。

rows:在执行这个查询时预计会从这个数据表里读出的数据行的个数。

extra:提供了与关联操作有关的信息,没有则什么都不写。

2.组合索引

    (1).组合索引的创建,这里。我们同样给出俩个创建的方法。

        ①:在创建表的时候创建。

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `st_name` varchar(50) DEFAULT NULL,
  `st_age` int(10) DEFAULT NULL,
  `st_sex` varchar(10) DEFAULT NULL,
  `st_num` varchar(50) DEFAULT NULL,
  `st_major` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  index st_multi_idx(st_name,st_age)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

②:在创建表之后建立索引

create index st_multi_idx on student(st_name,st_age);

    (2).组合索引基本使用,通过查询不同的字段,我们可以知道使组合索引的基本使用。它遵循"最左前缀原则"。

    (3).组合索引查询以及最左前缀原则

         我们在student表的st_name和st_age上建立了一个组合索引。然后我们分别通过查询st_name,st_age以及组合st_name和st_age进行数据查询,但是呢我们发现对st_age进行查询的时候。没有使用索引,连可以使用的索引都没有。这是为什么呢?原来,组合索引的使用遵循最左前缀原则。简单的说就是,对于我们建立的组合索引,你要使用,那么我们查询的时候就必须包含我们在创建索引的时候第一个字段,而且是要这一个字段开头。如:我们创建组合索引  st_mult_idx(st_name,st_age,st_num)。那么只有(st_name),(st_name,st_age),(st_name,st_age,st_num)能够使用所建立的组合索引。

    (4).使用注意事项

         组合索引在使用的时候,我们需要把查询频率比较高的字段放置在索引的最左侧。

3.全文索引

  (1).全文索引的创建

①.在创建数据库表的时候创建

 DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `st_name` varchar(50) DEFAULT NULL,
  `st_age` int(10) DEFAULT NULL,
  `st_sex` varchar(10) DEFAULT NULL,
  `st_num` varchar(50) DEFAULT NULL,
  `st_major` varchar(50) DEFAULT NULL,
  `st_intro` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  FULLTEXT index st_ftxt_idx(st_intro)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

②.在创建好数据库表以后创建

  (2).全文索引的使用

①.添加俩条记录到数据库中,如下:

INSERT INTO `student` VALUES ('1', '张三', '20', '男', '123456', '计算机科学', '你好,这就是一个小测试');
INSERT INTO `student` VALUES ('2', '李四', '21', '男', '456789', '计算机科学', 'this is just a test');

②.进行对st_intr字段的全文索引相关查询

  (3).使用注意事项

①.全文索引在创建的时候只能够在MyISAM存储引擎上面进行。如在InnoDB索引上使用,将会报错:

②.全文索引只能够针对字符类型的字段建立,如char,varchar,text等和字符串存储有关的字段才能建立。否则会报错。如:

③.在使用全文索引的时候,需要查询的SQL借助match函数。如上面我们使用的查询操作。

④.在使用全文索引查询的时候,匹配使用的字符的长度是有限制的(至少4个字符)。同时进行全文索引查找的时候。由于它进行查询匹配的时候并不是说只要这一个字符串中有,就会把结果查询出来,而是通过类似于'灰度计算'的方式进行一个匹配。达到一定的条件,才可以把数据查询出来。同时他仅仅只能够对英文进行查询,不支持对中文全文索引查询。如:

MySQL索引的数据结构(Hash索引和BTree索引)

       因为索引和存储引擎是相关联的,不同的存储引擎匹配有不同的索引。MyISAM和InnoDB存储引擎,只支持BTREE索引(默认使用),不能更改。而MEMORY/HEAP存储引擎:支持HASH和BTREE索引。那么,常用的BTREE数据机构和HASH数据结构有什么样的特点和好处呢?

      下面我们一起来看看BTREE索引和HASH索引之间各有什么相应的特点。

      1.BTREE索引特点

       (1).树形结构描述

             树形数据结构是一类重要的非线性数据结构。树形数据结构可以表示数据表之间一对多的关系。其中以树与二叉树最为常用,直观看来,树是以分支关系定义的层次结构。树形数据结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形数据结构来形象表示。下面是一个简单的二叉树结构以及部分和树相关的专业术语:

树的数据结构

相关的基本术语:

1.节点:数据元素以及指向子树的分支。简单的说就是数据之间连接的位置点,如A,B,C。

2.根(根节点):非空树中无前驱结点的结点,也就是树的最上面的一个节点。如A。

3.结点的度:结点拥有的子树数。如A结点有2个子树,其度为2。

4.树的度:树内各结点的度的最大值。如上图树的深度为2。

5.叶子结点(终端结点):度为0的结点。如上图的D,E,F,G都是叶子结点。

6.分支结点(非终端结点):度不为0的结点。A,B,C都是分支结点。

       (2).BTREE结构特点

      在树结构数据中较为常见的就是二叉树(Binary Tree)。它是一种较为特殊的树形数据结构。它的特点是每一个节点至多只有俩个子树(即二叉树中不存在度大于2的节点)。并且二叉树的子树有左右之分。次序不能够相互的颠倒。

      B-树索引是基于二叉树结构的一种数据结构。常见的BTREE索引一般由三个部分内容组成:一个根节点(位于最上面),多个分支节点(中间),以及最下边的叶子节点(位于最底下,叶子节点中就存储直接指向数据表中的行信息)。一个简单的BTREE索引结构如下:

         BTREE索引访问特点:

         ①.BTREE是一种平衡树,从根节点开始查找到也子节点上的数据存储行的路径长度是一样的。最多需要访问H个节点。(H为树的高度)

         ②.存储在每一个叶子节点上面出了存放索引键的相关信息之外,还存储了指向与该 叶子节点相邻的后一个叶子节点的指针信息(增加了顺序访问指针),加快检索多个相邻的叶子节点 。

         ③.在数据的存储访问上,MySQL利用磁盘预读的特点,把一个节点的大小设置成一页的大小,每次磁盘读取一页的数据就能在一次 IO操作的情况下将整个节点的数据读出来。

            

      2.HASH数据结构特点

        (1).哈希结构简述 

             我们之前说的树形结构的数据查找一般是按照二分查找的方式进行数据的查找。尽管和之前的遍历的方式在效率上有了较高的提升。但是还有没有一种更为简便的方法来获取我们需要查找的数据呢?如果说我们能够通过一个已知的值,通过一个特殊的计算或者是对照方法就可以获取到我们需要的数据。这样是不是会更为简便呢?下面我们就来说一下HASH数据结构。

             要说哈希表,我们先说一个技术:散列技术,所谓的散列技术是指在记录的存储位置和它的关键字之间建立一个确定的对应关系f(x),使每一个关键字都对应一个存储位置。(这一个映射有点类似于Map集合。但是具体的映射关系是有函数f(x)确定)。采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为哈希表。

      (2).哈希表查找数据

           ①.存储数据时,将数据存入通过哈希函数计算所得哪那个地址里面。 
   ②.查找时,使用同一个哈希函数通过关键字key计算出存储地址,通过该地址即可访问到查找的记录。

           由于这一个存储值是有key计算出来的,那么在关联性较强或者是说区分度比较小的key在进行哈希查找的时候就有可能发生查找出来的数据一致或者是查找不出来。

      (3).哈希冲突

            理论状态下,俩个不同的key通过算法f(x)计算以后得到的存出结果是不一样的。但是呢在实际中。由于我们存储的数据在创建key的时候可能关联性比较强或者是说俩个key的区分度比较小。那么这一个时候就会出现计算出来的值是一样的。这就是哈希冲突。一般的哈希冲突的解决方法有:开放地址法;再哈希;链地址法;公共溢出区法。(具体详细解释省略)

      (4).哈希结构注意事项

           由于哈希表的特定的数据结构导致哈希索引的使用需要注意如下事项

            A.Hash索引基于Hash表实现,只有查询条件精确匹配Hash索引中的所有列才会用到hash索引。
            B.存储引擎会为Hash索引中的每一列都计算hash码,Hash索引中存储的即hash码,所以每次读取都会进行两次查询。
            C.Hash索引无法用于排序。
            D.Hash不适用于区分度小的列上,如性别字段。

 

      更多详细内容可以参考官方文档:https://dev.mysql.com/doc/refman/5.7/en/index-btree-hash.html

       

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔笛手7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值