0 0

ORACLE的外键约束是否必要30

    小弟刚刚走出校门。在学校学习ORACLE数据库的时候知道数据库有完整性约束来保证数据完整性。但是,毕业后进入的头一家公司,也就是目前这家公司,所有的数据库表没有一点儿的外键约束。问了里头的高手,搞java的都不晓得为什么这么规定,搞ORACLE的说外键约束在对表做操作的时候会执行检查操作,浪费性能开销。我一直不明白这句话的意思,节省了性能开销不也是在破坏数据完整性?当业务改变的时候导致规则的改变就无法达到只修改数据库约束规则不改变应用程序代码的目的,使得应用程序和数据库高度耦合。
    举个简单的例子说:比如,原来系统业务规则为当删除主表的行时,同时删除子表的相关数据行。在应用程序中的程序代码就是先查询子表相关数据进行删除,然后再删除主表。当业务规则改变为:删除主表记录后并不删除子表记录,而是将子表记录外键置空。这时又得在程序中将所有子表相关数据查询出来外键置空,主表在删除。
    而用上外键约束时,只需要在程序中写一次删除主表记录的代码,然后通过操作数据库改变外键约束规则就可达到目的。
    当然我只是刚刚从学校出来的菜鸟,学识浅薄,在大型项目中是否需要牺牲完整性约束而提高系统性能我还没发评估,这也就是我想问的问题。在现实的项目中怎么去识别需要不需要完整性约束规则?或者说目前的企业级项目中是否也像我们公司一样出于性能考虑都没有使用完整性约束?
    望高手大牛们给小弟指点迷津。在此谢过~·

问题补充:
蔡华江 写道
这个问题去itpub上问才有人解释得清楚 
http://www.itpub.net/thread-1313696-1-1.html

正方:代表人物newkid。主要论点如下
引用

QUOTE:原帖由 newkid 于 2010-6-10 22:48 发表

记得我不止一次在这里和别人争过这个问题了。
1. 你的程序再严谨也有可能出现BUG;你自己判断不如交给数据库判断,它做得又快又好。
    大多数人的程序没有考虑并发问题。一旦考虑了就得手工加锁,效率很低。
    数据可能绕过你的应用程序进入数据库。
2. 性能问题:难道你自己做就没有开销?
    一个外键判断分摊到事务级别,开销可以忽略,用户完全没有察觉。
    如果是批量导入数据,可以先暂时屏蔽外键,事后用NOVALIDATE选项快速恢复,前提是你的数据是干净的。
3. 举个麻烦的例子看看?
    外键约束正是为了防止你乱来,这是给你的保护。
    开车系安全带麻烦吧?有时候它能救你的命。
4. nyfor说过了可以用延迟约束。但根据我的经验没什么必要。凡是有外键则父亲数据必定先生成。比方说你的入库单,入库明细需要这个单号,那么父亲表(入库单)肯定要先生成。

此外,外键还会给CBO提供重要的信息,用来生成最优计划。

反方:代表人物qingyun。主要论点如下

QUOTE:原帖由 qingyun 于 2010-6-10 13:32 发表
我不太喜欢外键,
原因:
   1.程序逻辑,完整性,我会在存储过程或包等地方做严谨的判断;
   2.性能问题,这是我最不喜欢用的关键原因,比如一个业务流水表,频繁插入数据,如果这个表身上有3外键,那么每次插入一条,就必须对这3个外键对应的 3个表做相应的查找判断有无对应数据,如果这3个表也很大,那就这3个表的判断时间就很常,虽然外键指向的关联表的字段肯定是索引,但是我觉得很多时候,这样的判断本来就在程序里控制好了,通过外键再判断一次,就是降低性能;而且其实有的地方判不判断也无所谓的,但是用了外键,就必须化时间去判断,无论 oracle内部多么优化外键对于数据的检索速度,它总是一个不小的消耗;
   3.维护麻烦,很多公司的软件都是定制的,这种定制的东西,随意性相对较大,项目开发实施过程中,需要经常对表修修补补;还有就是业务逻辑有bug或者其他情况,需要经常手工维护数据,有错综复杂的外键关联着,很是麻烦;
   4.外键定死了两个表之间数据的先后生成关系,最常见的是单据主从表,有的时候,在生成单据的时候,是先生成明细,再生成主表;如果钉死了外键,这个就没法实现;
 
  当然有些关键的业务,确实需要外键;


为什么说这个话题,我今天把项目数据库建立好后,用了很少的外键,周围同事说数据不严谨,需要错综复杂的那些相同字段名的外键都建立起来,这个我很不情愿;

比如这个数据库一共100个表,按他们的想法,外键就可能有300个;我晕,太教条主义了;
如果说让我建300个索引,我很乐意,因为提高运作效率的,而外键只是检测严谨性,对数据库的运作效率只有降低,没有任何提高的可能性;


其实这只是设计习惯的问题 ,有兴趣大家随便聊聊自己的习惯。

还有一个反方的声音有独特见解,一起放上来供大家参考

QUOTE:原帖由 ruideliang 于 2010-6-12 14:42 发表
外键是暴露的,程序是封闭的,同样是经过测试的程序和外键约束,人为因素造成约束失效的可能性谁大谁小,很明显,所以反对使用外键,因为与系统高可用性目的冲突


哇,太悲剧了。里面说到newkid 正在做证券软件。不过他还没开始动手。但是我们公司就是做证券软件的,里面表就是没有外键。不知道newkid 大师到时候会怎么考虑的。哈哈哈
2010年8月18日 09:33

