-
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个答案 按时间排序 按投票排序
-
这个可能还和系统实际的开发、上线、维护等等有一定关系,后台数据结构关联少一些,数据库移植要方便些,前台程序对数据库的操作,灵活性大些。
就像楼上提到的,现在很多公司的很多人,都有这种思想:不管是哪个数据库软件,在一般项目应用中,用得最多的功能,就是数据存储,其它功能用得相对较少。有的时候,需要在不同的数据库软件之间进行数据移植,如果数据结构太过复杂,那么在移植时,是相当麻烦的。我个人也偏向于数据结构做到最简单,通过前台应用程序去控制相应逻辑即可。2010年8月18日 09:54
-
这个问题去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
-
事实上不会有那么多变化。。特别是小公司
也许你会想。。什么什么面向接口编程。。数据层跟业务层通过接口解耦,以便换一种实现,但事实上不会换另一种实现。。小公司几乎是这样。。我现在的公司连接口都省了。。。没那么多讲究。。要的只是功能和效率。。我刚来那会儿都晕了2010年8月18日 09:41
-
引用搞ORACLE的说外键约束在对表做操作的时候会执行检查操作,浪费性能开销。我一直不明白这句话的意思,节省了性能开销不也是在破坏数据完整性?
很巧! 我们系统 外键也很少!
07年的系统!用了这么久 感觉还可以!
首先肯定加了外键 对大系统来说是有点 浪费开销! 现在还有好多人鼓励 NO sql 纯粹没关系!
表设计的好 也不会 破坏数据完整性 的!
而且这种表设计 和 开发代码都很容易上手!
这是我的实际经验!
2010年8月18日 09:39
相关推荐
### Oracle定义约束:外键约束详解 #### 一、引言 在数据库设计与管理过程中,维护数据的一致性和完整性是非常重要的。Oracle数据库系统提供了一系列的机制来帮助开发者和管理员达到这一目标,其中最重要的机制之一...
在这种情况下,禁用所有表的外键约束就显得非常有必要。 首先,让我们了解一下如何在Oracle中批量禁用所有表的外键约束。这通常涉及到三个主要步骤: 1. **删除所有外键约束**:虽然在实际操作中我们可能并不需要...
Oracle 是一款功能强大且广泛应用的关系数据库管理系统,作为Oracle运维人员,熟悉常用的命令和语句是非常必要的。本文档汇总了 Oracle 日常运维中常用的命令和语句,包括登录 Oracle 数据库、创建数据表、约束的...
这里的`fk_edon`是外键约束的名称,而`REFERENCES i_tops(edon)`指明了这个外键约束关联的是哪个表以及表中的哪一列。 #### 5. 检查约束 (CHECK) 检查约束用于限制列中数据的有效范围,例如限制某列的值只能在某个...
这样,当试图删除父表中的记录时,Oracle会检查是否存在子表中依赖该记录的外键,从而决定是否允许删除。创建外键约束的语法如下: ```sql CREATE TABLE table_name ( column1 datatype, FOREIGN KEY (column1) ...
通过以上步骤,我们成功地在Oracle中创建了表空间、用户、表、序列,设置了主键、外键和约束,并插入了数据。这些操作是构建关系型数据库系统的基本组成部分,对于数据库管理和应用程序开发至关重要。
- **外键约束处理:** 尽管原表的外键约束在新表创建时不被自动复制,但这并不意味着无法在新表中维护这些关系。在创建新表后,可以使用`ALTER TABLE`命令显式添加外键约束,从而确保新表与原有表之间的数据一致性。...
在Oracle数据库中,外键约束用于维护参照完整性,确保表之间的关联数据的一致性。在清空表数据之前,首先需要删除这些约束,因为它们可能会阻止直接删除数据。例如,在提供的代码中,`alter table Da_pic drop ...
- 导入完成后,检查数据库中的数据是否完整无误,特别是主键、外键约束是否正确。 完成以上步骤后,你应该成功地在Linux上的Oracle数据库中导入了数据泵文件。记住,良好的数据库管理和维护实践,包括定期备份和...
- **解除外键约束**:首先解除子表中的外键约束。 - **重建母表**:然后重建母表。 - **激活外键**:最后重新激活子表的外键约束。 #### 十三、归档与非归档模式的区别及其优缺点 - **归档模式**:支持全量备份,...
9. **索引和约束**:重建索引和外键约束,以保持数据的完整性和查询性能。 10. **测试**:在生产环境导入数据前,务必在测试环境中进行完整的功能测试,以确保迁移后的系统能够正常运行。 以上就是从SQL Server...
在这个示例中,`build_constraints`函数将根据设计文档中的信息(如是否为主键、外键等)构建相应的SQL约束部分。这需要对SQL语法有深入的理解,特别是Oracle数据库特有的约束类型。 此外,为了确保安全性和效率,...
- 导入时要谨慎处理数据冲突,比如主键冲突、外键约束等。 总之,Oracle的Export和Import工具是数据库管理中的重要工具,它们为企业级的数据迁移和备份提供了一套强大且灵活的解决方案。通过正确使用这两个工具,...
13. ORA-02292:integrity constraint (constraint name) violated - child record found - 违反外键约束,子表中有与父表相关的记录。删除或更新数据前检查关联关系。 14. ORA-00936:missing expression - SQL...
- 禁用目标库的trigger和外键约束:为了复制的稳定性和性能,可能需要禁用触发器和外键约束。 - 创建目标端GoldenGate表空间:为GoldenGate在目标端创建表空间。 - 创建目标端GoldenGate模式用户:在目标端数据库中...
在不影响子表的情况下重建母表,可以通过使子表的外键约束无效,重建母表后再激活外键约束。 12. 归档模式与非归档模式的区别及优缺点 归档模式允许备份所有数据库事务并恢复到任意时间点,而非归档模式则不能恢复...
4. **外键约束 (FOREIGN KEY)**:外键用于定义两个表之间的关联,通常是从表引用主表的主键或唯一键。这样可以确保数据的一致性,因为外键列的值必须存在于主表的主键列中或为NULL。 5. **检查约束 (CHECK)**:检查...
- **如果删除的行违反了外键关系定义,则外键约束可以阻止删除**:这是外键约束的主要功能之一。当一个表中有指向另一个表的外键时,如果试图删除主键表中的行,而次键表中存在对应的外键值时,删除操作会被阻止。 -...
为了保证数据的完整性和一致性,可以为表添加主键和外键约束。以下是具体操作步骤: 1. **编辑表**: - 右键点击`DEPENDENTS`表,选择`Edit`。 - 转到`PrimaryKey`选项卡,选择`ID`列为表的主键。 - 转到`...