在数据库中,表是存储和组织数据的核心载体。掌握表的创建、修改、删除等操作,是数据库开发和管理的基础技能。本文将基于 MySQL 数据库环境(不同数据库,SQL 语句有稍微差异),详细讲解表的创建、修改和删除等操作方法。
创建表的核心语句是 CREATE TABLE,其基本语法结构为:
CREATE TABLE [IF NOT EXISTS] 表名 ( 列名1 数据类型 [约束条件], 列名2 数据类型 [约束条件], ... [表级约束条件] ) [ENGINE=存储引擎] [DEFAULT CHARSET=字符集];
详细说明:
IF NOT EXISTS:可选,避免创建已存在的表时抛出错误。
数据类型:如 INT(整数)、VARCHAR(n)(可变长度字符串)、DATE(日期)等。
约束条件:如 PRIMARY KEY(主键)、UNIQUE(唯一)、NOT NULL(非空)等。
存储引擎:常用 InnoDB(支持事务、外键),默认值通常为 InnoDB。
字符集:常用 utf8mb4(兼容 emoji,全面支持 UTF-8)。
示例:创建一个存储用户信息的 users 表,然后插入一条数据到该数据表
-- 如果 users 表不存在,则创建 users 表
> CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY AUTO_INCREMENT, -- 主键,自增
username VARCHAR(50) NOT NULL, -- 用户名,非空
age INT, -- 年龄,允许空
create_time DATETIME -- 创建时间
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
0 row(s) modified.
-- 向 users 中插入一条数据
> INSERT INTO users(username, age, create_time) VALUES ('Tom', 28, now())
1 row(s) modified.
-- 查询 users 表中的数据
> SELECT * FROM users
id|username|age|create_time |
--+--------+---+-------------------+
1|Tom | 28|2026-01-06 02:29:13|
1 row(s) fetched.NULL 表示 “无值” 或 “未知值”,与空字符串('')、0 有本质区别。在创建表时,若未显式指定 NOT NULL,列默认允许存储 NULL。
示例:允许 age 为 NULL(未填写年龄时):
> CREATE TABLE IF NOT EXISTS users ( id INT PRIMARY KEY AUTO_INCREMENT, -- 主键,自增 username VARCHAR(50) NOT NULL, -- 用户名,非空 age INT, -- 年龄,允许空 create_time DATETIME -- 创建时间 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 0 row(s) modified.
插入包含 NULL 值的数据:
-- 手动设置 age 的值为 NULL
> INSERT INTO users(username, age, create_time) VALUES ('Tom', NULL, now())
1 row(s) modified.
-- 查询数据验证
> SELECT * FROM users
id|username|age|create_time |
--+--------+---+-------------------+
1|Tom | |2026-01-06 02:34:43|
1 row(s) fetched.注意:NULL 值参与计算时结果仍为 NULL,统计时需用 COUNT(列名) 而非 COUNT(*),因为 COUNT(*) 会包含 NULL 值。
例如:统计拥有年龄信息的用户数量
-- 错误:直接使用 * 进行统计,即使 age 为 NULL,也会被统计到 > SELECT COUNT(*) FROM users COUNT(*)| --------+ 1| 1 row(s) fetched. -- 正确:直接指定列名,仅仅统计 age 列 > SELECT COUNT(age) FROM users COUNT(age)| ----------+ 0| 1 row(s) fetched.
默认值(DEFAULT)用于当插入数据时未指定该列值时,自动填充预设值,避免手动输入重复值。语法格式如下:
列名 数据类型 DEFAULT 默认值
示例:创建 orders 表,指定 status 列默认值为 1(表示未支付),create_time 列默认值为当前时间
> CREATE TABLE IF NOT EXISTS orders ( id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(30) NOT NULL, status INT DEFAULT 1, -- 默认值1 create_time DATETIME DEFAULT CURRENT_TIMESTAMP -- 默认当前时间 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 0 row(s) modified.
插入数据时不指定 status 和 create_time,自动使用默认值:
-- 插入后 status=1,create_time=执行SQL的当前时间
> INSERT INTO orders (order_no) VALUES ('ORD20260105001')
1 row(s) modified.
-- 查询插入结果
> SELECT * FROM orders
id|order_no |status|create_time |
--+--------------+------+-------------------+
1|ORD20260105001| 1|2026-01-06 02:54:50|
1 row(s) fetched.
当表创建后,若需要调整列结构(如新增列、修改列类型、删除列),需使用 ALTER TABLE 语句,下面将分别介绍新增列、修改列等。
特别注意:操作 ALTER TABLE 一定要格外小心!改动前务必做好表的完整备份(既要备份表结构,也要备份数据)。因为表结构的修改没法撤销:多增加了不需要的列,可能删不掉;要是误删了重要列,列里的所有数据就都没了。
语法格式如下:
ALTER TABLE 表名 ADD [COLUMN] 列名 数据类型 [约束条件] [FIRST|AFTER 已有列];
示例:给 users 表新增 email 列(非空,放在 username 后):
-- 添加字段 email > ALTER TABLE users ADD COLUMN email VARCHAR(100) NOT NULL AFTER username 0 row(s) modified. -- 使用 mysql 客户端查看 users 数据表的结构 mysql> show create table users \G *************************** 1. row *************************** Table: users Create Table: CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `email` varchar(100) NOT NULL, `age` int DEFAULT NULL, `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
语法格式如下:
ALTER TABLE 表名 MODIFY [COLUMN] 列名 新数据类型 [新约束条件];
示例:将 users 表的 age 列类型改为 TINYINT,并添加默认值 18:
-- 修改 age 字段 > ALTER TABLE users MODIFY COLUMN age TINYINT DEFAULT 18 1 row(s) modified. -- 使用 mysql 客户端查看 users 数据表的结构 mysql> show create table users \G *************************** 1. row *************************** Table: users Create Table: CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `email` varchar(100) NOT NULL, `age` tinyint DEFAULT '18', `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
语法格式如下:
ALTER TABLE 表名 DROP [COLUMN] 列名;
示例:删除 users 表的 create_time 列:
-- 删除 create_time 列 > ALTER TABLE users DROP COLUMN create_time 0 row(s) modified. -- 使用 mysql 客户端查看 users 数据表的结构 mysql> show create table users \G *************************** 1. row *************************** Table: users Create Table: CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `email` varchar(100) NOT NULL, `age` tinyint DEFAULT '18', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
语法格式如下:
ALTER TABLE 表名 CHANGE [COLUMN] 旧列名 新列名 数据类型 [约束条件];
示例:将 users 表的 username 列改为 user_name:
-- 重命名 username 列 > ALTER TABLE users CHANGE COLUMN username user_name VARCHAR(50) NOT NULL 0 row(s) modified. -- 使用 mysql 客户端查看 users 数据表的结构 mysql> show create table users \G *************************** 1. row *************************** Table: users Create Table: CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, `user_name` varchar(50) NOT NULL, `email` varchar(100) NOT NULL, `age` tinyint DEFAULT '18', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 1 row in set (0.00 sec)
注意:修改表结构会锁表(InnoDB 在 MySQL 8.0 后优化了锁机制),生产环境需避开高峰期操作;修改列类型可能导致数据丢失(如字符串改整数),需提前备份。
删除表会彻底移除表结构和所有数据,且无法撤销,操作需谨慎。语法如下:
DROP TABLE [IF EXISTS] 表名;
详细说明:
IF EXISTS:可选,避免删除不存在的表时抛出错误。
示例:删除 orders 表:
-- 删除 orders 表 > DROP TABLE IF EXISTS orders 0 row(s) modified. -- 查看所有表,orders 表已经被删除 > show tables Tables_in_sql_demo| ------------------+ order | order_product | product | product_category | user | user_backup | user_bak | user_copy | user_copy2 | users | 10 row(s) fetched.
补充:若需仅清空表数据(保留表结构),使用 TRUNCATE TABLE 表名;,效率比 DELETE 更高(不记录日志),但同样不可回滚。
重命名表可通过 RENAME TABLE 或 ALTER TABLE 实现,推荐使用 RENAME TABLE(更简洁)。
语法如下:
RENAME TABLE 旧表名 TO 新表名;
示例:将 users 表重命名为 user_info:
-- 重命名表 > RENAME TABLE users TO user_info 0 row(s) modified. -- 查看所有表名,验证结果 > show tables Tables_in_sql_demo| ------------------+ order | order_product | product | product_category | user | user_backup | user_bak | user_copy | user_copy2 | user_info | 10 row(s) fetched.
语法如下:
ALTER TABLE 旧表名 RENAME [TO] 新表名;
示例:
-- 重命名表 > ALTER TABLE user_info RENAME TO users 0 row(s) modified. -- 查看所有表名,验证结果 > show tables Tables_in_sql_demo| ------------------+ order | order_product | product | product_category | user | user_backup | user_bak | user_copy | user_copy2 | users | 10 row(s) fetched.
注意:重命名表后,基于该表的视图、存储过程等会失效,需同步修改。