我在 CSDN 学院发布的 SQL 入门视频教程。
第二范式声明了需要满足第一范式的所有规则,而且任何列不存在对主键的部分依赖。
考虑一个客户-订单关系,需要存储的内容包括客户ID、客户姓名、订单ID、订单细节和购买日期:
CREATE TABLE CUSTOMERS(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
ORDER_ID INT NOT NULL,
ORDER_DETAIL VARCHAR (20) NOT NULL,
SALE_DATE DATETIME,
PRIMARY KEY (CUST_ID, ORDER_ID)
);
(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
ORDER_ID INT NOT NULL,
ORDER_DETAIL VARCHAR (20) NOT NULL,
SALE_DATE DATETIME,
PRIMARY KEY (CUST_ID, ORDER_ID)
);
该表满足第一范式,因为它遵守了第一范式的所有规则。该表的主键由CUST_ID和ORDER_ID组成。
但是它不满足第二范式,因为存在对主键和列的部分依赖。CUST_NAME依赖于CUST_ID,而客户姓名和购买的订单直接没有实际联系。订单细节和购买日期也依赖于ORDER_ID,但是它们不依赖于CUST_ID,因为CUST_ID和ORDER_DETAIL或SALE_DATE之间没有关系。
为了让该表满足第二范式,需要将这些列拆掉成3个表。
首先,创建一个客户信息表:
CREATE TABLE CUSTOMERS(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
PRIMARY KEY (CUST_ID)
);
(
CUST_ID INT NOT NULL,
CUST_NAME VARCHAR (20) NOT NULL,
PRIMARY KEY (CUST_ID)
);
然后,创建一个存储订单明细的表:
CREATE TABLE ORDERS(
ORDER_ID INT NOT NULL,
ORDER_DETAIL VARCHAR (20) NOT NULL,
PRIMARY KEY (ORDER_ID)
);
(
ORDER_ID INT NOT NULL,
ORDER_DETAIL VARCHAR (20) NOT NULL,
PRIMARY KEY (ORDER_ID)
);
最后,创建一个只包含CUST_ID和ORDER_ID的表,用于记录客户的订单信息:
CREATE TABLE CUSTMERORDERS(
CUST_ID INT NOT NULL,
ORDER_ID INT NOT NULL,
SALE_DATE DATETIME,
PRIMARY KEY (CUST_ID, ORDER_ID)
);
(
CUST_ID INT NOT NULL,
ORDER_ID INT NOT NULL,
SALE_DATE DATETIME,
PRIMARY KEY (CUST_ID, ORDER_ID)
);