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

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

这篇文章主要是参考了StackOverFlow网站上的一个话题Are foreign keys really necessary in a databasedesign?(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)保证了参照的完整性(referentialintegrity)。

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

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

Andthat‘s the point, really. Developers can‘t get things right, so ensuring thedatabase 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 towear seat belts ;-) –  Tony Andrews

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

Adatabase schema without FK constraints is like driving without a seat belt. Oneday, you‘ll regret it. Not spending that little extra time on the designfundamentals and data integrity is a sure fire way of assuring headaches later.

外键可以提高性能。

Theyalso improve performance because they‘re normally indexed by default.

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

Otherdatabases may automatically create indexes for foreign keys, but SQL Serverdoes not. In SQL Server, foreign key relationships are only constraints. Youmust defined your index on foreign keys separately (which can be of benefit.)

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

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

Foreignkeys allow someone who has not seen your database before to determine therelationship between tables.

Everythingmay be fine now, but think what will happen when your programmer leaves andsomeone else has to take over.

Foreign keys will allowthem to understand the database structure without trawling through thousand oflines of code.

时间: 2024-11-09 00:35:49

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

mysql中的外键foreign key

一.如果一张表中有一个非主键的字段指向了别一张表中的主键,就将该字段叫做外键. 一张表中可以有多个外键. 外键的默认作用有两点: 1.对子表(外键所在的表)的作用:子表在进行写操作的时候,如果外键字段在父表中找不到对应的匹配,操作就会失败. 2.对父表的作用:对父表的主键字段进行删和改时,如果对应的主键在子表中被引用,操作就会失败. 外键的定制作用----三种约束模式: district:严格模式(默认), 父表不能删除或更新一个被子表引用的记录. cascade:级联模式, 父表操作后,子表关

外键(foreign key)的使用及其优缺点

如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键.由此可见,外键表示了两个关系之间的相关联系.以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表.外键又称作外关键字. 优点: 1.由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据 的完整性,而用外键即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性. eg:数据库和应用是一对多的关系,A应用会维护他那部分数据的完整性,系统一变大时,增

MYSQL外键(Foreign Key)的使用

转载自:http://www.cppblog.com/wolf/articles/69089.html#Post 原文实在太精辟又形象,忍不住转载过来留下笔记,像作者致敬 在MySQL 3.23.44版本后,InnoDB引擎类型的表支持了外键约束.外键的使用条件:1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后的版本有可能支持,但至少目前不支持):2.外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显示建立: 3.外

mysql 外键(FOREIGN KEY)使用介绍

一.基本概念 1.MySQL中"键"和"索引"的定义相同,所以外键和主键一样也是索引的一种.不同的是MySQL会自动为所有表的主键进行索引,但是外键字段必须由用户进行明确的索引.用于外键关系的字段必须在所有的参照表中进行明确地索引,InnoDB不能自动地创建索引. 2.外键可以是一对一的,一个表的记录只能与另一个表的一条记录连接,或者是一对多的,一个表的记录与另一个表的多条记录连接. 3.如果需要更好的性能,并且不需要完整性检查,可以选择使用MyISAM表类型,如果

SQLite从什么版本开始支持外键(Foreign Key)

http://androidren.com/index.php?qa=298&qa_1=sqlite%E4%BB%8E%E4%BB%80%E4%B9%88%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E6%94%AF%E6%8C%81%E5%A4%96%E9%94%AE-foreign-key 从SQLite 3.6.19 开始支持 外键约束. 参考: http://sqlite.org/foreignkeys.html Foreign key constraints

Oracle之外键(Foreign Key)用法详解(一)

Oracle外键(Foreign Key)用法详解(一) 1.目标 演示如何在Oracle数据库中使用外键 2.什么是外键? 1)在Oracle数据库中,外键是用来实现参照完整性的方法之一.打个形象的比喻,外键是指定义外键的表的列的值必须在另一个表中出现. 2)被参照的表称之为父表(parent table),创建外键的表称之为子表(child table).子表中的外键关联了父表中的主键. 3)外键可以在创建表时定义或者通过ALTER TABLE语句创建. 3.创建表时定义外键 语法: CRE

数据库开发——参照完整性——在外键中使用Delete on cascade选项

原文:数据库开发--参照完整性--在外键中使用Delete on cascade选项 原文: http://www.mssqltips.com/sqlservertip/2743/using-delete-cascade-option-for-foreign-keys/?utm_source=dailynewsletter&utm_medium=email&utm_content=headline&utm_campaign=2012731 参照完整性在设计数据库时需要重视,在我作为

数据库设计中主键字段类型的选择

很久都没有写过博客了,从最后一次发表的文章到现在已经是两个多月的时间了,一直都想写点什么,可一直没有时间(其实都是借口),随笔内容无疑就是工作学习中的总结,经验的分享,也是自己成长的一面镜子,好了,言规正传,这次谈谈在数据库设计中主键字段类型的选择. 做web 开发时,经常要与数据库交互,数据库主键的选择也犹为重要,怎么么选择数据库主键字段的类型,主要从以下几个方面考虑: 1. 首先要符合业务需求,这是设计中重要的出发点 2. 数据库的迁移问题,考虑在后期是否要经常迁移,数据库高度唯一性 3.程

sql数据库删除表的外键约束(INSERT 语句与 FOREIGN KEY 约束"XXX"冲突。该冲突发生于数据库"XXX",表"XXX", column 'XXX)

使用如下SQL语句查询出表中外键约束名称: 1 select name 2 from sys.foreign_key_columns f join sys.objects o on f.constraint_object_id=o.object_id 3 where f.parent_object_id=object_id('表名') 执行如下SQL语句删除即可. 1 alter table 表名 drop constraint 外键约束名 sql数据库删除表的外键约束(INSERT 语句与 F

ORACLE: 查询(看)表的主键、外键、唯一性约束和索引

ORACLE: 查询(看)表的主键.外键.唯一性约束和索引 1.查找表的所有索引(包括索引名,类型,构成列) select t.*,i.index_type from user_ind_columns t,user_indexes i where t.index_name = i.index_name and t.table_name = i.table_name and t.table_name = 表名 2.查找表的主键(包括名称,构成列): select cu.* from user_co