MYSQL学习与实验(五)——索引实验

发布于 2020-12-05  422 次阅读


5.索引实验

5.1索引的定义

​ 索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。

​ 通过索引,查询数据时不用读完记录的所有信息,而只是查询索引列。否则,数据库系统将读取每条记录的所有信息进行匹配。

​ 可以把索引比作新华字典的音序表。例如,要查“库”字,如果不使用音序,就需要从字典的 400 页中逐页来找。但是,如果提取拼音出来,构成音序表,就只需要从 10 多页的音序表中直接查找。这样就可以大大节省时间。 因此,使用索引可以很大程度上提高数据库的查询速度,还有效的提高了数据库系统的性能。

5.2使用索引的优点

①通过创建唯一索引可以保证数据库表中每一行数据的唯一性。

②可以给所有的 MySQL 列类型设置索引。

③可以大大加快数据的查询速度,这是使用索引最主要的原因。

④在实现数据的参考完整性方面可以加速表与表之间的连接。

⑤在使用分组和排序子句进行数据查询时也可以显著减少查询中分组和排序的时间

5.3使用索引的缺点

①创建和维护索引组要耗费时间,并且随着数据量的增加所耗费的时间也会增加。

②索引需要占磁盘空间,除了数据表占数据空间以外,每一个索引还要占一定的物理空间。如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。

③当对表中的数据进行增加、删除和修改的时候,索引也要动态维护,这样就降低了数据的维护速度。

5.4 MySQL 中,通常有以下两种方式访问数据库表的行数据

5.4.1 顺序访问

​ 顺序访问是在表中实行全表扫描,从头到尾逐行遍历,直到在无序的行数据中找到符合条件的目标数据。顺序访问实现比较简单,但是当表中有大量数据的时候,效率非常低下。例如,在几千万条数据中查找少量的数据时,使用顺序访问方式将会遍历所有的数据,花费大量的时间,显然会影响数据库的处理性能。

5.4.2索引访问

​ 索引访问是通过遍历索引来直接访问表中记录行的方式。使用这种方式的前提是对表建立一个索引,在列上创建了索引之后,查找数据时可以直接根据该列上的索引找到对应记录行的位置,从而快捷地查找到数据。索引存储了指定列数据值的指针,根据指定的排序顺序对这些指针排序。

​ 例如,在学生基本信息表 tb_students 中,如果基于 student_id 建立了索引,系统就建立了一张索引列到实际记录的映射表。当用户需要查找 student_id 为 12022 的数据的时候,系统先在 student_id 索引上找到该记录,然后通过映射表直接找到数据行,并且返回该行数据。因为扫描索引的速度一般远远大于扫描实际数据行的速度,所以采用索引的方式可以大大提高数据库的工作效率。

​ 简而言之,不使用索引,MySQL 就必须从第一条记录开始读完整个表,直到找出相关的行。表越大,查询数据所花费的时间就越多。如果表中查询的列有一个索引,MySQL 就能快速到达一个位置去搜索数据文件,而不必查看所有数据,这样将会节省很大一部分时间。

5.5索引类型

5.5.1B-TREE索引

①普通索引(INDEX):最基本索引,没有唯一性限制
②唯一性索引(UNIQUE):索引列的值不能重复
③主键(PRIMARY KEY):创建表的时候指定,每个表只能有一个主键,主键的值不可重复,也不可为空(NULL)

5.5.2HASH索引(当表类型为MEMORY或HEAP时可用)

创建 HASH索引

创建一个包含 (employeeID, name, education) 等字段的临时员工表(tmpEmployee),并在该表的员工编号字段上创建一个HASH索引

首先创建表:

create table if not exists tmpEmployee(employeeID varchar(6) primary key
not null,name varchar(10) not null,education varhcar(10));

然后建立一个hash索引:create index 索引名 using hash on 表名

create index in_hash using hash on tmpEmployee(employeeId);
在这里插入图片描述

5.5.3R-TREE索引

​ MySQL支持对空间数据库进行R-TREE索引

5.6MySQL 提供了三种创建索引的方法:

5.6.1 使用 CREATE INDEX 语句

​ 可以使用专门用于创建索引的 CREATE INDEX 语句在一个已有的表上创建索引,但该语句不能创建主键

语法格式:

CREATE <索引名> ON <表名> (<列名> [<长度>] [ ASC | DESC])

语法说明如下:

①<索引名>`:指定索引名。一个表可以创建多个索引,但每个索引在该表中的名称是唯一的。

②<表名>`:指定要创建索引的表名。

③<列名>`:指定要创建索引的列名。通常可以考虑将查询语句中在 JOIN 子句和 WHERE 子句里经常出现的列作为索引列。

④<长度>`:可选项。指定使用列前的 length 个字符来创建索引。使用列的一部分创建索引有利于减小索引文件的大小,节省索引列所占的空间。在某些情况下,只能对列的前缀进行索引。索引列的长度有一个最大上限 255 个字节(MyISAM 和 InnoDB 表的最大上限为 1000 个字节),如果索引列的长度超过了这个上限,就只能用列的前缀进行索引。另外,BLOB 或 TEXT 类型的列也必须使用前缀索引。

