mysql的存储格式_MySQL · 存储引擎 · MySQL的字段数据存储格式

概述

MySQL支持多种存储引擎,而InnoDB是MySQL事务型数据库的首选引擎,也是MySQL从5.6版本以来的默认存储引擎。

InnoDB的存储格式已经有太多介绍性的文章,讲述了Tablespaces, Segments, Exents, Pages, Records等概念。其中很少有人对行存Record的不同数据字段进行介绍。本文讨论分析一下常见的字段数据在MySQL和InnoDB种不同的存储格式,并给出方法,大家可以自行学习其他没有涉及的字段。这里讨论的MySQL和InnoDB都是MySQL 5.7或MySQL 8.0, 过早的版本不在本文讨论范围。

字段数据格式学习方法

因为MySQL可以对接不同独立的存储引擎,MySQL和其对应的存储引擎对数据的存储方式就可能不同。因此MySQL必然会在计算层和存储层有不同的存储格式,也会有对应的数据转化方法。

对于InnoDB而言,有两个方法对于数据格式的转化最为关键。

MySQL数据 -> InnoDB数据  (row0mysql.cc)

/** Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format. */

row_mysql_store_col_in_innobase_format()

InnoDB数据 -> MySQL数据  (row0sel.cc)

/** Convert a field from Innobase format to MySQL format. */

row_sel_store_mysql_field

大家可以使用GDB设置断点在以上两个函数,就可以清楚的认识到不同字段数据的存储格式了。

常见字段数据格式

Numeric Data Types

INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT

Table:  Required Storage and Range for Integer Types Supported by MySQL

Type

Storage (Bytes)

Minimum Value Signed

Minimum Value Unsigned

Maximum Value Signed

Maximum Value Unsigned

TINYINT

1

-128

0

127

255

SMALLINT

2

-32768

0

32767

65535

MEDIUMINT

3

-8388608

0

8388607

16777215

INT

4

-2147483648

0

2147483647

4294967295

BIGINT

8

-2

0

2-1

2-1

MySQL使用little-endian格式存储integer数据,InnoDB使用big-endian格式,并且符号为是取反处理。InnoDB这样设计存储Integer的好处是在数据比较的时候,可以直接一个一个byte去比较 - memcmp。

举例:BIGINT value 1000

InnoDB format

1000 stored as bigint (8 bytes) in Hex as:

0x800x00 0x00 0x00 0x000x00 0x03 0xe8

-1000 stored as bigint (8 bytes) in Hex as:

0x7f 0xff 0xff 0xff 0xff 0xff 0xfc 0x18

MySQL format:

1000 stored in Hex as:

0xe8    0x03    0x00    0x00    0x00    0x00    0x00    0x00

DECIMAL

这里MySQL和InnoDB存储格式一致,不需要做特别转换。Decimal需要声明precision和scale,例如decimal(30,15)。精度表示值存储的有效位数,小数位数表示小数点后可以存储的位数。

举例:decimal(30,15) value

1000.01 stored (14 bytes) in Hex as:

0x80    0x00    0x00    0x00    0x00    0x03    0xe8    0x00

0x98    0x96    0x80    0x00    0x00    0x00

FLOAT, DOUBLE

FLOAT/DOUBLE类型表示近似数字数据值。这里MySQL和InnoDB存储格式一致,不需要做特别转换。MySQL将四个字节用于单精度值,并将八个字节用于双精度值。单精度FLOAT列存储精度范围是从0到23, 双精度FLOAT列存储精度范围是从24到53。

举例:double

1000.01 stored (8 bytes) in Hex as:

0xae    0x47    0xe1    0x7a    0x14    0x40    0x8f    0x40

Date and Time Data Types

时间相关的存储格式:

Type

Storage as of MySQL 5.6.4

YEAR

1 byte, little endian

DATE

3 bytes, little endian

TIME

3 bytes + fractional-seconds storage, big endian

TIMESTAMP

4 bytes + fractional-seconds storage, big endian

DATETIME

5 bytes + fractional-seconds storage, big endian

TIME encoding for non-fractional part:

1 bit sign (1= non-negative, 0= negative)

1 bit unused (reserved for future extensions)

10 bits hour (0-838)

6 bits minute (0-59)

6 bits second (0-59)

---------------------

24 bits = 3 bytes

DATETIME encoding for non-fractional part:

1 bit sign (1= non-negative, 0= negative)

17 bits year*13+month (year 0-9999, month 0-12)

5 bits day (0-31)

5 bits hour (0-23)

6 bits minute (0-59)

6 bits second (0-59)

---------------------------

40 bits = 5 bytes

举例:

Datetime value: ‘1970-1-1 00:00:00’

innodb data: 0x99    0x02    0xc2    0x00    0x00

Datetime value: ‘2019-12-19 03:14:07’

innodb data: 0x99    0xa4    0xe6    0x33    0x87

查看落盘数据格式

还有其他常用字段大家可以通过前文的方法,自行学习下。在了解了不同字段的存储格式后,我们也可以从InnoDB落盘数据上得到验证。

hexdump -C -v table.ibd > table.txt

找到对应table的数据文件,用hexdump把table数据以hex方式打印到一个文本文件内,然后就可以用编辑器打开浏览。这里可以结合上文中得到的不同字段hex的表示,在文本文件中搜寻。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值