mysql日常总结
1.innodb中数据是如何存储的?
数据以文件的形式(xxx.ibd)存储在磁盘中。文件的格式是页。每页16KB。页中存储数据行、页目录,还有页头,文件头,文件尾等。数据页中的记录按照「主键」顺序组成单向链表。因为链表插入和删除都很快,但是查找不是很方便,所有就引入页目录的概念。
将数据行进行分组,用槽记录每个分组中的最大记录。多个槽就组成了页目录。
为什么要分组?
因为如果不分组,每条记录都放1个槽,那么槽也会很多,所以就进行分组放到1个槽里。
对于主键索引,每个槽有1-8个数据行。
2.数据是如何查找的
因为有多个数据页,所有就需要有索引。索引的结构是B+树。B+树的每个节点都是一个数据页。从根节点开始,通过二分法快速定位到所要查找记录的页,定位到页以后,在该页内进行二分法,快速定位到数据所在的分组(槽),最后在分组内进行遍历查找。
3.聚簇索引和非聚簇索引的区别
区别在于叶子节点存放什么数据。
聚簇索引的叶子节点,存放的是实际数据,所有完整的用户记录都存放在聚簇索引的叶子节点。
二级索引的叶子节点存放主键值,而不是实际数据。
一张表只能有1个聚簇索引(主键),但可以有多个非聚簇索引
4. 回表
如果某个查询使用了二级索引,但查询的数据不是主键值,就需要在二级索引中找到主键,然后再去聚簇索引中获得数据行,这个过程就叫回表。
5.B+树的特点
- 只有叶子节点才存放数据,非叶子节点仅用来存放目录项作为索引
- 非叶子节点分为不同层次,通过分层降低每一层的搜索量
- 所有节点按照索引键大小排序,构成一个双向链表,便于范围查询
总结二
1.innodb数据是按【数据页】为单位来读写的,默认数据页大小是16KB。每个数据页之间,通过双向链表的形式组织起来,物理上不连续,但逻辑上连续
2.数据页内包含用户记录,每个记录之间用单向链表的方式组织起来。
3.为加快在数据页内高效查询记录,设计了一个页目录。页目录存储各个槽(分组),且主键值是有序的,于是可以通过二分查找法的方式进行检索从而提高效率
4.为了高效查询记录所在数据页,innodb采用B+树做索引。每个节点都是一个数据页。
5.聚簇索引的叶子节点,存储的是实际数据。一个表只能有1个聚簇索引;
非聚簇索引叶子节点,存储的是主键值。一个表中可以有多个二级索引
6.使用二级索引查找数据时,如果查询的数据能在二级索引中找到,那么就是覆盖索引。
如果查找的数据不在二级索引里,那么就需要在二级索引中先找到主键,然后再在聚簇索引中通过主键获得数据行,这个过程就叫回表。
1.mysql null值会占用空间吗?
2.mysql怎么知道varchar(n) 实际占用数据的大小
3.varchar(n)中n最大取值为多少
4.行溢出后,mysql如何处理的
mysql每一张表的数据都存放在一个独立的.ibd文件。这个文件也被称为独占表空间文件。
表空间文件的结构是怎样的
表空间有段(segment)、区(extent)、页(page)、行组成。
innodb存储引擎的逻辑存储结构
数据库表中的记录都是按行进行存放的,每行记录根据不同的行格式,有不同存储结构。
页,记录是按照行来存储,但数据库的读写都是以页为单位。
区,B+树中每一层都是通过双向链表连接起来的,如果是以页为单位来分配存储空间,那么链表中相邻的两个页之间的物理位置并不连续,可能离得很远,那么磁盘查询时会大量随机IO。
解决这个问题,就是让链表中相邻的页的物理位置也相邻。范围查询性能也高。
所以在表中数据量大的时候,为某个索引分配空间的时候,就不再按照页为单位分配了,而是按照区为单位分配,每个区的大小为1MB。对于16KB的页来说,连续的64个页会被划为1个区,这样使得链表中相邻的页的物理位置也相邻,就有使用顺序IO了
