数据库文件的存储
MySQL给用户提供存储服务,存储的数据在磁盘中。
找到一个文件的全部,本质就是在磁盘中找到所有保存这个文件的扇区。
系统读取磁盘是以块为单位的,基本单位为4KB.
MySQL作为一款应用软件可被认为成一种特殊的文件系统,它有更高的IO场景。为提高效率,MySQL进行IO的基本单位是16KB,叫做MySQL的page.

注意 :
1.MySQL中的数据文件是以page为单位保存在磁盘中的。
2.MySQL的CURD操作要通过计算找到要修改的位置。
3.计算需要CPU参与,所以要将数据先加载到内存中。所以在特定的时间内,数据一定是磁盘和内存中都有。操作完内存数据后以特定的刷新策略刷新到磁盘,这时是磁盘和内存的数据交互(IO),基本单位为page。
4.MySQL服务器在内存中运行时,在服务器内部申请了叫做Buffer Poll的大内存空间来进行各种缓存。
5.提高算法效率的因素:a.组织数据的方式 b.算法本身
索引的理解
建立测试表:

插入一些数据:

发现默认是有序的。是mysqld自己做的,为了很方便的引入目录。
注意,在MySQL服务器内部的缓冲区中,MySQL要将多个同时存在的page用链表管理起来。


数据库在插入数据时要对其进行排序是因为要优化查询的效率。页内部存放数据的模块实质上也是一个链表的结构,链表的特点是增删快,查改慢,所以优化查询效率很重要。有序后在查找时从头到尾都是有效查找。
引入目录

随着数据量的增大,MySQL中必定会有多个页来存储数据,然后通过指针的方式将所有的page组织起来。
用上述图中的方法仍然需要大量的IO,将下一个page加载到内存进行线性检测,显得之前的目录杯水车薪。
解决方案:
给page也带上目录:
1.使用一个目录项来指向某一页,而这个目录项存放的是将要指向的页中存放的最小数据的键值。
2.和页内目录不同的地方在于这种目录管理的级别是页,而页内目录管理级别是行。
3.每个目录的构成都是键值+指针。

目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址。
以后我们检索数据时自顶向下来遍历 。

最终目录和数据成了一棵B+树,我们已经给表user完成了主键索引。

为什么InnoDB不用B树作为底层索引?
对我们来说的最大区别:
1.B树结点既有数据又有page指针,而B+只有叶子结点有数据,其他目录页只有键值和page指针。
2.B+叶子结点全部相连,而B没有。
所以:
1.结点不存储数据就可以存更多的目录,使得树更矮,所以IO操作次数更少。
2.叶子结点相连便于进行范围查找。
聚簇索引 VS 非聚簇索引
MyISAM存储引擎--主键索引
MyISAM同样使用B+树作为索引结果,叶子结点的data域存放的是数据记录的地址。
下图为 MyISAM 表的主索引,其中Col1 为主键。

MyISAM 最大的特点是将索引Page和数据Page分离,也就是叶子节点没有数据,只有对应数据的地址
而InnoDB 是将索引和数据放在一起的。


MyISAM这种用户数据与索引数据分离的索引方案,叫做非聚簇索引。


InnoDB 这种用户数据与索引数据在一起索引方案,叫做聚簇索引。
MySQL除了默认会建立主键索引外,用户也可能按照其他列信息建立索引,这种索引叫做辅助(普通)索引。
对于 MyISAM ,建立辅助(普通)索引和主键索引没有差别 ,无非就是主键不能重复,而非主键可重复。
下图就是基于 MyISAM 的 Col2 建立的索引,和主键索引无差别:

InnoDB 除了主键索引,用户也会建立辅助(普通)索引,我们以上表中的 Col3 建立对应的辅助索引如下
图:

InnoDB 的非主键索引中叶子节点并没有数据,而只有对应记录的key值。所以InnoDB 通过辅助(普通)索引,找到目标记录需要两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。这种过程,叫做回表查询。
索引操作
创建主键索引
法一:
sql
create table user1(id int primary key, name varchar(30));
法二:
sql
create table user2(id int, name varchar(30), primary key(id));
法三:
sql
create table user3(id int, name varchar(30));
-- 创建表以后再添加主键
alter table user3 add primary key(id);
主键索引的特点:
1.一个表中最多一个主键索引。
2.效率高。
3.创建主键索引的列,它的值不能是null且不能重复。
4.主键索引的列基本上是int.
唯一索引的创建
法一:
sql
create table user4(id int primary key, name varchar(30) unique);
法二:
sql
create table user5(id int primary key, name varchar(30), unique(name));
法三:
sql
create table user6(id int primary key, name varchar(30));
alter table user6 add unique(name);
唯一索引的特点:
1.一个表中,可以有多个唯一索引
2.查询效率高
3.如果在某一列建立唯一索引,必须保证这列不能有重复数据
4.如果一个唯一索引上指定not null,等价于主键索引。
普通索引的创建
法一:
sql
create table user8(id int primary key,
name varchar(20),
email varchar(30),
index(name) --在表的定义最后,指定某列为索引
);
法二:
sql
create table user9(id int primary key, name varchar(20), email varchar(30));
alter table user9 add index(name); --创建完表以后指定某列为普通索引
法三:
sql
create table user10(id int primary key, name varchar(20), email varchar(30));
-- 创建一个索引名为 idx_name 的索引
create index idx_name on user10(name);
普通索引的特点:
1.一个表中可以有多个普通索引,普通索引在实际开发中用的比较多。
2.如果某列需要创建索引,但是该列有重复的值,那么我们就应该使用普通索引。
查询索引
法一:
sql
show keys from 表名

法二:
sql
show index from 表名;
法三:
sql
desc 表名;
删除索引
1.删除主键索引
sql
alter table 表名 drop primary key;
2.删除其他索引
sql
alter table 表名 drop index 索引名;
索引名就是show keys from 表名中的Key_name 字段.
sql
drop index 索引名 on 表名;
索引创建原则
1.频繁作为查询条件的字段应该创建索引。
2.唯一性太差的字段不适合单独创建索引(即使频繁作为查询条件)
3.更新非常频繁的字段不适合创建索引。
4.不会出现在where子句中的字段不该创建索引。
全文索引的创建
当对有大量文字的字段进行检索时,会使用到全文索引。MySQL提供全文索引机制,但要求表的存储引擎必须是MyISAM,且默认的全文索引支持英文,不支持中文。

查询有没有database数据
如果使用如下查询方式,虽然查询出数据,但是没有使用到全文索引:

key为null表示没有用到索引。
如何使用全文索引?
