我们依次系统性、详细地解答你的问题,适合初学者深入理解 MySQL 的查询与建模知识。
概念:
聚合函数(Aggregate Function)用于对一组数据执行计算,返回单个结果。常见于统计、汇总分析中。
常见聚合函数:
函数名 | 作用 |
---|---|
COUNT() |
统计记录数量 |
SUM() |
求总和 |
AVG() |
求平均值 |
MAX() |
求最大值 |
MIN() |
求最小值 |
GROUP_CONCAT() |
把一组值拼接成字符串(常用于分组后显示所有同组内容) |
关键字 | 作用 |
---|---|
FROM |
指定查询的数据表或子查询源 |
JOIN |
用于多表连接,如:INNER JOIN 、LEFT JOIN 等 |
WHERE |
过滤记录(在分组前执行) |
GROUP BY |
按字段分组,常与聚合函数一起使用 |
ORDER BY |
排序,可指定升序(ASC)或降序(DESC) |
HAVING |
对分组后的结果过滤(如:HAVING COUNT(*) > 1 ) |
SELECT |
指定查询哪些字段或表达式 |
DISTINCT |
去重,返回唯一值组合 |
LIMIT |
限制返回记录数,例如 LIMIT 10 |
概念:
窗口函数(Window Function)对查询结果中的每一行计算值,但不像聚合函数那样“合并”行。
常见函数:
ROW_NUMBER()
:分组内行号RANK()
、DENSE_RANK()
:分组内排名SUM() OVER()
:累计求和AVG() OVER()
:移动平均使用场景:
类型 | 说明 |
---|---|
内连接(INNER JOIN) | 仅返回两个表中匹配的记录 |
左连接(LEFT JOIN) | 返回左表所有记录,即使右表无匹配也保留 |
右连接(RIGHT JOIN) | 返回右表所有记录,即使左表无匹配也保留 |
全连接(FULL JOIN) | 返回左右表所有记录,MySQL 不支持,需要用 UNION 模拟 |
子查询(Subquery):
一个查询语句嵌套在另一个查询语句中。
用途:
WHERE
条件(如:id IN (SELECT ...)
)FROM
)SELECT (SELECT COUNT(*) FROM ...)
)关系 | 表设计方式 |
---|---|
一对一 | 在任一表加唯一外键 |
多对一 | “多”的一方表中加外键指向“一”的一方 |
多对多 | 引入中间表,包含两个外键(各指向一方) |
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学生ID',
name VARCHAR(50) COMMENT '姓名',
gender ENUM('男','女') COMMENT '性别'
);
CREATE TABLE student_register (
register_id INT PRIMARY KEY COMMENT '学籍号(主键)',
student_id INT UNIQUE COMMENT '学生ID(唯一外键)',
FOREIGN KEY (student_id) REFERENCES student(id)
);
register_id
是学籍号student_id
是唯一外键,确保一对一关系CREATE TABLE class (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '班级ID',
class_name VARCHAR(50) COMMENT '班级名'
);
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学生ID',
name VARCHAR(50),
class_id INT COMMENT '班级ID(外键)',
FOREIGN KEY (class_id) REFERENCES class(id)
);
CREATE TABLE teacher (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '教师ID',
name VARCHAR(50)
);
CREATE TABLE student_teacher (
student_id INT,
teacher_id INT,
PRIMARY KEY (student_id, teacher_id),
FOREIGN KEY (student_id) REFERENCES student(id),
FOREIGN KEY (teacher_id) REFERENCES teacher(id)
);
student_teacher
表示多对多关系。一对一:
任选其一,但要加上 UNIQUE
保证一对一。推荐把“次要”信息表加外键指向主表。
多对一:
外键放在“多”的一方,因为多个学生对应一个班级,就让学生表加外键 class_id
。
理由:
外键表示“我从属谁”,由“多”的一方维护指向“一”的一方的约束。
FOREIGN KEY (...) REFERENCES ... ON DELETE ... ON UPDATE ...
操作 | 说明 |
---|---|
CASCADE |
删除或更新父表记录时,子表记录也随之删除或更新 |
SET NULL |
删除或更新父表记录时,子表对应字段设为 NULL |
RESTRICT |
如果子表有引用,不允许删除或更新父表记录 |
NO ACTION |
与 RESTRICT 类似,标准语法但效果一样 |
SET DEFAULT |
MySQL 不支持 |
定义:
用于建立多对多关系的中间桥梁表,包含两张主表的外键。
用途示例:
student_teacher
user_role
product_tag
基本实体:
student
course
enrollment
-- 学生表
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '学生ID',
name VARCHAR(50) COMMENT '学生姓名'
);
-- 课程表
CREATE TABLE course (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '课程ID',
name VARCHAR(100) COMMENT '课程名称',
teacher VARCHAR(50) COMMENT '任课老师'
);
-- 选课记录(中间表)
CREATE TABLE enrollment (
student_id INT COMMENT '学生ID',
course_id INT COMMENT '课程ID',
score DECIMAL(5,2) DEFAULT NULL COMMENT '成绩(可选)',
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES student(id),
FOREIGN KEY (course_id) REFERENCES course(id)
);
每行说明:
student.id
/ course.id
是主键,唯一标识学生和课程enrollment
是中间表,建立学生与课程的多对多关系score
可选字段,用于存成绩