#### 15.9.1.2 创建压缩表

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

压缩表可以在[每表文件](glossary.html#glos_file_per_table)表空间或在[通用表空间](glossary.html#glos_general_tablespace).表压缩不适用于 InnoDB[系统表空间](glossary.html#glos_system_tablespace).系统表空间（空间 0，[.ibdata 文件](glossary.html#glos_ibd_file)) 可以包含用户创建的表，但它也包含内部系统数据，这些数据永远不会被压缩。因此，压缩仅适用于存储在 file-per-table 或通用表空间中的表（和索引）。

##### 在 File-Per-Table 表空间中创建压缩表

要在 file-per-table 表空间中创建压缩表，[`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table)必须启用（默认）。您可以在 MySQL 配置文件中设置此参数（`我的.cnf`要么`我的.ini`) 或动态地，使用[`放`](set-variable.html)陈述。

之后[`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table)选项已配置，指定`ROW_FORMAT=压缩`条款或`KEY_BLOCK_SIZE`条款，或两者，在一个[`创建表`](create-table.html)要么[`更改表`](alter-table.html)语句以在 file-per-table 表空间中创建压缩表。

例如，您可以使用以下语句：

```
SET GLOBAL innodb_file_per_table=1;
CREATE TABLE t1
 (c1 INT PRIMARY KEY)
 ROW_FORMAT=COMPRESSED
 KEY_BLOCK_SIZE=8;
```

##### 在通用表空间中创建压缩表

要在通用表空间中创建压缩表，`FILE_BLOCK_SIZE`必须为通用表空间定义，在创建表空间时指定。这`FILE_BLOCK_SIZE`值必须是相对于[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)值和压缩表的页大小，由[`创建表`](create-table.html)要么[`更改表`](alter-table.html) `KEY_BLOCK_SIZE`子句，必须等于`文件块大小/1024`.例如，如果[`innodb_page_size=16384`](innodb-parameters.html#sysvar_innodb_page_size)和`文件块大小=8192`， 这`KEY_BLOCK_SIZE`表的个数必须为 8。有关详细信息，请参阅第 15.6.3.3 节，“通用表空间”[.](general-tablespaces.html)以下示例演示了创建通用表空间和添加压缩表。

该示例假定一个默认值innodb_page_size[`16K。`](innodb-parameters.html#sysvar_innodb_page_size)这`FILE_BLOCK_SIZE`8192 要求压缩表有一个`KEY_BLOCK_SIZE`8。

```
mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB;

mysql> CREATE TABLE t4 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
```

##### 笔记

-   从 MySQL 8.0 开始，压缩表的表空间文件是使用物理页面大小而不是`InnoDB`页面大小，这使得空压缩表的表空间文件的初始大小比以前的 MySQL 版本小。

-   如果您指定`ROW_FORMAT=压缩`, 你可以省略`KEY_BLOCK_SIZE`;这`KEY_BLOCK_SIZE`设置默认为一半[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)价值。

-   如果您指定一个有效的`KEY_BLOCK_SIZE`值，可以省略`ROW_FORMAT=压缩`;压缩是自动启用的。

-   确定最佳价值`KEY_BLOCK_SIZE，`通常，您为此子句创建具有不同值的同一个表的多个副本，然后测量结果的大小`.ibd`文件并查看每个文件在现实中的表现如何[工作量](glossary.html#glos_workload).对于通用表空间，请记住删除表不会减小通用表空间的大小`.ibd`文件，也不会将磁盘空间返回给操作系统。有关详细信息，请参阅[第 15.6.3.3 节，“通用表空间”](general-tablespaces.html).

-   这`KEY_BLOCK_SIZE`value 被视为提示；可以使用不同的尺寸`InnoDB`如有必要。对于 file-per-table 表空间，`KEY_BLOCK_SIZE`只能小于或等于[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)价值。如果您指定的值大于[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)值，指定的值被忽略，发出警告，并且`KEY_BLOCK_SIZE`设置为一半[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)价值。如果`innodb_strict_mode=ON`, 指定一个无效的`KEY_BLOCK_SIZE`值返回错误。对于一般表空间，有效`KEY_BLOCK_SIZE`值取决于`FILE_BLOCK_SIZE`表空间的设置。有关详细信息，请参阅[第 15.6.3.3 节，“通用表空间”](general-tablespaces.html).

-   `InnoDB`支持 32KB 和 64KB 页面大小，但这些页面大小不支持压缩。有关详细信息，请参阅[`innodb_page_size`](innodb-parameters.html#sysvar_innodb_page_size)文档。

-   默认未压缩大小`InnoDB`数据[页面](glossary.html#glos_page)为 16KB。根据选项值的组合，MySQL 为表空间数据文件使用 1KB、2KB、4KB、8KB 或 16KB 的页面大小（`.ibd`文件）。实际的压缩算法不受`KEY_BLOCK_SIZE`价值;该值决定了每个压缩块有多大，这反过来又会影响可以将多少行打包到每个压缩页面中。

-   在 file-per-table 表空间中创建压缩表时，设置`KEY_BLOCK_SIZE`等于`InnoDB` [页面大小](glossary.html#glos_page_size)通常不会导致太大的压缩。例如，设置`KEY_BLOCK_SIZE=16`通常不会导致太大的压缩，因为正常`InnoDB`页面大小为 16KB。此设置对于具有许多长的表可能仍然有用[`斑点`](blob.html),[`VARCHAR`](char.html)要么[`文本`](blob.html)列，因为这样的值通常可以很好地压缩，因此可能需要更少的[溢出页面](glossary.html#glos_overflow_page)如中所述[第 15.9.1.5 节，“InnoDB 表的压缩如何工作”](innodb-compression-internals.html).对于一般表空间，一个`KEY_BLOCK_SIZE`值等于`InnoDB`页面大小是不允许的。有关详细信息，请参阅[第 15.6.3.3 节，“通用表空间”](general-tablespaces.html).

-   表的所​​有索引（包括[聚集索引](glossary.html#glos_clustered_index)) 使用相同的页面大小进行压缩，如`创建表`要么`更改表`陈述。表属性如`ROW_FORMAT`和`KEY_BLOCK_SIZE`不属于`创建索引`语法`InnoDB`表，如果它们被指定则被忽略（尽管，如果指定，它们会出现在[`显示创建表`](show-create-table.html)陈述）。

-   有关性能相关的配置选项，请参阅[第 15.9.1.3 节，“调整 InnoDB 表的压缩”](innodb-compression-tuning.html).

##### 压缩表的限制

-   压缩表不能存储在`InnoDB`系统表空间。

-   通用表空间可以包含多个表，但压缩表和未压缩表不能在同一个通用表空间中共存。

-   压缩适用于整个表及其所有关联索引，而不适用于单个行，尽管有子句名称`ROW_FORMAT`.

-   `InnoDB`不支持压缩临时表。什么时候[`innodb_strict_mode`](innodb-parameters.html#sysvar_innodb_strict_mode)已启用（默认），[`创建临时表`](create-table.html)如果返回错误`ROW_FORMAT=压缩`要么`KEY_BLOCK_SIZE`被指定。如果[`innodb_strict_mode`](innodb-parameters.html#sysvar_innodb_strict_mode)被禁用，发出警告并使用非压缩行格式创建临时表。同样的限制适用于[`更改表`](alter-table.html)对临时表的操作。
