E-R圖
E-R是“實體-聯繫”的簡稱。它是描述現實世界概念結構模型的有效方法。
是表示概念模型的一種方式
用矩形表示實體型,矩形框內寫明實體名;
用橢圓表示實體的屬性,並用無向邊將其與相應的實體型連接起來;
用菱形表示實體型之間的聯繫,在菱形框內寫明聯繫名,並用無向邊分別與有關實體型連接起來,同時在無向邊旁標上聯繫的類型(1:1,1:n或m:n)
實體A對實體B爲1對1,則在表A或表B中創建一個字段,存儲另一個表的主鍵值
實體A對實體B爲1對多:在表B中創建一個字段,存儲表A的主鍵值
實體A對實體B爲多對多:新建一張表C,這個表只有兩個字段,一個用於存儲A的主鍵值,一個用於存儲B的主鍵值
三範式
第一範式
原子性,表的字段不可再拆分成更小的字段。
第二範式
在滿足第一範式的基礎上,非主鍵必須完全依賴主鍵,而不是僅僅依賴主鍵的一部分。
舉個例子,美國銷售軍火的時候,對每一樣武器,根據國家或地區的不同而給出不同的價格。建個表看看:
CREATE TABLE weapon_price
(
wp_id UNSIGNED INT NOT NULL AUTO_INCREMENT, -- 武器編號
cs_id UNSIGNED INT NOT NULL , -- 消費者 id
wp_price UNSIGNED INT NOT NULL, -- 武器價格, 根據武器買主的不同而不同
cs_name VARCHAR(40) NOT NULL -- 消費者的稱呼,例如 菲律賓/韓國
);
weapon_price 用於描述武器的價格,價格根據(武器,消費者)的不同而不同。
對於此表 (wp_id,cs_id) 是其主鍵。其中 wp_price 是完全依賴於 (wp_id,cs_id) 的,而 cs_name 則只依賴於 cs_id ,即只依賴於主鍵的一部分。
這種情況導致的問題是什麼呢?
增:造成冗餘。cs_name 重複出現,如果有許多武器的買主都是韓國,那麼 cs_name 就會在這張表中出現很多次,造成浪費。
刪:無
改:假如”菲律賓”後來改名了,那麼數據庫管理者不得不把表中所有 相關的 cs_name 全都改一遍。
查:無
如何應對呢?
把 cs_name 挪到別的表裏,可以建一個 consumer 表,其中含 (cs_id,cs_name) 兩個字段。
第三範式
滿足第二範式並且每個字段都不間接依賴於主鍵列。
CREATE TABLE province
(
pr_id UNSIGNED INT NOT NULL AUTO_INCREMENT, -- 主鍵
pr_name VARCHAR(20) NOT NULL, -- 省份名, 完全依賴於主鍵, pr_id 定了, pr_name 就定了
PRIMARY KEY(pr_id)
);
CREATE TABLE city
(
ct_id UNSIGNED INT NOT NULL AUTO_INCREMENT, -- 主鍵
ct_name VARCHAR(20) NOT NULL, -- 完全依賴於主鍵,ct_id 定了,ct_name 就定了
pr_id UNSIGNED INT NOT NULL , -- 完全依賴於主鍵,ct_id 定了,就可以確定 pr_id
pr_name VARCHAR(20) NOT NULL, -- 完全依賴於主鍵,ct_id 定了,就可以確定 pr_name
PRIMARY KEY(ct_id),
FOREIGN KEY(pr_id) REFERENCES province(pr_id) ON DELETE CASCADE
);
上述的這兩張表都滿足第二範式,不過,注意到 city 表中的 pr_name 字段雖然完全依賴於 ct_id , 但是它是通過 pr_id 傳遞依賴於 ct_id 的。
傳遞依賴的壞處:
增:明顯 pr_name 出現冗餘。
刪:無
改:改動 province 表的 pr_name 字段,也要同時修改 city 表中的 pr_name 。一不小心就出問題。
查:無