数据类型存储要求
磁盘上表数据的存储要求取决于几个因素。不同的存储引擎表示数据类型,并以不同的方式存储原始数据。表数据可能会被压缩,无论是针对列还是整行,都会使表或列的存储需求的计算复杂化。
尽管磁盘上的存储布局有所不同,但内部MySQL API可以通信和交换有关表行的信息,但使用的一致性数据结构适用于所有存储引擎。
本节包含有关MySQL支持的每种数据类型的存储要求的准则和信息,包括使用固定大小表示形式的数据类型的存储引擎的内部格式和大小。信息按类别或存储引擎列出。
表的内部表示形式的最大行大小为65,535字节,即使存储引擎能够支持更大的行也是如此。该图不包括BLOB
或TEXT
列,它们仅贡献9到12个字节。对于BLOB
和TEXT
数据,信息内部存储在与行缓冲区不同的内存区域中。不同的存储引擎根据它们用于处理相应类型的方法,以不同的方式处理此数据的分配和存储。有关更多信息,请参见备用存储引擎,以及“表列数和行大小的限制”。
InnoDB表存储要求
有关表的存储要求的信息,请参见“ InnoDB行格式”InnoDB
。
NDB表存储要求
重要
NDB
表使用 4字节对齐; 所有NDB
数据存储均以 4字节的倍数完成。因此,通常需要15个字节的列值在NDB
表中需要16个字节。例如,在NDB
表中,TINYINT
,SMALLINT
,MEDIUMINT
,和INTEGER
(INT
)列类型均需要每记录4个字节存储由于取向因子。每列占用一些存储空间。尽管单个列不是 4字节对齐的,但每行保留4字节(32位)用于列所需的前1-32位,然后再保留4字节用于位33-64,依此类推。
BIT(M)
M
BIT
NDB
BIT
虽然
NULL
本身本身不需要任何存储空间,但是NDB
如果表定义包含允许NULL
最多32NULL
列的任何列,则每行保留4个字节。(如果定义的NDB群集表包含32NULL
列以上至64NULL
列,则每行保留8个字节。)
每个使用NDB
存储引擎的表都需要一个主键。如果您未定义主键,则由创建“隐藏”主键NDB
。该隐藏的主键每个表记录消耗31-35个字节。
您可以使用ndb_size.pl Perl脚本来估计NDB
存储需求。它连接到当前的MySQL(不是NDB群集)数据库,并创建有关如果使用NDB
存储引擎该数据库需要多少空间的报告。有关更多信息,请参见“ndb_size.pl— NDBCLUSTER大小要求估计器”。
数值类型存储要求
数据类型 | 需要存储 |
---|---|
TINYINT | 1个字节 |
SMALLINT | 2字节 |
MEDIUMINT | 3个字节 |
INT ,INTEGER | 4字节 |
BIGINT | 8字节 |
FLOAT(p) | 如果0 <=p <= 24,则为4个字节;如果25 <=p <= 53 ,则为8个字节 |
FLOAT | 4字节 |
DOUBLE[PRECISION] ,REAL | 8字节 |
DECIMAL(M,D) ,NUMERIC(M,D) | 变化;见下面的讨论 |
BIT(M) | 约(M +7)/ 8字节 |
对值DECIMAL
(和NUMERIC
)列使用二进制格式,包9个十进制(基体10)的数字成四个字节表示。每个值的整数和小数部分的存储分别确定。九位数字的每个倍数需要四个字节,而“剩余”数字则需要四个字节的一部分。下表给出了多余数字的存储要求。
剩余数字 | 字节数 |
---|---|
0 | 0 |
1个 | 1个 |
2 | 1个 |
3 | 2 |
4 | 2 |
5 | 3 |
6 | 3 |
7 | 4 |
8 | 4 |
日期和时间类型存储要求
对于TIME
,DATETIME
和TIMESTAMP
列,在MySQL 5.6.4之前创建的表所需的存储与从5.6.4以后创建的表所需的存储不同。这是由于5.6.4中的更改,允许这些类型具有小数部分,需要0到3个字节。
数据类型 | MySQL 5.6.4之前需要存储 | 从MySQL 5.6.4开始需要存储 |
---|---|---|
YEAR | 1个字节 | 1个字节 |
DATE | 3个字节 | 3个字节 |
TIME | 3个字节 | 3字节 +小数秒存储 |
DATETIME | 8字节 | 5字节 +小数秒存储 |
TIMESTAMP | 4字节 | 4字节 +小数秒存储 |
从MySQL 5.6.4开始,的存储YEAR
和DATE
保持不变。然而TIME
,DATETIME
和TIMESTAMP
以不同方式表示。DATETIME
的打包效率更高,非小数部分需要5个字节,而不是8个字节,并且这三个部分的小数部分都需要0到3个字节,具体取决于存储值的小数秒精度。
分数秒精度 | 需要存储 |
---|---|
0 | 0字节 |
一二 | 1个字节 |
3 4 | 2字节 |
5、6 | 3个字节 |
例如,TIME(0)
,TIME(2)
,TIME(4)
,和TIME(6)
使用3,4,5,和6个字节,分别。TIME
并且TIME(0)
是等效的,并且需要相同的存储空间。
有关时间值的内部表示的详细信息,请参见MySQL内部:重要算法和结构。
字符串类型存储要求
在下表中,M
以字符表示非二进制字符串类型的已声明列长度,以二进制字符串类型表示字节。L
表示给定字符串值的实际长度(以字节为单位)。
数据类型 | 需要存储 |
---|---|
CHAR(M) | 紧凑的InnoDB行格式系列优化了可变长度字符集的存储。请参阅 COMPACT行格式存储特征。否则,M ×w 字节255,其中为字符集中最大长度字符所需的字节数。<=M<= w |
BINARY(M) | M 字节,0 255<=M<= |
VARCHAR(M) ,VARBINARY(M) | L 如果列值需要0到255个字节,则L + 1个字节;如果值可能需要超过255个字节,则 + 2个字节 |
TINYBLOB ,TINYTEXT | L + 1个字节,其中L <2 8 |
BLOB ,TEXT | L + 2个字节,其中L <2 16 |
MEDIUMBLOB ,MEDIUMTEXT | L + 3个字节,其中L <2 24 |
LONGBLOB ,LONGTEXT | L + 4个字节,其中L <2 32 |
ENUM('value1','value2',...) | 1或2个字节,取决于枚举值的数量(最大65,535个值) |
SET('value1','value2',...) | 1、2、3、4或8个字节,具体取决于集合成员的数量(最多64个成员) |
可变长度字符串类型使用长度前缀加数据存储。长度前缀需要一到四个字节,具体取决于数据类型,并且前缀的值是L
(字符串的字节长度)。例如,一个MEDIUMTEXT
值的存储需要L
字节来存储值,再加上三个字节来存储值的长度。
要计算用于存储特定CHAR
,VARCHAR
或TEXT
列值的字节数,必须考虑用于该列的字符集以及该值是否包含多字节字符。特别是在使用utf8
Unicode字符集时,必须记住,并非所有字符都使用相同数量的字节。utf8mb3
和utf8mb4
字符集可能需要每个字符最多三个和四个字节,分别。有关用于不同类别的utf8mb3
或utf8mb4
字符的存储的详细信息,请参见“ Unicode支持”。
VARCHAR
,,VARBINARY
和BLOB
和TEXT
类型是可变长度类型。对于每种存储需求,取决于以下因素:
- 列的实际长度值
- 列的最大可能长度
- 用于列的字符集,因为某些字符集包含多字节字符
例如,一VARCHAR(255)
列可以容纳最大长度为255个字符的字符串。假设该列使用latin1
字符集(每个字符一个字节),则实际需要的存储量是字符串的长度(L
),再加上一个字节来记录字符串的长度。对于字符串'abcd'
,L
为4,存储要求为五个字节。如果改为声明同一列使用ucs2
双字节字符集,则存储要求为10个字节:的长度'abcd'
为8个字节,并且该列需要两个字节来存储长度,因为最大长度大于255(最大510)个字节)。
或列中可以存储的有效最大字节数取决于65535字节的最大行大小,该大小在所有列之间共享。对于存储多字节字符的列,有效最大字符数要少。例如,字符每个字符最多需要四个字节,因此使用该字符集的列可以声明为最多16,383个字符。请参见“数据表的限制”。VARCHAR
VARBINARY
VARCHAR
utf8mb4
VARCHAR
utf8mb4
InnoDB
encodes fixed-length fields greater than or equal to 768 bytes in length as variable-length fields, which can be stored off-page. For example, a CHAR(255)
column can exceed 768 bytes if the maximum byte length of the character set is greater than 3, as it is with utf8mb4
.
NDB
存储引擎支持可变宽度的列。这意味着VARCHAR
NDB群集表中的列所需的存储量与任何其他存储引擎相同,但这些值是4字节对齐的。因此,使用字符集'abcd'
存储在VARCHAR(50)
列中的latin1
字符串需要8个字节(而不是MyISAM
表中相同列值的5个字节)。
TEXT
和BLOB
列在中的实现不同NDB
;列中的每一行TEXT
都由两个独立的部分组成。其中之一具有固定大小(256字节),并且实际上存储在原始表中。另一个包含超过256个字节的任何数据,这些数据存储在隐藏表中。第二个表中的行始终为2000字节长。这意味着,TEXT
如果size
<= 256 size
,则列的大小为256(其中代表行的大小);否则,列的大小为256 。否则,大小为256 +size
(2000×(size
-256)%2000)。
ENUM
对象的大小由不同的枚举值的数量确定。一个字节用于最多255个可能值的枚举。两个字节用于可能值介于256和65,535之间的枚举。请参见“ ENUM类型”。
SET
对象的大小由不同集合成员的数量确定。如果设置的大小为N
,则对象占用字节,四舍五入为1、2、3、4或8个字节。一个最多可以有64个成员。请参见“ SET类型”。(N +7)/8
SET
空间类型存储要求
MySQL使用4个字节存储几何值,以指示SRID,后跟该值的WKB表示。该LENGTH()
函数返回值存储所需的字节空间。
有关WKB和空间值的内部存储格式的描述,请参见“支持的空间数据格式”。
JSON存储要求
通常,JSON
列的存储需求与LONGBLOB
或LONGTEXT
列的存储需求大致相同;也就是说,JSON文档占用的空间与存储在这些类型之一的列中的文档字符串表示形式所使用的空间大致相同。但是,存储在JSON文档中的各个值的二进制编码(包括查找所需的元数据和字典)会产生开销。例如,存储在JSON文档中的字符串需要4到10个字节的额外存储空间,具体取决于字符串的长度以及存储该字符串的对象或数组的大小。
另外,MySQL对JSON
列中存储的任何JSON文档的大小施加了限制,以使其不能大于的值max_allowed_packet
。