"""
MySQL中的索引的存储类型有两种:BTREE、HASH
SHOW INDEX FROM 表名\G; 显示表里面所有的索引值
"""
"""
一 、 索引的优、缺点以及使用原则
优点:
1、查询某条数据的时候,不用在遍历整个表,提高效率。
2、所有的MySql列类型(字段类型)都可以被索引,也就是可以给任意字段设置索引
3、大大加快数据的查询速度
缺点:
1、创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加
2、索引也需要占空间,我们知道数据表中的数据也会有最大上限设置的,如果我们有大量的索引,索引文件可能会比数据文件更快达到上限值
3、当对表中的数据进行增加、删除、修改时,索引也需要动态的维护,降低了数据的维护速度。
使用原则:
通过上面说的优点和缺点,我们应该可以知道,并不是每个字段都设置索引就好,也不是索引越多越好,而是需要自己合理的使用。
1、对经常更新的表就避免对其进行过多的索引,对经常用于查询的字段应该创建索引。
2、数据量小的表最好不要使用索引,因为由于数据较少,可能查询全部数据花费的时间比遍历索引的时间还要短,索引就可能不会产生优化效果。
3、在一同值少的列上(字段上)不要建立索引,比如在学生表的"性别"字段上只有男,女两个不同值。相反的,在一个字段上不同值较多可是建立索引。
"""
"""
二、索引的分类
注意:索引是在存储引擎中实现的,也就是说不同的存储引擎,会使用不同的索引
MyISAM和InnoDB存储引擎:只支持BTREE索引, 也就是说默认使用BTREE,不能够更换
MEMORY/HEAP存储引擎:支持HASH和BTREE索引
1、索引我们分为四类来讲 单列索引(普通索引,唯一索引,主键索引),组合索引,全文索引,空间索引
1.1、单列索引:一个索引只包含单个列,但一个表中可以有多个单列索引。 这里不要搞混淆了。
1.1.1、普通索引:
MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一点。
1.1.2、唯一索引:
索引列中的值必须是唯一的,但是允许为空值
1.1.3、主键索引:
是一种特殊的唯一索引,不允许有空值
1.2、组合索引:
在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合。
这个如果还不明白,等后面举例讲解时在细说。
1.3、全文索引 MyISAM引擎
全文索引,只有在 MyISAM引擎 上才能使用,只能在 CHAR,VARCHAR,TEXT 类型字段上使用全文索引,介绍了要求,说说什么是全文索引,就是在一堆文字中,通过其中
的某个关键字等,就能找到该字段所属的记录行,比如有"你是个大煞笔,二货 ..." 通过大煞笔,可能就可以找到该条记录。这里说的是可能,因为全文索引的使用
涉及了很多细节,我们只需要知道这个大概意思,如果感兴趣进一步深入使用它,那么看下面测试该索引时,会给出一个博文,供大家参考.
1.4、空间索引 MyISAM引擎
空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON。
在创建空间索引时,使用SPATIAL关键字。
要求,引擎为MyISAM,创建空间索引的列,必须将其声明为NOT NULL。具体细节看下面
"""
"""
创建普通索引: 唯一 全文 空间
语法: create table tablename [UNIQUE|FULLTEXT|SPATIAL|...]([字段1,字段类型1,字段2,字段类型2 .....] index | key (字段名称)[ASC|DESC] )
如果你选取的字段是普通字段,那么即则是普通索引
CREATE TABLE c(
id INT(11) NOT NULL auto_increment,
name VARCHAR(10) NULL,
age TINYINT(3) NULL,
KEY id3 (id)
)
-- 注意 : 可以给索引起别名,比如说这里面的 id3 就是别名
-- 如果不起别名,那么字段名就是索引名。
CREATE TABLE `a` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(10) DEFAULT NULL,
`age` tinyint(3) DEFAULT NULL,
INDEX `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- INSERT INTO a (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ;
SELECT * from a ;
EXPLAIN SELECT * from a WHERE id=2; # 这个就是 id 索引,这里面查询根据索引值进行查询,速度会很快
EXPLAIN SELECT * from a WHERE age=6; # age 不是索引,获取数据的时候要遍历整个表里面的数据
INSERT INTO b (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ;
EXPLAIN SELECT * from b WHERE id=2;
EXPLAIN SELECT * from b WHERE age=6;
INSERT INTO c (NAME,age) VALUES("haha",6),("cc",8),("aa",10) ;
EXPLAIN SELECT * from c WHERE id=2;
EXPLAIN SELECT * from c WHERE age=6;
"""
"""
创建唯一索引:
-- 创建唯一索引 UNIQUE INDEX|KEY 索引别名 (字段名称)
CREATE TABLE t(
id INT(11) NOT NULL,
name CHAR(30),
UNIQUE INDEX unique_id(id)
);
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`name` char(30) DEFAULT NULL,
UNIQUE KEY `unique_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入数据:
-- INSERT INTO t (id,NAME) VALUES (1,"aa"),(2,"bb"),(3,"cc");
-- INSERT INTO t (id,NAME) VALUES (4,"aa")
-- INSERT INTO t (id,NAME) VALUES (4,"ee")
# 这句话会报错,因为我们已经创建了 id 唯一索引,id值不能重复,其他值可以重复
EXPLAIN SELECT * FROM t WHERE id=1;
"""
"""
创建主键索引:
-- 创建主键索引
CREATE TABLE t3(
id INT(11) NOT NULL ,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
)
CREATE TABLE t2(
id INT(11) NOT NULL,
name CHAR(30) NULL,
PRIMARY KEY(id)
);
-- 主键索引 id 作为索引,主键索引是特殊的唯一索引,索引值
CREATE TABLE `t2` (
`id` int(11) NOT NULL,
`name` char(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO t2 VALUES(1,'aaa'),(2,"bbb");
SELECT * FROM t2;
EXPLAIN SELECT * FROM t2 WHERE id = 1;
"""
"""
创建 组合索引:
-- 创建组合索引
-- 组合索引就是在多个字段上创建一个索引
-- 比如说:创建一个表t3,在表中的id、name和age字段上建立组合索引
# drop TABLE IF NOT EXISTS `haha`
格式 : drop table if exists 表名
DROP TABLE if EXISTS t3;
CREATE TABLE t3(
id INT(11) NOT NULL,
NAME CHAR(30) NOT NULL,
age INT(3) NULL,
info VARCHAR(255),
INDEX (id,name,age)
)
-- DDL语句 :
CREATE TABLE `t4` (
`id` int(11) NOT NULL,
`NAME` char(30) NOT NULL,
`age` int(3) DEFAULT NULL,
`info` varchar(255) DEFAULT NULL,
KEY `id` (`id`,`NAME`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 表 t3 没有给组合索引命名,默认为第一个值 id 就是索引的别名
DROP TABLE if EXISTS t4;
CREATE TABLE t4(
id INT(11) NOT NULL,
NAME CHAR(30) NOT NULL,
age INT(3) NULL,
info VARCHAR(255),
INDEX MultiIdx (id,name,age)
)
-- 表 t4 组合索引的别名为 MultiIdx
数据库查询的时候按照最左索引的方法来查询。
比如说: 这里面是(id,name,age)按照索引查必须字段 必须是(id),(id,name),(id,name,age),否则的话不按照索引 来查,还是会遍历表,不根据索引查询.
INSERT INTO t4 (id,NAME,age,info) VALUES(1,"a",10,"aa"),(2,"b",20,"bb");
SELECT * from t4;
EXPLAIN SELECT * FROM t4 WHERE id=1; # 按照索引进行查询
EXPLAIN SELECT * FROM t4 WHERE id=1 AND name="a"; # 按照索引进行查询
EXPLAIN SELECT * FROM t4 WHERE name="a" AND age=10; # 遍历表t4
组合索引就是多个字段的索引值。
"""
"""
添加索引:
第一种方式: 修改表结构来添加索引
alter table a add index index_name(字段名称)
egg: ALTER TABLE book ADD INDEX BkNameIdx(bookname(30));
第二种方式: 使用CREATE INDEX创建索引
格式:CREATE [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KEY] 索引名称 ON 表名(创建索引的字段名[length])[ASC|DESC]
CREATE INDEX BkBookNameIdx ON book(bookname);
egg : create index index_name on t4(字段名称)
create index cc on field_name # 创建索引
alter table table_name add index cc (field_name) # 添加索引 alter 语句
"""
"""
删除索引:
删除book表中名为BkNameIdx的索引
格式一:ALTER TABLE 表名 DROP INDEX 索引名。
ALTER TABLE book DROP INDEX BkBookNameIdx;
egg: alter table t4 drop index (索引名称)
alter table t4 drop index (索引名称)
格式二:DROP INDEX 索引名 ON 表名;
DROP INDEX BkNameIdx ON book;
egg: drop index (索引名称) on t4;
drop index (索引名称) on 表名
"""
"""
十二、全文检索——MATCH和AGAINST
1、SELECT MATCH(note_text)AGAINST('PICASO') FROM tb_name;
2、InnoDB引擎不支持全文检索,MyISAM可以;
"""
# 单列索引(普通索引,唯一索引,主键索引)、 组合索引、 全文索引、 空间索引。 后两个用到的时候在说,前两个一定要记住
"""
注意 : 一个表只有一个主键,不存在删除某一列的主键,主键是唯一的
"""