人在江湖

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            82 Posts :: 10 Stories :: 169 Comments :: 0 Trackbacks

          今天看天乙社區的程序,發現一個外鍵都沒有啊,太狠了。上網看了一些資料,稍微整理了一下。

          這個帖子很牛:

          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,不用外鍵而用程序控制數據一致性和完整性時,應該寫一層來保證,然后個個應用通過這個層來訪問數據庫。

          posted on 2011-02-17 00:58 人在江湖 閱讀(2819) 評論(12)  編輯  收藏 所屬分類: others

          Feedback

          # re: 咱數據庫使用外鍵么? 2011-02-17 09:52 simaliu
          外鍵顯然是和業務邏輯相關的,把本來屬于業務邏輯的處理放到數據庫顯然不是個好想法。  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 10:50 人在江湖
          @simaliu
          建了外鍵反應并保證了業務邏輯,也沒實現業務邏輯。應用層的業務邏輯該怎么寫還是怎么寫啊。外鍵保證了業務邏輯沒有數據不一致的漏洞。現實地說,業務邏輯往往容易忽略并發情況,而并發情況容易造成數據不一致。  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 11:14 penngo
          習慣設計時考慮完整的外鍵,開發時不用或少用外鍵,放在程序里面處理。  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 11:50 @joe
          一般建議對索引加外鍵,可以防止鎖表。  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 12:34 人在江湖
          @@joe
          對索引加外鍵還是對外鍵加索引?  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 13:23 Jonathank
          什么叫“小系統”?
          這就是作者對系統設計的態度嗎?

          系統沒有大小之分,只有對應用場景的現實價值的區別。別用那么膚淺的眼光去看待系統,更加不要以此來導向系統設計。  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 13:25 淘寶皇冠店
          很好65565  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 13:26 淘寶皇冠店126
          很好645565  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 13:27 人在江湖
          @Jonathank
          呵呵,Martin大叔也沒把transaction script一棒子打死吧  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 17:39 陳于喆
          基本上我的系統是沒有外鍵的,有一個重要點就是我始終認為外鍵是對業務邏輯對數據庫的入侵,當然了,這個在于你怎么定位數據庫的層  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-17 17:57 rox
          雖然自己不用,但不反對外鍵或者存儲過程的使用。
          只要整個團隊統一標準,并能夠在此之上做到長期穩健快速的維護。  回復  更多評論
            

          # re: 咱數據庫使用外鍵么? 2011-02-20 16:17 tbw淘寶
          很明顯,博主說得是天涯社區吧。。。。話說天涯的數據系統真的很給力。。。  回復  更多評論
            

          主站蜘蛛池模板: 平利县| 社旗县| 云梦县| 泰顺县| 宁阳县| 石屏县| 嘉善县| 綦江县| 淮阳县| 虞城县| 天全县| 腾冲县| 万宁市| 红河县| 宝丰县| 麟游县| 名山县| 资溪县| 仁化县| 汉寿县| 普宁市| 司法| 稻城县| 湘乡市| 囊谦县| 陇南市| 开平市| 宁城县| 富宁县| 瑞安市| 綦江县| 陵水| 灵丘县| 望城县| 澄迈县| 赤壁市| 团风县| 龙口市| 通许县| 黄浦区| 桐庐县|