是否应该使用外键

ITPUB上看到这个主题,没忍住说了几句,后来想想,干脆在这里贴出来。

ITPUB原文:http://www.itpub.net/thread-1313696-1-1.html

 

 

其实我刚开始接触Oracle的时候,也不喜欢外键,而且当时总是听别人提到利用外键会影响性能。

但是随着对Oracle理解的加深,越来越觉得外键很难被别的方式所取代。

前一段时间,一个系统为了避免出现DELETE语句,采用了DELETE_FLAG的方式实现。这就带来了一个问题,Oracle提供的主外键功能不满足要求,于是为了实现满足这种情况下的主外键关系,只好自己实现外键的功能。一旦你自己考虑并发、锁以及多版本一致性的问题,你就会发现Oracle的外键为你实现了多少的功能,而如果你考虑的不周全,就会导致违反约束的数据产生。

无法利用主外键时控制主子表的并发访问(一):http://yangtingkun.itpub.net/post/468/453295

无法利用主外键时控制主子表的并发访问(二):http://yangtingkun.itpub.net/post/468/453397

无法利用主外键时控制主子表的并发访问(三):http://yangtingkun.itpub.net/post/468/453590

在我碰到的大多数系统中,如果是通过程序来维护外键的,不可避免的都可以在数据库表中找到违反约束的记录存在。

任何程序都很难避免bug的存在,而且真正了解Oracle并发和锁机制原理的程序员就更少了,连最简单的乐观锁定和悲观锁定都不清楚的程序员也不在少数,因此指望通过程序来完全实现外键的功能,很容易在多用户并发的时候造成bug。而指望通过严格测试来避免并发性的bug还是很困难的。

更何况,数据库中的数据有可能被客户端、网页程序以及后台JOB程序同时修改,任何一种程序的问题都可能会导致脏数据的引入,相对而言,通过外键来实现可以避免任何途径的脏数据的写入,包括后台的直接修改。

当然,外键只是一个工具,恰当的使用可以避免很多数据问题,不恰当的时候有时候也很容易引起性能问题,比如外键列上没有建立对应的索引。

增加外键后必然会带来性能影响,这是勿庸置疑的。如果一张表上有230个外键,那么这张表的DML操作肯定要比没有外键的情况下慢一些。

但是,不能由于外键带来性能影响就否认外键的功能。

首先,这230列的约束是否是业务需要,如果需要,那么这种性能影响就是不可避免的,无论是通过外键实现,还是通过程序实现,都一样会带来性能的影响,而且一般来说,在Oracle中通过外键实现,都要比通过程序实现也快,先不说你自己实现的功能能否比Oracle实现的更迅速,至少通过外键实现不需要和数据库进行那么多次的数据交互。而通过程序,则大量的检查和锁表是不可避免的。

也有人提到了如果100张表可能需要建立300个约束,导致性能太差。

我要说的仍然是,是否这300个外键约束都是业务必须的,如果是,没有办法这就是必须要加的,如果不是,那么大可不必在所有的地方都增加外键。

如果在程序中仅对其中的56张表的10来个外键约束进行判断,然后和数据库中的300个外键去比较,并评价Oracle的外键性能太差,恐怕是有失公允的。

在所有字段被引用的情况都增加外键,不过是从一个极端走向了另一个极端。外键确实可以带来很大的方便,但是外键必要条件,很多时候外键完全没有必要。

有时经常会增加一些日志表,这些表就没有建立外键的意义。

有些非关键性业务表一样不需要建立外键。

再次重申,外键仅仅是一个工具,如何应用则要看使用者了。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-665425/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-665425/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值