数据库外键的使⽤和原则
外键的作⽤:
保持数据⼀致性,完整性,主要⽬的是控制存储在外键表中的数据。使两张表形成关联,外键只能引⽤外表中的列的值!
例如:
a b 两个表
a表中存有客户号,客户名称
b表中存有每个客户的订单
有了外键后
你只能在确信b 表中没有客户x的订单后,才可以在a表中删除客户x
建⽴外键的前提:本表的列必须与外键类型相同(外键必须是外表主键)。
指定主键关键字: foreign key(列名)
引⽤外键关键字: references <;外键表名>(外键列名)
事件触发限制: on delete和on update , 可设参数cascade(跟随外键改动), restrict(限制外表中的外键改动),set Null(设空值),set Default(设默认值),[默认]no action
例如:
outTable表主键 id 类型 int
创建含有外键的表:
create table temp(
id int,
name char(20),
foreign key(id) references outTable(id) on delete cascade on update cascade);
说明:把id列设为外键参照外表outTable的id列当外键的值删除本表中对应的列筛除当外键的值改变本表中对应的列值改变。
⼦表,⽗表的定义:拥有外键的表是⼦表。主键被其它表引⽤的表是⽗表。
换句话说:因为⽗表的标识被很多个⼦表中的记录引⽤,所以叫⽗表。
拥有外键关系,并且可以随便删除数据,不影响其它表的数据的那个表叫⼦表。
使⽤的时候谁做为谁的外键,主要从以下两点考虑:
1/,删除是如何相互影响的,删除记录受约束的那个是⽗表,不受约束的那个是⼦表;
2/,记录必须先存在的是⽗表;
两种⽤途:
1/, 最常⽤的⼀种: 减少重复数据.表A中拥有外键,表B的数据基本是不允许删除的.这时选择对 INSERT 和 UPDATE 强制关
系即可.
2/,其次,是增加⼀个从属表. 如果表A删除⼀条记录时,表B中也随着删除⼀条相关联的记录,那么外键关系中,表A的主键是
表B的外键。这种关系,实际上表B是表A的从属表(即表A是⽗表),选择对 INSERT 和 UPDATE 强制关系时,如果向表B
中插⼊数据,表A中必须已经存在对应的记录。选择级联删除相关的字段时,删除表A中的⼀条记录,就会删除对应的表B中
的⼀条记录。
今天有朋友问我"外键的作⽤是什么"
当朋友问我外键的作⽤是什么时,我也愣了⼀下,平常都是在这么⽤,还没有真正的总结过,外分键的作⽤呢.下⾯,我总结了⼀下外键的作⽤:外键 (FK) 是⽤于建⽴和加强两个表数据之间的链接的⼀列或多列。通过将保存表中主键值的⼀列或多列添加到另⼀个表中,可创建两个表之间的链接。这个列就成为第⼆个表的外键。
FOREIGN KEY 约束的主要⽬的是控制存储在外键表中的数据,但它还可以控制对主键表中数据的修改。例如,如果在 publishers 表中删除⼀个出版商,⽽这个出版商的 ID 在 titles 表中记录书的信息时使⽤了,则这两个表之间关联的完整性将被破坏,titles 表中该出版商的书籍因为与 publishers 表中的数据没有链接⽽变得孤⽴了。FOREIGN KEY 约束防⽌这种情况的发⽣。如果主键表中数据的更改使之与外
键表中数据的链接失效,则这种更改是不能实现的,从⽽确保了引⽤完整性。如果试图删除主键表中的⾏或更改主键值,⽽该主键值与另⼀个表的 FOREIGN KEY 约束值相关,则该操作不可实现。若要成功更改或删除 FOREIGN KEY 约束的⾏,可以先在外键表中删除外键数据或更改外键数据,然后将外键链接到不同的主键数据上去。
外键是⽤来控制数据库中数据的数据完整性的
就是当你对⼀个表的数据进⾏操作
和他有关联的⼀个或更多表的数据能够同时发⽣改变
这就是外键的作⽤
[精] 谈谈外键
外键 (FK) 是⽤于建⽴和加强两个表数据之间的链接的⼀列或多列。通过将保存表中主键值的⼀列或多列添加到另⼀个表中,可创建两个表之间的链接。这个列就成为第⼆个表的外键。
FOREIGN KEY 约束的主要⽬的是控制存储在外键表中的数据,但它还可以控制对主键表中数据的修改。例如,如果在 publishers 表中删除⼀个出版商,⽽这个出版商的 ID 在 titles 表中记录书的信息时使
⽤了,则这两个表之间关联的完整性将被破坏,titles 表中该出版商的书籍因为与 publishers 表中的数据没有链接⽽变得孤⽴了。FOREIGN KEY 约束防⽌这种情况的发⽣。如果主键表中数据的更改使之与外键表中数据的链接失效,则这种更改是不能实现的,从⽽确保了引⽤完整性。如果试图删除主键表中的⾏或更改主键值,⽽该主键值与另⼀个表的 FOREIGN KEY 约束值相关,则该操作不可实现。若要成功更改或删除 FOREIGN KEY 约束的⾏,可以先在外键表中删除外键数据或更改外键数据,然后将外键链接到不同的主键数据上去。
外键是⽤来控制数据库中数据的数据完整性的
就是当你对⼀个表的数据进⾏操作
和他有关联的⼀个或更多表的数据能够同时发⽣改变
这就是外键的作⽤
外键是数据库⼀级的⼀个完整性约束,就是数据库基础理论书中所说的“参照完整性”的数据库实现⽅式。
外键属性当然是可以去掉的,如果你不想再⽤这种约束,对编程当然不会有什么影响,但相应的录⼊数据的时候就不对录⼊的数据进
⾏“参照完整性”检查了。
例如有两个表
A(a,b) :a为主键,b为外键(来⾃于B.b)
B(b,c,d) :b为主键
如果我把字段b的外键属性去掉,对编程没什么影响。
如上⾯,A中的b要么为空,要么是在B的b中存在的值,有外键的时候,数据库会⾃动帮你检查A的b是否在B的b中存在。
1、外建表达的是参照完整性:这是数据固有的,与程序⽆关。因此,应该交给DBMS来做。
2、使⽤外建,简单直观,可以直接在数据模型中体现,⽆论是设计、维护等回有很⼤的好处,特别是对于分析现有的数据库的好处时⾮常明显的--前不久我分析了⼀个企业现有的数据库,⾥⾯的参照完整性约束有的是外键描述,有的是⽤触发器实现,感觉很明显。当然,⽂档⾥可能有,但是也可能不全,但是外键就⾮常明显和直观。
数据库设计的意义
3、既然我们可以⽤触发器或程序完成的这个⼯作(指参照完整性约束),DBMS已经提供了⼿段,为什么我们要⾃⼰去做?⽽且我们做的应该说没有RDBMS做得好。实际上,早期的RDBMS并没有外键,现在都有了,我认为数据库⼚商增加这个功能是有道理的。从这个⾓度来说,外键更⽅便。
4、关于⽅便,根据我带项⽬的情况来看,程序员确实有反映,主要是在调试时输⼊数据⿇烦:如果数据可以违反参照完整性,那么就是说参照完整性本⾝就不对名誉业务冲突,此时也不应该⽤触发期货程序实现;否则,说明数据是错误的,根本就不应该进⼊数据库!⽽且,这也应该是测试系统的⼀个内容:阻⽌⾮法数据。实际上,前台程序应该对这种提交失败做出处理。数据是企业的⽽⾮程序的,储程序要尽量与数据分离,反之亦然。
最后说⼀下,建键⼏个原则:
1、为关联字段创建外键。
2、所有的键都必须唯⼀。
3、避免使⽤复合键。
4、外键总是关联唯⼀的键字段。
这个帖⼦很⽜:
我的观点是,外键在初始阶段能加的都加上,只有迫不得已的时候才disable或drop掉。遇到性能瓶颈的时候,尽量采⽤其它⽅式调优,⽽不要轻易牺牲掉外键。有外键约束的时候,写程序的确会有约束,但从直觉上说这种约束⼀定程度上揭⽰了设计或实现上不合理的地⽅。带着外键写出来的应⽤更倾向于严谨。产品上线之前如果确实需要通过牺牲外键达到性能上的优化,再捡相对不重要的外键废弃掉,同时要把这个document下来,下次遇到数据不⼀致问题的时候,是个线索。两点说明:1. 我们在做的⼀个项⽬确实是⼩项⽬。 2. 我得承认我最近三年开发都不⽤关系型数据库,貌似 no sql那么nb的key-value pair存数据,其实这三年在持久层上很多纠结。如果我说的不对,请指正!
下⾯引⽤⼀些有见地的想法:
× ⽀持外键的:
1. 你的程序再严谨也有可能出现BUG;你⾃⼰判断不如交给数据库判断,它做得⼜快⼜好。
⼤多数⼈的程序没有考虑并发问题。⼀旦考虑了就得⼿⼯加锁,效率很低。
数据可能绕过你的应⽤程序进⼊数据库。
2. 性能问题:难道你⾃⼰做就没有开销?
⼀个外键判断分摊到事务级别,开销可以忽略,⽤户完全没有察觉。
如果是批量导⼊数据,可以先暂时屏蔽外键,事后⽤NOVALIDATE选项快速恢复,前提是你的数据是⼲净的。
也有⼈提到了如果100张表可能需要建⽴300个约束,导致性能太差。
我要说的仍然是,是否这300个外键约束都是业务必须的,如果是,没有办法这就是必须要加的,如果不是,那么⼤可不必在所有的地⽅都增加外键。
如果在程序中仅对其中的5、6张表的10来个外键约束进⾏判断,然后和数据库中的300个外键去⽐较,并评价Oracle的外键性能太差,恐怕是有失公允的。
× 反对外键的:
的确外键在⼤系统中⽤的很少,在开发初级,设计数据库的时候⼀般会加⼊外键,以保证系统设计的完整性和业务需求的完整性,也便于开发⼈员了解业务规则,在程序中加以控制,很多⼤系统在系统稳定后,会逐步将外键去掉,以保证性能,将太多的功能强加于数据库,虽然说数据库很强⼤,但是毕竟很多⼈不信任数据库的能强⼤到什么都能⼲的地步。所以在⼀个⼤系统中外键见的少也不⾜为奇,⼩系统就⽆所谓了,⽤不⽤外键取决于设计⼈员,这样的系统也随处可见。
另引⽤⼀篇:
数据库设计是否需要外键。这⾥有两个问题:⼀个是如何保证数据库数据的完整性和⼀致性;⼆是第⼀条对性能的影响。
正⽅观点:
1,由数据库⾃⾝保证数据⼀致性,完整性,更可靠,因为程序很难100%保证数据的完整性,⽽⽤外键即使在数据库服务器当机或者出现其他问题的时候,也能够最⼤限度的保证数据的⼀致性和完整性。
eg:数据库和应⽤是⼀对多的关系,A应⽤会维护他那部分数据的完整性,系统⼀变⼤时,增加了B应⽤,A和B两个应⽤也许是不同的开发团队来做的。他们如何协调保证数据的完整性,⽽且⼀年以后如果⼜增加了C应⽤呢?
2,有主外键的数据库设计可以增加ER图的可读性,这点在数据库设计时⾮常重要。
3,外键在⼀定程度上说明的业务逻辑,会使设计周到具体全⾯。
反⽅观点:
1,可以⽤触发器或应⽤程序保证数据的完整性
2,过分强调或者说使⽤主键/外键会平添开发难度,导致表过多等问题
3,不⽤外键时数据管理简单,操作⽅便,性能⾼(导⼊导出等操作,在insert, update, delete 数据的时候更快)
eg:在海量的数据库中想都不要去想外键,试想,⼀个程序每天要insert数百万条记录,当存在外键约束的时候,每次要去扫描此记录是否合格,⼀般还不⽌⼀个字段有外键,这样扫描的数量是成级数的增长!我的⼀个程序⼊库在3个⼩时做完,如果加上外键,需要28个⼩时!
结论:
1. 在⼤型系统中(性能要求不⾼,安全要求⾼),使⽤外键;在⼤型系统中(性能要求⾼,安全⾃⼰控制),不⽤外键;⼩系统随便,最好⽤外键。
2. ⽤外键要适当,不能过分追求
3. 不⽤外键⽽⽤程序控制数据⼀致性和完整性时,应该写⼀层来保证,然后个个应⽤通过这个层来访问数据库。
4.不管是否加外键,⼀定要索引。
主键和外键是把多个表组织为⼀个有效的关系数据库的粘合剂。主键和外键的设计对物理数据库的性能和可⽤性都有着决定性的影响。
必须将数据库模式从理论上的逻辑设计转换为实际的物理设计。⽽主键和外键的结构是这个设计过程的症结所在。⼀旦将所设计的数据库⽤于了⽣产环境,就很难对这些键进⾏修改,所以在开发阶段就设计好主键和外键就是⾮常必要和值得的。
主键:
关系数据库依赖于主键---它是数据库物理模式的基⽯。主键在物理层⾯上只有两个⽤途:
1. 惟⼀地标识⼀⾏。
2. 作为⼀个可以被外键有效引⽤的对象。
基于以上这两个⽤途,下⾯给出了我在设计物理层⾯的主键时所遵循的⼀些原则:
1. 主键应当是对⽤户没有意义的。如果⽤户看到了⼀个表⽰多对多关系的连接表中的数据,并抱怨它没有什么⽤处,那就证明它的主键设计地很好。
2. 主键应该是单列的,以便提⾼连接和筛选操作的效率。
注:使⽤复合键的⼈通常有两个理由为⾃⼰开脱,⽽这两个理由都是错误的。其⼀是主键应当具有实际
意义,然⽽,让主键具有意义只不过是给⼈为地破坏数据库提供了⽅便。其⼆是利⽤这种⽅法可以在描述多对多关系的连接表中使⽤两个外部键来作为主键,我也反对这种做法,理由是:复合主键常常导致不良的外键,即当连接表成为另⼀个从表的主表,⽽依据上⾯的第⼆种⽅法成为这个表主键的⼀部分,然,这个表⼜有可能再成为其它从表的主表,其主键⼜有可能成了其它从表主键的⼀部分,如此传递下去,越靠后的从表,其主键将会包含越多的列了。
3. 永远也不要更新主键。实际上,因为主键除了惟⼀地标识⼀⾏之外,再没有其他的⽤途了,所以也就没有理由去对它更新。如果主键需要更新,则说明主键应对⽤户⽆意义的原则被违反了。
注:这项原则对于那些经常需要在数据转换或多数据库合并时进⾏数据整理的数据并不适⽤。
4. 主键不应包含动态变化的数据,如时间戳、创建时间列、修改时间列等。
5. 主键应当有计算机⾃动⽣成。如果由⼈来对主键的创建进⾏⼲预,就会使它带有除了惟⼀标识⼀⾏以外的意义。⼀旦越过这个界限,就可能产⽣认为修改主键的动机,这样,这种系统⽤来链接记录⾏、管理记录⾏的关键⼿段就会落⼊不了解数据库设计的⼈的⼿中。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。