下面我将为您完整地构建一个学生课程数据库,包括:
- 数据库设计目标
- 核心实体与关系分析
- 数据表结构设计
- 表关系图 (E-R 图)
- 创建表的 SQL 代码
- 示例数据
- 常用查询示例
数据库设计目标
这个数据库旨在高效、准确地存储和管理学生、课程、教师以及他们之间的选课、授课等信息,主要目标包括:

- 记录学生的基本信息。
- 记录课程的基本信息和描述。
- 记录教师的基本信息。
- 记录学生选修了哪些课程,以及成绩。
- 记录教师教授了哪些课程。
- 支持常见的查询,如“查找某个学生的所有课程和成绩”、“查找某门课的所有学生及平均分”等。
核心实体与关系分析
在设计数据库时,我们首先要识别出核心的“事物”(实体)以及它们之间的关系。
-
实体:
- 学生: 代表数据库中的每一位学生。
- 课程: 代表学校开设的每一门课程。
- 教师: 代表学校聘请的每一位教师。
-
关系:
- 学生 与 课程: 一个学生可以选修多门课程,一门课程也可以被多个学生选修,这是一个 多对多 关系。
- 教师 与 课程: 一个教师可以教授多门课程,一门课程也可以由多个教师教授(同一门课在不同学期由不同老师上),这也是一个 多对多 关系。
为了解决这些“多对多”关系,我们需要引入 关联表:

