索引的分类与使用

索引的分类与使用

索引的分类

MySQL的索引包括普通索引、唯一索引、全文索引、单列索引、多列索引和空间索引等。

  • 功能逻辑上说,索引主要有 4 种,分别是普通索引、唯一索引、主键索引、全文索引。
  • 按照 物理实现方式,索引可以分为 2 种:聚簇索引和非聚簇索引。
  • 按照 作用字段个数进行划分,分成单列索引和联合索引。
  1. 普通索引

在创建普通索引时,不附加任何限制条件,只是用于提高查询效率。这类索引可以创建在任何数据类型中,其值是否唯一和非空,要由字段本身的完整性约束条件决定。建立索引以后,可以通过索引进行查询。例如,在表student的字段name上建立一个普通索引,查询记录时就可以根据该索引进行查询。

  1. 唯一索引

使用UNIQUE参数可以设置索引为唯一性索引,在创建唯一性索引时,限制该索引的值必须是唯一的,但允许有空值。在一张数据表里可以有多个唯一索引。

例如,在表student的字段email中创建唯一性索引,那么字段email的值就必须是唯一的。通过唯一性索引,可以更快速地确定某条记录。

  1. 主键索引

主键索引就是一种特殊的唯一性索引,在唯一索引的基础上增加了不为空的约束,也就是NOT NULL+UNIQUE,一张表里最多只有一个主键索引。
Why?这是由主键索引的物理实现方式决定的,因为数据存储在文件中只能按照一种顺序进行存储。

  1. 单列索引

在表中的单个字段上创建索引。单列索引只根据该字段进行索引。单列索引可以是普通索引,也可以是唯一性索引,还可以是全文索引。只要保证该索引只对应一个字段即可。一个表可以有多个单列索引。

  1. 多列(组合、联合)索引

多列索引是在表的多个字段组合上创建一个索引。该索引指向创建时对应的多个字段,可以通过这几个字段进行查询,但是只有查询条件中使用了这些字段中的第一个字段时才会被使用。例如,在表中的字段id、name和gender上建立一个多列索引idx_id_name_gender,只有在查询条件中使用了字段id时该索引才会被使用。使用组合索引时遵循最左前缀集合

  1. 全文检索

全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。全文索引非常适合大型数据集,对于小的数据集,它的用处比较小。

使用参数FULLTEXT可以设置索引为全文索引。在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。全文索引只能创建在CHARVARCHARTEXT类型及其系列类型的字段上,**查询数据量较大的字符串类型的字段时,使用全文索引可以提高查询速度。**例如,表student的字段informationTEXT类型,该字段包含了很多文字信息。在字段information上建立全文索引后,可以提高查询字段information的速度。

全文检索典型的有两种类型:自然语言的全文检索和布尔全文检索。

  • 自然语言搜索引擎将计算每一个文档对象和查询的相关度。这里,相关度是基于匹配的关键词的个数,以及关键词在文档中出现的次数。**在整个索引中出现次数越少的词语,匹配时的相关度就越高。**相反,非常常见的单词将不会被搜索,如果一个词语的在超过50%的记录中都出现了,那么自然语言的搜索将不会搜索这类词语。

MySQ 前只有Myisam支持,5.6.4版本以后 innodb才支持,但是官方版本不支持中文分词,需要第三方分词插件。在5.7.6版本,MySQL内置了ngram全文解析器,用来支持亚洲语种的分词。测试或使用全文索引时,要先看一下自己的MySQL版本、存储引擎和数据类型是否支持全文索引。

随着大数据时代的到来,关系型数据库应对全文索引的需求已力不从心,逐渐被solrElasticSearch等专门的搜索引擎所替代。

  1. 补充:空间索引

使用参数SPATIAL可以设置索引为空间索引。空间索引只能建立在空间数据类型上,这样可以提高系统获取空间数据的效率。MySQL中的空间数据类型包括GEOMETRYPOINTLINESTRINGPOLYGON等。目前只有MyISAM存储引擎支持空间检索,而且索引的字段不能为空值。对于初学者来说,这类索引很少会用到。

小结:不同的存储引擎支持的索引类型也不一样

**InnoDB :**支持 B-tree、Full-text 等索引,不支持 Hash
索引;

MyISAM : 支持 B-tree、Full-text 等索引,不支持 Hash 索引;

**Memory :**支持 B-tree、Hash 等
索引,不支持 Full-text 索引;

**NDB :**支持 Hash 索引,不支持 B-tree、Full-text 等索引;

**Archive :**不支持 B-tree、Hash、Full-text 等索引;

创建索引

MySQL支持多种方法在单个或多个列上创建索引:在创建表的定义语句CREATE TABLE中指定索引列,使用ALTER TABLE语句在存在的表上创建索引,或者使用CREATE INDEX语句在已存在的表上添加索引。

创建表的时候创建索引 (隐式的方式创建索引)

