1、索引

索引分类:主键索引、唯一索引、普通索引、组合索引、以及全文索引(elasticsearch);

1.1、主键索引

非空唯一索引,一个表只有一个主键索引;在innodb中,主键索引的B+树包含表格信息

PRIMARY KEY(key) // 括号中的key为列名

1.2、唯一索引

不可以出现相同的值,可以有NULL值(NULL值也不能重复)

UNIQUE(key) // 括号中的key为列名

1.3、普通索引

允许出现相同的索引内容

INDEX(key)
-- OR
KEY(key[,...])

1.4、组合索引

对表上的多个列进行索引

INDEX idx(key1,key2[,...]);
UNIQUE(key1,key2[,....]);
PRIMARY KEY(key1,key2[,....]);

1.5、全文索引

将存储在数据库当中的整本书和整篇文章中的任意内容信息查找出来的技术;

关键词 FULLTEXT;

在短字符串中用 LIKE % ;在全文索引中用 match 和 against ;

1.6、主键选择

innodb 中表是索引组织表,每张表有且仅有一个主键;

1.如果显示设置 PRIMARY KEY ,则该设置的key为该表的主键;

2.如果没有显示设置,则从非空唯一索引中选择;

 1. 只有一个非空唯一索引,则选择该索引为主键;

 2. 有多个非空唯一索引,则选择声明的第一个为主键;

没有非空唯一索引,则自动生成一个 6 字节的 _rowid 作为主键;

2、约束

为了实现数据的完整性,对于innodb,提供了以下几种约束,primary key,unique key,

foreign key, default, not null;

2.1、外键约束(不建议使用)

外键用来关联两个表,来保证参照完整性;MyISAM存储引擎本身并不支持外键,只起到注释作用;而innodb完整支持外键;

外键约束具有事务性。

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;
-- 被引用的表为父表,引用的表称为子表,上面例子中child为子表,parent为父表;
-- 外键定义时,可以设置行为 ON DELETE 和 ON UPDATE,行为发生时的操作可选择:
-- CASCADE 子表做同样的行为 ,如父表删除添加等,子表也会有相同变化
-- SET NULL 更新子表相应字段为 NULL ,如父表删除对应行,子表会设为null
-- NO ACTION 父类做相应行为报错 ,如父表做出改变,子表报错
-- RESTRICT 同 NO ACTION

2.2、约束与索引的区别

创建主键索引或者唯一索引的时候同时创建了相应的约束;但是约束时逻辑上的概念;索引是一个数据结构既包含逻辑的概念也包含物理的存储方式;

3、索引实现

3.1、 B+树

索引是基于B+树实现的

B+树全称:多路平衡搜索树,减少磁盘访问次数;用来组织磁盘数据,以页为单位,物理磁盘页一般为4K,innodb 默认页大小为 16K;对页的访问是一次磁盘io,缓存中会缓存常访问的页;

特征:非叶子节点只存储索引信息,叶子节点存储具体数据信息;叶子节点之间互相连接,方便范围查询;

每个索引对应着一个 B+ 树;

​为了支持范围查询:

 所有的非父节点都会存储一个p,用于存储同一层中上一个节点与下一个节点的磁盘地址。比如查找索引值在1~22之间的数据,就可以通过页5->页6->页7,页2->页3的顺序来找数据,这样能够减少回溯,避免每一次都要有这样的过程(访问完叶节点 -> 返回父节点 -> 找下一个叶节点)

C++后台开发系统学习地址:C/C++Linux服务器开发高级架构师/C++后台开发架构师​

以下C++后台开发学习资料,面试题,教学视频,C++后台开发学习路线图,免费分享有需要的可以自行添加:学习资料群720209036 自取

3.2、B+树层高

B+树的一个节点对应一个数据页;B+树的层越高,那么要读取到内存的数据页越多,io次数越多;

innodb一个节点16kB;

假设:

key为10byte且指针大小6byte,假设一行记录的大小为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 =

17179869184;

注意: 若数据超过500w行的时候,需要进行分表分库,不要将数据都放在一个表中

3.3、关于自增id

如果自增id超过了最大值会报错;

若担心自增值会过大,可以使用bigint类型,bigint的范围为(-263, 263-1)。

3.4、聚集索引

定义:按照主键构造的 B+ 树;叶子节点中存放数据页;数据也是索引的一部分;

innodb是这样子的

# table id name
select * from user where id >= 18 and id < 40;

​使用myisam创建数据库,会在mysql对应路径下生成*.frm, *.myd, *.myi文件。

