1、数据更新有可能和约束冲突。
2、当前的数据库设计如此灵活,以致于不支持引用完整性约束。
3、数据库为外键建立的索引会影响性能。
4、当前使用的数据库不支持外键。
5、定义外键的语法并不简单,还需要查阅。
即使第一感觉告诉你,省略外键约束能使得数据库设计更加简单、灵活,或者执行更加高效,你还是不得不在其他方面付出相应的代价 -- 必须增加额外的代码来手动维护引用完整性。
1、完整性问题
很多人对引用完整性的解决方案是通过编写特定的程序代码来确保数据间的关系的。每次插入新记录时,需要确保外键列所引用的值在其对应的表中存在;每次删除记录时,需要确保所有相关的表都要同时合理地更新。
为了避免在没有外键约束的情况下产生引用的不完整状态,需要在任何改变生效前执行额外的select查询,以此来确保这些改变不会导致引用错误。
比如,在插入一条记录前之前,需要检查对应的被引用记录是否存在:
select Account_Id from Account where Account_Id = 1
然后才能执行Insert操作。要删除一条记录,需要先确认没有别的记录引用了该条记录:
select bug_id from Bugs where reported_by = 1
2、级联问题
另外很多开发人员避免使用外键约束的理由,是因为这些约束会使得更新多张表中相关联的列变得比较麻烦。比如删除一条被其他记录依赖的数据时,不得不删除所有的子记录来避免违反外键约束:
delete from Account where RoleId = 1
delete from Role RoleId = 1 另外还有updateupdate Role set RoleId = 2
update Account set Role = 2 where RoleId = 1
1、我要怎么写这个查询语句来检查一个值是否没有同时在两张表中存在。
通常这样的需要是为了查找那些孤立的行,那些被遗忘的数据记录行。
2、有没有一种简单的方法来判断在一张表中存在的数据是否也在第二张表中存在?
这么做是用来确认父记录确实存在,外键会自动完成这些,并且外键会使用附表的索引尽可能搞笑地完成。
3、外键?有人告诉我别用它,因为那会影响数据库的效率。
性能总是用来裁剪设计的一个很好的理由,但总是会引入更多的问题,甚至包括性能问题本身。我 之前就看到过,说增加外键增删改的速度会变慢的说法。但请记住,这种说法只适用于这张表是用于大规模增删改的情况。对于一张主要就是用来大范围增删改的表,不用外键似乎无可厚非。 但是如果一张表,增删改并不多,这种说法就不成立了。相反,你避免了外键,却不得不使用更多的手段去维护数据完整性。对于开销方面,的确对增删改需要那么一点额外的系统开销,但是同时另一方面赚会来的有:
1、不需要在更新或删除记录前执行select进行检查。
2、在同步修改时不需要再锁住整张表。
3、不再需要执行定期的监控脚本来修正不可避免的垃圾数据,孤立数据。
外键是一个使用很方便的东西,提高性能,还能帮助你在任何简单或复杂的形式的数据变更下始终维持引用完整性。
总结:客观的分析,本人还是建议使用外键。
探讨了数据库设计中使用外键的争议性话题,分析了不使用外键可能导致的问题及额外工作,如手动维护引用完整性和执行冗余查询等,并最终强调了外键的重要性。
&spm=1001.2101.3001.5002&articleId=44773873&d=1&t=3&u=12687f824aa2465c8d056ff3d1026e71)
2751

被折叠的 条评论
为什么被折叠?