举例:

CREATE TABLE dept(
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(20)
);
CREATE TABLE emp(
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20) UNIQUE,
dept_id INT,
CONSTRAINT emp_dept_id_fk FOREIGN KEY(dept_id) REFERENCES dept(dept_id)
);

但是如果要显式的方式创建索引的话,基本语法如下:

CREATE TABLE table_name [col_name data_type][UNIQUE | FULLTEXT | SPATIAL] [INDEX | KEY] [index_name] (col_name [length]) [ASC | DESC]
  • UNIQUEFULLTEXTSPATIAL 为可选参数,分别表示唯一索引、全文索引和空间索引;
  • INDEXKEY 为同义词,两者的作用相同,用来指定创建索引;
  • index_name 指定索引的名称,为可选参数,如果不指定,那么MySQL默认col_name为索引名;
  • col_name 为需要创建索引的字段列,该列必须从数据表中定义的多个列中选择;
  • length 为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度;
  • ASCDESC 指定升序或者降序的索引值存储。

创建普通索引

在book表中的year_publication字段上建立普通索引,SQL语句如下:

# 显示的方式创建普通索引 
CREATE TABLE book(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
# 声明索引
INDEX idx_bname(book_name)
);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3bmL4DWR-1647694353453)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220319185201341.png)]

用命令行查看索引

SHOW CREATE TABLE book\G

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BcFHdAEx-1647694353453)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220319190131103.png)]

第二种方式

SHOW INDEX  FROM book;
SHOW INDEX  FROM book/G

创建唯一索引

显示创建

#①创建唯一索引
CREATE TABLE book1(
book_id INT ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
# 声明索引
UNIQUE INDEX uk_idx_cmt(COMMENT)
);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FByXOdLz-1647694353454)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220319192126456.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-phmSD6AS-1647694353454)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220319192211490.png)]

主键索引

创建和删除主键索引

#③主键索引
DROP TABLE book2;
CREATE TABLE book2(
book_id INT  PRIMARY KEY ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR
);

SHOW INDEX FROM book2;
#通过删除主键约束的方式删除主键索引
ALTER TABLE book2
DROP PRIMARY KEY;

创建单列索引

DROP TABLE book3;
CREATE TABLE book3(
book_id INT  ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
UNIQUE KEY idx_bname(book_name)
);
SHOW INDEX FROM book3;

创建联合索引

# ⑤创建联合索引
CREATE TABLE book4(
book_id INT  ,
book_name VARCHAR(100),
AUTHORS VARCHAR(100),
info VARCHAR(100) ,
COMMENT VARCHAR(100),
year_publication YEAR,
 KEY mul_bid_bname_info(book_id,book_name,info)
);
SHOW INDEX FROM book4;

这下面的顺序也是B+树排序的时候按照列排序的顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cF0jDqqw-1647694353455)(C:/Users/losser/AppData/Roaming/Typora/typora-user-images/image-20220319203552548.png)]

# 分析,这个是按照最左前缀原则
EXPLAIN SELECT *
FROM book4 WHERE book_id=1001 AND book_name = 'mysql';

# 先按照book_id进行排序,相同再按照book_name排序,再相同再按照info排序
# 这是不用id直接找name所有索引就用不上
EXPLAIN SELECT *
FROM book4 WHERE book_name = 'mysql'

创建全文索引

FULLTEXT全文索引可以用于全文搜索,并且只为CHARVARCHARTEXT列创建索引。索引总是对整个列进行,不支持局部(前缀)索引。

举例1:创建表test4,在表中的info字段上建立全文索引,SQL语句如下:

CREATE TABLE test4(
id INT NOT NULL,
name CHAR(30) NOT NULL,
age INT NOT NULL,
info VARCHAR(255),
FULLTEXT INDEX futxt_idx_info(info)
) ENGINE=MyISAM;

在MySQL5.7及之后版本中可以不指定最后的ENGINE了,因为在此版本中InnoDB支持全文索引。

语句执行完毕之后,使用SHOW CREATE TABLE查看表结构:

SHOW INDEX FROM test4;

举例2:

CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR (200),
body TEXT,
FULLTEXT index (title, body)
) ENGINE = INNODB ;

创建了一个给title和body字段添加全文索引的表。

举例3:

CREATE TABLE `papers` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) DEFAULT NULL,
`content` text,
PRIMARY KEY (`id`),
FULLTEXT KEY `title` (`title`,`content`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

不同于like方式的的查询:

SELECT * FROM papers WHERE content LIKE%查询字符串%;

全文索引用match+against方式查询:

SELECT * FROM papers WHERE MATCH(title,content) AGAINST (‘查询字符串’);

注意点

  1. 使用全文索引前,搞清楚版本支持情况;
  2. 全文索引比 like + % 快 N 倍,但是可能存在精度问题
  3. 如果需要全文索引的是大量数据,建议先添加数据,再创建索引。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值