专栏名称: java一日一条
主要是讲解编程语言java,并且每天都推送一条关于java编程语言的信息
目录
相关文章推荐
51好读  ›  专栏  ›  java一日一条

MySQL 如何存储长度很长的数据字段

java一日一条  · 公众号  · Java  · 2017-02-24 22:25

正文

最近,在工作中遇到了MySQL中如何存储长度较长的字段类型问题,于是花了一周多的时间抽空学习了一下,并且记录下来。

MySQL大致的逻辑存储结构在这篇文章中有介绍,做为基本概念: InnoDB 逻辑存储结构

注:文中所指的大数据指的是长度较长的数据字段,包括varchar/varbinay/text/blob。

Compact行格式

我们首先来看一下行格式为Compact是如何存储大数据的:


我们建立一张测试表,插入数据:

我们使用 py_innodb_page_info.py 工具来查看表中的页分布:

可以看出,第4页的 , page level 格式为数据页,存放着MySQL的行数据。 可以理解为MySQL存放大数据的地方,暂且叫作外部存储页。Compact格式没有将大数据全部放在数据页中,而是将一部分数据放在了外部存储页中。那么,是全部数据在外部存储页中,还是一部分数据。假如是一部分数据,这一部分是多少呢?

我们使用 hexdump -Cv row.ibd 查看一下数据页 , page level ,也就是第4页:

我们可以看出,数据页中存储了一部分数据,算下来一共是768字节,然后剩余部分存储在外部存储页中。那么数据页与外部存储页、外部存储页与外部存储页是如何连接在一起的呢?

我们观察这一行:

这一行是前缀768字节的结尾。注意最后的20个字节:

  • 00 00 00 02:4字节,代表外部存储页所在的space id

  • 00 00 00 04:4字节,代表第一个外部页的Page no

  • 00 00 00 26:4字节,值为38,指向blob页的header

  • 00 00 00 00 00 00 fc fc:8字节,代表该列存在外部存储页的总长度。此处的值为64764,加上前缀768正好是65532。(注意一点,虽然表示BLOB长度的是8字节,实际只有4个字节能使用,所有对于BLOB字段,存储数据的最大长度为4GB。)

验证下第一个外部存储页的头部信息:

前38个字节为File Header(关于InnoDB数据页的详细结构请参见《MySQL技术内幕 InnoDB存储引擎》4.4),这个简单提一下:

  • cd c3 b6 8e:4字节,该页的checksum。

  • 00 00 00 04:4字节,页偏移,此页为表空间中的第5个页。

  • 00 00 00 00:4字节,当前页的上一个页。此页为 ,所以没有上一页。

  • 00 00 00 00:4字节,当前页的下一个页。此页为 ,所以没有下一页。

  • 00 00 00 00 00 06 b8 a2:8字节,该页最后被修改的日志序列位置LSN。

  • 00 0a:2字节,页类型,0x000A代表BLOB页。

  • 00 00 00 00 00 00 00 00:8字节,略过。

  • 00 00 00 02:页属于哪个表空间,此处指表空间的ID为2。

之后是4字节的 00 00 3f ca ,这里的值为16330,代表此BLOB页的有效数据的字节数。 00 00 00 05 代表下一个BLOB页的page number。

我们看最后一个 ,第8个页:

最后一页的有效数据大小为0x00003d9e=15774,768+16330*3+15774 = 65532字节,符合初始插入数据的大小。
由于这是最后一个 ,所以指向下一个 的指针为ff ff ff ff。

由此我们可以很清晰的看出数据页与BLOB页的连接关系(引用淘宝数据库月报上的一张图):

我们来再看一个比较有意思的例子。:







请到「今天看啥」查看全文


推荐文章
哈尔滨日报  ·  财政部定了:养老金今年这么涨……
7 年前
创业邦  ·  哇!这里有个活动百宝箱!
7 年前
暴走大事件  ·  蓝翔快来,有人要向你挑战!
7 年前