|
|
51CTO旗下网站
|
|
移步端
  • 扒一扒InnoDB数量在硬盘上是如何存放的

    在InnoDB官方,每个表都有各自的主人翁键(Primary Key),如果在创造表的时节显式的概念主键,则InnoDB存储引擎会按如下方式选择或创办主键。

    笔者:读书Java的小姐姐 来源:读书Java的小姐姐| 2020-01-15 15:29

    本文转载自微信公众号「读书Java的小姐姐」,转载本文请联系学习Java的小姐姐公众号。

    目录组织表

    在InnoDB存储引擎中,表面都是按照主键顺序组织存放的,这种存储方式的外表被称为索引组织表。

    在InnoDB官方,每个表都有各自的主人翁键(Primary Key),如果在创造表的时节显式的概念主键,则InnoDB存储引擎会按如下方式选择或创办主键。

    第一判断表面中是否有非空的目录,如果有则第一个定义之非空索引作为东道主键

    如果不符合上述条件,InnoDB存储引擎自动创建一个6个字节大小的指针

    这样的叙说太干瘪啦,咱们来动手操作下。

    1.慎选第一个定义之非空索引

    第一,咱们创建表student,并填充两枝测试数据,说话如下:

          
    1. create table student( 
    2. int , 
    3. int not null
    4. int not null
    5. UNIQUE key (a), 
    6. UNIQUE key (c), 
    7. UNIQUE key (b) 
    8. ); 
    9. insert into student select 1,2,3; 
    10. insert into student select 4,5,6; 

    运作结果如下,咱们可以看到_rowid的值等于列c的值,那就阐明当前存储的组织是将c表现东道主键的。此外a是可以为空的,虽然他定义唯一键的是第一个,但仍然不会作为东道主键。b虽然是先定义列,但是定义唯一键是在c后,故此也不会把作为唯一键。

    2.机动创建6个字节大小的指针

    第一,咱们创建表score,并填充两枝测试数据,说话如下:

          
    1. create table score( 
    2. int , 
    3. int , 
    4. int
    5. UNIQUE key (a), 
    6. UNIQUE key (c), 
    7. UNIQUE key (b) 
    8. ); 
    9. insert into score select 1,2,3; 
    10. insert into score select 4,5,6; 

    运作结果如下,直接报错了,不觉得_rowid是它的列名,因为没有满足条件的进能成为他的主人翁键,所以他就自动创建指针来解决问题啦。

    InnoDB的逻辑存储结构(完全)

    表面空间

    表面空间可以看做是InnoDB存储引擎逻辑结构的最高层,故此的多寡都存放在表面空间里面。

    在默认情况下,InnoDB存储引擎有一度共享表空间ibdata1,即一切数据都存放在这个表空间里面。当然也得以在my.ini数文件中滥用innodb_file_per_table,则每张表的多寡就足以单独放在一个表空间中。

    瞩目:即使启用innodb_file_per_table数,一部分回滚信息,系统事务信息等还是在共享的外表空间中,他随着岁月之转移大小还是会不断增大的。单独的外表空间只会存放一些数目及索引信息。

    在InnoDB存储引擎中,对段的治本都是由引擎自身所形成的,DBA决不能也没必要对他进行控制。

    区是由继续页组成的蓝天,在其他情况下每个区的高低都是1MB,页的高低为16kb,所以一个省一共有64个连续的页。

    下详细描述。

    下详细描述。

    InnoDB列记录格式(根本)

    InnoDB存储引擎和大多数必发娱乐登录一样,记录是以行的样式纯纯的,这就是意味着页中保存着表的一条龙行数据。这就是说问题就来了,她这一行数据是包括哪些部分,除了具体的多寡,还有其它的组成部分额外信息吗?

    第一,咱们先来看一下如果没有指定行格式,他默认的排格式是什么?

    兴建表test,获得的字段a,b ,c 。

          
    1. create table test( 
    2. varchar(10), 
    3. varchar (10) not null
    4. char(10) 
    5. ); 
    6. insert into test values'001','Andy','compter'); 
    7. insert into test values'002','Bob',NULL); 

    如下图所示,默认的排格式是Compact ,该行格式是在MySQL5.0官方引入的,他设计目标是高校的存储数据。大概来说,一度页存放的排数据越多,他性质越高。针对这个描述,咱们先放在一边,后看到其它的排格式,咱们对比着看,为啥compact性能高?


    从图为行格式Compact的简易结构,先看一眼,重点分为两个组成部分,额外信息和实际数据。额外信息包括变成字段长度,NULL值列表,记录头信息,实在数据即为该行记录有好多列,每趟数据有哪些。其中记录头信息包括记录删除位,记录类型,从一个指针的岗位。

    瞩目,记录头信息还有很多为其它信息,但是重要的就这几个。只是不知晓他们是干撒的,一面懵逼中,没事,这还是混个面熟,从一些来慢慢盘他。

    变长字段长度

    MySQL支持一些变长的多寡类型,如varchar,text,blob,变长长度存储多少字节的多寡是不一定的,故此我们在储存真实数据的时节,要求将这些数据占用的字节数也要存储起来。

    刚才我们新增了两枝数据,先拿第一个数目为例,名将真正数据占用的字节长度都存放在记录的起始部位,故而形成一个变长字段长度列表,逆序存放。如下图,故此最终第一枝记录存放的十六进制为08 04 03,她们之间没有空格,是为了炫耀的功力才加了空格。那第二枝记录很显然是03 03.

    瞩目:如果表中没有变长字段,则该字段不存在。

    NULL值列表

    咱们掌握表中的某些列可能存储NULL值,如果这些NULL值放在记录的真正数据中存储会占用空间,故此Compact名将这些值为NULL的进统一管理起来,存储在NULL表面中。

    瞩目:跟变长字段一样,如果表中没有NULL值的进,则该字段不存在。瞩目:MySQL规定NULL值列表必须是整数个字节的位表示,如果采取的福利制位歌手不是整数个字节,则在字节的高位补0.

    着重列数据虽然没有NULL值,但是a,c是可能存储NULL值的进,故此NULL值列表如下,0表示列所对应的值不为NULL,1表示列所对应的值为NULL。

    其次列数据a不是NULL,c是NULL,故此对应的NULL值列表如下。

    记录头信息

  • 记录删除位(delete_mask):0为未删除,1为删除
  • 记录类型(record_type):0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录。
  • 从一个指针的岗位(next_record):表示从目前记录的真正数据到副一枝记录的真正数据之间的地点偏移量。比如第一枝记录的next_record为20,这就是说意味从主要枝记录的真正数据的地点处向后找32个字节便是副一枝记录的真正数据。实际上就是链表组织。
  • InnoDB数量页结构(根本)

    从图为数据页的总体布局,咱们先来了解下大概,再慢慢盘它。

    文件头(File Header)

    页的组成部分通用信息,包括该页属于哪个表空间,InnoDB存储引擎页的项目。

    页头(Page Header)

    记录数据页的状态信息。

    最小记录+最大记录(Infimum+supermum)

    在InnoDB存储引擎中,每个数据页都有两枝虚拟的排记录,用于限定记录的境界。

    Infimum记录是指比该页中任何主键值都要小的值,Supermum记录是指比该页中任何主键值都要大的值。

    这两个值在页创建时都会把的创造,并且在其他情况下不会把删除。

    这两枝记录的结构十分简单,都是有5个字节大小的记录头信息和8个字节的稳定部分构成的。

    瞩目:地方提到了最小记录的record_type为2,最大记录的record_type为3。

    他家记录(User Records)

    根本来了,此处是数量实际存储位置,地方已经针对行格式做了详尽的分割,如今咱就长话短说啦。

    如果我删除了第二列记录,这条记录并不是立刻删除了,只是将删除记录位改为1啦。并且将它面前一枝数据的指针指向他后面一枝数据的地点,故而跳过这一枝数据。

    至于为什么会这样做呢?是为了节省时间和空中的损耗。如果在删除的时节,立刻从光盘上移除,这就是说其他记录在光盘上重新排列需要性能消耗,故此在删除的时节,只会将全部被删除的记录组成一个垃圾链表,稍后操作。或者有新纪录插入的时节,覆盖掉刚才的存储空间。

    空闲空间(Free Space)

    不重要。

    页面目录(Page Directory)

    咱们今天已经找到记录在页面中按照主键由小到达顺序组成一个单链表,那如果想根据主键查询页中的某条记录怎么办?

    最蠢的主意肯定是按单链表之程序从头到尾的追寻,因为只有掌握前面一枝记录的记录的地点,才能根据指针找到副一枝记录。但是这个有个显著的弱点,就是太慢了,如果有1000条数据,一度个之询问,如果最终一枝记录才满足条件,那就太浪费时间啦。

    咱们可以先下顺序表中考虑,如果顺序表中要找一个记录,咱们除了从头开始查之外,还可以行使二分法,可以提升查询速度。

    这就是说在单链表中是否可以行使二分法呢?答案是确认的。即采取目录的样式,名将全部的记录划分为多个记录块,下一场取每个记录块的最大的值,名将他构成一个目录,在摸索的时节,先查目录,能判断在谁区间内。其一过程就类似于在书中找到某一个概念,要下目录先找一样。

    文章尾部(File Tailer)

    不重要。哈哈哈。

    写在最后

    写在最后

    该篇借鉴的博文,图书如下。

    《MySQL艺术内幕——InnoDB存储引擎》MySQL是如何运作的https://blog.csdn.net/u010922732/article/details/82994253#%E4%B8%80%20%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E%E4%BD%9C%E7%94%A8%E4%BA%8E%E4%BB%80%E4%B9%88%E5%AF%B9%E8%B1%A1

    https://juejin.im/post/5cb3e3dfe51d456e3428c0db

    【编纂推荐】

    1. 保护数据高可用也要「狡兔三窟」
    2. 大用户量与高性能SSD硬盘的比较
    3. 成千上万专利技术加持下西部数据,为液冷数据中心存储安全赋能
    4. 一再!必发娱乐登录如何存储时间?你真的了解吗?
    5. 详解Redis5.0数量淘汰策略
    【义务编辑: 武晓燕 TEL:(010)68476606】

    点赞 0
  • InnoDB  数量  硬盘
  • 分享:
    大家都在看
    猜你喜欢
  • 订阅专栏+更多

    Python使用场景实战手册

    Python使用场景实战手册

    Python使用场景实战手册
    共3章 | KaliArch

    118人口订阅学习

    一步到位玩儿透Ansible

    一步到位玩儿透Ansible

    Ansible
    共17章 | 骏马金龙1

    186人口订阅学习

    云架构师修炼手册

    云架构师修炼手册

    云架构师之必不可少技能
    共3章 | Allen在路上

    132人口订阅学习

    读 书 +更多

    八万里路云和月――一度国家扶贫开发工作任重而道远县的

    通榆,其一距离各个交通枢纽都远远的偏僻小县城,满载着电子商务的末班车,踏上了云高速,开拓了隆重的电商致富之新战场,贯彻了一...

    订阅51CTO邮刊

    点击这里查看样刊

    订阅51CTO邮刊

    51CTO劳务号

    51CTO官微



    <kbd id="38f76d0d"></kbd>


  • 
       

      <li id="6720a530"></li>