背景概念
- 主键索引(primary key)
- 唯一索引(unique)
- 普通索引(index)
- 全文索引(fulltext)--解决中子文索引问题

局部性原理:
- 时间局部性:如果一个数据被访问,在不久后它很可能再次被访问
- 空间局部性:如果一个数据被访问,其周围的数据不久后很有可能再次被访问
对操作系统和MySQL来说,其加载数据时会把该数据周围一部分数据都加载进去,因为周围的数据访问的概率很高,后续访问时不必重新去硬盘读取数据,减少了IO次数。
磁盘的一个扇区大小是512 byte,对于操作系统来说,不会以扇区为单位读取,而是以块为单位读取,一般来说基本单位是4 kb。
show global status like 'innodb_page_size';
page
我们知道MySQL中不止一个page,而是有多个page,此时就要进行组织管理:



我们发现这就是一个B+树结构,上层节点存储下层节点的信息,只有最后一层叶子节点存储数据,叶子节点通过链表互相连接。
之所以叶子节点要通过链表连接起来,是因为当一个page内部的数据查询完毕,有可能接下来查询的内容就在下一张page中,此时就不再通过根节点往下查询,而是直接通过链表next指针访问下一张page。
复盘一下:
- Page分为目录页和数据页。目录页只放各个下级Page的最小键值。
- 查找的时候,自定向下找,只需要加载部分目录页到内存,即可完成算法的整个查找过程,大大减少了IO次数。
在InnoDB和MyISAM引擎中,都使用B+Tree作为索引结构,也有部分其它存储引擎会使用hash结构作为索引,比如NDB,但是B+Tree依然是主流。因为hash结构的索引,每次查询数据都要重新计算哈希函数,范围查找能力很差。
聚簇索引

create table innodb_test( id int primary key, name varchar(10) not null)engine=innodb;
建好表后在数据库中就会出现如下文件
后缀为ibd
的文件存储表的索引和数据。
非聚簇索引

create table myisam_test( id int primary key, name varchar(10) not null)engine=myisam;
建好表后在数据库中就会出现如下文件
- sdi:存储表的结构
MYD
:存储数据MYI
:存储索引
索引操作
创建主键索引
- 第一种方式:在创建表的时候,直接在字段名后指定 primary key
create table user1(id int primary key, name varchar(10));
- 第二种方式:在创建表的最后,指定某列或某几列为主键索引
create table user2(id int, name varchar(10), primary key(id));
- 第三种方式:创建表以后再添加主键
create table user3(id int, name varchar(10));
alter table user3 add primary key(id);
创建唯一键索引
- 第一种方式:在表定义时,在某列后直接指定unique唯一属性
create table user4(id int primary key, name varchar(10) unique);
- 第二种方式:创建表时,在表的后面指定某列或某几列为unique
create table user5(id int primary key, name varchar(10), unique(name));
- 第三种方式:创建表以后再添加唯一键
create table user6(id int primary key, name varchar(10));
alter table user6 add unique(name);
创建辅助索引
- 第一种方式:在表的定义最后,指定某列为索引
create table user8(id int primary key,
name varchar(10),
email varchar(30),
index(name));
- 第二种方式:创建完表以后指定某列为辅助索引
create table user9(id int primary key,
name varchar(10),
email varchar(30));
alter table user9 add index(name);
create table user10(id int primary key,
name varchar(10), email varchar(30));
create index idx_name on user10(name);
我们知道InnoDB
采用聚簇索引方案,即其索引的叶子节点存储的是数据的值,那么如果创建多个索引,岂不是每一个索引都要保存一份数据?
其实不是,对于聚簇索引而言,其辅助索引存储的是主键的值:
当通过辅助索引查询时,会通过key
找到对应主键,然后再通过主键去主键索引查找正行数据。
查询索引
show index/keys from 表名\G
例如,我们使用以下代码来创建表user
create table user(id int primary key,
name varchar(10) unique,
email varchar(30),
index(email));
我们可以看到三行索引介绍。
删除索引
- 第一种方法:删除主键索引
alter table 表名 drop primary key;
-
第二种方法:其他索引的删除,语法中索引名就是show index from 表名中的 Key_name 字段
alter table 表名 drop index 索引名;
- 第三种方法方法
drop index 索引名 on 表名;
创建全文索引
CREATE TABLE articles (
id int auto_increment primary key,
title varchar(200),
body text,
fulltext (title,body)
)engine=MyISAM;
INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
select * from articles where body like '%database%';

select * from articles where match(title,body) against ('database');