索引
索引分类:
- 主键索引
- 唯一索引
- 普通索引
- 组合索引
- 全文索引
主键索引
非空唯一索引,一个表只有一个主键索引;在 innodb
中,主键索引的 B+ 树包含表数据信息;
sql
PRIMARY KEY(key1, key2);
唯一索引
不可以出现相同的值,可以有 NULL
值;
sql
UNIQUE(key);
普通索引
允许出现相同的索引内容
sql
INDEX(key)
-- OR
KEY(key[,...])
组合索引
对表上的多个列进行索引
sql
INDEX idx(key1, key2[,...]);
UNIQUE(key1, key2[,...]);
PRIMARY KEY(key1, key2[,...]);
全文索引
将存储在数据库当中的整本书和整篇文章中的任意内容信息查找出来的技术;关键词 FULLTEXT
;
在短字符串中用 LIKE %
;在全文索引中用 match
和 against
;
主键选择
innodb
中表是索引组织表,每张表有且只有一个主键;
- 如果显示设置
PRIMARY KEY
,则该设置的 key 为代表的主键; - 如果没有显示设置,则从非空唯一索引中选择;
- 只有一个非空唯一索引,则选择该索引为主键;
- 有多个非空唯一索引,则选择声明的第一个为主键;
- 没有非空唯一索引,则自动生成一个 6 字节的
_rowid
作为主键;
约束
为了实现数据完整性,对于 innodb
,提供了以下几种约束:
- primary key
- unique key
- foreign key
- default
- not null
外键约束
外键约束用来关联两个表,来保证参照完整性;MyISAM
存储引擎本身不支持外键,只起注释作用;而 innodb
完整支持外键,并且具备事务性;
sql
create table parent (
id int not null ,
primary key (id)
) engine = innodb;
create table child (
id int,
parent_id int,
foreign key (parent_id) references parent(id) on delete cascade on update cascade
) engine = innodb;
insert into parent values (1);
insert into parent values (2);
insert into child values (10, 1);
insert into child values (20, 2);
delete from parent where id = 1;
- 被引用的表为父表,引用的表为子表;
- 外键定义时,可以设置行为 ON DELETE 和 ON UPDATE,行为发生时的操作可选择:
- CASCADE:子表做同样行为
- SET NULL:更新子表相应的字段为 NULL
- NO ACTION:父类做相应行为报错
- RESTRICT:同 NO ACTION
约束和索引的区别
创建主键索引或者唯一索引的时候同时创建了相应的约束;但是约束是逻辑上的概念;索引时一个数据结构即包含逻辑的概念也包含物理存储方式;
索引实现
索引存储
innodb
由段,区,页组成;段分为数据段,索引段,回滚段等;区大小为 1 MB(一个区有 64 个连续页构成);页的默认值为 16 K;页为逻辑页,磁盘物理页大小一般为 4 K 或 8 K;为了保证区中的页的连续,存储引擎一般一次从磁盘中申请 4-5 个区;
页
页是 innodb
磁盘管理的最小单位;默认 16 K,可通过 innodb_page_size
参数来修改;
B+树的一个节点的大小就是该页的值;
B+树
- 全称:多路平衡搜索树,减少磁盘访问次数;用来组织磁盘数据,以页为单位,物理磁盘页一般为 4 K,
innodb
默认页大小为 16 K;对页的访问是一次磁盘 IO,缓存中会缓存常访问的页; - 特征:非叶子节点只存储索引信息,叶子节点存储具体数据信息;叶子节点之间互相连接,方便范围查询;
- 每个索引对应一个 B+ 树;
B+树层高问题
B+ 树的一个节点对应一个数据页;B+ 树层高越高要读取到内存的数据页越多,IO 次数越多;
innodb
一个节点 16KB;
假设:key 为 10byte 且指针大小 6 byte,假设一行记录的大小为 1KB;那么一个非叶子节点可存下
16KB / 16byte = 1024
个(key + point);每个叶子节点可存储 1024 行数据;结论:2层 B+ 树叶子节点 1024 个,可容纳最大记录数为:1024*16 = 16384;3层 B+ 树叶子节点 1024*1024 ,可容纳最大记录数为:1024*1024*16 = 16777216;4层 B+ 树叶子节点 1024*1024*1024,可容纳最大记录数为:1024*1024*1024*16 = 17179869185;
关于自增 ID
- 超过类型最大值会报错;
- 类型
bigint
范围:( − 2 63 -2^{63} −263, 2 63 − 1 2^{63} - 1 263−1) - 假设采用
bigint
,1 秒插入 1 亿条数据,大概需要 5849 年才会用完索引;
聚集索引
按照主键构造的 B+ 树;叶子节点中存放数据页;数据也是索引的一部分;
sql
select * from user where id >= 18 and id < 40;
辅助索引
叶子节点不包含行记录的全部数据;辅助索引的叶子节点中,除了用来排序的 key 还包含一个 bookmark;该书签存储了聚集索引的 key;
sql
select * from user where lockyNum = 33;
innodb 体系结构
Buffer Pool
Buffer Pool 缓存表和索引数据;采用 LRU 算法,让 Buffer Pool 只缓存比较热的数据;