5个答案 按时间排序 按投票排序

0 0

        这个可能还和系统实际的开发、上线、维护等等有一定关系,后台数据结构关联少一些,数据库移植要方便些,前台程序对数据库的操作,灵活性大些。
        就像楼上提到的,现在很多公司的很多人,都有这种思想:不管是哪个数据库软件,在一般项目应用中,用得最多的功能,就是数据存储,其它功能用得相对较少。有的时候,需要在不同的数据库软件之间进行数据移植,如果数据结构太过复杂,那么在移植时,是相当麻烦的。我个人也偏向于数据结构做到最简单,通过前台应用程序去控制相应逻辑即可。

2010年8月18日 09:54
0 0

那么数据库的设计也就是方便编程。。。也不会考虑太多的业务变化。。没那么多变化,最多朝升级扩展的方向想一下

2010年8月18日 09:43
0 0

这个问题去itpub上问才有人解释得清楚 
http://www.itpub.net/thread-1313696-1-1.html

正方:代表人物newkid。主要论点如下

引用

QUOTE:原帖由 newkid 于 2010-6-10 22:48 发表

记得我不止一次在这里和别人争过这个问题了。
1. 你的程序再严谨也有可能出现BUG;你自己判断不如交给数据库判断,它做得又快又好。
    大多数人的程序没有考虑并发问题。一旦考虑了就得手工加锁,效率很低。
    数据可能绕过你的应用程序进入数据库。
2. 性能问题:难道你自己做就没有开销?
    一个外键判断分摊到事务级别,开销可以忽略,用户完全没有察觉。
    如果是批量导入数据,可以先暂时屏蔽外键,事后用NOVALIDATE选项快速恢复,前提是你的数据是干净的。
3. 举个麻烦的例子看看?
    外键约束正是为了防止你乱来,这是给你的保护。
    开车系安全带麻烦吧?有时候它能救你的命。
4. nyfor说过了可以用延迟约束。但根据我的经验没什么必要。凡是有外键则父亲数据必定先生成。比方说你的入库单,入库明细需要这个单号,那么父亲表(入库单)肯定要先生成。

此外,外键还会给CBO提供重要的信息,用来生成最优计划。

反方:代表人物qingyun。主要论点如下

QUOTE:原帖由 qingyun 于 2010-6-10 13:32 发表
我不太喜欢外键,
原因:
   1.程序逻辑,完整性,我会在存储过程或包等地方做严谨的判断;
   2.性能问题,这是我最不喜欢用的关键原因,比如一个业务流水表,频繁插入数据,如果这个表身上有3外键,那么每次插入一条,就必须对这3个外键对应的 3个表做相应的查找判断有无对应数据,如果这3个表也很大,那就这3个表的判断时间就很常,虽然外键指向的关联表的字段肯定是索引,但是我觉得很多时候,这样的判断本来就在程序里控制好了,通过外键再判断一次,就是降低性能;而且其实有的地方判不判断也无所谓的,但是用了外键,就必须化时间去判断,无论 oracle内部多么优化外键对于数据的检索速度,它总是一个不小的消耗;
   3.维护麻烦,很多公司的软件都是定制的,这种定制的东西,随意性相对较大,项目开发实施过程中,需要经常对表修修补补;还有就是业务逻辑有bug或者其他情况,需要经常手工维护数据,有错综复杂的外键关联着,很是麻烦;
   4.外键定死了两个表之间数据的先后生成关系,最常见的是单据主从表,有的时候,在生成单据的时候,是先生成明细,再生成主表;如果钉死了外键,这个就没法实现;
 
  当然有些关键的业务,确实需要外键;


为什么说这个话题,我今天把项目数据库建立好后,用了很少的外键,周围同事说数据不严谨,需要错综复杂的那些相同字段名的外键都建立起来,这个我很不情愿;

比如这个数据库一共100个表,按他们的想法,外键就可能有300个;我晕,太教条主义了;
如果说让我建300个索引,我很乐意,因为提高运作效率的,而外键只是检测严谨性,对数据库的运作效率只有降低,没有任何提高的可能性;


其实这只是设计习惯的问题 ,有兴趣大家随便聊聊自己的习惯。

还有一个反方的声音有独特见解,一起放上来供大家参考

QUOTE:原帖由 ruideliang 于 2010-6-12 14:42 发表
外键是暴露的,程序是封闭的,同样是经过测试的程序和外键约束,人为因素造成约束失效的可能性谁大谁小,很明显,所以反对使用外键,因为与系统高可用性目的冲突

2010年8月18日 09:42
0 0

事实上不会有那么多变化。。特别是小公司

也许你会想。。什么什么面向接口编程。。数据层跟业务层通过接口解耦,以便换一种实现,但事实上不会换另一种实现。。小公司几乎是这样。。我现在的公司连接口都省了。。。没那么多讲究。。要的只是功能和效率。。我刚来那会儿都晕了

2010年8月18日 09:41
0 0

引用
搞ORACLE的说外键约束在对表做操作的时候会执行检查操作,浪费性能开销。我一直不明白这句话的意思,节省了性能开销不也是在破坏数据完整性?


很巧! 我们系统 外键也很少!

07年的系统!用了这么久 感觉还可以!
首先肯定加了外键 对大系统来说是有点 浪费开销! 现在还有好多人鼓励 NO sql 纯粹没关系!

表设计的好 也不会 破坏数据完整性 的!
而且这种表设计 和 开发代码都很容易上手!
这是我的实际经验!

2010年8月18日 09:39

相关推荐

Global site tag (gtag.js) - Google Analytics