什么是数据库冗余?
数据库冗余指的是在一个数据库中存储了相同或相似的数据信息,造成了资源的浪费和数据操作上的不方便。冗余数据不仅浪费存储资源,还有可能导致数据的不一致性,降低了数据的可靠性和可维护性。
三范式
第一范式(1NF)
第一范式(1NF)是指在关系表中的每个属性都不可再分。
实现1NF的方式很简单,只需要将不可再分的属性拆分成单一的属性即可,例如,将学生信息表分解成学生编号、姓名、性别、年龄、出生日期、家庭地址、电话等单一属性,确保每一列中放置的都是同一类型的数据。
CREATE TABLE student(
id INT PRIMARY KEY,
name VARCHAR(20),
gender VARCHAR(2),
age INT,
birthday DATE,
address VARCHAR(50),
phone VARCHAR(11)
);
第二范式(2NF)
第二范式(2NF)是在1NF基础上,要求每个非主键列完全依赖于主键,而不是仅依赖于主键的一部分。
这意味着,如果表中存在联合主键列,那么每个非主键列都必须完全依赖于这个联合主键,不能只依赖于其中的一部分主键。
例如,下面这张订单表就不符合2NF的要求。因为订单表两个主键为order_id和product_id,但是item_price字段仅依赖于product_id,而不依赖于整个联合主键。
CREATE TABLE order(
order_id INT,
product_id INT,
product_name VARCHAR(50),
item_price DECIMAL(10,2)
);
为了符合2NF的要求,我们需要将该表拆分成两个独立的表,一个是订单表,另一个是产品表:
CREATE TABLE order(
order_id INT,
product_id INT,
PRIMARY KEY(order_id, product_id)
);
CREATE TABLE product(
product_id INT PRIMARY KEY,
product_name VARCHAR(50),
item_price DECIMAL(10,2)
);
第三范式(3NF)
第三范式(3NF)是在2NF的基础上,要求非主键列之间互不依赖,即不存在传递依赖关系。
传递依赖关系指的是,如果A->B,B->C,那么A->C,也就是说,存在两个非主键列之间的依赖关系,导致一个非主键列依赖于另一个非主键列。
例如,下面这张订单表就不符合3NF的要求。因为产品名称字段已经包含在产品表中,而在订单表中仍然存在该字段,造成了数据冗余。
CREATE TABLE order(
order_id INT,
product_id INT,
product_name VARCHAR(50),
item_price DECIMAL(10,2)
);
为了符合3NF的要求,我们需要将该表拆分成三个独立的表,分别是订单表、产品表和产品名称表:
CREATE TABLE order(
order_id INT,
product_id INT,
PRIMARY KEY(order_id, product_id)
);
CREATE TABLE product(
product_id INT PRIMARY KEY,
item_price DECIMAL(10,2)
);
CREATE TABLE product_info(
product_id INT,
product_name VARCHAR(50),
PRIMARY KEY(product_id)
);
总结
通过采用三范式,我们可以有效地解决数据库中的冗余问题,减少了存储资源的浪费,提高了数据的可靠性和可维护性。