*.frm:表信息文件

*.myd:数据文件(堆构建的)

*.myi:索引文件 (B+树构建的,叶子节点里面存储的是索引值+对应数据的磁盘地址)

通过索引文件找到对应数据的地址,再到数据文件中查找的过程称为回表查询

使用myisam创建数据库,会在mysql对应路径下生成*.frm和*.idb文件,其中*.idb存放的是索引和数据。

3.5 辅助索引

定义:叶子节点不包含行记录的全部数据;辅助索引的叶子节点中,除了用来排序的 key 还包含一个bookmark ;该书签存储了聚集索引的 key;

辅助索引是按照非主键索引构造的。

-- 某个表 包含 id name lockyNum; id是主键,lockyNum存储辅助索引;
select * from user where lockyNum = 33;

​解析:

有两棵B+树。

一颗是根据id创建的聚集索引,叶子节点数据由多个主键索引+行数据组成

一颗是根据lockyNum创建的辅助索引,叶子节点数据由多个辅助索引+bookmark所组成。(bookmark对应一个主键)

根据lockyNum查找数据时,找到对应的辅助索引,再通过对应的bookmark去聚集索引中找具体的数据。从辅助索引跳到聚集索引也称为回表查询。

3.6、索引存储方式

innodb由段、区、页组成;段分为数据段、索引段、回滚段等;区大小为 1 MB(一个区由64个连续页构成);页的默认值为16k;页为逻辑页,磁盘物理页大小一般为 4K 或者 8K;为了保证区中的页的连续,存储引擎一般一次从磁盘中申请 4~5 个区;

3.7、最左匹配原则

对于组合索引,从左到右依次匹配,遇到 > < between like 就停止匹配;

有where,group by,having,order by, join on的时候会尝试通过索引来查找

如k1,k2构成组合索引:

当单独使用k2时,会全表查询;

当同时使用k1,k2时并且没有 > < between like ,会用辅助索引查找;

3.8、覆盖索引

从辅助索引中就能找到数据,而不需通过聚集索引查找;利用辅助索引树高度一般低于聚集索引树;较少磁盘 io;

即避免回表查询,select的时候不要全表展示出来,可以只展示出辅助索引中的数据,这样就不需要回表查询,或者只用主键进行匹配。

3.9、索引失效

1、select … where A and B 若 A 和 B 中有一个不包含索引,则索引失效;

2、索引字段参与运算,则索引失效;例如: from_unixtime(idx) = ‘2021-04-30’;

3、索引字段发生隐式转换,则索引失效;例如: ‘1’ 隐式转换为 1 ;

4、LIKE 模糊查询,通配符 % 开头,则索引失效;例如: select * from user where name like ‘%Mark’;

5、在索引字段上使用 NOT <> != 索引失效;如果判断 id <> 0 则修改为 idx > 0 or idx < 0 ;

6、组合索引中,没使用第一列索引,索引失效;

7、in + or 索引失效;单独的in 是不会失效的;not in 肯定失效的;

3.10、索引原则

1、查询频次较高且数据量大的表建立索引;索引选择使用频次较高,过滤效果好的列或者组合;

2、使用短索引;节点包含的信息多,较少磁盘io操作;比如:smallint,tinyint;

3、对于很长的动态字符串,考虑使用前缀索引;

4、对于组合索引,考虑最左侧匹配原则和覆盖索引;

5、尽量选择区分度高的列作为索引;该列的值相同的越少越好;

6、尽量扩展索引,在现有索引的基础上,添加复合索引;最多6个索引

7、不要 select * ; 尽量只列出需要的列字段;方便使用覆盖索引;

8、索引列,列尽量设置为非空;

9、可选:开启自适应 hash 索引或者调整 change buffer;

4、innodb体系结构

4.1 Buffer Pool

Buffer pool 缓存表和索引数据;采用 LRU 算法(原理如下图)让 Buffer pool 只缓存比较热的数据 ;

​4.2、Change buffer

Change buffer 缓存非唯一索引的数据变更(DML操作),Change buffer 中的数据将会异步merge 到磁盘当中;

技术参考资料:

​推荐一个零声教育C/C++后台开发的免费公开课程,个人觉得老师讲得不错,分享给大家:C/C++后台开发高级架构师,内容包括Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

