## 11.7 数据类型存储要求

[](<>)[](<>)

-   [InnoDB 表存储要求](storage-requirements.html#data-types-storage-reqs-innodb)

-   [NDB 表存储要求](storage-requirements.html#data-types-storage-reqs-ndb)

-   [数字类型存储要求](storage-requirements.html#data-types-storage-reqs-numeric)

-   [日期和时间类型存储要求](storage-requirements.html#data-types-storage-reqs-date-time)

-   [字符串类型存储要求](storage-requirements.html#data-types-storage-reqs-strings)

-   [空间类型存储要求](storage-requirements.html#data-types-storage-reqs-gis)

-   [JSON 存储要求](storage-requirements.html#data-types-storage-reqs-json)

    磁盘上表数据的存储要求取决于几个因素。不同的存储引擎表示数据类型和存储原始数据的方式不同。表数据可能会针对一列或整行进行压缩，从而使表或列的存储要求的计算变得复杂。

    尽管磁盘上的存储布局存在差异，但用于通信和交换有关表行信息的内部 MySQL API 使用适用于所有存储引擎的一致数据结构。

    本节包括 MySQL 支持的每种数据类型的存储要求的指南和信息，包括使用固定大小表示的数据类型的存储引擎的内部格式和大小。信息按类别或存储引擎列出。

[](<>)

表的内部表示最大行大小为 65,535 字节，即使存储引擎能够支持更大的行。这个数字不包括[`斑点`](blob.html)要么[`文本`](blob.html)列，仅占此大小的 9 到 12 个字节。为了[`斑点`](blob.html)和[`文本`](blob.html)数据，信息在内部存储在与行缓冲区不同的内存区域中。不同的存储引擎根据它们用于处理相应类型的方法，以不同的方式处理这些数据的分配和存储。有关详细信息，请参阅[第 16 章，*替代存储引擎*](storage-engines.html)， 和[第 8.4.7 节，“表列数和行大小的限制”](column-count-limit.html).

### InnoDB 表存储要求

[](<>)[](<>)

看[第 15.10 节，“InnoDB 行格式”](innodb-row-format.html)有关存储要求的信息`InnoDB`表。

### NDB 表存储要求

[](<>)[](<>)

重要的

[`新开发银行`](mysql-cluster.html)表格使用 4 字节对齐；全部[`新开发银行`](mysql-cluster.html)数据存储以 4 字节的倍数进行。因此，通常占用 15 个字节的列值需要 16 个字节[`新开发银行`](mysql-cluster.html)桌子。例如，在[`新开发银行`](mysql-cluster.html)表[`小音`](integer-types.html),[`小灵通`](integer-types.html),[`中型`](integer-types.html)， 和[`整数`](integer-types.html)([`INT`](integer-types.html)) 列类型由于对齐因素，每条记录需要 4 个字节的存储空间。

每个`少量（*`米`*)`列需要*`米`*位的存储空间。虽然是个人[`少量`](bit-type.html)列是*不是*4字节对齐，[`新开发银行`](mysql-cluster.html)每行保留 4 个字节（32 位）用于所需的前 1-32 位`少量`列，然后是位 33-64 的另外 4 个字节，依此类推。

虽然一个`空值`本身不需要任何存储空间，[`新开发银行`](mysql-cluster.html)如果表定义包含任何允许的列，则每行保留 4 个字节`空值`, 最多 32`空值`列。（如果 NDB Cluster 表定义了超过 32`空值`最多 64 列`空值`列，然后每行保留 8 个字节。）

每个表使用[`新开发银行`](mysql-cluster.html)存储引擎需要一个主键；如果您没有定义主键，则会创建一个“隐藏的”主键[`新开发银行`](mysql-cluster.html).这个隐藏的主键每条表记录消耗 31-35 个字节。

[](<>)

您可以使用[**数据库\_大小.pl**](mysql-cluster-programs-ndb-size-pl.html)Perl 脚本估计[`新开发银行`](mysql-cluster.html)存储要求。它连接到当前的 MySQL（不是 NDB Cluster）数据库，并创建一个关于该数据库在使用[`新开发银行`](mysql-cluster.html)存储引擎。看[第 23.5.28 节，“ndb_size.pl — NDBCLUSTER 大小需求估计器”](mysql-cluster-programs-ndb-size-pl.html)了解更多信息。

### 数字类型存储要求

[](<>)[](<>)

| 数据类型 | 需要存储 |
| ---- | ---- |
| [`小音`](integer-types.html) | 1 个字节 |
| [`小灵通`](integer-types.html) | 2 个字节 |
| [`中型`](integer-types.html) | 3 个字节 |
| [`INT`](integer-types.html),[`整数`](integer-types.html) | 4字节 |
| [`大整数`](integer-types.html) | 8 个字节 |
| `漂浮（*`p`*)` | 如果 0 \\\<= 则为 4 个字节*`p`*\\\<= 24，如果 25 \\\<= 则为 8 个字节*`p`*\\\<= 53 |
| [`漂浮`](floating-point-types.html) | 4字节 |
| `双[精度]`,[`真实的`](floating-point-types.html) | 8 个字节 |
| `十进制（*`米`*,*`D`*)`,`数字（*`米`*,*`D`*)` | 变化;见以下讨论 |
| `少量（*`米`*)` | 大约 （*`米`*+7)/8 字节 |

价值观[`十进制`](fixed-point-types.html)（和[`数字`](fixed-point-types.html)) 列使用二进制格式表示，该格式将九个十进制（以 10 为基数）数字打包成四个字节。每个值的整数和小数部分的存储分别确定。每个九位数字的倍数需要四个字节，而“剩余”数字需要四个字节的一部分。下表给出了多余数字所需的存储空间。

| 剩余数字 | 字节数 |
| ---- | --- |
| 0 | 0 |
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
| 5 | 3 |
| 6 | 3 |
| 7 | 4 |
| 8 | 4 |

### 日期和时间类型存储要求

[](<>)[](<>)[](<>)[](<>)

为了[`时间`](time.html),[`约会时间`](datetime.html)， 和[`时间戳`](datetime.html)列，在 MySQL 5.6.4 之前创建的表所需的存储与从 5.6.4 开始创建的表不同。这是由于 5.6.4 中的更改允许这些类型具有小数部分，这需要 0 到 3 个字节。

| 数据类型 | MySQL 5.6.4 之前需要存储 | MySQL 5.6.4 所需的存储空间 |
| ---- | ------------------ | ------------------- |
| [`年`](year.html) | 1 个字节 | 1 个字节 |
| [`日期`](datetime.html) | 3 个字节 | 3 个字节 |
| [`时间`](time.html) | 3 个字节 | 3 字节 + 小数秒存储 |
| [`约会时间`](datetime.html) | 8 个字节 | 5 字节 + 小数秒存储 |
| [`时间戳`](datetime.html) | 4字节 | 4 字节 + 小数秒存储 |

从 MySQL 5.6.4 开始，存储[`年`](year.html)和[`日期`](datetime.html)保持不变。然而，[`时间`](time.html),[`约会时间`](datetime.html)， 和[`时间戳`](datetime.html)有不同的表示。[`约会时间`](datetime.html)更有效地打包，非小数部分需要 5 个字节而不是 8 个字节，并且所有三个部分都有一个小数部分，需要 0 到 3 个字节，具体取决于存储值的小数秒精度。

| 小数秒精度 | 需要存储 |
| ----- | ---- |
| 0 | 0 字节 |
| 1, 2 | 1 个字节 |
| 3、4 | 2 个字节 |
| 5、6 | 3 个字节 |

例如，[`时间(0)`](time.html), [`时间(2)`](time.html), [`时间(4)`](time.html)， 和[`时间(6)`](time.html)分别使用 3、4、5 和 6 个字节。[`时间`](time.html)和[`时间(0)`](time.html)是等效的并且需要相同的存储空间。

有关时间值的内部表示的详细信息，请参阅[MySQL 内部结构：重要的算法和结构](https://dev.mysql.com/doc/internals/en/algorithms.html).

### 字符串类型存储要求

[](<>)[](<>)

在下表中，*`米`*表示非二进制字符串类型的声明列长度和二进制字符串类型的字节。*`大号`*表示给定字符串值的实际长度（以字节为单位）。

| 数据类型 | 需要存储 |
| ---- | ---- |
| `字符（*`米`*)` | 紧凑的 InnoDB 行格式系列优化了可变长度字符集的存储。看[COMPACT 行格式存储特性](innodb-row-format.html#innodb-compact-row-format-characteristics).否则，*`米`*×*`w`*字节，`<= *`米`* <=`255，在哪里*`w`*是字符集中最大长度字符所需的字节数。 |
| `二进制（*`米`*)` | *`米`*字节，0`<= *`米`* <=` 255 |
| `VARCHAR(*`米`*)`, `变量（*`米`*)` | *`大号`*+ 1 个字节，如果列值需要 0 - 255 个字节，*`大号`*+ 2 个字节，如果值可能需要超过 255 个字节 |
| [`小斑点`](blob.html), [`小文本`](blob.html) | *`大号`*+ 1 个字节，其中*`大号`* \\\< 2<sup>8</sup> |
| [`斑点`](blob.html), [`文本`](blob.html) | *`大号`*+ 2 个字节，其中*`大号`* \\\< 2<sup>16</sup> |
| [`中块`](blob.html), [`中文本`](blob.html) | *`大号`*+ 3 个字节，其中*`大号`* \\\< 2<sup>24</sup> |
| [`长块`](blob.html), [`长文`](blob.html) | *`大号`*+ 4 个字节，其中*`大号`* \\\< 2<sup>32</sup> |
| `枚举（'*`价值1`*','*`价值2`*',...)` | 1 或 2 个字节，取决于枚举值的数量（最多 65,535 个值） |
| `放（'*`价值1`*','*`价值2`*',...)` | 1、2、3、4 或 8 个字节，取决于集合成员的数量（最多 64 个成员） |

可变长度字符串类型使用长度前缀加数据存储。长度前缀根据数据类型需要一到四个字节，前缀的值为*`大号`*（字符串的字节长度）。例如，存储一个[`中文本`](blob.html)价值要求*`大号`*字节存储值加上三个字节存储值的长度。

计算用于存储特定的字节数[`字符`](char.html),[`VARCHAR`](char.html)， 要么[`文本`](blob.html)列值，您必须考虑用于该列的字符集以及该值是否包含多字节字符。特别是，当使用`utf8`Unicode 字符集，您必须记住，并非所有字符都使用相同的字节数。`utf8mb3`和`utf8mb4`字符集每个字符最多分别需要三个和四个字节。对于用于不同类别的存储的细分`utf8mb3`要么`utf8mb4`字符，见[第 10.9 节，“Unicode 支持”](charset-unicode.html).

[](<>)[](<>)[](<>)

[`VARCHAR`](char.html),[`变量`](binary-varbinary.html), 和[`斑点`](blob.html)和[`文本`](blob.html)类型是可变长度类型。对于每个，存储要求取决于以下因素：

-   列值的实际长度

-   列的最大可能长度

-   列使用的字符集，因为有些字符集包含多字节字符

    例如，一个`VARCHAR(255)`column 可以保存最大长度为 255 个字符的字符串。假设该列使用`拉丁语1`字符集（每个字符一个字节），实际需要的存储是字符串的长度（*`大号`*)，加上一个字节来记录字符串的长度。对于字符串`'A B C D'`,*`大号`*为 4，存储要求为 5 个字节。如果同一列被声明为使用`ucs2`双字节字符集，存储要求为10字节：长度`'A B C D'`是 8 个字节，并且该列需要两个字节来存储长度，因为最大长度大于 255（最多 510 个字节）。

    有效最大数量*字节*可以存储在一个[`VARCHAR`](char.html)要么[`变量`](binary-varbinary.html)列的最大行大小为 65,535 字节，由所有列共享。为一个[`VARCHAR`](char.html)存储多字节字符的列，有效的最大数量*人物*少。例如，`utf8mb4`每个字符最多需要四个字节，所以一个[`VARCHAR`](char.html)使用的列`utf8mb4`字符集最多可以声明为 16,383 个字符。看[第 8.4.7 节，“表列数和行大小的限制”](column-count-limit.html).

`InnoDB`将长度大于或等于 768 字节的固定长度字段编码为可变长度字段，可以在页外存储。例如，一个`字符(255)`如果字符集的最大字节长度大于 3，则列可以超过 768 个字节，因为它与`utf8mb4`.

这[`新开发银行`](mysql-cluster.html)存储引擎支持可变宽度列。这意味着一个[`VARCHAR`](char.html)NDB Cluster 表中的列需要与任何其他存储引擎相同的存储量，但这些值是 4 字节对齐的。因此，字符串`'A B C D'`存储在一个`VARCHAR(50)`列使用`拉丁语1`字符集需要 8 个字节（而不是 5 个字节用于同一列值）`MyISAM`桌子）。

[`文本`](blob.html),[`斑点`](blob.html)， 和[`JSON`](json.html)列在[`新开发银行`](mysql-cluster.html)存储引擎，其中列中的每一行由两个独立的部分组成。其中之一是固定大小（256 字节`文本`和`斑点`, 4000 字节`JSON`)，并且实际上存储在原始表中。另一个包含超过 256 字节的任何数据，这些数据存储在隐藏的 blob 部分表中。第二个表中的行大小由列的确切类型决定，如下表所示：

| 类型 | 斑点零件尺寸 |
| --- | ------ |
| [`斑点`](blob.html),[`文本`](blob.html) | 2000 |
| [`中块`](blob.html),[`中文本`](blob.html) | 4000 |
| [`长块`](blob.html),[`长文`](blob.html) | 13948 |
| [`JSON`](json.html) | 8100 |

这意味着一个大小[`文本`](blob.html)如果列是 256*`尺寸`*\\\<= 256（其中*`尺寸`*表示行的大小）；否则，大小为 256 +*`尺寸`*+ (2000 × (*`尺寸`*− 256) % 2000)。

没有 blob 部分被单独存储`新开发银行`为了`小斑点`要么`小文本`列值。

你可以增加一个`新开发银行`blob 列的 blob 部分最大为 13948 使用`NDB_COLUMN`创建或更改父表时在列注释中。在 NDB 8.0.30 及更高版本中，还可以为`文本`,`斑点`， 要么`JSON`列，使用`NDB_TABLE`在列评论中。看[新开发银行\_列选项](create-table-ndb-comment-options.html#create-table-ndb-comment-column-options)， 了解更多信息。

[](<>)

一个大小[`枚举`](enum.html)对象由不同枚举值的数量决定。一个字节用于最多包含 255 个可能值的枚举。两个字节用于具有 256 到 65,535 个可能值的枚举。看[第 11.3.5 节，“ENUM 类型”](enum.html).

[](<>)

一个大小[`放`](set.html)对象由不同集合成员的数量决定。如果设置的大小是*`ñ`*, 对象占据`(*`ñ`*+7)/8`字节，四舍五入为 1、2、3、4 或 8 个字节。一种[`放`](set.html)最多可以有 64 个成员。看[第 11.3.6 节，“SET 类型”](set.html).

### 空间类型存储要求

[](<>)[](<>)[](<>)

MySQL 使用 4 个字节存储几何值以指示 SRID，后跟该值的 WKB 表示。这[`长度（）`](string-functions.html#function_length)函数返回值存储所需的空间（以字节为单位）。

有关 WKB 和空间值的内部存储格式的说明，请参阅[第 11.4.3 节，“支持的空间数据格式”](gis-data-formats.html).

### JSON 存储要求

一般来说，存储需求[`JSON`](json.html)列与 a 的列大致相同`长块`要么`长文`柱子;也就是说，JSON 文档占用的空间与存储在其中一种类型的列中的文档字符串表示所占用的空间大致相同。但是，存储在 JSON 文档中的各个值的二进制编码（包括查找所需的元数据和字典）会产生开销。例如，存储在 JSON 文档中的字符串需要 4 到 10 个字节的额外存储空间，具体取决于字符串的长度以及存储它的对象或数组的大小。

此外，MySQL 对存储在`JSON`列，使其不能大于[`max_allowed_pa​​cket`](server-system-variables.html#sysvar_max_allowed_packet).
