MySQL三範式

本文的示例代碼參考normalization

目錄

Startup

vim startup.sql
DROP DATABASE IF EXISTS normalization;
CREATE DATABASE IF NOT EXISTS normalization;
USE normalization;

DROP TABLE IF EXISTS `startup`;
CREATE TABLE `startup` (
`Full Names`        VARCHAR(64)  NOT NULL,
`Physical Address`  VARCHAR(64)  NOT NULL,
`Movies Rented`     VARCHAR(64)  NOT NULL,
`Saluation`         VARCHAR(64)  NOT NULL
);
INSERT INTO `startup` VALUES
('Janet Jones','First Street Plot No 4','Pirates of the Caribbean, Clash of the Titans','Ms.'),
('Robert Phil','3rd Street 34','Forgetting Sarah Marshal, Daddy\'s Little Girls','Mr.'),
('Robert Phil','5th Avenue','Clash of the Titans','Mr.');
source ./startup.sql;

select * from startup;
+-------------+------------------------+------------------------------------------------+-----------+
| Full Names  | Physical Address       | Movies Rented                                  | Saluation |
+-------------+------------------------+------------------------------------------------+-----------+
| Janet Jones | First Street Plot No 4 | Pirates of the Caribbean, Clash of the Titans  | Ms.       |
| Robert Phil | 3rd Street 34          | Forgetting Sarah Marshal, Daddy's Little Girls | Mr.       |
| Robert Phil | 5th Avenue             | Clash of the Titans                            | Mr.       |
+-------------+------------------------+------------------------------------------------+-----------+

問題: 'Movies Rented'列有多個值

1NF

1NF(First Normal Form): 每一列只包含單一值 即所有屬性都是不可分的基本數據項

vim 1nf.sql
USE normalization;

DROP TABLE IF EXISTS `1nf`;
CREATE TABLE `1nf` (
`Full Names`        VARCHAR(64)  NOT NULL,
`Physical Address`  VARCHAR(64)  NOT NULL,
`Movies Rented`     VARCHAR(64)  NOT NULL,
`Saluation`         VARCHAR(64)  NOT NULL
);
INSERT INTO `1nf` VALUES
('Janet Jones','First Street Plot No 4','Pirates of the Caribbean','Ms.'),
('Janet Jones','First Street Plot No 4','Clash of the Titans','Ms.'),
('Robert Phil','3rd Street 34','Forgetting Sarah Marshal','Mr.'),
('Robert Phil','3rd Street 34','Daddy\'s Little Girls','Mr.'),
('Robert Phil','5th Avenue','Clash of the Titans','Mr.');
source ./1nf.sql;

select * from 1nf;
+-------------+------------------------+--------------------------+-----------+
| Full Names  | Physical Address       | Movies Rented            | Saluation |
+-------------+------------------------+--------------------------+-----------+
| Janet Jones | First Street Plot No 4 | Pirates of the Caribbean | Ms.       |
| Janet Jones | First Street Plot No 4 | Clash of the Titans      | Ms.       |
| Robert Phil | 3rd Street 34          | Forgetting Sarah Marshal | Mr.       |
| Robert Phil | 3rd Street 34          | Daddy's Little Girls     | Mr.       |
| Robert Phil | 5th Avenue             | Clash of the Titans      | Mr.       |
+-------------+------------------------+--------------------------+-----------+

什麼是Primary Key

  • Primary Key標識表數據唯一性
Primary Key值唯一

Primary Key值不可爲空

Primary Key值不可更改

Primary Key值自動生成在插入數據後

什麼是Partial Functional Dependency

  • Primary Key(X, Y) -> (Z) 但是Primary Key(X, Y)的真子集(X)or(Y) -> (Z) 則(Z)部分函數依賴於Primay Key(X, Y)

2NF

2NF(Second Normal Form): 滿足1NF且沒有Partial Functional Dependency 即每個非主屬性都完全函數依賴於Primary Key

什麼是Full Functional Dependency

  • Primary Key(X, Y) -> (Z) 且不存在Primary Key(X, Y)的真子集(X)or(Y) -> (Z) 則(Z)完全函數依賴於Primay Key(X, Y)
vim 2nf.sql
USE normalization;

DROP TABLE IF EXISTS `2nf_t1`;
CREATE TABLE `2nf_t1` (
`Membership ID`     INT(10)  NOT NULL,
`Full Names`        VARCHAR(64)  NOT NULL,
`Physical Address`  VARCHAR(64)  NOT NULL,
`Saluation`         VARCHAR(64)  NOT NULL
);
INSERT INTO `2nf_t1` VALUES
(1,'Janet Jones','First Street Plot No 4','Ms.'),
(2,'Robert Phil','3rd Street 34','Mr.'),
(3,'Robert Phil','5th Avenue','Mr.');