后端开发【一大波有用知识】数据库之mysql索引原理详解相关推荐

  1. mysql数据 odbc_MySQL数据库之mysql odbc 配置详解、解决方案

    本文主要向大家介绍了MySQL数据库之mysql odbc 配置详解.解决方案 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 1.安装mysql 以及mysql odbc 要注 ...

  2. mysql odbc_MySQL数据库之mysql odbc 配置详解、解决方案

    本文主要向大家介绍了MySQL数据库之mysql odbc 配置详解.解决方案 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 1.安装mysql 以及mysql odbc 要注 ...

  3. 后端开发【一大波有用知识】MySQL索引原理(索引、约束、索引实现、索引失效、索引原则)以及SQL优化

    一.索引 索引分类:主键索引.唯一索引.普通索引.组合索引.以及全文索引(elasticsearch) 主键索引 非空唯一索引,一个表只有一个主键索引:在 innodb 中,主键索引的 B+ 树包含表 ...

  4. 后端开发【一大波有用知识】Redis的线程模型和异步机制

    文章目录 Redis 6.0引入多线程 异步机制 Redis pipeline技术 Redis 事务 ACID特性分析 redis 发布订阅 我们通常说,Redis 是单线程,主要是指 Redis 的 ...

  5. 后端开发【一大波有用知识】tcp/ip定时器与滑动窗口详解

    为什么udp有包长,而tcp没有包长. 首先,send()发送一次发送1k,发送一次缓冲区满了就会返回-1.2k发送出去后缓冲区被清空,send()才会被再次调用.最大传输片会打印四个包发送.而最大传 ...

  6. 后端开发【一大波有用知识】Redis中的IO多线程(线程池)

    一.Redis中的IO多线程原理 ​服务端收到一条信息,给它deconde成一条命令 然后根据命令获得一个结果(reply) 然后将结果encode后,发送回去 redis的单线程是指,命令执行(lo ...

  7. 后端开发【一大波有用知识】网络通信模型和网络IO管理

    简单的C/S通信模型(accept阻塞的话,就只能一个客户端接进来) socket()函数 //函数原型.返回:若是成功则为非负数,如出错则为 -1 int socket(int domin, int ...

  8. 后端开发【一大波有用知识】—Redis,Memcached,Nginx网络组件

    reator网络编程 epoll被称为事件管理器,利用管理器去管理多个连接. int clientfd=accept(listenfd,addr,sz); clientfd ==-1 &&am ...

  9. 后端开发【一大波有用知识】定时器方案红黑树,时间轮,最小堆

    目录: 一.如何组织定时任务? 定时器收网络IO处理造成误差特别大,该怎么处理? 用何种数据机构存储定时器? 红黑树如何解决相同时间的key值的? 最小堆 时间轮 一个帮助理解单层级时间轮的例子 如何 ...

最新文章

  1. Asp.Net源码(转载)
  2. maven项目中测试代码
  3. Django08:模型层(ORM)--测试脚本/必知的13条/神器的双下划线查询/多表操作
  4. [转载]我的WafBypass之道(upload篇)
  5. *如何循序渐进向DotNet架构师发展(转)
  6. linux用户及权限详解(20170425)
  7. 数据库技大会五周年 技术领袖共聚DTCC
  8. linux备份能压缩吗,Linux备份与压缩命令
  9. JDK 运行参数 JAVA -Dxxx与System.setProperty()的关系
  10. 如何点亮或者关闭EMC VMAX的磁盘指示灯
  11. Md5(base64)加密与解密实战
  12. 应用排行榜第一名脸萌只是刹那的烟火
  13. 【informix】informix 日期字段
  14. c语言乘法运算出负数,C语言用数组表示大数 乘法得出的结果怎么是负数之类的奇怪数字?...
  15. 全程实操 | 最新版OpenCV4.4免费视频课程送给大家
  16. SIM7600CE重置功能
  17. Python实现最速下降法(The steepest descent method)详细案例
  18. 产品运营模型:AARRR模型
  19. HTTP 状态返回码
  20. 批量出售QQ群idcnd传媒提供

热门文章

  1. linux下安装hp1005打印驱动
  2. 汇编中的la_MIPS汇编与指令
  3. 小米采用意法半导体低功耗电磁罗盘模块LSM303D
  4. win10下安装Prodave6.2
  5. 【雷达通信】基于matlab雷达仿真模拟系统【含Matlab源码 150期】
  6. 动态sql批量插入数据
  7. Dubbo基本原理与超时机制
  8. String a =new String(“abc”);和String b=”abc”;的区别
  9. vps租用php源码,php多用户自动刷分源码
  10. pandas时序数据分析