创建与操纵表
CREATE TABLE / 数据类型 / 约束 / ALTER TABLE / DROP TABLE
前面一直在用现成的 users 和 orders 表。这一章学怎么自己建表、改结构、删表。
CREATE TABLE:建表
基本语法
还是从熟悉的 users 表看起:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age INT,
city VARCHAR(50),
salary DECIMAL(8,2)
);一行一行看:
CREATE TABLE users— 表名叫 usersid INT AUTO_INCREMENT PRIMARY KEY— 整数,自增,主键name VARCHAR(20) NOT NULL— 最长 20 个字符,不能为空age INT— 整数,可以为 NULLcity VARCHAR(50)— 最长 50 个字符salary DECIMAL(8,2)— 总共 8 位,小数点后 2 位(如 123456.78)
命名规则
- 表名和列名用小写字母 + 下划线:
user_orders、created_at - 名字要让人一眼看懂:
u不如users,od不如order_date - 同一个库里表名不能重复
- 避免用 MySQL 关键字当表名(比如
order、group、select)
数据类型速查
不需要背全部,记住最常用的几个就行:
| 类型 | 用途 | 示例 |
|---|---|---|
INT | 整数 | age INT |
DECIMAL(M,D) | 精确小数(钱) | salary DECIMAL(10,2) |
VARCHAR(N) | 变长字符串 | name VARCHAR(50) |
CHAR(N) | 定长字符串 | code CHAR(6) |
TEXT | 长文本 | content TEXT |
DATE | 日期 | birth_date DATE |
DATETIME | 日期+时间 | created_at DATETIME |
BOOLEAN | 布尔(实为 TINYINT) | is_active BOOLEAN |
VARCHAR vs CHAR
-- VARCHAR:存多少占多少(有弹性)
name VARCHAR(50); -- 存 '张三' 只占 2 个字符空间
-- CHAR:固定长度,不够就补空格
code CHAR(6); -- 存 'ABC' 实际存 'ABC '💡 一般用 VARCHAR 就行。CHAR 适合长度固定的数据(如身份证号、邮政编码)。
DECIMAL:存钱专用
salary DECIMAL(8,2); -- 最大 999999.99
price DECIMAL(10,2); -- 最大 99999999.99钱一定用 DECIMAL,别用 FLOAT/DOUBLE。浮点数有精度误差,0.1 + 0.2 可能不等于 0.3,算账时差一分钱都麻烦。
约束:让数据不乱来
约束是建表时定下的规矩,防止脏数据。
NOT NULL:不能为空
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL, -- 必填
email VARCHAR(50) -- 可选
);DEFAULT:默认值
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
product VARCHAR(50) NOT NULL,
quantity INT DEFAULT 1, -- 不填就是 1
order_date DATE DEFAULT (CURDATE()) -- 不填就是今天
);插入时不写这些列,自动用默认值:
INSERT INTO orders (product) VALUES ('鼠标');
-- quantity = 1, order_date = 当天日期UNIQUE:不能重复
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
email VARCHAR(50) UNIQUE, -- 所有人 email 不能一样
phone VARCHAR(20) UNIQUE -- 手机号也不能重复
);插重复 email 会报错 Duplicate entry。但 NULL 不受限制——可以有多行的 UNIQUE 列为 NULL。
PRIMARY KEY:主键
id INT AUTO_INCREMENT PRIMARY KEY主键 = NOT NULL + UNIQUE,一张表只能有一个主键。
每个表都应该有主键——它是每一行数据的"身份证号"。以后更新、删除、关联查询都靠它精确定位。
FOREIGN KEY:外键
外键保证两张表之间的数据引用关系不乱:
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
product VARCHAR(50),
FOREIGN KEY (user_id) REFERENCES users(id)
);效果:
- 插入 orders 时,
user_id必须在 users 表中存在 - 删除 users 中某一行时,如果 orders 里有引用,MySQL 会阻止删除
-- 如果 users 里没有 id=99,这会报错
INSERT INTO orders (user_id, product) VALUES (99, '鼠标');
-- ERROR: Cannot add or update a child row: a foreign key constraint fails💡 外键约束能防"幽灵数据"(引用了不存在的行),但也会影响性能。实际项目中有时在建表时声明外键但不开启约束,改用应用层校验。
ALTER TABLE:改表结构
表建好了想改结构?用 ALTER。
加列
ALTER TABLE users
ADD phone VARCHAR(20) AFTER name;AFTER name 指定加在 name 列后面,不加这句默认加在最后。
改列
-- 把 name 的长度从 VARCHAR(20) 改成 VARCHAR(50)
ALTER TABLE users
MODIFY name VARCHAR(50) NOT NULL;⚠️
MODIFY必须把列定义写全,包括 NOT NULL 等约束——少写了约束就丢了。
删列
ALTER TABLE users
DROP COLUMN phone;列里的数据也一起没了,确认再操作。
重命名列
ALTER TABLE users
CHANGE phone telephone VARCHAR(20);CHANGE 同时改列名和定义。只改列名不改定义,写法也一样。
DROP TABLE:删表
DROP TABLE users_backup;整张表连同数据一起消失。没有回收站,没有后悔药。
🚨 删表前先
SHOW TABLES;确认表名,再SELECT COUNT(*) FROM xxx;确认数据量,双重保险。
安全版:有就删,没有就算了
DROP TABLE IF EXISTS temp_data;表不存在也不会报错,适合写脚本清理临时表。
RENAME TABLE:重命名
RENAME TABLE users TO employees;一口气改多张表:
RENAME TABLE
users TO employees,
orders TO employee_orders;动手前的好习惯
-- 1. 看现有表结构
DESC users;
-- 2. 看建表语句(完整的,含约束和默认值)
SHOW CREATE TABLE users;
-- 3. 想清楚改什么、影响哪些数据,再动手小结
从用别人的表到自己建表——这是从"查询工"到"数据库管理者"的跨越:
- CREATE TABLE — 表名、列名、类型、约束,一个都不能少
- 数据类型选对很重要 —
INT存整数、VARCHAR存字符串、DECIMAL存精确金额 - 约束是数据的守门员 —
NOT NULL不让空、DEFAULT给默认值、PRIMARY KEY唯一标识 - ALTER TABLE 改结构 — ADD 加列、MODIFY 改类型、DROP 删列
- DROP / RENAME TABLE — 删表不可逆,重命名前确认谁在用
💡 建表之前先在纸上画出列名和类型,想清楚每列的约束再动手。表结构一旦上线就不好大改了。
自主练习
- 新建一张
products表,包含 id、name(NOT NULL)、price DECIMAL(8,2)、stock INT(DEFAULT 0) - 给
products表加一列category VARCHAR(20) - 把
products的stock列默认值改成 10 - 建一张
orders_backup表(结构参考 orders),然后DROP掉 - 用
SHOW CREATE TABLE users看看完整的建表语句长什么样