假设我们要设计一个学生管理系统,需要存储以下信息:
单表设计:
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
(主键)、GradeName
Courses
CourseID
(主键)、CourseName
、Teacher
Enrollments
StudentID
(外键)、CourseID
(外键)、Score
Students.StudentID
)。Enrollments
表中缓存StudentName
)。通过逐步应用范式,数据库结构从单一表优化为多个关联表,显著提升了数据一致性和维护性。实际设计中需结合业务需求,在规范化与性能之间找到平衡。