文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  ALTER TABLE 示例

15.1.9.3 ALTER TABLE 示例

从如下所示创建的表 t1 开始

CREATE TABLE t1 (a INTEGER, b CHAR(10));

要将表名从 t1 重命名为 t2

ALTER TABLE t1 RENAME t2;

要将列 aINTEGER 更改为 TINYINT NOT NULL(名称保持不变),并将列 bCHAR(10) 更改为 CHAR(20),并将其从 b 重命名为 c

ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);

要添加一个名为 d 的新 TIMESTAMP

ALTER TABLE t2 ADD d TIMESTAMP;

要在列 d 上添加索引,并在列 a 上添加 UNIQUE 索引

ALTER TABLE t2 ADD INDEX (d), ADD UNIQUE (a);

要删除列 c

ALTER TABLE t2 DROP COLUMN c;

要添加一个名为 c 的新 AUTO_INCREMENT 整数列

ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
  ADD PRIMARY KEY (c);

我们将 c 索引为 PRIMARY KEY,因为 AUTO_INCREMENT 列必须被索引,并且我们将 c 声明为 NOT NULL,因为主键列不能为 NULL

对于 NDB 表,还可以更改用于表或列的存储类型。例如,考虑如下所示创建的 NDB

mysql> CREATE TABLE t1 (c1 INT) TABLESPACE ts_1 ENGINE NDB;
Query OK, 0 rows affected (1.27 sec)

要将此表转换为基于磁盘的存储,可以使用以下 ALTER TABLE 语句

mysql> ALTER TABLE t1 TABLESPACE ts_1 STORAGE DISK;
Query OK, 0 rows affected (2.99 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `c1` int(11) DEFAULT NULL
) /*!50100 TABLESPACE ts_1 STORAGE DISK */
ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)

表空间在最初创建表时不一定要被引用;但是,表空间必须由 ALTER TABLE 引用

mysql> CREATE TABLE t2 (c1 INT) ts_1 ENGINE NDB;
Query OK, 0 rows affected (1.00 sec)

mysql> ALTER TABLE t2 STORAGE DISK;
ERROR 1005 (HY000): Can't create table 'c.#sql-1750_3' (errno: 140)
mysql> ALTER TABLE t2 TABLESPACE ts_1 STORAGE DISK;
Query OK, 0 rows affected (3.42 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t2` (
  `c1` int(11) DEFAULT NULL
) /*!50100 TABLESPACE ts_1 STORAGE DISK */
ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.01 sec)

要更改单个列的存储类型,可以使用 ALTER TABLE ... MODIFY [COLUMN]。例如,假设您使用以下 CREATE TABLE 语句创建了一个具有两列的 NDB Cluster Disk Data 表

mysql> CREATE TABLE t3 (c1 INT, c2 INT)
    ->     TABLESPACE ts_1 STORAGE DISK ENGINE NDB;
Query OK, 0 rows affected (1.34 sec)

要将 c2 列从基于磁盘的存储更改为内存存储,请在 ALTER TABLE 语句使用的列定义中包含 STORAGE MEMORY 子句,如下所示

mysql> ALTER TABLE t3 MODIFY c2 INT STORAGE MEMORY;
Query OK, 0 rows affected (3.14 sec)
Records: 0  Duplicates: 0  Warnings: 0

您可以使用类似的方式,通过在 STORAGE DISK 中指定,将内存列转换为基于磁盘的列。

c1 使用基于磁盘的存储,因为这是表的默认值(由 CREATE TABLE 语句中的表级 STORAGE DISK 子句确定)。但是,列 c2 使用内存存储,这可以从 SHOW CREATE TABLE 的输出中看到

mysql> SHOW CREATE TABLE t3\G
*************************** 1. row ***************************
       Table: t3
Create Table: CREATE TABLE `t3` (
  `c1` int(11) DEFAULT NULL,
  `c2` int(11) /*!50120 STORAGE MEMORY */ DEFAULT NULL
) /*!50100 TABLESPACE ts_1 STORAGE DISK */ ENGINE=ndbcluster DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.02 sec)

添加 AUTO_INCREMENT 列时,列值会自动填充序列号。对于 MyISAM 表,您可以在执行 ALTER TABLE 之前执行 SET INSERT_ID= 来设置第一个序列号,或者使用 AUTO_INCREMENT= 表选项。

对于 MyISAM 表,如果不更改 AUTO_INCREMENT 列,则序列号不受影响。如果删除一个 AUTO_INCREMENT 列,然后添加另一个 AUTO_INCREMENT 列,则序列号将从 1 开始重新排序。

使用复制时,向表中添加 AUTO_INCREMENT 列可能不会在副本和源上生成相同的行排序。这是因为对行进行编号的顺序取决于用于表的特定存储引擎以及插入行的顺序。如果在源和副本上具有相同的顺序很重要,则必须在分配 AUTO_INCREMENT 编号之前对行进行排序。假设您要向表 t1 添加一个 AUTO_INCREMENT 列,以下语句将生成一个与 t1 相同的新表 t2,但带有一个 AUTO_INCREMENT

CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY)
SELECT * FROM t1 ORDER BY col1, col2;

这假设表 t1 具有列 col1col2

这组语句还会生成一个与 t1 相同的新表 t2,并添加了一个 AUTO_INCREMENT

CREATE TABLE t2 LIKE t1;
ALTER TABLE t2 ADD id INT AUTO_INCREMENT PRIMARY KEY;
INSERT INTO t2 SELECT * FROM t1 ORDER BY col1, col2;
重要

为了保证源和副本上的顺序相同,所有 t1 的列都必须在 ORDER BY 子句中被引用。

无论使用哪种方法创建和填充具有 AUTO_INCREMENT 列的副本,最后一步都是删除原始表,然后重命名副本

DROP TABLE t1;
ALTER TABLE t2 RENAME t1;