- 选课记录: 用于连接“学生”和“课程”,记录每个学生选了哪门课,以及具体成绩。
- 授课记录: 用于连接“教师”和“课程”,记录哪个教师教授了哪门课。
数据表结构设计
基于以上分析,我们设计以下五个数据表:
a. students (学生表)
存储学生的基本信息。
| 字段名 | 数据类型 | 约束 | 描述 |
|---|---|---|---|
student_id |
INT |
PRIMARY KEY, AUTO_INCREMENT |
学生ID,唯一标识 |
student_name |
VARCHAR(50) |
NOT NULL |
学生姓名 |
gender |
CHAR(1) |
性别 (M/F 或 其他) | |
birth_date |
DATE |
出生日期 | |
enrollment_date |
DATE |
NOT NULL |
入学日期 |
major |
VARCHAR(100) |
所学专业 |
b. teachers (教师表)
存储教师的基本信息。
| 字段名 | 数据类型 | 约束 | 描述 |
|---|---|---|---|
teacher_id |
INT |
PRIMARY KEY, AUTO_INCREMENT |
教师ID,唯一标识 |
teacher_name |
VARCHAR(50) |
NOT NULL |
教师姓名 |
gender |
CHAR(1) |
性别 | |
department |
VARCHAR(100) |
所属院系 | |
email |
VARCHAR(100) |
UNIQUE |
电子邮箱,唯一 |
c. courses (课程表)
存储课程的基本信息。
| 字段名 | 数据类型 | 约束 | 描述 |
|---|---|---|---|
course_id |
INT |
PRIMARY KEY, AUTO_INCREMENT |
课程ID,唯一标识 |
course_name |
VARCHAR(100) |
NOT NULL |
课程名称 |
credits |
INT |
NOT NULL |
学分 |
description |
TEXT |
课程描述 |
d. enrollments (选课记录表)
关联学生和课程,记录选课和成绩信息。
| 字段名 | 数据类型 | 约束 | 描述 |
|---|---|---|---|
enrollment_id |
INT |
PRIMARY KEY, AUTO_INCREMENT |
选课记录ID |
student_id |
INT |
FOREIGN KEY -> students(student_id) |
关联学生ID |
course_id |
INT |
FOREIGN KEY -> courses(course_id) |
关联课程ID |
semester |
VARCHAR(20) |
NOT NULL |
学期 ( '2025-Fall') |
grade |
DECIMAL(5, 2) |
成绩 ( 95.50) | |
enrollment_date |
TIMESTAMP |
DEFAULT CURRENT_TIMESTAMP |
选课时间 |
注意: (student_id, course_id, semester) 可以设置为 UNIQUE 约束,防止一个学生在同一学期重复选同一门课。
e. teachings (授课记录表)
关联教师和课程,记录授课信息。
| 字段名 | 数据类型 | 约束 | 描述 |
|---|---|---|---|
teaching_id |
INT |
PRIMARY KEY, AUTO_INCREMENT |
授课记录ID |
teacher_id |
INT |
FOREIGN KEY -> teachers(teacher_id) |
关联教师ID |
course_id |
INT |
FOREIGN KEY -> courses(course_id) |
关联课程ID |
semester |
VARCHAR(20) |
NOT NULL |
学期 |
classroom |
VARCHAR(50) |
教室 |
注意: (teacher_id, course_id, semester) 可以设置为 UNIQUE 约束,防止一位教师在同一学期重复教授同一门课。
表关系图 (E-R Diagram)
这是一个简化的实体-关系图,可以帮助你直观地理解表结构:
+-----------+ +-----------------+ +----------+
| students | | enrollments | | courses |
+-----------+ +-----------------+ +----------+
| student_id|----<--| student_id (FK) |---->--| course_id|
| student_name| | course_id (FK) | | course_name|
| ... | | grade | | credits |
+-----------+ | semester | | ... |
+-----------------+ +----------+
^
|
|
+-----------+ +-----------------+
| teachers | | teachings |
+-----------+ +-----------------+
| teacher_id|----<--| teacher_id (FK) |
| teacher_name| | course_id (FK) |
| ... | | semester |
+-----------+ +-----------------+
创建表的 SQL 代码
这是在 MySQL 中创建这些表的 SQL 语句。
-- 创建学生表
CREATE TABLE students (
student_id INT AUTO_INCREMENT PRIMARY KEY,
student_name VARCHAR(50) NOT NULL,
gender CHAR(1),
birth_date DATE,
enrollment_date DATE NOT NULL,
major VARCHAR(100)
);
-- 创建教师表
CREATE TABLE teachers (
teacher_id INT AUTO_INCREMENT PRIMARY KEY,
teacher_name VARCHAR(50) NOT NULL,
gender CHAR(1),
department VARCHAR(100),
email VARCHAR(100) UNIQUE
);
-- 创建课程表
CREATE TABLE courses (
course_id INT AUTO_INCREMENT PRIMARY KEY,
course_name VARCHAR(100) NOT NULL,
credits INT NOT NULL,
description TEXT
);
-- 创建选课记录表
CREATE TABLE enrollments (
enrollment_id INT AUTO_INCREMENT PRIMARY KEY,
student_id INT NOT NULL,
course_id INT NOT NULL,
semester VARCHAR(20) NOT NULL,
grade DECIMAL(5, 2),
enrollment_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 外键约束
FOREIGN KEY (student_id) REFERENCES students(student_id) ON DELETE CASCADE,
FOREIGN KEY (course_id) REFERENCES courses(course_id) ON DELETE CASCADE,
-- 防止同一学生在同一学期重复选同一门课
UNIQUE (student_id, course_id, semester)
);
-- 创建授课记录表
CREATE TABLE teachings (
teaching_id INT AUTO_INCREMENT PRIMARY KEY,
teacher_id INT NOT NULL,
course_id INT NOT NULL,
semester VARCHAR(20) NOT NULL,
classroom VARCHAR(50),
-- 外键约束
FOREIGN KEY (teacher_id) REFERENCES teachers(teacher_id) ON DELETE CASCADE,
FOREIGN KEY (course_id) REFERENCES courses(course_id) ON DELETE CASCADE,
-- 防止同一教师在同一学期重复教授同一门课
UNIQUE (teacher_id, course_id, semester)
);
ON DELETE CASCADE 的作用是:当被引用的记录(如学生或课程)被删除时,所有引用它的记录(如选课记录)也会自动被删除,以保证数据的一致性。
示例数据
向表中插入一些示例数据,方便后续查询。
-- 插入学生数据
INSERT INTO students (student_name, gender, birth_date, enrollment_date, major) VALUES
('张三', 'M', '2002-05-15', '2025-09-01', '计算机科学'),
('李四', 'F', '2003-02-20', '2025-09-01', '软件工程'),
('王五', 'M', '2002-11-30', '2025-09-01', '计算机科学');
-- 插入教师数据
INSERT INTO teachers (teacher_name, department, email) VALUES
('陈老师', '计算机学院', 'chen@example.com'),
('刘老师', '计算机学院', 'liu@example.com');
-- 插入课程数据
INSERT INTO courses (course_name, credits, description) VALUES
('数据库原理', 4, '关系型数据库设计与SQL语言'),
('数据结构', 3, '数组、链表、栈、队列、树、图等基本数据结构'),
('算法分析', 3, '时间复杂度与空间复杂度分析');
-- 插入选课记录数据
INSERT INTO enrollments (student_id, course_id, semester, grade) VALUES
(1, 1, '2025-Fall', 88.50), -- 张三选了数据库原理
(1, 2, '2025-Fall', 92.00), -- 张三选了数据结构
(2, 1, '2025-Fall', 95.00), -- 李四选了数据库原理
(3, 3, '2025-Fall', 85.00); -- 王五选了算法分析
-- 插入授课记录数据
INSERT INTO teachings (teacher_id, course_id, semester, classroom) VALUES
(1, 1, '2025-Fall', 'A101'), -- 陈老师教数据库原理
(2, 2, '2025-Fall', 'B205'), -- 刘老师教数据结构
(1, 3, '2025-Fall', 'A102'); -- 陈老师教算法分析
常用查询示例
我们可以用 SQL 来进行各种查询了。
查询1:查找“张三”同学的所有课程和成绩
SELECT
c.course_name,
e.grade,
e.semester
FROM
students s
JOIN
enrollments e ON s.student_id = e.student_id
JOIN
courses c ON e.course_id = c.course_id
WHERE
s.student_name = '张三';
查询2:查找“数据库原理”这门课的所有学生及其成绩
SELECT
s.student_name,
e.grade
FROM
courses c
JOIN
enrollments e ON c.course_id = e.course_id
JOIN
students s ON e.student_id = s.student_id
WHERE
c.course_name = '数据库原理';
查询3:查找“陈老师”教授的所有课程
SELECT
c.course_name,
t.semester,
t.classroom
FROM
teachers tch
JOIN
teachings t ON tch.teacher_id = t.teacher_id
JOIN
courses c ON t.course_id = c.course_id
WHERE
tch.teacher_name = '陈老师';
查询4:查找“李四”同学在“2025-Fall”学期的所有课程信息(包括授课教师)
SELECT
c.course_name,
tch.teacher_name,
t.classroom
FROM
students s
JOIN
enrollments e ON s.student_id = e.student_id
JOIN
courses c ON e.course_id = c.course_id
JOIN
teachings t ON c.course_id = t.course_id AND e.semester = t.semester
JOIN
teachers tch ON t.teacher_id = tch.teacher_id
WHERE
s.student_name = '李四' AND e.semester = '2025-Fall';
查询5:计算“数据库原理”这门课的平均分
SELECT
c.course_name,
AVG(e.grade) AS average_grade
FROM
courses c
JOIN
enrollments e ON c.course_id = e.course_id
WHERE
c.course_name = '数据库原理';
这个学生课程数据库设计虽然基础,但它涵盖了关系型数据库设计的核心概念,如实体、关系、主键、外键和范式,是一个非常完整和实用的起点。