在数据库设计中,范式是确保数据库表结构合理性和数据完整性的规则。以下是三个不同领域的范式分析案例,我们将使用第一范式(1NF)、第二范式(2NF)和第三范式(3NF)来分析这些案例。
案例一:图书馆管理系统
第一范式(1NF)
问题描述:图书馆管理系统中的图书信息表包含重复的作者信息。
表结构:
CREATE TABLE Books (
BookID INT PRIMARY KEY,
Title VARCHAR(255),
Author VARCHAR(255),
Publisher VARCHAR(255),
Year INT
);
分析:
- BookID 是主键,唯一标识每本书。
- Title、Author、Publisher 和 Year 是图书的属性。
1NF 分析:
- 所有字段值都是原子的,不可分割。
- 每个字段都有唯一值,且每行数据有唯一标识。
第二范式(2NF)
问题描述:在上述表中,如果一本图书有多个作者,则作者信息会重复。
改进后的表结构:
CREATE TABLE Books (
BookID INT PRIMARY KEY,
Title VARCHAR(255),
Publisher VARCHAR(255),
Year INT
);
CREATE TABLE Authors (
AuthorID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE BookAuthors (
BookID INT,
AuthorID INT,
PRIMARY KEY (BookID, AuthorID),
FOREIGN KEY (BookID) REFERENCES Books(BookID),
FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID)
);
2NF 分析:
- Books 表只存储图书的基本信息。
- Authors 表存储作者信息,避免重复。
- BookAuthors 表是一个关联表,用于存储多对多的关系。
第三范式(3NF)
问题描述:如果出版社信息在多本图书中重复,则需要进一步优化。
改进后的表结构:
CREATE TABLE Books (
BookID INT PRIMARY KEY,
Title VARCHAR(255),
AuthorID INT,
PublisherID INT,
Year INT,
FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID),
FOREIGN KEY (PublisherID) REFERENCES Publishers(PublisherID)
);
CREATE TABLE Authors (
AuthorID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE Publishers (
PublisherID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE BookAuthors (
BookID INT,
AuthorID INT,
PRIMARY KEY (BookID, AuthorID),
FOREIGN KEY (BookID) REFERENCES Books(BookID),
FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID)
);
3NF 分析:
- Publishers 表存储出版社信息,避免重复。
- Books 表中的 PublisherID 字段引用 Publishers 表的主键。
- 所有表都遵循 2NF,且没有传递依赖。
案例二:在线购物平台
第一范式(1NF)
问题描述:在线购物平台中的用户信息表包含重复的地址信息。
表结构:
CREATE TABLE Users (
UserID INT PRIMARY KEY,
Name VARCHAR(255),
Email VARCHAR(255),
Address VARCHAR(255)
);
分析:
- UserID 是主键,唯一标识每个用户。
- Name、Email 和 Address 是用户的属性。
1NF 分析:
- 所有字段值都是原子的,不可分割。
- 每个字段都有唯一值,且每行数据有唯一标识。
第二范式(2NF)
问题描述:在上述表中,如果用户有多个地址,则地址信息会重复。
改进后的表结构:
CREATE TABLE Users (
UserID INT PRIMARY KEY,
Name VARCHAR(255),
Email VARCHAR(255)
);
CREATE TABLE Addresses (
AddressID INT PRIMARY KEY,
UserID INT,
Street VARCHAR(255),
City VARCHAR(255),
State VARCHAR(255),
ZipCode VARCHAR(255),
Country VARCHAR(255),
FOREIGN KEY (UserID) REFERENCES Users(UserID)
);
2NF 分析:
- Users 表只存储用户的基本信息。
- Addresses 表存储用户地址信息,避免重复。
- Addresses 表中的 UserID 字段引用 Users 表的主键。
第三范式(3NF)
问题描述:如果国家、州和城市信息在多本图书中重复,则需要进一步优化。
改进后的表结构:
CREATE TABLE Users (
UserID INT PRIMARY KEY,
Name VARCHAR(255),
Email VARCHAR(255)
);
CREATE TABLE Addresses (
AddressID INT PRIMARY KEY,
UserID INT,
Street VARCHAR(255),
City VARCHAR(255),
State VARCHAR(255),
ZipCode VARCHAR(255),
Country VARCHAR(255),
FOREIGN KEY (UserID) REFERENCES Users(UserID)
);
CREATE TABLE Countries (
CountryID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE States (
StateID INT PRIMARY KEY,
CountryID INT,
Name VARCHAR(255),
FOREIGN KEY (CountryID) REFERENCES Countries(CountryID)
);
CREATE TABLE Cities (
CityID INT PRIMARY KEY,
StateID INT,
Name VARCHAR(255),
FOREIGN KEY (StateID) REFERENCES States(StateID)
);
3NF 分析:
- Countries、States 和 Cities 表存储国家、州和城市信息,避免重复。
- Addresses 表中的 CountryID、StateID 和 CityID 字段引用相应的表的主键。
案例三:医院信息系统
第一范式(1NF)
问题描述:医院信息系统中的病人信息表包含重复的医生信息。
表结构:
CREATE TABLE Patients (
PatientID INT PRIMARY KEY,
Name VARCHAR(255),
Age INT,
DoctorName VARCHAR(255)
);
分析:
- PatientID 是主键,唯一标识每个病人。
- Name、Age 和 DoctorName 是病人的属性。
1NF 分析:
- 所有字段值都是原子的,不可分割。
- 每个字段都有唯一值,且每行数据有唯一标识。
第二范式(2NF)
问题描述:在上述表中,如果一名病人有多个医生,则医生信息会重复。
改进后的表结构:
CREATE TABLE Patients (
PatientID INT PRIMARY KEY,
Name VARCHAR(255),
Age INT
);
CREATE TABLE Doctors (
DoctorID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE PatientDoctors (
PatientID INT,
DoctorID INT,
PRIMARY KEY (PatientID, DoctorID),
FOREIGN KEY (PatientID) REFERENCES Patients(PatientID),
FOREIGN KEY (DoctorID) REFERENCES Doctors(DoctorID)
);
2NF 分析:
- Patients 表只存储病人信息。
- Doctors 表存储医生信息,避免重复。
- PatientDoctors 表是一个关联表,用于存储多对多的关系。
第三范式(3NF)
问题描述:如果科室信息在多本图书中重复,则需要进一步优化。
改进后的表结构:
CREATE TABLE Patients (
PatientID INT PRIMARY KEY,
Name VARCHAR(255),
Age INT
);
CREATE TABLE Doctors (
DoctorID INT PRIMARY KEY,
Name VARCHAR(255),
DepartmentID INT,
FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID)
);
CREATE TABLE Departments (
DepartmentID INT PRIMARY KEY,
Name VARCHAR(255)
);
CREATE TABLE PatientDoctors (
PatientID INT,
DoctorID INT,
PRIMARY KEY (PatientID, DoctorID),
FOREIGN KEY (PatientID) REFERENCES Patients(PatientID),
FOREIGN KEY (DoctorID) REFERENCES Doctors(DoctorID)
);
3NF 分析:
- Departments 表存储科室信息,避免重复。
- Doctors 表中的 DepartmentID 字段引用 Departments 表的主键。
- 所有表都遵循 2NF,且没有传递依赖。
