眾所周知,資料庫設計的好壞直接關係到資料庫啟動並執行效率。根據筆者的經驗,對於提升資料庫效能來說,合理的資料庫設計,比升級伺服器的硬體設定,還要來的有效。但是,筆者無論是在跟同事合作,又或者是在論壇上跟相關同行交流的時候,總是會發現有些人有一些不好的資料庫設計習慣,影響了資料庫的效能,增加了資料庫管理員的工作量。
筆者認為,為了提升資料庫的效能,在Oracle資料庫設計的時候,要做到五戒。
一戒:在小型表上不要建立索引。
毋庸置疑,索引可以提高資料庫查詢的效率。但是,俗話說,過之則不及。索引也必須用在合時的地方。如果索引設定不當,不但不會提升資料庫的效能,反而會起到相反的作用。如在小型資料庫上設定索引,而且這些表使用者更改的比較頻繁。如員工基本資料表,就是簡單的不超過十個欄位。這個表使用者需要經常的進行插入與刪除操作。當進行這些變更作業的時候,需要對索引進行維護。而這個維護的工作量可能比掃描資料表空間消耗更多的儲存空間。從而不但起步到改善資料庫效能的作用,反而是在拖後腿。
所以,在資料庫設計的時候,要做到的第一個戒條就是,不要再使用者經常更改的小型表上建立索引。否則的話,是得不償失的。
二戒:不要用使用者的鍵。
如我們在設計一個ERP系統資料庫的時候,有一張銷售訂單表。在這張表中,有一個銷售訂單號。那麼我們能否利用這個單號作為關聯其他表的外鍵呢?如在銷售出貨單上,需要關聯到銷售訂單。這個時候,我們能否把銷售訂單單號作為跟出貨單關聯的關鍵字呢?
答案是可以的,但是不是最優選擇。我們可以看一下ERP的後台資料庫。在銷售訂單表上,除了銷售訂單號這個唯一表示銷售訂單紀錄的欄位外,還有一個欄位就是銷售訂單ID。在前台的出貨單介面上雖然顯示的是銷售訂單號碼,但是,在後台卻儲存著的是銷售訂單ID。也就是說,資料庫不是以使用者的鍵作為主鍵,而是採用了資料庫自動維護的單據ID這個欄位。
為什麼要這麼設計呢?這就是筆者今天要談的第二個戒條,不要用使用者的鍵。通常情況下,不要選擇使用者可編輯的欄位作為外鍵或者主鍵。因為這會增加我們額外的工作量。
如果我們把銷售訂單號作為外鍵的話,則在建立銷售訂單紀錄後還要對使用者編輯欄位的行為施加限制,如判斷是否違反外鍵的強制性規則等等。有些系統把銷售訂單號設定為外鍵的話,則往往是把這個欄位設定為系統自動編號,並且使用者不可更改。可是,在實際工作中,企業員工往往需要編輯這個欄位。員工需要編輯這些不可編輯的欄位時系統缺乏靈活性的缺陷就體現出來了。而且,當使用者輸入完資料儲存的時候再提示紀錄不符合要求,則也不是很人性化的設計。
另外,我們還必須為此設計一些檢測和糾正鍵衝突的方法。如考慮這個外鍵的直是否在其他資料表中存在等等。雖然這通常只需要我們花點時間就可以搞定。但是從資料庫效能上來說,這個代價就比較大了。再則,如此的話,就不能夠很好的把系統的基本資料跟企業員工的資料實現很好的隔離。
所以,筆者認為,不要用使用者的鍵來作為我們資料庫設計的主鍵或則外鍵。或者說,資料庫設計時用到的鍵要讓資料庫系統進行自動維護,使用者不得更改這個維護規則。
三戒:不要用商務規則來實現資料的完整性。
資料的完整性有好幾種實現方法。如可以通過資料庫約束實現資料完整性;也可以通過前台系統的商務規則來實現資料的完整性。不過,筆者這裡要建議的是,在一些大型的資料庫中,不要試圖通過商務規則來實現資料的完整性,而儘可能的通過資料庫的約束來實現。因為若通過商務規則來實現完整性,往往會出現一些莫名其妙的錯誤。
如筆者就遇到過這一個案例。在資料庫設計的時候,把某個字元型欄位長度限制為最長50位。而在前台應用程式中,卻限制了60位。在員工資料資料的時候,在前台應用程式中,可以輸入55個字元。但是,下次使用者查詢的時候,卻發現後面幾個字元沒有了,只剩下前面那些內容。這主要是因為在資料儲存的時候,超過了資料庫的最長位元限制。資料庫就會自動把後面幾個字元去掉然後儲存。如此,使用者在前台輸入資料的時候,以為可以儲存。但是,實際上資料庫中儲存的資料是不全的。
所以,筆者的第三個戒條就是,不要利用商務規則在前台實現資料的完整性。只要有可能,就要盡量在資料庫系統層面實現資料的完整性。在資料庫層面實現資料完整性的同時,需要注意使用者的友好性。
一是要把違反約束資訊儘可能詳細的回饋給使用者。如銷售訂單號,在資料庫系統中設定了唯一性限制式。則當使用者在建立銷售訂單的時候,銷售訂單號重複時,就需要把這個約束的詳細資料反饋給前台使用者。若只顯示不能夠儲存這個錯誤資訊往往是不夠的。這會讓使用者摸不著頭腦。
二是在必要的時候,可以利用觸發器來實現資料的完整性。雖然在功能設計上,我們不建議在Oracle資料庫中採用觸發器來實現。如要把某個小寫金額轉換為大小金額。我們是建議通過前台應用程式實現。因為應用程式的執行效率要比資料庫的觸發器高。但是,在資料庫資料完整性上,在必要的時候,若靠資料庫約束無法實現完整性,我們仍然建議採用觸發器,而不是前台應用程式來實現。在任何情況下,不要依賴於應用程式來實現資料完整性。否則的話,很難保證資料庫約束與商務層約束的一致性。
四戒:在可能的情況下,不要讓前台應用程式直接存取資料表。
其實,在資料庫基礎資料表與前台應用程式之間,還有一個很好的“中間人”,那就是視圖。試圖是資料庫基礎資料表的一個抽象。他除了可以保障資料的品質外,還可以有效訪問前台應用程式對於資料的非法訪問。所以,一些安全性層級比較高的資料庫系統,在資料庫設計的時候,往往會在資料庫和前台應用程式代碼之間提供“視圖”這個中間人,讓其作為基礎資料表的“新聞發言人”。如此,前台應用程式在沒有必要的情況下,可以不直接存取資料表,而是通過視圖來對錶實現間接的訪問。
如在進行資料匯入程式設計的時候,通過視圖來實現則是一個很理想的方法。如使用者現在要匯入產品資訊,包括產品基本資料、供應商資訊、價格資訊等等。這些資訊在資料庫中往往包含在三種表中,分別為產品基本資料表、供應商資訊表、產品價格資訊表。若前台應用程式直接存取基礎資料表的話,就需要分別訪問這三張基礎資料表。這不但效率比較低,而且也不容易實現資料的完整性。此時,我們就可以利用視圖,把一些必須要填入的欄位組合在一張可更新視圖中。如此,前台應用程式只需要訪問一個資料庫物件即可。
再者,在資料庫報表設計上,更是要通過視圖來實現。而不要通過傳遞一段SQL代碼來查詢基礎資料表。這對於資料的安全性會帶來比較大的威脅。
所以,第四個戒條就是,在可能的情況下,不要讓前台應用程式直接存取資料表。
五戒:不要一直讓使用者輸入資料。
有些欄位其實不一定要讓使用者輸入,只需要使用者選擇即可。如在人事管理系統中,企業員工所屬的民族、職位、省份等等就沒有必要讓使用者手工輸入。而可以通過列表的形式讓員工來進行選擇。這種手段,是提高資料完整性的最佳方式之一。若能夠給使用者提供一個詳細的列表供其選擇,這樣將減少鍵入代碼的錯誤,同時提高資料庫的一致性;也可以提高使用者介面的友好性。
所以,在資料庫設計的時候,盡量使用列表欄位來供使用者選擇。若連省份等等欄位都要使用者手工輸入的話,則我們在資料庫完整性所花費的時間,就要很多。如在資料儲存的時候,都要去判斷使用者輸入的資料是否合乎完整性的規則。這顯然工作量要比設計一個列表欄位多得多。
故資料庫設計的第五個戒條就是不要老是讓使用者手工輸入資料。提供列表讓使用者進行選擇,使用者不僅可以提高效率,我們也可以省事,同時,也能夠保障資料的準確率。