(转)数据库该不该用外键

外键这个东西让多少程序员又爱又恨,虽然高效的保证了数据库的完整性,一度让我们觉得有了它,维护数据库是多么幸福的一件事情,我们不需要写那么多繁琐的代码来保证数据的完整性。可是随着我们的系统逐渐庞大,我们又发现它给我们带来了不少麻烦,复杂度、性能都受到了影响,于是我们就产生了到底该不该用外键的疑问。

不管是我们做程序设计的,还是社会上的各行各业,或是任何一件事情都是有一个度的约束。上学的时候政治课上总是在说事物都是具有两面性的,好的一面有,当然坏的一面也有,于是外键这个东西自然也逃不出这个道道。在我看来,任何一项技术都有它存在的价值,也许是我们没有发现,但并不代表它不存在,缺点同样如此。理论联系实际,这是我们都明白的道理,一味的说某个技术好或者坏而脱离实际应用的言论,那都是片面的。说的有点多了,下面就来谈谈外键这个东西吧。

先说说外键有那些好处:

1.通过外键,数据库自身能够保证数据的完整性与一致性,虽然我们在程序中也能够写些代码来维护,但是程序始终没有办法100%的保证数据的完整性与一致性。而外键本身属于数据库的一部分,所以在数据库服务器出现问题的时候,它也能最大限度的保存数据库的完整性与一致性。

2.有外键的数据库可以使ER图更具有可读性,数据库中表与表之间的关系更加一目了然,这对于系统的二次开发或是维护也是相当有用的。

3.在业务逻辑上,通过外键可以更加直观的理解业务逻辑,在设计功能时起到了辅助作用,让设计更加周到完善。

4.对于一个项目,开发人员总是不断变动的,开发人员的能力也是层次不齐的,那么通过代码来保证数据完整性更是难上加难的事情,有了外键在一定程度上约束了开发人员,能够避免一些低级错误而导致数据的不完整。

至于坏处也有以下几点:

1.过分使用外键,会让系统的开发难度增加,同时也导致表过多,增加了系统的复杂度。

2.性能问题,由于外键对数据库有了一定的约束,那么在我们每次进行数据库操作的时候必然要验证这个约束,对于数据量小的系统来说没有任何问题,但是当数据变的很庞大的时候,那么性能上的劣势就很明显了。

显而易见,对于外键的应用我们还是要根据具体的问题来分析。用会给我们这个系统带来什么好处,不用会给系统带来什么坏处,哪个更多一些,那我们的选择自然也就明了了。道理其实大家都明白,那我们究竟该怎么分析好与坏,或是怎么看出使用外键的时候是好处多一点还是坏处多一点呢。我认为,当我们开始做一个项目的时候,我们要从以下几个方面来分析该不该上外键约束:

1.项目业务逻辑的复杂度

业务逻辑其实是一个项目最根本的东西,是项目的一个核型,它就像一条主线,贯穿于项目的始末。所以当业务逻辑非常复杂的时候,那么各个实体之间的关系也是非常“暧昧”的,这里之所以用“暧昧”是因为有的时候实体之间的关系错综复杂,有很多都存在关联。这个时候外键恰恰帮我们理清了他们之间的关系,同时在项目中使用外键更容易保证数据的完整性与一致性。由于关系的复杂,我们已经没有办法使用程序来100%保证数据的完整性与一致性了。相反,如果业务逻辑不复杂,关系很明了,近似于“一夫一妻制”,那么我们在程序里就可以保证完整性与一致性了,当然也没有必要用外键的了。

2.项目计划进行的时间

程序员的流动性是很大的,也许一个项目开发到一半的时候,整个项目组除了项目经理外程序员都全部换人了,如果文档没有及时跟上,或是交接的时候不明确,那对于项目来说是很危险的。对于那些半路杀进来的程序员,虽然有经验的程序员会在编码的时候思考完整性的问题,但是由于各种原因,他们没有办法100%的通过程序保证数据的完整性与一致性。有经验的尚且如此,所以这个时候外键就为项目的完整性把好了最后一道关卡,无论他们对项目是否熟悉,在完整性与一致性的问题上面,数据库自身已经做好了充分的准备。相反,项目如果周期很短,人员变动也很小,那就可以撇开这个因素,从其他方面考虑是否需要使用外键。

3.安全性与完整性

这个问题其实最好理解,如果项目对数据有着非常苛刻的安全性、完整性与一致性的要求,那必然要用外键,可能会缺失一部分性能,即使是这样也是值得的,这样从最大程度上满足了项目的需求,这才是关键。

4.性能

上面第三点已经讨论的性能的问题了。对于大型的系统,如果每天有百万级的数据操作,这个时候如果使用外键,那性能就变成了致命的问题。外键就是一种约束,我们每操作一次insert、update或是delete的时候都要通过这个约束来验证数据是否完整一致。这个时候性能上的缺失可能是几小时甚至是几十个小时。

以上几点是我自己总结出来的,也许更有经验的人还会有其他方面的考虑,总而言之,技术是在不断发展的,每天都会有很多新的技术诞生,在我们了解它们之后更多的是应该去思考它们适用于哪些场合。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yangzhongwei1031/archive/2010/04/07/5459583.aspx

时间: 2024-08-14 15:06:26

(转)数据库该不该用外键的相关文章

Android数据库SQLite表内设置外键

