1. 动手前先备好一张能折腾的业务表
聊 MySQL 表数据查询之前,我建议你先别急着看语法,先把“实验环境”搭起来。我见过太多新手对着文档背了一堆 SELECT 的写法,结果一开 Navicat 连建表都磕磕绊绊。MySQL 这东西,你光看不练是真学不会,尤其是表结构设计、字段管理、多表关联这些操作,必须在真实的数据上折腾一遍才能形成肌肉记忆。
1.1 环境准备:Docker 五分钟拉起一个 MySQL 8.0
如果你电脑上还没有 MySQL 环境,我最推荐的方式是用 Docker 起一个临时实例。别一上来就去官网下载安装包,Windows 上装 MySQL 8.0 的过程中什么 Configuration of MySQL Server is taking、安装启动服务报错、端口被占用 这些问题,能把你一晚上的热情全磨没。Docker 就不一样,一条命令解决战斗:
bash复制docker run --name mysql-demo \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=root123456 \
-e MYSQL_DATABASE=shop_demo \
-d mysql:8.0
解释一下我为什么选 8.0 而不是 5.7:8.0 之后窗口函数、公共表表达式(CTE)、JSON 操作这些都完善了,后面我要讲的高级查询功能,5.7 要么不支持、要么用起来很别扭。如果你在公司还在维护 5.7 的老项目,也不亏,基础语法都是一套的。
拉起来之后连接测试一下:
bash复制docker exec -it mysql-demo mysql -uroot -proot123456
能看到 mysql> 提示符就说明环境 OK 了。如果你更习惯图形化工具,Navicat 或者 MySQL Workbench 都行。个人建议新手用 Workbench,免费、官方出、还自带 ER 图功能,后面你想把表导出成关系图也方便。Navicat 功能确实更强,但那个授权问题你得自己处理好。
提示:本地 3306 端口如果被占了,把
-p 3306:3306改成-p 3307:3306,后面连接时端口改成 3307 就行。
1.2 设计一张有业务代入感的订单表
很多教程建表都是 student、course、score 这类教学表,不是不行,但离真实业务太远。我这次直接用电商订单场景,做一张 orders 订单表加一张 users 用户表,后面讲查询、分组、关联、开窗函数全都围绕这套数据展开,你学完拿去面试或者做项目,思路是能直接迁移的。
sql复制USE shop_demo;
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
nickname VARCHAR(50) DEFAULT '' COMMENT '昵称',
age TINYINT UNSIGNED DEFAULT 0 COMMENT '年龄',
city VARCHAR(50) DEFAULT '' COMMENT '所在城市',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '订单ID',
user_id INT NOT NULL COMMENT '下单用户ID',
order_no VARCHAR(32) NOT NULL UNIQUE COMMENT '订单编号',
status TINYINT NOT NULL DEFAULT 0 COMMENT '订单状态:0-待付款 1-已付款 2-已发货 3-已完成 4-已取消',
total_amount DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '订单金额',
pay_time DATETIME DEFAULT NULL COMMENT '支付时间',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '下单时间',
KEY idx_user_id (user_id),
KEY idx_status (status),
KEY idx_created_at (created_at),
CONSTRAINT fk_orders_user FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
这个表结构我在字段类型上做了一些刻意选择,后面讲字段管理会具体说。先插入测试数据:
sql复制INSERT INTO users (username, nickname, age, city) VALUES
('zhangsan', '张三', 25, '北京'),
('lisi', '李四', 30, '上海'),
('wangwu', '王五', 28, '广州'),
('zhaoliu', '赵六', 22, '深圳'),
('sunqi', '孙七', 35, '北京'),
('zhouba', '周八', 27, NULL);
INSERT INTO orders (user_id, order_no, status, total_amount, pay_time, created_at) VALUES
(1, 'ORD202401010001', 3, 199.00, '2024-01-01 10:00:00', '2024-01-01 09:55:00'),
(1, 'ORD202401020002', 1, 59.90, '2024-01-02 14:20:00', '2024-01-02 14:15:00'),
(2, 'ORD202401030003', 3, 399.00, '2024-01-03 08:30:00', '2024-01-03 08:00:00'),
(2, 'ORD202401030004', 4, 89.00, NULL, '2024-01-03 11:00:00'),
(3, 'ORD202401040005', 2, 1299.00, '2024-01-04 16:40:00', '2024-01-04 16:20:00'),
(3, 'ORD202401050006', 0, 49.00, NULL, '2024-01-05 09:10:00'),
(4, 'ORD202401060007', 3, 2680.00, '2024-01-06 20:00:00', '2024-01-06 19:30:00'),
(5, 'ORD202401070008', 3, 158.00, '2024-01-07 12:00:00', '2024-01-07 11:45:00'),
(5, 'ORD202401080009', 2, 799.00, '2024-01-08 15:30:00', '2024-01-08 15:00:00'),
(6, 'ORD202401090010', 1, 329.00, '2024-01-09 18:25:00', '2024-01-09 18:20:00');
这套数据里我故意埋了几个坑:有用户没有城市(NULL),有订单还没有支付时间,有用户没有下单记录,有订单被取消。这些边界情况在实际业务里天天遇到,后面查询的时候你就知道为什么要留这些数据了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 字段管理:ALTER TABLE 不只是“加一列”那么简单
先给新手吃颗定心丸:MySQL 的字段操作无非就是增、删、改、查四种,语法不复杂,但踩坑的点特别多。我接过不少“接手半年后出问题”的案例,最后都定位到早期建表时字段设计不合理、后期硬改导致的。所以这一章不只是教命令,还讲什么时候该用哪个命令。
2.1 ALTER TABLE 四件套:ADD、MODIFY、CHANGE、DROP
先看最基础的增删改:
sql复制-- 新增字段:给 users 表加一个 vip_level 字段
ALTER TABLE users ADD COLUMN vip_level TINYINT NOT NULL DEFAULT 0 COMMENT '会员等级:0-普通 1-黄金 2-铂金 3-钻石';
-- 修改字段类型:把 nickname 从 50 扩到 100
ALTER TABLE users MODIFY COLUMN nickname VARCHAR(100) NOT NULL DEFAULT '' COMMENT '昵称';
-- 修改字段名和定义:把 vip_level 改名为 member_level,类型也改了
ALTER TABLE users CHANGE COLUMN vip_level member_level TINYINT NOT NULL DEFAULT 1 COMMENT '会员等级';
-- 删除字段:把 member_level 删掉
ALTER TABLE users DROP COLUMN member_level;
这里有一个新手最常见的困惑:MODIFY 和 CHANGE 到底什么区别?
MODIFY 只能改字段的数据类型、默认值、注释这些“属性”,改完字段名不变。CHANGE 可以重命名字段,同
