在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程序同时修改,任何一种程序的问题都可能会导致脏数据的引入,相对而言,通过外键来实现可以避免任何途径的脏数据的写入,包括后台的直接修改。
当然,外键只是一个工具,恰当的使用可以避免很多数据问题,不恰当的时候有时候也很容易引起性能问题,比如外键列上没有建立对应的索引。
增加外键后必然会带来性能影响,这是勿庸置疑的。如果一张表上有2、30个外键,那么这张表的DML操作肯定要比没有外键的情况下慢一些。
但是,不能由于外键带来性能影响就否认外键的功能。
首先,这2、30列的约束是否是业务需要,如果需要,那么这种性能影响就是不可避免的,无论是通过外键实现,还是通过程序实现,都一样会带来性能的影响,而且一般来说,在Oracle中通过外键实现,都要比通过程序实现也快,先不说你自己实现的功能能否比Oracle实现的更迅速,至少通过外键实现不需要和数据库进行那么多次的数据交互。而通过程序,则大量的检查和锁表是不可避免的。
也有人提到了如果100张表可能需要建立300个约束,导致性能太差。
我要说的仍然是,是否这300个外键约束都是业务必须的,如果是,没有办法这就是必须要加的,如果不是,那么大可不必在所有的地方都增加外键。
如果在程序中仅对其中的5、6张表的10来个外键约束进行判断,然后和数据库中的300个外键去比较,并评价Oracle的外键性能太差,恐怕是有失公允的。
在所有字段被引用的情况都增加外键,不过是从一个极端走向了另一个极端。外键确实可以带来很大的方便,但是外键必要条件,很多时候外键完全没有必要。
有时经常会增加一些日志表,这些表就没有建立外键的意义。
有些非关键性业务表一样不需要建立外键。
再次重申,外键仅仅是一个工具,如何应用则要看使用者了。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-665425/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/4227/viewspace-665425/