[求助]有关数据库建外键与不建外键的区别?

时间:2022-09-20 08:20:55
     在项目当中,我参与开发了数据库字典。在设计当中,项目经理的意思,就是把所有有关系的表都建立起主外键关系。我个人持反对状态。认为这样在程序上效率上会有点差距。但又拿不出数据出来证明,也因为我自己对建主外键关系有一种模糊感。现想请大家一起帮忙讨论下。是建外键好,还是不建外键好。他们各有什么优点

19 个解决方案

#1


不必把所有有关系的表建立主外键
要把关系密切,依赖关系的表建立主外键

#2


楼主先去学会基础知识吧.

#3


数据库的完整性还是有些必要的.... 

#4


能具体说一下吗?

#5


建立外间约束还是好一些的......

#6


在项目当中,我参与开发了数据库字典。在设计当中,项目经理的意思,就是把所有有关系的表都建立起主外键关系。我个人持反对状态。认为这样在程序上效率上会有点差距。但又拿不出数据出来证明,也因为我自己对建主外键关系有一种模糊感。现想请大家一起帮忙讨论下。是建外键好,还是不建外键好。他们各有什么优点

------------------------------

原则是:能不用尽量不用.

#7


能不用尽量不用

#8


性能不是靠牺牲数据完整性提高的,个人觉得要分情况,比如一个Fact表和GeoMapping有主外键关系可以通过GeoID提取数据,这样速度不经快而且能保证数据完整性.

#9


个人做法:在数据库中不建外键,在前台程序中控制外键关系

理由一是不管在数据库中是否有建立外键(其实可以推广到所有约束),在前台程序中必须判断约束,否则更新时极有可能不成功

#10


尽量少用,程序中多加判断

#11


引用 8 楼 dc1728 的回复:
性能不是靠牺牲数据完整性提高的,个人觉得要分情况,比如一个Fact表和GeoMapping有主外键关系可以通过GeoID提取数据,这样速度不经快而且能保证数据完整性.


提取数据与主外键设置毫无关系!

主外键关系只管作参照完整性检查.

#12


当你的业务逻辑层能绝对保证数据的完整性关系的时候,不建.

当你不知道你的业务逻辑层是否能保证数据的完整性关系的时候,建.

#13


有一个建议:
当系统处于开发阶段时,对速度要求不是很高,但业务逻辑又不十分完善时,先建.
当系统运行良好,但访问量增大,速度成瓶颈时,考虑去掉外键关系以加愉运行速度.

不过,个人觉得,还是建的好,必竟那是数据库的最后一道防线,对DBMS,咱们还是要给以信任的.再说了,现在的系统,有几个是由于DBMS而造成速度问题的呢!

#14


在此很感谢各位的发言:
各位的发言各有不同,我非常佩服各位的技术。但同时也很迷茫!也许大家说的都没错。只是大家所站的角度可能不同罢了。
其实我只想站在一个程序员的角度来考虑这个问题。
作为程序员来讲,我个人认为:首先是考虑效率问题,其次跟据项目的复杂度选择最优的完工计划。
根据以上两点我个人有一个思路。不知对与错,请各位指正:

从效率上来讲:
建外键的缺点:用户在执行插入操作时会去检索主表。如果插入的数据在主表中找不到,就会抛异常。这个异常用户是看不懂的。所以程序员要捕捉这个异常。但用Exception来捕捉,就有点太笼统了。所以最好的办法还是要通过程序员自己去查主表。这也就意味着要执行两次查询工作。优点:在参差不齐的程序员当中有时会忘记在程序当中作出判断,从而导致不合法的数据录入到数据库中去。而在建外键的情况下,这种不合法的数据就杜绝了。

从复杂度来讲:
建外键的缺点:对于程序员来讲。在众多建立关系的表中去理解出一条思路是非常困难的。相对于不建外键来说。显得有点复杂。感觉不知从何下手解决问题。在一个考虑在程序当中的实现问题。假如有三张表建立了外键关系。那么我要删第一张表中的某条记录时。也许你就会要去检索后面两张表的数据。如果在后面两张表中有这个数据。他就会抛异常。所以先要删除后面两张表的数据。这种牵一动百的事情对于程序员来说:这是一种可耻的行为。假如他们之间没有建立关系。也许也将要删除后面两张表的数据。但他是直接删除。而没有再去检索数据。

#15


最好是建。这样可以减少无效数据.

#16


假定有一个客户表和订单表
1、真正的外键关系是处于活动状态中客户才能下订单,这用外键关系如何表达,需要用视图,如果某一天规则变成变成只有一定效益的客户才能下订单,该如何在数据库中修改。
2、假如某一天,我发现客户代号编码有问题需要重新编码,请问该怎么办,那么客户表中旧客户代号不能删除,因为订单绝不能删除,

外键关系只是众多约束的一种,也是很简单的一种,如果在数据库中把所有约束考虑进去的话,会有极大的不方便

个人意见,欢迎讨论

#17


不建外建??
唉,你们对自己的业务逻辑处理能力和代码能力也太自信了吧!!!!
只有两种情况是不需要建立外建的:
1、两表之间没有关联关系,或者两表之间的关联关系无法用外建进行约束。
2、两表之间虽然有关联关系而且也能符合外建约束要求,但由于只是作为数据采集的占存表,并没有参与进一步的业务逻辑处理。
除了以上两条都应该建立外建约束,为什么,因为查错成本要远远高于开发成本。

#18


TO:Cson_cson
那除外键之外的约束,你是怎样处理的?
仅为讨论,别无他意。

