我在 CSDN 学院发布的 SQL 入门视频教程。
第三范式的表需要满足以下条件:
- 满足第二范式
- 所有的非主键列依赖于主键列
非主键列的依赖存在于数据直接。例如,在下面的表中,街道名称、城市和州取决于邮政编码。
CREATE TABLE CUSTOMERS(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
DOB DATE,
STREET VARCHAR(200),
CITY VARCHAR(100),
STATE VARCHAR(100),
ZIP VARCHAR(12),
EMAIL_ID VARCHAR(256),
PRIMARY KEY (CUST_ID)
);
(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
DOB DATE,
STREET VARCHAR(200),
CITY VARCHAR(100),
STATE VARCHAR(100),
ZIP VARCHAR(12),
EMAIL_ID VARCHAR(256),
PRIMARY KEY (CUST_ID)
);
地址和邮编的依赖关系称为传递依赖。为了满足第三范式,只需要将Street、City和State列移动到单独的表中,比如邮政编码表:
CREATE TABLE ADDRESS(
ZIP VARCHAR(12),
STREET VARCHAR(200),
CITY VARCHAR(100),
STATE VARCHAR(100),
PRIMARY KEY (ZIP)
);
(
ZIP VARCHAR(12),
STREET VARCHAR(200),
CITY VARCHAR(100),
STATE VARCHAR(100),
PRIMARY KEY (ZIP)
);
然后修改CUSTOMERS表:
CREATE TABLE CUSTOMERS(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
DOB DATE,
ZIP VARCHAR(12),
EMAIL_ID VARCHAR(256),
PRIMARY KEY (CUST_ID)
);
(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
DOB DATE,
ZIP VARCHAR(12),
EMAIL_ID VARCHAR(256),
PRIMARY KEY (CUST_ID)
);
消除传递依赖的好处包括两个方面。首先时间少了重复数据,所以数据库更小。
第二个好处是数据完整性。如果修改了重复的数据,存在部分修改的风险,尤其是分散在多个不同位置的重复数据。例如,如果地址和邮编数据存储在3个或4个不同的表中,任何邮编的修改需要涉及所有表中的记录。