『壹』 SQL中的數據冗餘的最佳解決方法是什麼
數據應該盡可能少地冗餘,這意味著重復數據應該減少到最少。比如說,一個部門雇員的電話不應該被存儲在不同的表中, 因為這里的電話號碼是雇員的一個屬性。如果存在過多的冗餘數據,這就意味著要佔用了更多的物理空間,同時也對數據的維護和一致性檢查帶來了問題,當這個員工的電話號碼變化時,冗餘數據會導致對多個表的更新動作,如果有一個表不幸被忽略了,那麼就可能導致數據的不一致性。 從一範式轉化到二範式根據第二範式的定義,轉化為二範式就是消除部分依賴。考察表1-1,我們可以發現,非主屬性<Project Name>部分依賴於主鍵中的<Project Number>; 非主屬性<Employee Name>,<Salary Category>和<Salary package>都部分依賴於主鍵中的<Employee Number>;表1-1的形式,存在著以下潛在問題:1. 數據冗餘:每一個欄位都有值重復;2. 更新異常:比如<Project Name>欄位的值,比如對值"TPMS"了修改,那麼就要一次更新該欄位的多個值;3. 插入異常:如果新建了一個Project,名字為TPT, 但是還沒有Employee加入,那麼<Employee Number>將會空缺,而該欄位是主鍵的一部分,因此將無法插入記錄;Insert into SAMPLE(PRJNUM, PRJNAME, EMYNUM, EMYNAME, SALCATEGORY, SALPACKAGE) values(100003, 'TPT', NULL, NULL, NULL, NULL)
4. 刪除異常:如果一個員工 200003, Kevin 離職了,要將該員工的記錄從表中刪除,而此時相關的Salary信息 C 也將丟失, 因為再沒有別的行紀錄下 Salary C的信息。Delete from sample where EMYNUM = 200003
Select distinct SALCATEGORY, SALPACKAGE from SAMPLE因此,我們需要將存在部分依賴關系的主屬性和非主屬性從滿足第一範式的表中分離出來,形成一張新的表,而新表和舊表之間是一對多的關系。由此,我們得到:
CREATE TABLE "PROJECT" ( "PRJNUM" INTEGER NOT NULL, "PRJNAME" VARCHAR(200)) IN "USERSPACE1";ALTER TABLE "PROJECT" ADD PRIMARY KEY ("PRJNUM");Insert into PROJECT(PRJNUM, PRJNAME) values(100001, 'TPMS'), (100002, 'TCT');
表1-2
表 1-3
CREATE TABLE "EMPLOYEE" ( "EMYNUM" INTEGER NOT NULL, "EMYNAME" VARCHAR(200), "SALCATEGORY" CHAR(1), "SALPACKAGE" INTEGER) IN "USERSPACE1";ALTER TABLE "EMPLOYEE" ADD PRIMARY KEY ("EMYNUM");Insert into EMPLOYEE(EMYNUM, EMYNAME, SALCATEGORY, SALPACKAGE) values(200001,'Johnson', 'A', 2000), (200002, 'Christine', 'B', 3000), (200003, 'Kevin', 'C',4000), (200004, 'Apple', 'B', 3000);Employee Number Employee Name Salary Category Salary Package200001 Johnson A 2000200002 Christine B 3000200003 Kevin C 4000200004 Apple B 3000
CREATE TABLE "PRJ_EMY" ( "PRJNUM" INTEGER NOT NULL, "EMYNUM" INTEGER NOT NULL) IN "USERSPACE1";ALTER TABLE "PRJ_EMY" ADD PRIMARY KEY ("PRJNUM", "EMYNUM");Insert into PRJ_EMY(PRJNUM, EMYNUM) values(100001, 200001), (100001, 200002),(100001, 200003), (100002, 200001), (100002, 200004);
同時,我們把表1-1的主鍵,也就是表1-2和表1-3的各自的主鍵提取出來,單獨形成一張表,來表明表1-2和表1-3之間的關聯關系:
表 1-4
這時候我們仔細觀察一下表1-2, 1-3, 1-4, 我們發現插入異常已經不存在了,當我們引入一個新的項目 TPT 的時候,我們只需要向表1-2 中插入一條數據就可以了, 當有新人加入項目 TPT 的時候,我們需要向表1-3, 1-4 中各插入一條數據就可以了。雖然我們解決了一個大問題,但是仔細觀察我們還是發現有問題存在。
回頁首
從二範式轉化到三範式考察表前面生成的三張表,我們發現,表1-3存在傳遞依賴關系,即:關鍵欄位< Employee Number > --> 非關鍵欄位< Salary Category > -->非關鍵欄位< Salary Package >。而這是不滿足三範式的規則的,存在以下的不足:1、 數據冗餘:<Salary Category>和<Salary Package>的值有重復;2、 更新異常:有重復的冗餘信息,修改時需要同時修改多條記錄,否則會出現數據不一致的情況;3、 刪除異常:同樣的,如果員工 200003 Kevin 離開了公司,會直接導致 Salary C 的信息的丟失。Delete from EMPLOYEE where EMYNUM = 200003
Select distinct SALCATEGORY, SALPACKAGE from EMPLOYEE因此,我們需要繼續進行規范化的過程,把表1-3拆開,我們得到:
表 1-5
和
表 1-6
這時候如果 200003 Kevin 離開公司,我們只需要從表 1-5 中刪除他就可以了, 存在於表1-6中的Salary C信息並不會丟失。但是我們要注意到除了表 1-5 中存在 Kevin 的信息之外, 表1-4中也存在 Kevin 的信息, 這很容易理解, 因為 Kevin 參與了項目 100001, TPMS, 所以當然也要從中刪除。 至此,我們將表1-1經過規范化步驟,得到四張表,滿足了三範式的約束要求,數據冗餘、更新異常、插入異常和刪除異常。在三範式之上,還存在著更為嚴格約束的BC範式和四範式,但是這兩種形式在商業應用中很少用到,在絕大多數情況下,三範式已經滿足了資料庫表規范化的要求,有效地解決了數據冗餘和維護操作的異常問題。