#19


引用 18 楼 jxwangjm 的回复:
TO:Cson_cson 
那除外键之外的约束,你是怎样处理的? 
仅为讨论,别无他意。

缺省值、非空、主键、唯一索引、触发器、存储过程...

#1


不必把所有有关系的表建立主外键
要把关系密切,依赖关系的表建立主外键

#2


楼主先去学会基础知识吧.

#3


数据库的完整性还是有些必要的.... 

#4


能具体说一下吗?

#5


建立外间约束还是好一些的......

#6


在项目当中,我参与开发了数据库字典。在设计当中,项目经理的意思,就是把所有有关系的表都建立起主外键关系。我个人持反对状态。认为这样在程序上效率上会有点差距。但又拿不出数据出来证明,也因为我自己对建主外键关系有一种模糊感。现想请大家一起帮忙讨论下。是建外键好,还是不建外键好。他们各有什么优点

------------------------------

原则是:能不用尽量不用.

#7


能不用尽量不用

#8


性能不是靠牺牲数据完整性提高的,个人觉得要分情况,比如一个Fact表和GeoMapping有主外键关系可以通过GeoID提取数据,这样速度不经快而且能保证数据完整性.

#9


个人做法:在数据库中不建外键,在前台程序中控制外键关系

理由一是不管在数据库中是否有建立外键(其实可以推广到所有约束),在前台程序中必须判断约束,否则更新时极有可能不成功

#10


尽量少用,程序中多加判断

#11


引用 8 楼 dc1728 的回复:
性能不是靠牺牲数据完整性提高的,个人觉得要分情况,比如一个Fact表和GeoMapping有主外键关系可以通过GeoID提取数据,这样速度不经快而且能保证数据完整性.


提取数据与主外键设置毫无关系!

主外键关系只管作参照完整性检查.

#12


当你的业务逻辑层能绝对保证数据的完整性关系的时候,不建.

当你不知道你的业务逻辑层是否能保证数据的完整性关系的时候,建.

#13


有一个建议:
当系统处于开发阶段时,对速度要求不是很高,但业务逻辑又不十分完善时,先建.
当系统运行良好,但访问量增大,速度成瓶颈时,考虑去掉外键关系以加愉运行速度.

不过,个人觉得,还是建的好,必竟那是数据库的最后一道防线,对DBMS,咱们还是要给以信任的.再说了,现在的系统,有几个是由于DBMS而造成速度问题的呢!

#14


在此很感谢各位的发言:
各位的发言各有不同,我非常佩服各位的技术。但同时也很迷茫!也许大家说的都没错。只是大家所站的角度可能不同罢了。
其实我只想站在一个程序员的角度来考虑这个问题。
作为程序员来讲,我个人认为:首先是考虑效率问题,其次跟据项目的复杂度选择最优的完工计划。
根据以上两点我个人有一个思路。不知对与错,请各位指正:

从效率上来讲:
建外键的缺点:用户在执行插入操作时会去检索主表。如果插入的数据在主表中找不到,就会抛异常。这个异常用户是看不懂的。所以程序员要捕捉这个异常。但用Exception来捕捉,就有点太笼统了。所以最好的办法还是要通过程序员自己去查主表。这也就意味着要执行两次查询工作。优点:在参差不齐的程序员当中有时会忘记在程序当中作出判断,从而导致不合法的数据录入到数据库中去。而在建外键的情况下,这种不合法的数据就杜绝了。

从复杂度来讲:
建外键的缺点:对于程序员来讲。在众多建立关系的表中去理解出一条思路是非常困难的。相对于不建外键来说。显得有点复杂。感觉不知从何下手解决问题。在一个考虑在程序当中的实现问题。假如有三张表建立了外键关系。那么我要删第一张表中的某条记录时。也许你就会要去检索后面两张表的数据。如果在后面两张表中有这个数据。他就会抛异常。所以先要删除后面两张表的数据。这种牵一动百的事情对于程序员来说:这是一种可耻的行为。假如他们之间没有建立关系。也许也将要删除后面两张表的数据。但他是直接删除。而没有再去检索数据。

#15


最好是建。这样可以减少无效数据.

#16


假定有一个客户表和订单表
1、真正的外键关系是处于活动状态中客户才能下订单,这用外键关系如何表达,需要用视图,如果某一天规则变成变成只有一定效益的客户才能下订单,该如何在数据库中修改。
2、假如某一天,我发现客户代号编码有问题需要重新编码,请问该怎么办,那么客户表中旧客户代号不能删除,因为订单绝不能删除,

外键关系只是众多约束的一种,也是很简单的一种,如果在数据库中把所有约束考虑进去的话,会有极大的不方便

个人意见,欢迎讨论

#17


不建外建??
唉,你们对自己的业务逻辑处理能力和代码能力也太自信了吧!!!!
只有两种情况是不需要建立外建的:
1、两表之间没有关联关系,或者两表之间的关联关系无法用外建进行约束。
2、两表之间虽然有关联关系而且也能符合外建约束要求,但由于只是作为数据采集的占存表,并没有参与进一步的业务逻辑处理。
除了以上两条都应该建立外建约束,为什么,因为查错成本要远远高于开发成本。

#18


TO:Cson_cson
那除外键之外的约束,你是怎样处理的?
仅为讨论,别无他意。

#19


引用 18 楼 jxwangjm 的回复:
TO:Cson_cson 
那除外键之外的约束,你是怎样处理的? 
仅为讨论,别无他意。

缺省值、非空、主键、唯一索引、触发器、存储过程...

#20