前面介绍了如何去创建一张表,以及如何为表创建索引、指定存储过程、约束等知识点,下面将整理总结一下 MySQL 中表的维护操作:
mysql> CREATE TABLE users (
-> user_id INT AUTO_INCREMENT PRIMARY KEY,
-> username VARCHAR(50) NOT NULL,
-> email VARCHAR(100) NOT NULL,
-> phone VARCHAR(20),
-> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.01 sec)后续操作将在上面的 users 表中进行。
给 users 表添加 age 和 nickname 列,如下:
-- 新增 age 列
mysql> ALTER TABLE users ADD COLUMN age INT AFTER username; -- 添加在 username 的后面
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
-- 新增 nickname 列
mysql> ALTER TABLE users ADD COLUMN nickname VARCHAR(50) FIRST; -- 添加在第一的位置
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table users \G
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`nickname` varchar(50) DEFAULT NULL, -- 这里
`user_id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`age` int DEFAULT NULL, -- 这里
`email` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)修改 users 表的 age 字段的类型和名称,如下:
-- 修改 age 字段类型为 tinyint
mysql> ALTER TABLE users MODIFY COLUMN age TINYINT UNSIGNED;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
-- 将 age 字段修改为 user_age 字段
mysql> ALTER TABLE users CHANGE COLUMN age user_age SMALLINT;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table users \G
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`nickname` varchar(50) DEFAULT NULL,
`user_id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`user_age` tinyint unsigned DEFAULT NULL,
`email` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)删除 users 表中的 nickname 列,如下:
mysql> ALTER TABLE users DROP COLUMN nickname;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table users \G
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`user_id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`user_age` tinyint unsigned DEFAULT NULL,
`email` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)为 users 表的 age 字段添加普通索引,如下:
mysql> ALTER TABLE users ADD INDEX idx_age (user_age);
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0删除 users 表中的 idx_age 索引,如下:
mysql> ALTER TABLE users DROP INDEX idx_age;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0将 users 表改为 user_accounts,如下:
mysql> ALTER TABLE users RENAME TO user_accounts;
Query OK, 0 rows affected (0.01 sec)
-- 再使用 rename table 将名称改回来
mysql> RENAME TABLE user_accounts TO users;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from users;
Empty set (0.00 sec)为了演示,下面将继续使用users表,并且添加两条数据,如下:
mysql> show create table users \G
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`user_id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`user_age` tinyint unsigned DEFAULT NULL,
`email` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
-- 插入数据
mysql> insert users(username,email,phone) values('张三','zhangsan@example.com','1234567890');
Query OK, 1 row affected (0.00 sec)
mysql> insert users(username,email,phone) values('李四','lisi@example.com','0987654321');
Query OK, 1 row affected (0.00 sec)
mysql> select * from users;
+---------+----------+----------+----------------------+------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+----------+----------+----------------------+------------+---------------------+
| 1 | 张三 | NULL | zhangsan@example.com | 1234567890 | 2026-07-10 14:01:59 |
| 2 | 李四 | NULL | lisi@example.com | 0987654321 | 2026-07-10 14:02:04 |
+---------+----------+----------+----------------------+------------+---------------------+
2 rows in set (0.00 sec)方法1:复制表结构(不含数据、不含索引)
-- 复制 users 表为 users_new 新表
mysql> CREATE TABLE users_new LIKE users;
Query OK, 0 rows affected (0.03 sec)
mysql> show create table users_new \G
*************************** 1. row ***************************
Table: users_new
Create Table: CREATE TABLE `users_new` (
`user_id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`user_age` tinyint unsigned DEFAULT NULL,
`email` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql> select * from users_new;
Empty set (0.00 sec)或者
mysql> CREATE TABLE users_empty AS SELECT * FROM users WHERE 1=0;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from users_empty;
Empty set (0.00 sec)方法2:复制表结构和数据(不含索引、约束)
-- 复制 users 的表结构和表数据
mysql> CREATE TABLE users_backup AS SELECT * FROM users;
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from users_backup;
+---------+----------+----------+----------------------+------------+---------------------+
| user_id | username | user_age | email | phone | created_at |
+---------+----------+----------+----------------------+------------+---------------------+
| 1 | 张三 | NULL | zhangsan@example.com | 1234567890 | 2026-07-10 14:01:59 |
| 2 | 李四 | NULL | lisi@example.com | 0987654321 | 2026-07-10 14:02:04 |
+---------+----------+----------+----------------------+------------+---------------------+
2 rows in set (0.00 sec)清空表有两种方式:
(1)DELETE:逐行删除,可回滚,记录日志,慢
mysql> DELETE FROM users;
Query OK, 2 rows affected (0.00 sec)
mysql> select * from users;
Empty set (0.00 sec)(2)TRUNCATE:删除整个表后重建,不可回滚,速度快
mysql> TRUNCATE TABLE users;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from users;
Empty set (0.00 sec)mysql> DESCRIBE users;
+------------+------------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+-------------------+-------------------+
| user_id | int | NO | PRI | NULL | auto_increment |
| username | varchar(50) | NO | | NULL | |
| user_age | tinyint unsigned | YES | | NULL | |
| email | varchar(100) | NO | | NULL | |
| phone | varchar(20) | YES | | NULL | |
| created_at | timestamp | YES | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+------------------+------+-----+-------------------+-------------------+
6 rows in set (0.00 sec)
mysql> SHOW COLUMNS FROM users;
+------------+------------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+-------------------+-------------------+
| user_id | int | NO | PRI | NULL | auto_increment |
| username | varchar(50) | NO | | NULL | |
| user_age | tinyint unsigned | YES | | NULL | |
| email | varchar(100) | NO | | NULL | |
| phone | varchar(20) | YES | | NULL | |
| created_at | timestamp | YES | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
+------------+------------------+------+-----+-------------------+-------------------+
6 rows in set (0.00 sec)mysql> SHOW CREATE TABLE users \G
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`user_id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`user_age` tinyint unsigned DEFAULT NULL,
`email` varchar(100) NOT NULL,
`phone` varchar(20) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)mysql> SHOW TABLE STATUS LIKE 'users' \G
*************************** 1. row ***************************
Name: users
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: 1
Create_time: 2026-07-10 13:57:44
Update_time: NULL
Check_time: NULL
Collation: utf8mb4_0900_ai_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)输出结果字段说明:
Name 表名,这里是 users。
Engine 表使用的存储引擎,本例 InnoDB。
Version 表文件格式版本,InnoDB 一般为 10,内部标识文件存储格式。
Row_format 行存储格式:
Dynamic:动态行,变长字段(VARCHAR/TEXT)溢出会存到溢出页,InnoDB 默认;
Compressed/Redundant/Compact 是其他行格式。
Rows MySQL 估算的总行数,InnoDB 是统计采样估算值,不是精确值;本例 0:表内目前无数据。
Avg_row_length 平均单行占用字节数,无数据时为 0。
Data_length 表数据部分占用字节数。本例 16384 = 16KB,InnoDB 即使空表也会分配最小页面(默认页 16KB)。
Max_data_length 该存储引擎理论支持的最大数据容量,InnoDB 该值无意义,显示 0。
Index_length 所有索引占用总字节数,本例 0 代表本表除主键外无二级索引(主键聚簇索引存在 Data_length 里)。
Data_free 表中空闲碎片空间(字节),大量删除数据后此处会有数值;0 代表无空闲碎片。
Auto_increment 下一条插入的自增 ID,这里是 1,说明从未插入过数据。
Create_time 表创建时间:2026-07-10 13:57:44。
Update_time 表数据最后修改时间,无数据更新则为 NULL。
Check_time 最后一次执行 CHECK TABLE 检查表的时间,未执行过则 NULL。
Collation 表默认字符集排序规则:utf8mb4_0900_ai_ci,支持完整 emoji。
Checksum 是否开启表校验和,NULL = 未开启。
Create_options 建表时附加选项(分区、压缩等),这里为空。
Comment 表注释,当前无注释。
mysql> SELECT
-> table_name,
-> ROUND(data_length/1024/1024, 2) AS data_size_mb,
-> ROUND(index_length/1024/1024, 2) AS index_size_mb,
-> ROUND((data_length+index_length)/1024/1024, 2) AS total_size_mb
-> FROM information_schema.tables
-> WHERE table_schema = 'shop' AND table_name = 'users';
+------------+--------------+---------------+---------------+
| TABLE_NAME | data_size_mb | index_size_mb | total_size_mb |
+------------+--------------+---------------+---------------+
| users | 0.02 | 0.00 | 0.02 |
+------------+--------------+---------------+---------------+
1 row in set (0.00 sec)字段计算说明:
存储单位底层是 Byte(字节)
换算:
/1024 → KB
再 /1024 → MB
ROUND(xxx,2):四舍五入保留 2 位小数
AS data_size_mb:给计算列起别名,方便查看
同理:
index_size_mb:索引总大小(MB)
total_size_mb:数据 + 索引合计大小(MB)
注意,其中 shop 是数据库名称。