美文网首页
Innodb之大对象字段是物理存储思路

Innodb之大对象字段是物理存储思路

作者: 超人也害羞 | 来源:发表于2019-12-22 16:54 被阅读0次

    最近工作的时候突然想到一个关于大对象存储的问题。先看看这个问题的背景。

    背景1:在mysql数据库(innodb引擎)中,我们有这样的业务场景,在一个表(下面我们称为tmp表)中有一个字段(我们称为describe字段)可能存储的内容会特别的大,假设describe字段的业务大小上限为64KB,使用TEXT类型来存储(文章最下方有字段参考)。
    背景2:我们都知道innodb把所有的字段都存储在聚簇索引的叶子节点上,而在数据库的存储设计中,innodb的一个page(默认为16K)是希望能存储多个叶子节点,这样在读一个page页的时候能读到更多的叶子节点,减少查询的磁盘io。

    那么问题来了:

    那么tmp表中的describe字段大小都一静超过了16k了,一个page页已经存储不下了,innodb是怎么解决这个问题的呢?**

    innodb是不是这么干的呢?

    猜测1:是不是会扩展一个page的大小或者说把两个page页当做一个page页。
    猜测2:会不会大字段就不放在叶子节点所在的页了,而是单独存储了。

    好吧,下面就是通过查找资料来验证自己的猜测了。

    问题探索

    我们先来看一个概念。
    数据行溢出: Innodb会将一条记录中的某些数据存储在真正的数据page之外
    它的物理存储结构其实是这样的,在page页面中只会保留describe字段的前768个字节的前缀数据,之后是偏移量,偏移量指向存储完整数据的行溢出页。

    行溢出数据的存储
    到这里,其实对文章开头提出来的问题是有一个解答了。但是我们继续深入探索一下,什么样的数据会出现行溢出的这种现象呢?

    行溢出的条件

    有一些人认为像BLOB、LONGBLOB这类的大对象数据类型会把数据存放在数据页面之外。但是如果BLOB只存放了10个字段的数据,这时候还会把数据丢到其他页面吗?想来不会这么蠢,看资料别人的实验也证明了这一点。然后像varchar这样的类型,如果它存储了16K的内容,这些内容会存储在叶子节点内吗?事实证明也不合理。innodb是b+树的存储结构,在一个page中不希望只存储1条记录,是否发生行溢出这与page的大小有关系,一切都是为了保证一个page中存储多条数据,如果因为一条记录的超大导致了这个page存储不下其他的记录,显然在搜索效率上是无法容忍的。至于具体到怎样的数据级别,是超过9000个字节会存储或者其他,我个人认为这个和innodb 定义的page有关系。(个人理解,仅供参考,欢迎指正、探讨与交流)


    来点赞吧,哈哈哈

    字段类型大小表

    字段类型 存储大小 解释
    CHAR 0-255字节 定长字符串
    VARCHAR 0-65535 字节(64KB) 变长字符串
    TINYBLOB 0-255字节 不超过 255个字符的二进制字符串
    TINYTEXT 0-255字节 短文本字符串
    BLOB 0-65 535字节(64KB) 二进制形式的长文本数据
    TEXT 0-65 535字节(64KB) 长文本数据
    MEDIUMBL OB 0-16 777 215字节(16M) 二进制形式的中等长度文本数据
    MEDIUMTE XT 0-16 777 215字节(16M) 中等长度文本数据
    LONGBLOB 0-4 294 967 295字节(4G) 二进制形式的极大文本数据
    LONGTEXT 0-4 294 967 295字节(4G) 极大文本数据

    相关文章

      网友评论

          本文标题:Innodb之大对象字段是物理存储思路

          本文链接:https://www.haomeiwen.com/subject/meppnctx.html