Android数据库SQLite表内设置外键 介绍 Android默认的数据是SQLite,但SQLite3.6.19之前(在2.2版本中使用的是3.6.22,因此如果你的应用只兼容到2.2版本就可以放心使用外键功能)是不支持外键的,如果有两张表需要关联,用外键是最省事的,但不支持的话怎么办呢?这里就有一个解决办法,就是用事务将两张表关联起来,并且最后生成一张视图. 现有两张表 Employees Dept 视图 ViewEmps:显示雇员信息和他所在的部门 创建数据库 自定义一个辅助类继承SQ

MyEclipse数据库教程:表、外键和索引的使用方法

MyEclipse数据库教程:表.外键和索引的使用方法 MyEclipse的数据库资源管理器工具提供了大量的向导和操作,来轻松地创建和删除表.关系和索引.在本教程中,你将学习到: 创建和删除表 创建和删除外键 创建和删除索引 没有MyEclipse?立即下载 1. 创建一个新的索引 创建索引是开发人员重要的性能工具,典型的就是在DBMS上创建一个表的索引键.然而可能在其他领域中经常需要使用ORDER BY或WHERE子句来增强性能.假设您可能在CITY中有很多订购的客户,您可以在该领域中创建索引

数据库多表关系(外键)

数据库多表关系(外键) 字段操作 create table tf1( id int primary key auto_increment, x int, y int ); # 修改 alter table tf1 modify x char(4) default ''; alter table tf1 change y m char(4) default ''; # 增加 mysql>: alter table 表名 add 字段名 类型[(长度) 约束]; # 末尾 eg>: alter t

[转帖]数据库,傻逼才用外键约束!

数据库,傻逼才用外键约束! 作者:孤独烟 来自:打杂的ZRJ 引言 其实这个话题是老生常谈,很多人在工作中确实也不会使用外键.包括在阿里的JAVA规范中也有下面这一条 [强制]不得使用外键与级联,一切外键概念必须在应用层解决. 但是呢,询问他们原因,大多是这么回答的 每次做DELETE 或者UPDATE都必须考虑外键约束,会导致开发的时候很痛苦,测试数据极为不方便. 坦白说,这么说也是对的.但是呢,不够全面,所以开一文来详细说明. 正文 首先我们明确一点,外键约束是一种约束,这个约束的存在,会保

逻辑数据库设计 - 无视约束(谈外键)

有一些开发人员不推荐使用完整性约束,你可能听过以下这么几点不使用外键的原因. 1.数据更新有可能和约束冲突. 2.当前的数据库设计如此灵活,以致于不支持引用完整性约束. 3.数据库为外键建立的索引会影响性能. 4.当前使用的数据库不支持外键. 5.定义外键的语法并不简单,还需要查阅. 一.反模式:无视约束 即使第一感觉告诉你,省略外键约束能使得数据库设计更加简单.灵活,或者执行更加高效,你还是不得不在其他方面付出相应的代价 -- 必须增加额外的代码来手动维护引用完整性. 1.完整性问题 很多人对

在数据库的设计中,外键(Foreign key)约束是否真的有必要呢?(一)

已经过去一段时间了.在数据库是否设置外键约束的问题,我和同事发生的争执.我是坚持使用外键约束,他们反对使用外键约束.于是,便有了这篇文章. 这篇文章主要是参考了StackOverFlow网站上的一个话题Are foreign keys really necessary in a databasedesign?(http://stackoverflow.com/questions/18717/are-foreign-keys-really-necessary-in-a-database-desig

SQL 数据库 子查询、主外键

子查询,又叫做嵌套查询. 将一个查询语句做为一个结果集供其他SQL语句使用,就像使用普通的表一样,被当作结果集的查询语句被称为子查询. 子查询有两种类型: 一种是只返回一个单值的子查询,这时它可以用在一个单值可以使用的地方,这时子查询可以看作是一个拥有返回值的函数: 另外一种是返回一列值的子查询,这时子查询可以看作是一个在内存中临时存在的数据表. 主键 数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过它可强制表的实体完整性.当创建或更改表时可通

开源进销存PSI - 数据库外键

今天在PSI的QQ群中聊起了数据库外键的话题,我就写这篇博文,说说我对数据库外键的一些考虑. 1.数据库设计中应该使用外键. 2.很杯具,PSI的数据库设计到目前为止,没有使用外键. 3.PSI会逐步把数据库外键给补上. 4.有些地方还真没法加上外键.举现在的例子: 4.1 t_warehouse_org中的org_id字段,即可以存储 t_org的id,又可以存储t_user的id,这个时候,外键就没法加了. 4.2 t_inventory_detail中的ref_number字段,可以存储多

SQL Server数据库中导入导出数据及结构时主外键关系的处理

2015-01-26 软件开发中,经常涉及到不同数据库(包括不同产品的不同版本)之间的数据结构与数据的导入导出.处理过程中会遇到很多问题,尤为突出重要的一个问题就是主从表之间,从表有外检约束,从而导致部分数据无法导入. 情景一.同一数据库产品,相同版本 此种情况下源数据库与目标数据库的数据结构与数据的导入导出非常简单. 方法1:备份源数据库,恢复到目标数据库即完成. 方法2:使用SQL Sever数据库自带的[复制数据库]功能或者[导入数据]功能按照向导操作即可. 情景二.同一数据库产品,不同版