
在 MySQL 中为已存在的表新增列(字段),主要使用
ALTER TABLE 语句。这是一个非常常见的操作,但也需要谨慎,尤其是在生产环境中。
最核心的语法结构如下:
ALTER TABLE table_name
ADD COLUMN column_name data_type [column_constraints];
-
ALTER TABLE table_name: 指定要修改的表名。
-
ADD COLUMN: 关键字,用于添加新列。COLUMN 关键字是可选的,ADD column_name 也可以。
-
column_name: 你想要添加的新列的名称。
-
data_type: 新列的数据类型,例如 INT, VARCHAR(255), DATETIME 等。
-
[column_constraints]: 可选的列约束,如 NOT NULL, DEFAULT 'value', UNIQUE, COMMENT '注释' 等。
假设我们有一个 students 表,初始结构如下:
+----+----------+-----+
| id | name | age |
+----+----------+-----+
| 1 | Alice | 20 |
| 2 | Bob | 22 |
+----+----------+-----+
为 students 表添加一个 email 列,类型为 VARCHAR,长度为 100。
ALTER TABLE students
ADD COLUMN email VARCHAR(100);
执行后,students 表结构变为:
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int | NO | PRI | NULL | |
| name | varchar(255) | YES | | NULL | |
| age | int | YES | | NULL | |
| email | varchar(100) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
注意:新添加的列会默认允许为 NULL,并且所有现有行的该列值都会是 NULL。
为 students 表添加一个 status 列,类型为 TINYINT,并设置默认值为 1(代表 “激活” 状态)。
ALTER TABLE students
ADD COLUMN status TINYINT DEFAULT 1;
执行后,所有现有行的 status 列都会被自动设置为 1。
重要:如果你要添加一个 NOT NULL 约束的列,必须为它提供一个 DEFAULT 值。否则,MySQL 不知道该如何填充已存在行的这个新列,操作会失败。
为 students 表添加一个 created_at 列,类型为 DATETIME,不允许为空,并设置默认值为当前时间戳。
ALTER TABLE students
ADD COLUMN created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;
这里 CURRENT_TIMESTAMP 是一个函数,会自动获取当前的日期和时间。
默认情况下,新列会添加到表的最后。你可以使用 FIRST 或 AFTER 关键字来控制新列的位置。
你可以在一个 ALTER TABLE 语句中同时添加多个列,用逗号隔开。
ALTER TABLE students
ADD COLUMN address VARCHAR(255),
ADD COLUMN phone VARCHAR(20) NOT NULL DEFAULT 'unknown';
-
性能影响:在非常大的表上执行 ALTER TABLE 可能会非常慢,并且在操作期间可能会锁定表,导致应用无法读写数据。对于大表,建议使用在线 schema 变更工具,如 Percona Toolkit 的 pt-online-schema-change 或 GitHub 的 gh-ost。
-
NOT NULL 约束:如上所述,为已有数据的表添加 NOT NULL 列时,必须提供 DEFAULT 值。
-
数据类型选择:为新列选择合适的数据类型和长度,这关系到存储空间和查询性能。例如,能用 INT 就不要用 BIGINT,能用 VARCHAR(50) 就不要用 VARCHAR(255)。
-
在线环境:在生产环境中执行此操作前,务必:
-
在测试环境中充分测试。
-
评估对应用的影响,并选择在业务低峰期执行。
-
(如果可能)备份数据库。