今天看天乙社區的程序,發現一個外鍵都沒有啊,太狠了。上網看了一些資料,稍微整理了一下。
這個帖子很牛:
http://www.itpub.net/viewthread.php?tid=1313696&extra=&page=1
我的觀點是,外鍵在初始階段能加的都加上,只有迫不得已的時候才disable或drop掉。遇到性能瓶頸的時候,盡量采用其它方式調優,而不要輕易犧牲掉外鍵。有外鍵約束的時候,寫程序的確會有約束,但從直覺上說這種約束一定程度上揭示了設計或實現上不合理的地方。帶著外鍵寫出來的應用更傾向于嚴謹。產品上線之前如果確實需要通過犧牲外鍵達到性能上的優化,再撿相對不重要的外鍵廢棄掉,同時要把這個document下來,下次遇到數據不一致問題的時候,是個線索。兩點說明:1. 我們在做的一個項目確實是小項目。 2. 我得承認我最近三年開發都不用關系型數據庫,貌似 no sql那么nb的key-value pair存數據,其實這三年在持久層上很多糾結。如果我說的不對,請指正!
下面引用一些有見地的想法:
× 支持外鍵的:
1. 你的程序再嚴謹也有可能出現BUG;你自己判斷不如交給數據庫判斷,它做得又快又好。
大多數人的程序沒有考慮并發問題。一旦考慮了就得手工加鎖,效率很低。
數據可能繞過你的應用程序進入數據庫。
2. 性能問題:難道你自己做就沒有開銷?
一個外鍵判斷分攤到事務級別,開銷可以忽略,用戶完全沒有察覺。
如果是批量導入數據,可以先暫時屏蔽外鍵,事后用NOVALIDATE選項快速恢復,前提是你的數據是干凈的。
也有人提到了如果100張表可能需要建立300個約束,導致性能太差。
我要說的仍然是,是否這300個外鍵約束都是業務必須的,如果是,沒有辦法這就是必須要加的,如果不是,那么大可不必在所有的地方都增加外鍵。
如果在程序中僅對其中的5、6張表的10來個外鍵約束進行判斷,然后和數據庫中的300個外鍵去比較,并評價Oracle的外鍵性能太差,恐怕是有失公允的。
× 反對外鍵的:
的確外鍵在大系統中用的很少,在開發初級,設計數據庫的時候一般會加入外鍵,以保證系統設計的完整性和業務需求的完整性,也便于開發人員了解業務規則,在程序中加以控制,很多大系統在系統穩定后,會逐步將外鍵去掉,以保證性能,將太多的功能強加于數據庫,雖然說數據庫很強大,但是畢竟很多人不信任數據庫的能強大到什么都能干的地步。所以在一個大系統中外鍵見的少也不足為奇,小系統就無所謂了,用不用外鍵取決于設計人員,這樣的系統也隨處可見。
另引用一篇:
引自http://blog.csdn.net/neusoft_lkz/archive/2009/07/21/4366668.aspx
數據庫設計是否需要外鍵。這里有兩個問題:一個是如何保證數據庫數據的完整性和一致性;二是第一條對性能的影響。
正方觀點:
1,由數據庫自身保證數據一致性,完整性,更可靠,因為程序很難100%保證數據的完整性,而用外鍵即使在數據庫服務器當機或者出現其他問題的時候,也能夠最大限度的保證數據的一致性和完整性。
eg:數據庫和應用是一對多的關系,A應用會維護他那部分數據的完整性,系統一變大時,增加了B應用,A和B兩個應用也許是不同的開發團隊來做的。他們如何協調保證數據的完整性,而且一年以后如果又增加了C應用呢?
2,有主外鍵的數據庫設計可以增加ER圖的可讀性,這點在數據庫設計時非常重要。
3,外鍵在一定程度上說明的業務邏輯,會使設計周到具體全面。
反方觀點:
1,可以用觸發器或應用程序保證數據的完整性
2,過分強調或者說使用主鍵/外鍵會平添開發難度,導致表過多等問題
3,不用外鍵時數據管理簡單,操作方便,性能高(導入導出等操作,在insert, update, delete 數據的時候更快)
eg:在海量的數據庫中想都不要去想外鍵,試想,一個程序每天要insert數百萬條記錄,當存在外鍵約束的時候,每次要去掃描此記錄是否合格,一般還不止一個字段有外鍵,這樣掃描的數量是成級數的增長!我的一個程序入庫在3個小時做完,如果加上外鍵,需要28個小時!
結論:
1,在大型系統中(性能要求不高,安全要求高),使用外鍵;在大型系統中(性能要求高,安全自己控制),不用外鍵;小系統隨便,最好用外鍵。
2,用外鍵要適當,不能過分追求
3,不用外鍵而用程序控制數據一致性和完整性時,應該寫一層來保證,然后個個應用通過這個層來訪問數據庫。