内容来自《MySQL从入门到精通》清华大学出版社一书的内容,随看书随打打笔记,会不断补充
MySQL支持多种方法在单个或多个列上创建索引:在创建表的定义语句CREATE TABLE中指定索引列,使用ALTER TABLE 语句在存在的表上创建索引,或者使用CREATE INDEX语句在已存在的表上添加索引。
使用CREATE TABLE创建表,除了可以定义列的数据类型,还可以定义主键约束,外键约束或者唯一性约束,而不论创建哪种约束,在定义约束的同时相当于在指定列上创建了一个索引。创建表时创建索引的基本语法格式:
CREATE TABLE table_name [col_name data_type]
[UNIQUE| FULLTEXT |SPATIAL] [INDEX|KEY] [INDEX_name] (col_name [length]) [ASC|DESC]
UNIQUE,FULLTEXT和SPATIAL为可选参数,分别表示唯一索引,全文索引和空间索引;INDEX与KEY为同义词,两者所用相同,用来指定创建索引;col_name为需要创建索引的字段列,该列必须从数据表中定义的多个列中选择;index_name指定索引名称,为可选参数,如果不指定,MySQL默认col_name为索引值;length为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度:ASC或DESC指定升序或者降序的索引值存储。
最基本的索引类型,没有唯一性之类的限制,其作用只是加快对数据的访问速度。
例:在book表中的year_publication字段上建立普通索引
CREATE TABLE book
(
bookid INT NOT NULL,
bookname VARCHAR(255) NOT NULL,
authors VARCHAR(255) NOT NULL,
info VARCHAR(255) NULL,
comment VARCHAR(255) NULL,
year_publication YEAR NOT NULL,
INDEX(year_publication)
);
执行完毕后,使用SHOW CREATE TABLE查看表结构
book表的year_publication字段上成功建立索引,其索引名称year_publication为MySQL自动添加。使用EXPLAIN语句查看索引是否正在使用:
各个解释行:
(1)select_type行指定所使用的SELECT查询类型,这里值为SIMPLE,表示简单的SELECT,不使用UNION或子查询。其它的可能取值有:PRIMARY,UNION,SUBQUER等。
(2)table行指定数据库读取的数据表的名字,它们按被读取的先后顺序排列
(3)PARTITIONS
表提供有关表分区的信息。
(4) type行指定了本数据表与其它数据表之间的关联关系,可能的取值有:system,const,eq_ref,ref,range,index和ALL。
(5)possible_keys行给出了MySQL在搜索数据记录时可选用的各个索引。
(6)key行是MySQL实际选用的索引
(7)key_len行给出索引按字节计算的长度,key_len数值越小,表示越快
(8)ref行给出了关联关系中另一个数据表里的数据列的名字
(9)rows行是MySQL在执行这个查询时预计会从这个数据表里读出的数据行的个数
(10) filtered它指返回结果的行占需要读到的行(rows列的值)的百分比。
(11) extra行提供了与关联操作有关的信息
可以看到,possible_keys和key的值都为year_publication,查询时使用了索引。
创建唯一索引的主要原因是减少查询索引列操作的执行时间,尤其是对比较庞大的数据表,它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
例:创建一个表t1,在表中的id字段上使用UNIQUE关键字创建唯一索引。
CREATE TABLE t1
(
id INT NOT NULL,
name CHAR(30) NOT NULL,
UNIQUE INDEX UniqIdx(id)
);
查看表结构:
id字段上已经成功建立了一个名为UniqIdx的唯一索引。
单列索引是在数据表的某个字段上创建的索引,一个表中可以创建多个单列索引。前面两个例子中创建的都是单列索引。
例:创建一个表t2,在表中的name字段上创建单列索引
CREATE TABLE t2
(
id INT NOT NULL,
name CHAR(50) NULL,
INDEX SingleIdx(name(20))
);
在name字段上成功建立了一个名为SingIdx的单列索引,索引长度为20。
组合索引是在多个字段上创建一个索引。
mysql创建组合索引报错-》有2种解决方式:
1.不要指定索引INDEX MultiIdx(id,name, age(100))中字段age(100)的长度
2.先创建表,再执行创建索引的命令CREATE INDEX MultiIdx ON t3(id,name, age(100))
例:创建表t3,在表中的id、name和age字段上建立组合索引
CREATE TABLE t3
(
id INT NOT NULL,
name CHAR(30) NOT NULL,
age INT NOT NULL,
info VARCHAR(255),
INDEX MultiIdx(id,name,age)
);
组合索引可起几个索引的作用,但是使用时并不是随便查询哪个字段都可以使用索引,而是遵从“最左前缀”:利用索引中最左边的列集来匹配行这样的列集称为最左前缀。例如这里由id、name和age 3个字段构成的索引,索引行中按id/name/age的顺序存放,索引可以搜索下面字段组合:(id, name, age)、(id, name)或者id。如果列不构成索引最左面的前缀,MySQL不能使用局部索引,如(age)或者(name,age)组合则不能使用索引查询。
在t3表中,查询id和name字段,使用EXPLAIN语句查看索引的使用情况:
如果查询name和age字段,则没有使用索引MultiIdx
FULLTEXT可以用于全文搜索。只有MyISAM存储引擎支持FULLTEXT索引,并且只为CHAR,VARCHAR和TEXT列创建索引。索引总是对整个列进行,不支持局部(前缀)索引。
例:创建表t4,在表中的info字段上建立全文索引
CREATE TABLE t4
(
id INT NOT NULL,
name CHAR(30) NOT NULL,
age INT NOT NULL,
info VARCHAR(255),
FULLTEXT INDEX FullTxtIdx(info)
) ENGINE=MyISAM;
因为MySQL5.6中默认存储引擎为InnoDB,在这里创建表时需要修改表的存储引擎为MyISAM,不然创建索引会出错。
由结果可以看到,info字段上已经成功建立了一个名为FullTxtIdx的FULLTEXT索引。全文索引非常适合于大型数据集,对于小的数据集,它的用处可能比较小。
空间索引必须在MyISAM类型的表中创建,且空间类型的字段必须为非空。
例:创建表t5,在空间类型为GEOMETRY的字段上创建空间索引
CREATE TABLE t5
( g GEOMETRY NOT NULL, SPATIAL INDEX spatIdx(g) )ENGINE=MyISAM;
t5表的g字段上创建了名称为spatIdx的空间索引。注意创建时指定空间类型字段值的非空约束,并且表的存储引擎为MyISAM。
在已经存在的表中创建索引,可以使用ALTER TABLE语句或者CREATE INDEX语句。
ALTER TABLE table_name ADD [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY]
[index_name] (col_name[length],...) [ASC|DESC]
与创建表时创建索引的语法不同的是,在这里使用了ALTER TABLE和ADD关键字,ADD表示向表中添加索引。
例:在book表中的bookname字段上建立名为BkNameIdx的普通索引
ALTER TABLE book ADD INDEX BkNameIdx ( bookname(30) );
使用SHOW INDEX语句查看表中的索引:
各个主要参数的主要意义:
(1)Table表示创建索引的表
(2)Non_unique表示索引非唯一,1代表是非唯一索引,0代表唯一索引
(3)Key_name表示索引名称
(4)Seq_in_index表示该字段在索引中的位置,单列索引该值为1,组合索引为每个字段在索引定义中的顺序。
(5)Column_name表示定义索引的列字段
(6)Sub_part表示索引的长度
(7)Null表示该字段是否能为空值
(8)Index_type表示索引类型
在添加完索引后,现在表中有两个索引。
在第一表中,可以看到book中存在一个索BkNameIdx的普通索引引year_publication之前定义的,该索引为非唯一索引。另一个是通过ALTER TABLE添加语句添加的BkNameIdx的普通索引,为非唯一索引,长度为30。
那么添加唯一索引。
ALTER TABLE book ADD UNIQUE INDEX UniqidIdx ( bookId );
例:在book表的bookId字段上建立名称为UniqidIdx 的唯一索引
可以看到Non_unique属性值为0,表示名称为UniqdIdx的索引为唯一索引,创建唯一索引成功。
创建组合索引。
ALTER TABLE book ADD INDEX BkAuAndInfoIdx ( authors(20),info(50) );
例:在book表的authors和info字段上建立组合索引
索引由两个字段组成,authors字段长度为20,在组合索引中的序号为1,该字段不允许有空值NULL;info字段长度为50,在组合索引总的序号为2,该字段可以为空值NULL。
创建全文索引。
例:创建表t6,在t6表上使用ALTER TABLE创建全文索引
首先创建表t6
CREATE TBALE t6
(
id INT NOT NULL,
info CHAR(255)
)ENGINE=MyISAM;
创建全文索引:
ALTER TABLE t6 ADD FULLTEXT INDEX infoFTIdx ( info );
创建了infoFTIdx的索引,该索引在info字段上创建,类型为FULLTEXT,允许空值。
创建空间索引。
例;创建表t7,在t7的空间数据类型字段g上创建名称为spatIdx的空间索引
CREATE TABLE t7 ( g GEOMETRY NOT NULL )ENGINE=MyISAM;
建立空间索引:
ALTER TABLE t7 ADD SPATIAL INDEX spatIdx(g);
CREATE INDEX语句可以在已经存在的表上添加索引,MySQL中CREATE INDEX被映射到一个ALTER TABLE语句上。
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
ON table_name (col_name[length],...) [ASC|DESC]
与第一种方法语法一样,只是关键字不同,可以将表删除DROP TABLE table_name;然后重新生成表进行测试,结果相同。