### 13.1.36 RENAME TABLE 语句

[](<>)

```
RENAME TABLE
    tbl_name TO new_tbl_name
    [, tbl_name2 TO new_tbl_name2] ...
```

[`重命名表`](rename-table.html)重命名一个或多个表。你必须有[`改变`](privileges-provided.html#priv_alter)和[`降低`](privileges-provided.html#priv_drop)原始表的权限，以及[`创建`](privileges-provided.html#priv_create)和[`插入`](privileges-provided.html#priv_insert)新表的权限。

例如，要重命名一个名为`旧表`到`新表`, 使用这个语句：

```
RENAME TABLE old_table TO new_table;
```

该语句等效于以下语句[`更改表`](alter-table.html)陈述：

```
ALTER TABLE old_table RENAME new_table;
```

`重命名表`, 不像[`更改表`](alter-table.html)，可以在单个语句中重命名多个表：

```
RENAME TABLE old_table1 TO new_table1,
             old_table2 TO new_table2,
             old_table3 TO new_table3;
```

重命名操作从左到右执行。因此，要交换两个表名，请执行此操作（假设具有中间名的表`tmp_table`尚不存在）：

```
RENAME TABLE old_table TO tmp_table,
             new_table TO old_table,
             tmp_table TO new_table;
```

表上的元数据锁是按名称顺序获取的，在某些情况下，当多个事务同时执行时，这会影响操作结果。看[第 8.11.4 节，“元数据锁定”](metadata-locking.html).

从 MySQL 8.0.13 开始，您可以重命名使用[`锁定表`](lock-tables.html)声明，前提是它们被锁定`写`锁定或者是重命名的产物`写`- 多表重命名操作中较早步骤中的锁定表。例如，这是允许的：

```
LOCK TABLE old_table1 WRITE;
RENAME TABLE old_table1 TO new_table1,
             new_table1 TO new_table2;
```

这是不允许的：

```
LOCK TABLE old_table1 READ;
RENAME TABLE old_table1 TO new_table1,
             new_table1 TO new_table2;
```

在 MySQL 8.0.13 之前，执行`重命名表`, 不能有被锁定的表`锁定表`.

在满足事务表锁定条件的情况下，原子地进行重命名操作；在重命名过程中，没有其他会话可以访问任何表。

如果在一个过程中发生任何错误`重命名表`，该语句失败并且没有进行任何更改。

您可以使用`重命名表`将表从一个数据库移动到另一个：

```
RENAME TABLE current_db.tbl_name TO other_db.tbl_name;
```

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

使用这种方法将所有表从一个数据库移动到另一个数据库实际上会重命名数据库（MySQL 没有单一语句的操作），除了原始数据库继续存在，尽管没有表。

喜欢`重命名表`,`更改表...重命名`也可用于将表移动到不同的数据库。无论使用何种语句，如果重命名操作会将表移动到位于不同文件系统上的数据库，则结果的成功是特定于平台的，并且取决于用于移动表文件的底层操作系统调用。

如果表有触发器，则尝试将表重命名为不同的数据库会失败，触发器在错误的架构中 ([`ER_TRG_IN_WRONG_SCHEMA`](https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html#error_er_trg_in_wrong_schema)） 错误。

未加密的表可以移动到启用加密的数据库中，反之亦然。但是，如果[`table_encryption_privilege_check`](server-system-variables.html#sysvar_table_encryption_privilege_check)变量启用时，[`TABLE_ENCRYPTION_ADMIN`](privileges-provided.html#priv_table-encryption-admin)如果表加密设置与默认数据库加密不同，则需要特权。

[](<>)

重命名`暂时的`表，`重命名表`不起作用。采用[`更改表`](alter-table.html)反而。

`重命名表`适用于视图，但不能将视图重命名为不同的数据库。

专门为重命名的表或视图授予的任何特权都不会迁移到新名称。它们必须手动更改。

`重命名表 *`tbl_name`* 到 *`new_tbl_name`*`更改内部生成的外键约束名称和用户定义的以字符串“开头的外键约束名称”*`tbl_name`*\_ibfk\_”来反映新的表名。`InnoDB`解释以字符串“”开头的外键约束名称*`tbl_name`*\_ibfk\_” 作为内部生成的名称。

除非存在冲突，否则指向重命名表的外键约束名称会自动更新，在这种情况下，语句将失败并出现错误。如果重命名的约束名称已经存在，则会发生冲突。在这种情况下，您必须删除并重新创建外键才能使其正常运行。

[](<>)

`重命名表 *`tbl_name`* 到 *`new_tbl_name`*`内部生成和用户定义的更改`查看`以字符串“”开头的约束名称*`tbl_name`*\_查克\_”来反映新的表名。MySQL 解释`查看`以字符串“”开头的约束名称*`tbl_name`*\_查克\_” 作为内部生成的名称。例子：

```
mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `i1` int(11) DEFAULT NULL,
  `i2` int(11) DEFAULT NULL,
  CONSTRAINT `t1_chk_1` CHECK ((`i1` > 0)),
  CONSTRAINT `t1_chk_2` CHECK ((`i2` < 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.02 sec)

mysql> RENAME TABLE t1 TO t3;
Query OK, 0 rows affected (0.03 sec)

mysql> SHOW CREATE TABLE t3\G
*************************** 1. row ***************************
       Table: t3
Create Table: CREATE TABLE `t3` (
  `i1` int(11) DEFAULT NULL,
  `i2` int(11) DEFAULT NULL,
  CONSTRAINT `t3_chk_1` CHECK ((`i1` > 0)),
  CONSTRAINT `t3_chk_2` CHECK ((`i2` < 0))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)
```