DROP TABLE IF EXISTS `2nf_t2`;
CREATE TABLE `2nf_t2` (
`Membership ID`     INT(10)  NOT NULL,
`Movies Rented`     VARCHAR(64)  NOT NULL
);
INSERT INTO `2nf_t2` VALUES
(1,'Pirates of the Caribbean'),
(1,'Clash of the Titans'),
(2,'Forgetting Sarah Marshal'),
(2,'Daddy\'s Little Girls'),
(3,'Clash of the Titans');
select * from 2nf_t1;
+---------------+-------------+------------------------+-----------+
| Membership ID | Full Names  | Physical Address       | Saluation |
+---------------+-------------+------------------------+-----------+
| 1             | Janet Jones | First Street Plot No 4 | Ms.       |
| 2             | Robert Phil | 3rd Street 34          | Mr.       |
| 3             | Robert Phil | 5th Avenue             | Mr.       |
+---------------+-------------+------------------------+-----------+

select * from 2nf_t2;
+---------------+--------------------------+
| Membership ID | Movies Rented            |
+---------------+--------------------------+
| 1             | Pirates of the Caribbean |
| 1             | Clash of the Titans      |
| 2             | Forgetting Sarah Marshal |
| 2             | Daddy's Little Girls     |
| 3             | Clash of the Titans      |
+---------------+--------------------------+

什麼是Transitive Functional Dependency

  • Primary Key(X) -> (Y) 且(Y) -> (Z) 則(Z)傳遞函數依賴於Primay Key(X)

3NF

3NF(Third Normal Form): 滿足2NF且沒有Transitive Functional Dependency 即非主屬性不依賴於其它非主屬性

vim 3nf.sql
USE normalization;

DROP TABLE IF EXISTS `3nf_t1`;
CREATE TABLE `3nf_t1` (
`Membership ID`     INT(10)  NOT NULL,
`Full Names`        VARCHAR(64)  NOT NULL,
`Physical Address`  VARCHAR(64)  NOT NULL,
`Saluation ID`      INT(10)  NOT NULL
);
INSERT INTO `3nf_t1` VALUES
(1,'Janet Jones','First Street Plot No 4',2),
(2,'Robert Phil','3rd Street 34',1),
(3,'Robert Phil','5th Avenue',1);

DROP TABLE IF EXISTS `3nf_t2`;
CREATE TABLE `3nf_t2` (
`Membership ID`     INT(10)  NOT NULL,
`Movies Rented`     VARCHAR(64)  NOT NULL
);
INSERT INTO `3nf_t2` VALUES
(1,'Pirates of the Caribbean'),
(1,'Clash of the Titans'),
(2,'Forgetting Sarah Marshal'),
(2,'Daddy\'s Little Girls'),
(3,'Clash of the Titans');

DROP TABLE IF EXISTS `3nf_t3`;
CREATE TABLE `3nf_t3` (
`Saluation ID`      INT(10)  NOT NULL,
`Saluation`         VARCHAR(64)  NOT NULL
);
INSERT INTO `3nf_t3` VALUES
(1,'Mr.'),
(2,'Ms.'),
(3,'Mrs.'),
(4,'Dr.');
select * from 3nf_t1;
+---------------+-------------+------------------------+--------------+
| Membership ID | Full Names  | Physical Address       | Saluation ID |
+---------------+-------------+------------------------+--------------+
| 1             | Janet Jones | First Street Plot No 4 | 2            |
| 2             | Robert Phil | 3rd Street 34          | 1            |
| 3             | Robert Phil | 5th Avenue             | 1            |
+---------------+-------------+------------------------+--------------+

select * from 3nf_t2;
+---------------+--------------------------+
| Membership ID | Movies Rented            |
+---------------+--------------------------+
| 1             | Pirates of the Caribbean |
| 1             | Clash of the Titans      |
| 2             | Forgetting Sarah Marshal |
| 2             | Daddy's Little Girls     |
| 3             | Clash of the Titans      |
+---------------+--------------------------+

select * from 3nf_t3;
+--------------+-----------+
| Saluation ID | Saluation |
+--------------+-----------+
| 1            | Mr.       |
| 2            | Ms.       |
| 3            | Mrs.      |
| 4            | Dr.       |
+--------------+-----------+

Summary

範式數據庫中每個事實數據會出現且只出現一次 相反 反範式數據庫中信息是冗餘的可能存儲在多個地方

  • 範式數據庫優點
很少或沒有重複數據 數據佔用空間更小 更新操作更少更快

很少或沒有重複數據 查詢數據更少需要DISTINCT或者GROUP BY
  • 範式數據庫缺點
因爲數據存在多張表 查詢數據需要關聯 且會使某些索引策略失效

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章