已经过去一段时间了。在数据库是否设置外键约束的问题,我和同事发生的争执。我是坚持使用外键约束,他们反对使用外键约束。于是,便有了这篇文章。

 

这篇文章主要是参考了StackOverFlow网站上的一个话题Are foreign keys really necessary in a database design?http://stackoverflow.com/questions/18717/are-foreign-keys-really-necessary-in-a-database-design

 

自己的一点理解,如有不正确之处,望指正!

 

关系型数据库在现实的使用当中占有相当大的比重。关系型数据库可以抽象为两部分内容:实体、实体与实体之间的关系。实体,应该就是对现实事物的一个抽象;而实体与实体之间的关系就是现实事物之间关联关系,而这种关联关系一般起到参照作用。例如,现实生活中一个用户要下订单,那么要建立一张“订单”表,那这个“订单”表就要信赖于“用户”表(“订单”表中的用户Id,可能要参照于用户表中的用户Id)。假如说,不存在这种参照关系,就可能会出现这种情况,“订单”表中有一张订单,但却不知道用户是谁,这就会让人觉得非常的奇怪:没有用户的订单,让人有点不知所措。

 

认知的角度来说,那这种参照关系(参照的完整性),肯定是需要的。那从实现的角度来说,应该怎么做呢?有两种方法,一种是从数据层面去约束,另一种是从应用层面中去约束。这两种实现方式该怎么理解呢?从数据层面,就是在数据库上建立外键约束,在存储或更新数据的时候,由数据库来检验这种参照的完整性,这部分工作是由数据库引擎来做的。而从应用层面,则是由程序员开发的程序来维护这种参照的完整性,这样,程序本身的好与坏或者程序员本身的素养就决定了参照完整性实现的好坏,换句话说,这是由人的工作质量好坏决定的。

 

从认知角度上来说,参照完整性是要做的;但从实现的角度来说,应该怎么哪种方式呢?一种是由数据库的引擎来做,一种是由程序员编写的程序来做。我觉得,这个回答应该是一边倒的,当然是由数据库的引擎来做。那为什么这么说呢?

 

Foreign keys help enforce referential integrity at the datalevel.外键约束(Foreign key constraint)从数据层面(data level)保证了参照的完整性(referential integrity)。

 

如果由程序员来做,那就有了一个前提:程序员编出的程序不会出错。稍微有点常识的人都会知道,人犯错误是难免的,程序员更是如此。所以,“参照完整性由程序员来维护”的想法,是不可靠的。在大的企业当中,常常是由多个应用程序访问同一个数据库。如果由程序员来维护这种参照完整性,那原则上每一个应用程序就应该有一套自己的方法去保证这种参照完整性,这无疑会增加开发的工作量;否则,就可能让数据库中产生垃圾数据。

“Supposea programmer is actually doing this in the right manner already”, Making such a supposition seems to me to be an extremely bad idea; in general software is phenomenally buggy.

 

And that's the point, really. Developers can't get things right, so ensuring the database can't be filled with bad data is a Good Thing. 

 

而且数据之间的参照完整性,应该独立于任何应用程序,换句话说,就是不受任何应用程序的影响,为这个数据库添加一个应用程序或减少一个应用程序,都不会破坏数据参照的完整性。

 

TonyAndrews说:我从来没有撞过电线杆,但是我觉得系安全带,还是比较好的。

Sofar, I've never driven into a lamp-post. But I still think it's a good idea to wear seat belts ;-) –  Tony Andrews

以外键约束(FK constraint)和安全带做对比。

A database schema without FK constraints is like driving without a seat belt. One day, you'll regret it. Not spending that little extra time on the design fundamentals and data integrity is a sure fire way of assuring headaches later.

 

外键可以提高性能。

They also improve performance because they're normally indexed by default.

 

外键可以提高性能,SQLServer是个例外。

Other databases may automatically create indexes for foreign keys, but SQL Server does not. In SQL Server, foreign key relationships are only constraints. You must defined your index on foreign keys separately (which can be of benefit.)

 

外键可以展示不同数据表之间的关系,让其他人尽快熟悉。

Without a foreign key how do you tell that two records in different tables are related?

 

Foreign keys allow someone who has not seen your database before to determine the relationship between tables.

 

Everything may be fine now, but think what will happen when your programmer leaves and someone else has to take over.

 

Foreign keys will allow them to understand the database structure without trawling through thousand of lines of code.