文章目录
- InnoDB页合并和页分裂
- 聚簇索引和非聚簇索引的区别
- 稀疏索引和稠密索引
- InnoDB和MyISAM的区别
- InnoDB存储引擎四大特性
- InnoDB逻辑存储结构
- MySQL二级缓存机制
- 事务
- 数据库的事务与一致性是怎么实现的?
- gap锁以及gap锁是如何解决幻读的
- sql优化的几种方法
- 索引覆盖
- MySQL索引为什么使用B+树而不是B树
- 事务的传播特性
- 对索引的理解以及B+树索引节点的大小
- 范式
- 查询优化
- 哪些情况下适合建索引,哪些情况下不适合建索引
- 索引失效的几种情况
- MySQL索引底层数据结构
- MySQL是如何解决幻读的
- mysql 排除慢查询 导致慢查询的原因
- MySQL定位慢查询以及索引优化
- Explain的坑以及如何分析SQL(explain走了索引,但实际走了全表)
- 为什么INNODB数据页面中最少存储2条记录?
- filesort
- binlog
- MySQL索引与锁的关系
- 唯一索引
- MySQL实现分布式锁
- char和varchar区别
- 分布式事务的一致性
- SQL语句
InnoDB页合并和页分裂
https://zhuanlan.zhihu.com/p/98818611
聚簇索引和非聚簇索引的区别
https://www.jianshu.com/p/fa8192853184
稀疏索引和稠密索引
对密集索引和稀疏索引的区分在与是否为每个索引键的值都建立索引,简单来说就是比如有一列的值如下:
1、2、3、4、5、6、7
密集索引的做法是为这7个值建立索引记录,那么就有7条索引记录,抽象索引记录如下:
1:到1的指针
2:到2的指针
…
7:到7的指针
稀疏索引的做法是将这个6个值分组,1、2、3和4、5、6和7分为不同的3组,取这三组中最小的索引键值作为索引记录中的索引值,抽象索引记录如下:
1:到顺序存储1、2、3的起始位置的指针
4:到顺序存在4、5、6的起始位置的指针
7:到顺序存储7的起始位置的指针
这两种索引都要通过折半查找或者叫做二分查找来确定数据位置,不同的是密集索引,只需要通过二分查找到搜索值=索引的索引记录就能确定准确的数据位置,而稀疏索引则需要先定位到搜索值>索引值的最小的那个,然后在通过起始位置去定位具体的偏移量。
这是两种不同的索引实现,一种建立了索引值与数据位置的1:1的关系,一种建立了索引值与数据位置1:n的关系。在大多数场景密集索引查询效率更高,在大多数场景稀疏索引占用空间更小。
InnoDB和MyISAM的区别
https://blog.csdn.net/qq_35642036/article/details/82820178
InnoDB存储引擎四大特性
https://www.jianshu.com/p/dcc0dc450a2c
InnoDB逻辑存储结构
它的所有数据都被逻辑地存放在表空间,表空间又由段,区,页组成。
段
段就是上图的segment区域,常见的段有数据段、索引段、回滚段等,在InnoDB存储引擎中,对段的管理都是由引擎自身所完成的。
区
区就是上图的extent区域,区是由连续的页组成的空间,无论页的大小怎么变,区的大小默认总是为1MB。
为了保证区中的页的连续性,InnoDB存储引擎一次从磁盘申请4-5个区,InnoDB页的大小默认为16kb,即一个区一共有64(1MB/16kb=16)个连续的页。
每个段开始,先用32页(page)大小的碎片页来存放数据,在使用完这些页之后才是64个连续页的申请。这样做的目的是,对于一些小表或者是undo类的段,可以开始申请较小的空间,节约磁盘开销。
页
页就是上图的page区域,也可以叫块。页是InnoDB磁盘管理的最小单位。默认大小为16KB,可以通过参数innodb_page_size来设置。
常见的页类型有:数据页,undo页,系统页,事务数据页,插入缓冲位图页,插入缓冲空闲列表页,未压缩的二进制大对象页,压缩的二进制大对象页等。
MySQL二级缓存机制
一级缓存:
也称本地缓存,sqlSession级别的缓存。一级缓存是一直开启的;与数据库同一次会话期间查询到的数据会放在本地缓存中。
如果需要获取相同的数据,直接从缓存中拿,不会再查数据库。
一级缓存失效的四种情况:
1.sqlSession不同。
2.sqlSession相同,查询条件不同。因为缓存条件不同,缓存中还没有数据。
3.sqlSession相同,在两次相同查询条件中间执行过增删改操作。(因为中间的增删改可能对缓存中数据进行修改,所以不能用)
4.sqlSession相同,手动清空了一级缓存。
二级缓存:全局缓存;基于namespace级别的缓存。一个namespace对应一个二级缓存。
工作机制:1.一个会话,查询一条数据,这个数据会被放在当前会话的一级缓存中。
2,如果会话被关闭了,一级缓存中的数据会被保存带二级缓存。新的会话查询信息就会参照二级缓存。
3.sqlSession > Employee>employee
sqlSession >DepartmentMapper=>Department
不同的namespace查出的数据会放在自己对应的缓存中。
效果:查出的数据首先放在一级缓存中,只有一级缓存被关闭或者提交以后,一级缓存数据才会转移到二级缓存。
事务
数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。
数据库的事务与一致性是怎么实现的?
https://blog.csdn.net/fanxing1964/article/details/82252774
gap锁以及gap锁是如何解决幻读的
sql优化的几种方法
索引覆盖
https://www.cnblogs.com/myseries/p/11265849.html
MySQL索引为什么使用B+树而不是B树
https://www.cnblogs.com/jasontec/p/9892875.html
事务的传播特性
https://www.cnblogs.com/cat-fish6/p/8709528.html
对索引的理解以及B+树索引节点的大小
范式
第一范式:一言以蔽之:“第一范式的数据表必须是二维数据表”,第一范式是指数据库的每一列都是不可分割的基本数据项,强调列的原子性,试题中某一属性不能拥有几个值。比如数据库的电话号码属性里面不可以有固定电话和移动电话值。 说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
第二范式建立在第一范式的基础上,即满足第二范式一定满足第一范式,第二范式要求数据表每一个实例或者行必须被唯一标识。除满足第一范式外还有两个条件,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。每一行的数据只能与其中一列相关,即一行数据只做一件事。只要数据列中出现数据重复,就要把表拆分开来。
第三范式若某一范式是第二范式,且每一个非主属性都不传递依赖于该范式的候选键,则称为第三范式,即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。
查询优化
哪些情况下适合建索引,哪些情况下不适合建索引
一、哪些情况下适合建索引
1. 频繁作为where条件语句查询的字段
2. 关联字段需要建立索引,例如外键字段,student表中的classid, classes表中的schoolid 等
3. 排序字段可以建立索引
4. 分组字段可以建立索引,因为分组的前提是排序
5. 统计字段可以建立索引,例如count(),max()
二、哪些情况下不适合建索引
1.频繁更新的字段不适合建立索引
2.where条件中用不到的字段不适合建立索引
3.表数据可以确定比较少的不需要建索引
4.数据重复且发布比较均匀的的字段不适合建索引(唯一性太差的字段不适合建立索引),例如性别,真假值
5. 参与列计算的列不适合建索引
索引失效的几种情况
1.有or必全有索引;
2.复合索引未用左列字段;
3.like以%开头;
4.需要类型转换;
5.where中索引列有运算;
6.where中索引列使用了函数;
7.如果mysql觉得全表扫描更快时(数据少);
https://www.cnblogs.com/liehen2046/p/11052666.html
MySQL索引底层数据结构
https://www.bilibili.com/read/cv3737726/
MySQL是如何解决幻读的
https://segmentfault.com/a/1190000012669504
mysql 排除慢查询 导致慢查询的原因
https://blog.csdn.net/qq_42052956/article/details/111387051
MySQL定位慢查询以及索引优化
https://blog.csdn.net/Hzt_fighting_up/article/details/78570641
Explain的坑以及如何分析SQL(explain走了索引,但实际走了全表)
https://blog.csdn.net/tracymm19891990/article/details/104798190/
为什么INNODB数据页面中最少存储2条记录?
如果只有一条记录的话,还能构成B+树吗?好像变成了链表。
filesort
https://zhuanlan.zhihu.com/p/102147059
binlog
https://blog.csdn.net/wwwdc1012/article/details/88373440
MySQL索引与锁的关系
如果我们的锁用到索引就是行锁,如果没有用到索引会先加表锁。因为没有用到索引,所以在查找的时候会进行全表扫描,在全表扫描的过程中会对所有的记录加锁,扫描完成后,在进行条件匹配时,对那些不满足条件的记录再释放锁,所以最终看到的结果就是对满足条件的记录加锁。
唯一索引
https://blog.csdn.net/weixin_33772645/article/details/92355203
https://www.ibm.com/docs/zh/db2/10.5?topic=indexes-unique-non-unique
MySQL实现分布式锁
https://segmentfault.com/a/1190000023045815
char和varchar区别
mysql中char与varchar的区别分析
1.都是用来存储字符串的,只是他们的保存方式不一样。
2.char有固定的长度,而varchar属于可变长的字符类型。
char是一种固定长度的类型,varchar则是一种可变长度的类型,它们的区别是:
char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,MySQL就会在它的右边用空格字符补足.在varchar(M)类型的数据列里,每个值只占用刚好够用的字节再加上一个用来记录其长度的字节(即总长度为L+1字节)。
varchar通常用于保存可变长字符串。在磁盘存储数据时,它只会占用实际使用到的空间,因此对性能有提升。vachar在保存数据时会额外使用1个或者2个字符,用于记录列的长度,如果列内字节长度小于等于255就使用1个字节记录,如果是大于255则使用2个字节记录。因为varchar是变长的,所以update操作可能会产生碎片,从而使列的长度变长,mysql还需要做额外的工作处理。其实varchar(5)和varchar(255)存储’hello’所用的空间是一样的,但是我们在实际使用的时候,列的长度还是越短越好,原因是更长的列会占用更多的内存,Mysql通常会分配固定大小的内存块保存内部值。这个在内存临时表做排序和操作的时候会变得很糟糕,在磁盘临时表进行排序时也会特别的糟糕。
再说一下char,对比下你就会明白。
char类型适用于存储固定长度的数据。比如说MD5后的密码,这个长度就是固定的32位,很适合使用char类型。因为char类型是固定长度,因此在修改数据时也不容易产生碎片。他在磁盘上的存储空间是固定的,如果存储的数据长度不够,会在右侧以空格的方式补充,方便进行比较。对于非常短的列(单字节字符集),char的效率比varchar要高,因为char不需要使用额外的字节去记录长度。
使用什么样的类型存储数据,要根据实际情况而定,最好是对各种存储类型都有一定的了解。
分布式事务的一致性
https://xiaomi-info.github.io/2020/01/02/distributed-transaction/
蚂蚁DTS https://tech.antfin.com/docs/2/46886
SQL语句
有学生表和成绩表,查成绩最高的前10个学生
select s.*,g.math from students s , grades g where s.id=g.id order by g.math desc limit 10;