⑤ASC|DESC:可选项。ASC指定索引按照升序来排列,DESC指定索引按照降序来排列,默认为ASC`。

例如,在employee表的name列建立一个索引in_employee

CREATE INDEX in_employee ON employee(name=);
CREATE INDEX in_employee ON student( name asc);  #升序索引

注:可以在创建表的同时创建索引

可以用

 SHOW INDEX FROM  表名   

显示已经创建的索引信息

show index from employee;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.6.2使用 CREATE TABLE 语句

索引也可以在创建表(CREATE TABLE)的同时创建。在 CREATE TABLE 语句中添加以下语句。语法格式:

CONSTRAINT PRIMARY KEY [索引类型] (<列名>,…)

在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的主键。

语法格式:

KEY | INDEX [<索引名>] [<索引类型>] (<列名>,…)

在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的索引。

语法格式:

UNIQUE [ INDEX | KEY] [<索引名>] [<索引类型>] (<列名>,…)

在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的唯一性索引。

语法格式:

FOREIGN KEY <索引名> <列名>

在 CREATE TABLE 语句中添加此语句,表示在创建新表的同时创建该表的外键。

在使用 CREATE TABLE 语句定义列选项的时候,可以通过直接在某个列定义后面添加 PRIMARY KEY 的方式创建主键。而当主键是由多个列组成的多列索引时,则不能使用这种方法,只能用在语句的最后加上一个 PRIMARY KRY(<列名>,…) 子句的方式来实现。

5.6.2.1唯一索引(unique):
create unique index in_name on employee (name);
在这里插入图片描述
5.6.2.2创建复合主键
create index in_employeeId_name on employee(employeID,name);
在这里插入图片描述
5.6.2.3创建表的时候创建索引

创建与department表相同结构的表department1,并将departName设为主键,departmentID上建立一个索引 。

首先建立一个表department1表:

CREATE TABLE `department1` (

  `departmentID` char(3 )  not null,

  `departName` char(20)  NOT NULL,

  `comment` varchar(100)  DEFAULT NULL,

  PRIMARY KEY (`departName`)

 ) ENGINE=InnoDB DEFAULT CHARSET=gbk ;

然后给department1表添加一个索引:

create index in_departmentId on department1(departmentID);
在这里插入图片描述

5.6.3 使用 ALTER TABLE 语句

CREATE INDEX 语句可以在一个已有的表上创建索引,ALTER TABLE 语句也可以在一个已有的表上创建索引。在使用 ALTER TABLE 语句修改表的同时,可以向已有的表添加索引。具体的做法是在 ALTER TABLE 语句中添加以下语法成分的某一项或几项。

语法格式:

ADD INDEX [<索引名>] [<索引类型>] (<列名>,…)

在 ALTER TABLE 语句中添加此语法成分,表示在修改表的同时为该表添加索引。

语法格式:

ADD PRIMARY KEY [<索引类型>] (<列名>,…)

在 ALTER TABLE 语句中添加此语法成分,表示在修改表的同时为该表添加主键。

语法格式:

ADD UNIQUE [ INDEX | KEY] [<索引名>] [<索引类型>] (<列名>,…)

在 ALTER TABLE 语句中添加此语法成分,表示在修改表的同时为该表添加唯一性索引。

语法格式:

ADD FOREIGN KEY [<索引名>] (<列名>,…)

在 ALTER TABLE 语句中添加此语法成分,表示在修改表的同时为该表添加外键。

5.7查看索引

SHOW INDEX FROM <表名> [ FROM <数据库名>]

语法说明如下:

①<表名>:指定需要查看索引的数据表名。

②<数据库名>:指定需要查看索引的数据表所在的数据库,可省略。比如,SHOW INDEX FROM student FROM test; 语句表示查看 test 数据库中 student 数据表的索引。

5.8删除索引

当不再需要索引时,可以使用 DROP INDEX 语句或 ALTER TABLE 语句来对索引进行删除。

5.8.1 使用 DROP INDEX 语句

语法格式:

DROP INDEX <索引名> ON <表名>

语法说明如下:

①<索引名>`:要删除的索引名。

②<表名>`:指定该索引所在的表名。

5.8.2使用 ALTER TABLE 语句

​ 根据 ALTER TABLE 语句的语法可知,该语句也可以用于删除索引。具体使用方法是将 ALTER TABLE 语句的语法中部分指定为以下子句中的某一项。

①DROP PRIMARY KEY:表示删除表中的主键。一个表只有一个主键,主键也是一个索引。

②DROP INDEX index_name:表示删除名称为 index_name 的索引。

③DROP FOREIGN KEY fk_symbol:表示删除外键。

注意:如果删除的列是索引的组成部分,那么在删除该列时,也会将该列从索引中删除;如果组成索引的所有列都被删除,那么整个索引将被删除。

使用DROP INDEX语句删除索引:

drop index in_employee on employee;
在这里插入图片描述

show create table employee;

注:也可以用 ALTER TABLE 来删除索引:

alter table employee drop index in_phone ;
在这里插入图片描述

5.9研究与思考

5.9.1使用CREATE INDEX语句能创建主键吗?添加主键与添加普通索引有什么区别?

​ 不能通过使用create index语句来创建主键。添加主键会自动创建主键索引,普通索引需要自己手动创建。

5.9.2如果删除基本表的一个列或者多个列,该列上的索引会受怎样的影响?

​ 索引是由数据库进行维护的,当我们对存在的索引进行增删查改的操作时,如果涉及到索引列,数据库都会对索引表进行更新。因此可以知道,当表中某个列被删除后,在该列上的索引也会被删除掉。

5.10详细的实验资料以及指导PPT请访问笔者GitHub地址:https://github.com/LJF2402901363/database_experiment.git


繁华落尽,雪花漫天飞舞。