假设我们要设计一个学生管理系统,需要存储以下信息:
单表设计:
CREATE TABLE Students (
StudentID INT PRIMARY KEY,
Name VARCHAR(100),
Gender CHAR(1),
BirthDate DATE,
ClassName VARCHAR(100),
HeadTeacher VARCHAR(100),
Grade VARCHAR(10),
Province VARCHAR(50),
City VARCHAR(50),
Street VARCHAR(100),
CourseID INT,
CourseName VARCHAR(100),
Teacher VARCHAR(100),
Score DECIMAL(5,2)
);
问题:
CourseID非空)。Address拆分为Province、City、Street。CourseID、CourseName、Teacher)与学生信息分离。CREATE TABLE Students (
StudentID INT PRIMARY KEY,
Name VARCHAR(100),
Gender CHAR(1),
BirthDate DATE,
ClassID INT,
Province VARCHAR(50),
City VARCHAR(50),
Street VARCHAR(100)
);
CREATE TABLE Courses (
CourseID INT PRIMARY KEY,
CourseName VARCHAR(100),
Teacher VARCHAR(100)
);
CREATE TABLE Enrollments (
StudentID INT,
CourseID INT,
Score DECIMAL(5,2),
PRIMARY KEY (StudentID, CourseID)
);
Students.ClassID仅依赖StudentID,但班级信息(如ClassName、HeadTeacher、Grade)未独立。Classes表存储班级详细信息。CREATE TABLE Classes (
ClassID INT PRIMARY KEY,
ClassName VARCHAR(100),
HeadTeacher VARCHAR(100),
GradeID INT
);
ALTER TABLE Students
ADD FOREIGN KEY (ClassID) REFERENCES Classes(ClassID);
Classes.GradeID依赖GradeName,但GradeName未独立。Grades表存储年级信息。CREATE TABLE Grades (
GradeID INT PRIMARY KEY,
GradeName VARCHAR(10)
);
ALTER TABLE Classes
ADD FOREIGN KEY (GradeID) REFERENCES Grades(GradeID);
Courses.Teacher决定CourseName(如教师只能教一门课),则存在主属性依赖。Teacher→CourseName,需拆分表:
CREATE TABLE Teachers (
TeacherID INT PRIMARY KEY,
TeacherName VARCHAR(100),
CourseName VARCHAR(100)
);
Students
StudentID(主键)、Name、Gender、BirthDate、ClassID(外键)、Province、City、Street
Classes
ClassID(主键)、ClassName、HeadTeacher、GradeID(外键)Grades
GradeID(主键)、GradeNameCourses
CourseID(主键)、CourseName、TeacherEnrollments
StudentID(外键)、CourseID(外键)、ScoreStudents.StudentID)。Enrollments表中缓存StudentName)。通过逐步应用范式,数据库结构从单一表优化为多个关联表,显著提升了数据一致性和维护性。实际设计中需结合业务需求,在规范化与性能之间找到平衡。