1.目的:
用于评估和指导数据库模式的设计,以确保数据的一致性、完整性和有效性。
2.细节:
• 第一范式(1NF)要求每个属性都是原子的,即不可再分的。每个属性只能包含一个值,不能包含多个值或多个属性。
• 第二范式(2NF)要求数据表中的非主键属性必须完全依赖于主键,即非主键属性必须完全依赖于整个主键,而不是依赖于主键的一部分----(表中信息直接与主键相关,而不是间接或关联相关,一对多关联关系最好剥离出来)。
• 第三范式(3NF)要求数据表中的非主键属性不应该存在传递依赖关系。换句话说,非主键属性应该直接依赖于主键,而不是依赖于其他非主键属性(不应该在一个表中设计存在多级关联关系。)。
• 第四范式(4NF)要求数据表中的非主键属性不应该存在多值依赖关系。即如果一个属性依赖于另一个非主键属性的多个值,那么应该将这些多个值拆分为单独的关系模式(非主键值不宜用于表达一对多关系)。
• 第五范式(5NF)是在第四范式的基础上进一步分解多值依赖关系,以消除冗余和重复的数据。
3.正反示例(只解释不好理解的):
3.1第二范式(2NF):
正例:一个订单表和一个商品表的SQL代码示例。
订单表(Orders):
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
-- 其他订单相关字段
);
CREATE TABLE OrderItems (
order_item_id INT PRIMARY KEY,
order_id INT,
product_id INT,
quantity INT,
-- 其他订单项相关字段
);
商品表(Products):
CREATE TABLE Products (
product_id INT PRIMARY KEY,
product_name VARCHAR(100),
-- 其他商品相关字段
);
反例:一个订单表中包含多个商品号的SQL代码示例。
订单表(Orders):
CREATE TABLE Orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
product_ids VARCHAR(100), -- 多个商品号存储在同一个字段中
-- 其他订单相关字段
);
3.2第三范式(3NF):
正例:
假设有一个学生表,包含以下字段:学生ID(主键)、学生姓名、学生年龄、学生所在班级、班级所在学校。
在符合第三范式的情况下,可以使用SQL创建两个表:
- 学生信息表(Student):
CREATE TABLE Student (
student_id INT PRIMARY KEY,
student_name VARCHAR(50),
student_age INT,
class_id INT,
FOREIGN KEY (class_id) REFERENCES Class(class_id)
);
- 班级信息表(Class):
CREATE TABLE Class (
class_id INT PRIMARY KEY,
school_name VARCHAR(100)
);
在这个例子中,班级所在学校直接依赖于班级ID,通过外键约束关联了班级信息表。
反例:
假设有一个订单表,包含以下字段:订单ID(主键)、订单日期、订单总金额、客户ID、客户姓名、客户所在城市。
在不符合第三范式的情况下,可以使用SQL创建一个表:
CREATE TABLE Order (
order_id INT PRIMARY KEY,
order_date DATE,
order_amount DECIMAL(10, 2),
customer_id INT,
customer_name VARCHAR(50),
customer_city VARCHAR(50)
);
3.3第四范式(4NF):
为了符合第四范式,需要将多值属性拆分为单独的关系模式。可以创建一个订单表和一个订单商品表:
正例
- 订单表(Order):
CREATE TABLE Order (
order_id INT PRIMARY KEY,
order_date DATE,
order_amount DECIMAL(10, 2)
);
- 订单商品表(OrderItem):
CREATE TABLE OrderItem (
order_item_id INT PRIMARY KEY,
order_id INT,
item_name VARCHAR(50),
FOREIGN KEY (order_id) REFERENCES Order(order_id)
);
在这个例子中,将订单商品拆分为一个独立的关系模式,通过订单ID和订单商品ID建立关联关系。这样就消除了非主键多值依赖关系。
反例
在不符合第四范式的情况下,可以使用SQL创建一个表:
CREATE TABLE Order (
order_id INT PRIMARY KEY,
order_date DATE,
order_amount DECIMAL(10, 2),
order_items VARCHAR(100)
);