#### 15.6.1.2 外部创建表

创作的原因多种多样`InnoDB`外部表格；也就是说，在数据目录之外创建表。例如，这些原因可能包括空间管理、I/O 优化或将表放置在具有特定性能或容量特征的存储设备上。

`InnoDB`支持以下外部建表方式：

-   [使用数据目录子句](innodb-create-table-external.html#innodb-create-table-external-data-directory)

-   [使用 CREATE TABLE ... TABLESPACE 语法](innodb-create-table-external.html#innodb-create-table-external-tablespace-syntax)

-   [在外部通用表空间中创建表](innodb-create-table-external.html#innodb-create-table-external-tablespace)

##### 使用数据目录子句

您可以创建一个`InnoDB`通过指定一个外部目录中的表`数据目录`条款中的`创建表`陈述。

```
CREATE TABLE t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/external/directory';
```

这`数据目录`在 file-per-table 表空间中创建的表支持子句。表是在 file-per-table 表空间中隐式创建的，当[`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table)变量已启用，默认情况下是启用的。

```
mysql> SELECT @@innodb_file_per_table;
+-------------------------+
| @@innodb_file_per_table |
+-------------------------+
|                       1 |
+-------------------------+
```

有关 file-per-table 表空间的更多信息，请参阅[第 15.6.3.2 节，“File-Per-Table 表空间”](innodb-file-per-table-tablespaces.html).

当您指定一个`数据目录`a中的子句`创建表`语句，表的数据文件（`*`表名`*.ibd`) 在指定目录下的架构目录中创建。

从 MySQL 8.0.21 开始，在数据目录之外创建的表和表分区使用`数据目录`子句仅限于已知的目录`InnoDB`.此要求允许数据库管理员控制创建表空间数据文件的位置并确保在恢复期间可以找到数据文件（请参阅[崩溃恢复期间的表空间发现](innodb-recovery.html#innodb-recovery-tablespace-discovery)）。已知目录是由[`数据目录`](server-system-variables.html#sysvar_datadir),[`innodb_data_home_dir`](innodb-parameters.html#sysvar_innodb_data_home_dir)， 和[`innodb_directories`](innodb-parameters.html#sysvar_innodb_directories)变量。您可以使用以下语句检查这些设置：

```
mysql> SELECT @@datadir,@@innodb_data_home_dir,@@innodb_directories;
```

如果您要使用的目录未知，请将其添加到[`innodb_directories`](innodb-parameters.html#sysvar_innodb_directories)在创建表之前进行设置。这[`innodb_directories`](innodb-parameters.html#sysvar_innodb_directories)变量是只读的。配置它需要重新启动服务器。有关设置系统变量的一般信息，请参阅[第 5.1.9 节，“使用系统变量”](using-system-variables.html).

以下示例演示了使用`数据目录`条款。假设[`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table)变量已启用并且该目录已知`InnoDB`.

```
mysql> USE test;
Database changed

mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/external/directory';

# MySQL creates the table's data file in a schema directory
# under the external directory

$> cd /external/directory/test
$> ls
t1.ibd
```

###### 使用说明：

-   MySQL 最初保持表空间数据文件处于打开状态，从而阻止您卸载设备，但如果服务器繁忙，最终可能会关闭该文件。注意不要在 MySQL 运行时意外卸载外部设备，或者在设备断开连接时启动 MySQL。在缺少关联的数据文件时尝试访问表会导致需要重新启动服务器的严重错误。

    如果在预期路径中找不到数据文件，则服务器重新启动可能会失败。在这种情况下，您可以从备份中恢复表空间数据文件或删除表以从[数据字典](glossary.html#glos_data_dictionary).

-   在将表放置在 NFS 挂载的卷上之前，请查看中列出的潜在问题[将 NFS 与 MySQL 一起使用](disk-issues.html#disk-issues-nfs).

-   如果使用 LVM 快照、文件副本或其他基于文件的机制来备份表的数据文件，请始终使用[`冲洗表...用于出口`](flush.html#flush-tables-for-export-with-list)首先声明以确保内存中缓冲的所有更改[酡](glossary.html#glos_flush)在备份发生之前到磁盘。

-   使用`数据目录`在外部目录中创建表的子句是使用的替代方法[符号链接](symbolic-links.html)， 哪一个`InnoDB`不支持。

-   这`数据目录`在源和副本位于同一主机上的复制环境中不支持子句。这`数据目录`子句需要完整的目录路径。在这种情况下复制路径将导致源和副本在同一位置创建表。

-   从 MySQL 8.0.21 开始，在 file-per-table 表空间中创建的表不能再在 undo 表空间目录中创建 ([`innodb_undo_directory`](innodb-parameters.html#sysvar_innodb_undo_directory)) 除非直接知道`InnoDB`.已知目录是由[`数据目录`](server-system-variables.html#sysvar_datadir),[`innodb_data_home_dir`](innodb-parameters.html#sysvar_innodb_data_home_dir)， 和[`innodb_directories`](innodb-parameters.html#sysvar_innodb_directories)变量。

##### 使用 CREATE TABLE ... TABLESPACE 语法

[`创建表...表空间`](create-table.html)语法可以与`数据目录`子句在外部目录中创建表。为此，请指定`innodb_file_per_table`作为表空间名称。

```
mysql> CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE = innodb_file_per_table
       DATA DIRECTORY = '/external/directory';
```

此方法仅支持在 file-per-table 表空间中创建的表，但不需要[`innodb_file_per_table`](innodb-parameters.html#sysvar_innodb_file_per_table)要启用的变量。在所有其他方面，这种方法等同于`创建表...数据目录`上述方法。适用相同的使用说明。

##### 在外部通用表空间中创建表

您可以在驻留在外部目录中的通用表空间中创建表。

-   有关在外部目录中创建通用表空间的信息，请参阅[创建通用表空间](general-tablespaces.html#general-tablespaces-creating).

-   有关在通用表空间中创建表的信息，请参阅[将表添加到通用表空间](general-tablespaces.html#general-tablespaces-adding-tables).
