網際網路與資料庫的對話錄
2002/06/18
一進小博家的大門,小君就馬上從背包裡拿出上次整理的那本筆記本,迅速地翻到其中一頁,稍微看了一下內容後,抬頭好奇地問:「師父哥哥,我有個疑惑耶,為甚麼有時候可以看到一個資料庫裡面,只有一個資料表格,卻包含有很多個欄位;有時候卻又看到同一個功能的資料庫裡,有許多的資料表,每個資料表的欄位卻不多,但是這兩個資料庫所呈現的的用途卻一模一樣。到底這二者是差在哪裡啊?又到底怎樣才算是好的資料庫設計呢?
聽完小君的問題,小博將筆記本借過去翻閱一下,詳細閱讀倒數幾頁之後,滿心歡喜地說:「喔,妳問的問題越來越有深度了,想必這幾天不見,妳一定偷偷跑去外面練個幾招了。」
被小博一眼就看穿這幾天的行蹤,小君頓時之間覺得有點不好意思,只好顧左右而言它:「沒有,沒有,我只是跑到重慶南路上的電腦書籍專賣書店去翻一翻幾本介紹資料庫系統的書,講老實話,那些書真的要在短時間內看得懂還真是不容易呢。」
小博其實不是要虧小君,他真正的用意是想誇讚小君在學習資料庫系統這件事情上面表現得很不錯,藉此激發小君的學習欲望與潛力:「不錯不錯,妳很有上進心,我相信再努力下去,妳一定也可以成為資料庫系統領域裡的專家。」
聽到小博這麼誇讚自己,小君的內心可是「爽」的很,只見她用一雙手遮住眼睛臉紅紅地說:「這還要靠師父哥哥您的大力指導呢。」
小博看到小君已樂得快要飛上天了,心想目的既然已經達到,該是降溫冷卻的時候,於是語氣一轉,突然間正經八百地說:「好說好說,言歸正傳,妳的問題其實就在於資料表格是否有執行『正規化』動作。」
學習一個新的領域的知識就是如此,會一而再,再而三地接連地碰到許多新的名詞或牽扯其它領域的觀念,這時候能夠做的就是—「小心學習,虛心請教」才是學習者的最上策。小君提高音調地問:「蝦米?正規化?又來了一個新名詞,我該把我的筆記本準備好才對。」
小博等小君準備好速記時的各種前置動作,才慢慢地開始說:「我們先假設現在有一個資料表格,叫做學生選課資料表,裡面包含學生學號、課程編號、學分數、以及成績等值組,如果這個時候有一門新課程要開了,妳想會發生甚麼問題呢?」
小君搔一搔頭髮,並反握鉛筆輕敲自己的頭額,再用一種不太確定的語器說:「會有甚麼問題呢?讓我想想看,首先,在這個叫做學生選課的資料表格中,主鍵值應該是學生學號加上課程編號吧。」
小博不想說太多,他想讓小君用「自己的話」說出問題的癥結所在,這樣才會將學到的觀念融會貫通:「是這樣子沒錯,然後呢?」
小君將舌頭伸入牙齒的上顎,裝成一隻母猩猩的樣子,一邊比動作一邊繼續思考小博的問題,過了幾分鐘後才恢復正常並興奮地回答:「既然是新課程的話,一開始一定沒有開始收學生嘛。如果只把課號與學分數加入表格內,等一下,那不是讓主鍵值的其中一個學生學號欄位變成虛值了嗎?這就違反了個體整合限制條件了嘛。」
小博一邊鼓掌一邊模仿香港電影中周星馳的誇張語氣說:「厲害,厲害,高招,高招,沒想到妳看的出來。」
小君嘴巴笑得好開,幾乎可以吞下一個傳統鹹肉粽(嗯,有點想吃呢,怎麼辦呀?)了,只見她心花怒放地笑著說:「這是當然的囉,所謂名師出高徒就是這麼一回事嘛。」
小博瞭解小君為什麼會這麼高興,他自顧自地繼續說:「這就是所謂的新增異常,也就是說這樣的新增是不被資料庫系統允許的。」
小君雖然靠自己的力量推導出這個問題的答案,但還是非常地不解,她滿臉狐疑地問:「那不是變成任何老師開新課程的資料都無法輸入到表格中嗎?這種情況不是很不合理嗎?」
小博就是在等待這一刻來到,當小君推導出來的答案和現實狀況產生某種衝突時,他再針對這些衝突或矛盾進行解釋,會比在一開始就把重點直接說出來要好得太多,至少對小君而言,她將會對這個觀念有非常深入的印象,不會一下子就忘記。小博一開始先從附和小君的話說起:「沒錯,這的確是非常的不合理,但這是因為資料表格設計不良而導致的。我們必須要做的動作,就是將表格中造成異常的部分屬性從表格中分離出來,產生另外一個新的表格,而這樣的過程就稱為『正規化』動作。」
小君在心裡重複一遍又一遍唸著小博說的話,每暗誦一遍,再思考一下,就覺得更能掌握「正規化」的整個概念,唸到第六遍時,她已經能夠完全明白小博想要表達的意思了。她恍然大悟地叫著:「原來這就叫做正規化啊,哈哈哈,看起來蠻有用的。」
小君剛剛的所有動作與結果,小博均看在眼裡。這些情況讓他回憶起自己過去學習電腦的經驗也是同樣的過程,他很高興能夠將所學習到的知識再傳授給其他人,並再次和小君沉浸在這種學習過程所產生的快樂中。他對小君的話做了一個總結性的歸納:「當然啦,妳再想想看,如果現在將學生選課資料表格縮減成三個欄位,分別為學生學號、課程編號、成績,而再另外產生一個資料表格,叫做課程資料表格,其中只有兩個欄位,就是課程編號以及學分數,妳再看看會不會發生剛剛的問題呢?」
果然這種學習過程所產生的大量喜悅是一種學習時的「腎上腺素」,不僅可以強化學習者的信心,更間接地促成一種學習過程的良性循環。小君思考小博繼續提出的問題,過了一會兒後,小君很有自信地說:「果然不會了耶,當我們要開新課程的時候,只要將新的課程資訊加到課程資料表格中,如此就動不到學生選課資料表格了,也就不會發生『新增異常』的問題了。」
小博補足小君沒有注意到的地方,讓小君更明瞭正規化的好處:「其實這樣子的修正,除了在新增資料的時候能解決異常的問題,刪除資料或更新資料時,也同樣解決了其它的異常問題。」
聽完小博的補充,小君若以所思地回答:「是不是說假如使用原本的表格,當只有一個人修某門課程,而後這個人又退選掉時,這個課程的資訊也一併從表格中被永久刪除了。」
為了讓「正規化」的觀念有個圓滿的結局,小博問小君最後一個問題:「完全正確,那妳要不要也順便說說為甚麼更新資料的時候也會產生異常問題。」
小君興在頭上,聽完小博的問題後就開始認真地想答案,過了好一會兒才胸有成竹地說:「我試著說看看,當某門課程想要從三學分的課變成四學分的課時,原來的表格修改起來就很吃力不討好了,萬一有某一些資料沒有被改到,不就造成了資料彼此間的不一致了嗎?」
小博很滿意小君的表現與這次教學過程中的互動模式,他舉起大姆指,對小君比出一個「棒」的手勢,並面帶微笑地說:「不錯不錯,我看妳是學通了。」
小君也非常謙虛地回應小博的誇獎:「師父哥哥,過獎過獎。」
學習新領域的知識有時候是需要「乘勝追擊」的,就拿目前這種情況來說明,小君由於事先已經有稍做準備,所以學習的過程中就特別順暢容易,如果這個時候小博見好就收,下回再擱來的話,未免太可惜了,正確的做法應該趁小君樂在學習時,繼續進行下一階段的課題,雖然對小君而言困難了點,但學習過程的障礙會比較容易去克服。小博想通了以後,決定再接再厲,幫助小君挑戰正規化的進階課題,只見他不慌不忙地說:「其實正式來說,資料庫系統的正規化共可分為第一正規化、第二正規化、第三正規化、BCNF、第四正規化、第五正規化、第六正規化、第七正規化等等,不過對於一般的資料庫系統來說,只做第一階到第三階正規化就可以了,其他更高階的通常只會在很特殊的情況下才會出現,因此沒有必要耗費資源去考慮不太會發生的情形。而且前三階正規化就可應付絕大多數的資料庫系統所需要了。」
雖然「犛哩扣摳(國語發音,台語意義)」地聽了小博說了一大堆關於正規化的類別,但小君此時的興趣正高昂,絲毫不覺得半點疲倦,不僅如此,她還表達想繼續聽的意願:「原來正規化有這麼多種啊,我倒想聽聽這些正規化的分別在哪裡。」
小博也同樣很亢奮,誰叫小君的表現太優異了,他用一種急促地聲音回答:「沒問題,馬上就告訴妳。第一正規化的定義就是:關聯表的每一個屬性皆為單值。」
不等小博說完,小君就插嘴道:「也就是說如果有些屬性如果有多個值,像住址欄,有人可能有多間房子,那麼它的住址欄可能不只填一個住址,那麼是不是要做點修正,才能符合第一正規化的要求。」
小博停頓了一下,想一想是否正確,過了一會兒後才明確地回答:「妳說的完全正確,然而在接著說第二正規化之前,首先我要先告訴妳甚麼叫做功能相依。」
從字面上完全推導不出這個專有名詞的真正涵意,小君只好棄械投降,搔一搔頭髮後百般不情願地道:「嗯,這的確是有點抽象ㄟ。」
小博提醒小君待會的解釋可是要寫在筆記本中,否則再過不久後,一定會忘得一乾二淨。等小君準備好後,小博才開始解釋:「一般能當主鍵值的屬性,它應該要有一個特色,那就是它可以唯一決定所有其他的屬性,換句話說,所有其他的屬性就會功能相依於主鍵了。」
小君點點頭,這還不難瞭解,但她相信這幾句話絕對不是重點,他可等不及要聽完全部的解釋了。只見小君迅速地抄寫完畢,抬頭問小博:「這還算容易理解,嗯,再來呢?」
小博眼看小君已經將他剛剛說的話全部記錄在筆記本上,他接著說:「但有的時候有些屬性,並不是功能相依於主鍵值,而是功能相依於主鍵中的部分屬性時,那麼就稱為部分功能相依於主鍵了。如果只功能相依於主鍵的所有屬性的話,就稱為完全功能相依於主鍵了。」
小君不僅聽得懂,還準備舉一反三,來個「徒兒大進擊」呢,只見她興沖沖地回應小博的話:「那我懂了,之前那個學生選課資料表,學分數就是功能相依於課程編號,而課程編號只是主鍵的部分屬性,使得學分數部分功能相依於主鍵學生學號加上課程編號了。」
小博滿心希望小君在資料庫系統上能夠「青出於藍,而勝於藍」,因此他絲毫不吝嗇誇讚小君:「妳的觀察力很強的嘛。」
小君像個小孩子似的手舞足蹈地說:「這是一定要的啦,這是一定要的啦!」
小博被小君逗得好不開心,他一邊模仿小君的動作一邊說:「知道了部分功能相依以後呢,我就開始來定義甚麼是第二正規化了。」
小君體力充沛,比了許久都不覺得累,她一邊比一邊插斷小博的話,搶著說:「我猜之前那個還沒拆開的學生選課資料表,一定是沒有符合第二正規化才出問題的是吧。」
小博覺得這個動作做久好酸痛呀,於是他停止這個手勢,也示意小君停下來專心聽他講:「妳猜的很準,我現在開始定義囉。第二正規化的定義就是:所有非鍵值屬性完全功能相依於主鍵或候選鍵。」
就算這次小君很認真聽,仍然有聽沒有懂,她捏著鼻子,用怪怪的假鼻音問到:「師父哥哥,有點不懂耶,為甚麼功能相依於候選鍵也算?」
小博鼓勵小君多動動頭腦想一想這個問題:「妳想想看喔,如果今天除了學生學號外,又有學生姓名的欄位,而且學生姓名也都不同,其他的欄位當然也功能相依於學生姓名了啊?這樣子不符合第二正規化有點太嚴苛了。」
小君反覆思考小博的話,發現確實如他所說的一樣,會產生過於嚴苛的問題。她吐了一下舌頭,並俏皮地說:「我懂了,因為課程編號在學生選課資料表中,並非候選鍵,而學分數卻功能相依於它,而造成了學分數部分功能相依於主鍵學生學號加課程編號了,因此違反了第二正規化的要求,我說的對不對啊?小博哥哥。」
小博露出一嘴潔白的牙齒,微笑著說:「對極了。」
好還要再更好,這是人之常情,小君當然也不例外,在聽完第二正規化是蝦米碗糕之後,小君當下決定再接再厲,繼續挑戰第三正規化。小君採用試探性的語氣問小博:「那第三正規化呢?是不是限制會更多啊?會不會很難啊?」
小博早就猜到小君會提出這個問題,他好整以暇地清一清喉嚨後,才慢吞吞地說:「那是當然的囉,第三正規化一開始的定義就是一定要滿足第二正規化,然後再滿足我接下來要講的性質,不過在我要說下去之前呢,我先講個例子,讓妳知道即使滿足了第二正規化的表格,仍然可能發生新增,刪除,更新的異常問題的。」
看見小博已經啟程出發前進了,小君當然也不敢怠慢。她開始集中注意力,專注聽講:「是喔,那我可要仔細聽囉。」
為了容易理解,小博先舉一個例子,稍後在利用這個例子來解釋為什麼一個已經第二正規化的表格,仍舊會發生新增、刪除與更新的異常問題。他一邊在小君的筆記本上畫出這個表格的所有欄位,一邊說明:「假如說現在有一個表格叫做課程資料表格,它有課程編號、課程名稱、教師編號、教師姓名四個欄位。如果這時候學校新聘了一位老師,妳猜會發生甚麼事?」
小君看著小博畫在筆記本上的表格,沉思了一會兒後嘗試著提出自己的看法:「我先來觀察一下這個表格,主鍵值是課程編號,其他的屬性完全功能相依於主鍵值,可見這是第二正規化表格,如果這時候學校新聘了一位老師,那不是讓課程編號跟課程名稱都是虛值嗎,因為剛聘的老師應該是還沒開課的嘛,這就違反了主鍵不能是虛值的個體整合性限制條件了啊。」
小博拍拍手,誇了一下小君:「我可愛的小君,妳可是越來越聰慧了。」
小君笑呵呵地回答:「哈哈,看看是誰教的嘛。」
小博繼續引導小君回答問題:「嗯,那我再來驗收一下,妳認為刪除與更新,是不是也會有問題呢?」
小君又看了一下筆記本,嘴中唸唸有辭,好像在暗地推導規則似的,過了許久後,眼睛突然閃亮了起來,興奮地說:「ㄝ,我想想看喔,如果某位老師只開了一門課,結果因為人數不足,開不成這門課,那麼原本開課的記錄會被刪除,這樣子的話,老師的資料也就被一起刪除掉啦。」
小博不想打斷小君的話,繼續讓她說:「不錯,再來呢?」
小君這會可不讓小博等待了,只見小博的話剛一說完,小君就接著說:「如果說老師人數增加,教師編號可能從兩碼變三碼,因此必須要重新編碼吧,那這樣如果漏了幾筆沒修改到,就會造成資料不一致的狀況了。我記得我們公司就遇過這種狀況。因為有一陣子老闆新請了一些員工,結果員工代碼不夠用了。」
小博希望小君把這個案例說得再清楚點,因為有助於瞭解第二正規化後的刪除異常問題。小博提示小君說下去:「最後是怎麼處理呢?」
這又是一個會勾起小君不好的回憶的案例,她用一種超級怨懟的語氣述說著:「還不是我們資訊部門的幾個人要開始加夜班,把公司裡的每一份表格都拿來修改,好怕改錯,或是漏改,事後被老闆罵喔。現在想起來這樣的工作真的好笨喔。不過現在有了電腦化,但資料更多了,改起來也是頗麻煩的。」
小博頗有同感地回應小君的話:「沒錯啊,雖然現在有了電腦,但資料沒有系統式的管理,一樣也是沒有效率。」
小君一副受難者見證的表情:「我實在是太感同身受了。」
有了這些悲慘的事例做為佐證,小博相信小君待會在學習「遞移相依性」時,一定會學習得更好。他開始說明:「會發生這樣的問題,主要是因為資料表中存在了遞移相依性的結果。」
小君「啊」的一聲,驚訝的語氣中帶點些許的無奈:「啊!遞移相依性?又是一個專有名詞,唉,術語真是越來越多囉。」
小博拍拍小君的肩膀,要她別擔心,有他在一切就輕鬆搞定了。他邊打氣邊說:「別怕,讓我告訴妳,妳馬上就會懂了。」
小君握住小博的手,擺出一切就交給你的臉孔,並且語重心長地說:「嗯,本姑娘洗耳恭聽。」
小博早已經準備好要怎麼說,一收到小君萬事具備的訊號後,他就開始「咕嚕咕嚕」地講了起來:「所謂的『遞移相依』,也就是說,表格中某個屬性除了功能相依於主鍵外,它還相依於某個不是候選鍵的屬性。這樣好了,我用符號來告訴妳,如果x是主鍵,y、z都是非候選鍵的屬性,當然y就功能相依於x,而z也功能相依於x,這時候,如果z功能相依於y,那麼z、y、x也就產生了遞移性的關係了。」
小君望著筆記本上小博剛剛畫的表格,想要驗證小博的話,可是看了老半天,就是不確定這個表格是否也有「遞移相依性」的問題,她抬頭求助小博:「就這個課程資料表格而言,也有遞移相依性嗎?」
小博也低頭看了一下這個表格,馬上回應小君的問題:「這個課程資料表格,的確有遞移相依性,妳注意看教師編號與教師姓名這兩個欄位。」
小君依照小博的指示依序檢查那二個欄位,發現確實有這種相依性存在其中,他高興地說:「沒錯耶,教師姓名的確是功能相依於教師編號的。這麼說來,課程編號、教師編號、以及教師姓名三個屬性間產生了遞移相依性了。」
在確定小君完全瞭解「遞移相依性」後,小博更進一步地提出解決的方案:「既然發現了遞移相依性,我們就要想辦法把它從表格裡移除,以消除前面所提到的新增、刪除、及更新的異常現象,進而符合資料庫系統的第三正規化。」
小君心中已經有了腹案,只是不太確定罷了,她決定還是請教小博,聽聽看正確的解決步驟到底是怎麼一回事:「要怎麼樣才能把遞移相依性給移除呢?」
小博不敢說得太簡略,怕小君有聽沒有懂,這才更遭呢!他慢條斯理地說:「將遞移相依性移除,我們還是利用分解表格的老方法,首先先把產生遞移相依的兩個屬性從表格中分離出來。以課程資料表為例,我們將教師標號與教師姓名獨立出來,產生新的教師資料表。而原本的課程資料表,則保留教師編號,而形成具有課程編號、課程名稱、教師編號三個欄位的表格。」
小君根據小博的指示,在筆記本上原本已經第二正規化的表格下方,再新增二個表格上去,各是課程資料表格與教師資料表格,並註明上下方三個表格彼此間的關係為何。畫好之後,小君還端詳了筆記本一會兒,思考小博剛剛說明的觀念,邊看邊說:「真的耶,這樣一來,我要新增教師姓名,只要在教師資料表新增即可,刪除課程的時候也不會影響到教師的資料,更新教師資料的時候,只要再教師資料表中改一次就好,再也不用擔心少改了一筆,這樣的第三正規化表格,實在是太方便了。」
小博附和小君的想法:「當然囉,優良的設計總是能帶給人們便利的。」