精华内容
下载资源
问答
  • 数据库外键作用和设置外键时四个选项的含义
    千次阅读
    2018-02-19 11:25:38

    一、设置外键的作用与好处

    • 可用于检查参照完整性。即阻止非法数据的存入,例如A表中的b列是外键,来源是B表的主键b列,此时在向A表存入数据时数据库会自动检查A表的b列的值在B表的b列中是否存在。
    • 方便、简单、直观。
    • 可以设置级联操作,外键来源删除和修改时数据库会自动进行级联删除和修改。

    二、设置外键时四个选项的含义

    • RESTRICT:表示阻止级联执行
    • NO ACTION:表示无操作
    • CASCADE:表示级联执行
    • SET NULL:表示在删除或者更新时将其值设置为NULL
    更多相关内容
  • 一·首先是外键作用与设置  保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值!  例如:  a b 两个表  a表中存有客户号,客户名称  b表中...
  •  对于主/外键/索引来说,在一些开发团队中被认为是处理数据库关系的利器,也被某些开发团队认为是处理某些具体业务的魔鬼,您的观点呢?在实际应用中您会采取哪种方式?  大家共同观点:  主键和索引是不可...
  • 数据库外键作用

    千次阅读 2015-08-12 17:38:40
    外键作用: 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有客户号,客户名称 b表中存有每个客户的...

    外键的作用:

    保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值!

    例如:

    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、外键总是关联唯一的键字段。

    外键的作用?

    外键是数据库一级的一个完整性约束,就是数据库基础理论书中所说的“参照完整性”的数据库实现方式。

    外键属性当然是可以去掉的,如果你不想再用这种约束,对编程当然不会有什么影响,但相应的录入数据的时候就不对录入的数据进行“参照完整性”检查了。

    例如有两个表

    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的外键性能太差,恐怕是有失公允的。

    × 反对外键的:

    的确外键在大系统中用的很少,在开发初级,设计数据库的时候一般会加入外键,以保证系统设计的完整性和业务需求的完整性,也便于开发人员了解业务规则,在程序中加以控制,很多大系统在系统稳定后,会逐步将外键去掉,以保证性能,将太多的功能强加于数据库,虽然说数据库很强大,但是毕竟很多人不信任数据库的能强大到什么都能干的地步。所以在一个大系统中外键见的少也不足为奇,小系统就无所谓了,用不用外键取决于设计人员,这样的系统也随处可见。

    另引用一篇:

    引自http://blog.csdn.net/neusoft_lkz/archive/2009/07/21/4366668.aspx

    数据库设计是否需要外键。这里有两个问题:一个是如何保证数据库数据的完整性和一致性;二是第一条对性能的影响。
    正方观点:
    1,由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的完整性,而用外键即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。
    eg:数据库和应用是一对多的关系,A应用会维护他那部分数据的完整性,系统一变大时,增加了B应用,A和B两个应用也许是不同的开发团队来做的。他们如何协调保证数据的完整性,而且一年以后如果又增加了C应用呢? 
    2,有主外键的数据库设计可以增加ER图的可读性,这点在数据库设计时非常重要。
    3,外键在一定程度上说明的业务逻辑,会使设计周到具体全面。
    反方观点:
    1,可以用触发器或应用程序保证数据的完整性
    2,过分强调或者说使用主键/外键会平添开发难度,导致表过多等问题
    3,不用外键时数据管理简单,操作方便,性能高(导入导出等操作,在insert, update, delete 数据的时候更快)
    eg:在海量的数据库中想都不要去想外键,试想,一个程序每天要insert数百万条记录,当存在外键约束的时候,每次要去扫描此记录是否合格,一般还不止一个字段有外键,这样扫描的数量是成级数的增长!我的一个程序入库在3个小时做完,如果加上外键,需要28个小时!

    结论:
    1,在大型系统中(性能要求不高,安全要求高),使用外键;在大型系统中(性能要求高,安全自己控制),不用外键;小系统随便,最好用外键。
    2,用外键要适当,不能过分追求
    3,不用外键而用程序控制数据一致性和完整性时,应该写一层来保证,然后个个应用通过这个层来访问数据库。


    数据库中主键和外键的设计原则

    http://www.cnblogs.com/tianyamoon/archive/2008/04/02/1134394.html

    主键和外键是把多个表组织为一个有效的关系数据库的粘合剂。主键和外键的设计对物理数据库的性能和可用性都有着决定性的影响。

    必须将数据库模式从理论上的逻辑设计转换为实际的物理设计。而主键和外键的结构是这个设计过程的症结所在。一旦将所设计的数据库用于了生产环境,就很难对这些键进行修改,所以在开发阶段就设计好主键和外键就是非常必要和值得的。

    主键:

    关系数据库依赖于主键---它是数据库物理模式的基石。主键在物理层面上只有两个用途:

    1. 惟一地标识一行。

    2. 作为一个可以被外键有效引用的对象。

    基于以上这两个用途,下面给出了我在设计物理层面的主键时所遵循的一些原则:

    1. 主键应当是对用户没有意义的。如果用户看到了一个表示多对多关系的连接表中的数据,并抱怨它没有什么用处,那就证明它的主键设计地很好。

    2. 主键应该是单列的,以便提高连接和筛选操作的效率。

    注:使用复合键的人通常有两个理由为自己开脱,而这两个理由都是错误的。其一是主键应当具有实际意义,然而,让主键具有意义只不过是给人为地破坏数据库提供了方便。其二是利用这种方法可以在描述多对多关系的连接表中使用两个外部键来作为主键,我也反对这种做法,理由是:复合主键常常导致不良的外键,即当连接表成为另一个从表的主表,而依据上面的第二种方法成为这个表主键的一部分,然,这个表又有可能再成为其它从表的主表,其主键又有可能成了其它从表主键的一部分,如此传递下去,越靠后的从表,其主键将会包含越多的列了。

    3. 永远也不要更新主键。实际上,因为主键除了惟一地标识一行之外,再没有其他的用途了,所以也就没有理由去对它更新。如果主键需要更新,则说明主键应对用户无意义的原则被违反了。

    注:这项原则对于那些经常需要在数据转换或多数据库合并时进行数据整理的数据并不适用。

    4. 主键不应包含动态变化的数据,如时间戳、创建时间列、修改时间列等。

    5. 主键应当有计算机自动生成。如果由人来对主键的创建进行干预,就会使它带有除了惟一标识一行以外的意义。一旦越过这个界限,就可能产生认为修改主键的动机,这样,这种系统用来链接记录行、管理记录行的关键手段就会落入不了解数据库设计的人的手中。

    展开全文
  • 数据库——外键作用

    千次阅读 2019-08-15 12:47:02
    我们用一个比较实际的例子来描述问题,并讲解外键作用: 当我们在网上购物的时候,我们有我们的帐号,还有我们所在不同地方的地址信息如公司,学校,家里,或者给亲戚朋友送个礼物,收货人信息也不一样。 我们...

    我们用一个比较实际的例子来描述问题,并讲解外键作用:

    • 当我们在网上购物的时候,我们有我们的帐号,还有我们所在不同地方的地址信息如公司,学校,家里,或者给亲戚朋友送个礼物,收货人信息也不一样。

    我们就一步一步讨论以上提到的这些信息如何更合理的存储在数据库中

    • 第一步、我们把所用信息都存入到一个表中:
    create table user_info(
      id char(36) primary key,
      user_name varchar(30) not null,
      password varchar(30) not null,
      real_name varchar(8),
      mobile char(11),
      address varchar(150)
    );
    insert into user_info (id,user_name,password,real_name,mobile,address) 
    values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','qiangzhogshou','123456','小明','12345678912','物理课');
    insert into user_info (id,user_name,password,real_name,mobile,address) 
    values ('cc95772b-75a2-4702-bd99-4c3b0322d606','qiangzhogshou','123456','李华','12345678934','英语课');
    insert into user_info (id,user_name,password,real_name,mobile,address)
    values ('c63028fd-cf8d-4dac-a278-b5cc8fd61e3c','qiangzhogshou','123456','文言文','12345678956','语文课');
    

    在这里插入图片描述
    我们发现如果在同一个表中,同一个账户的地址信息每增加一行都要多重复一行该账户的注册信息
    问题:这种表结构存在严重的字段冗余(user_name和password列),如果个人信息字段比较多这一问题表现的越严重。

    • 第二步、把这些信息存入到两个表中(把账户信息,地址信息分开存储)
    create table user_info(
      id char(36) primary key,
      user_name varchar(30) not null,
      password varchar(30) not null
    )
    insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','qiangzhogshou','123456');
    
    create table address(
      id char(36) primary key,
      user_info_id char(36),
      real_name varchar(8) not null,
      mobile char(11) not null,
      address varchar(150) not null
    )
    insert into address (id,user_info_id,real_name,mobile,address) 
    values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','小明','12345678912','物理课');
    insert into address (id,user_info_id,real_name,mobile,address) 
    values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李华','12345678934','英语课');
    insert into address (id,user_info_id,real_name,mobile,address) 
    values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','文言文','12345678956','语文课');
    
    • 如下图为user_info表
      在这里插入图片描述
    • 如下图为address表
      在这里插入图片描述
      我们会发现,这样就基本解决了字段冗余的问题,帐户表中每个账户有不同的id,而address表中,用于对应账户信息的,只有一条账户id。

    但是
    ①我们只是在address表里面写了一个新字段,内容是账户id,这只是在逻辑上把两个表联系起来,我们看到两个表的时候,比对了就知道
    而数据库系统并没有建立起来两个表之间的联系,它只知道有两个表,不管内容一不一样,多么有逻辑,如果在建表的时候,没有建立两个表字段上逻辑关系的物理连接,数据库就只知道这是两个分开的表。
    ②这就导致,在对表执行操作的时候,无法捆绑另一个表信息的同步:比如删除了user_info中的数据,那么逻辑上应该地址也没有用了,但是因为是两个独立的表,address中的数据不会受影响。又或者在address中添加了一个随意的user_info_id的数据,但user_info中并不存在该用户;这两个例子中的“剩下的地址”和“不存在的用户”都是我们要继续解决的问题。

    问题:这种表结构消除了字段冗余,但由于只是逻辑上的“外键”关系,所以依然无法保证数据完整性。

    • 第三步、在第二步的基础上建立两个表逻辑上的物理连接:外键

    外键:一个表(表一)中的主键字段数据,可以索引到另一个表(表二)的对应字段数据,那么这个(表二中的)对应字段即为(表二的)外键。

    作用:根据逻辑上的分析,通过外键:实现实际上的物理链接

    应用到本例:

    create table user_info(
      id char(36) primary key,
      user_name varchar(30) not null,
      password varchar(30) not null
    )
    insert into user_info (id,user_name,password) values ('51b28fe1-4ebf-41ac-a17b-d5e276861fd0','qiangzhogshou','123456');
    
    create table address(
      id char(36) primary key,
      user_info_id char(36),
      real_name varchar(8) not null,
      mobile char(11) not null,
      address varchar(150) not null,
      constraint address_user_info_id_fk foreign key(user_info_id) references user_info(id)
    )
    insert into address (id,user_info_id,real_name,mobile,address) 
    values ('bfb9472a-7911-4e6f-a479-3b719454ebab','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','小明','12345678912','物理课');
    insert into address (id,user_info_id,real_name,mobile,address) 
    values ('5227c6b9-45a2-44aa-8ac0-1f63a38d3b65','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','李华','12345678934','英语课');
    insert into address (id,user_info_id,real_name,mobile,address) 
    values ('30b8584b-aa6a-4516-a623-03f487058586','51b28fe1-4ebf-41ac-a17b-d5e276861fd0','文言文','12345678956','语文课');
    
    • 如下图为user_info表
      在这里插入图片描述
    • 如下图为address表
      在这里插入图片描述
      我们发现:
      ①使用外键前后,两个表看起来没有区别(这也可以说明:第二步中,只是逻辑通)
      ②外键的使用语句:
      constraint address_user_info_id_fk foreign key(user_info_id) references user_info(id)

    结果:这种方案为user_info_id添加了外键,指向user_info表的主键,该约束起到了保护数据完整性的作用:如果删除的用户信息id已经在address表中使用,则该条数据无法删除;无法向address表中添加用户id不存在的地址信息。

    总结:

    外键的作用:
    ①解决了数据冗余问题
    ②实现两个表数据库内的的物理连接
    ③避免了脏数据的产生

    展开全文
  • 1. 关系数据库外键概念理论(大学时学习的概念) 教材是:王珊,萨师煊老师的数据库系统概论——第五版,这里直接丢截图了。 有三类完整性约束,分别是:实体完整性、参照完整性以及用户定义的完整性。 其中实体...

    1. 关系数据库外键概念理论(大学时学习的概念)

    教材是:王珊,萨师煊老师的数据库系统概论——第五版,这里直接丢截图了。

    在这里插入图片描述

    • 有三类完整性约束,分别是:实体完整性、参照完整性以及用户定义的完整性。
    • 其中实体完整性参照完整性是关系模型必须满足的完整性约束条件,被称作是关系的两个不变性,应该由关系系统自动支持(例如MySQL要负责这部分约束的检查)
    • 用户定义的完整性是应用领域需要遵循的约束条件,体现了具体领域中的语义约束
      • 不做强制检查,最多让人感觉不符合现实或者有点蠢,和程序员不怎么相关😛😛😛
      • 比如:成绩只能是0-100,年龄只能是0-150以内,生日只能是1.1-12.31,类似这种语义约束。

    1.1 实体完整性

    在这里插入图片描述
    主要用来描述,数据库中每行数据都应该是可区分的(有某个属性是唯一的!)


    1.2 ✅ 参照完整性

    在这里插入图片描述

    在这里插入图片描述

    • 可以看到,数据库理论中
    • 假如F属性是一个表R的属性,但是不是主码;属性K是表S的主码。(表R和表S不一定是不同的表)。如果FK对应,则称F是表R的外码,并称表R是参照关系(参照表),表S是被参照关系。
    • 可以去看看1.5 MySQL数据库操作示例

    在这里插入图片描述
    在这里插入图片描述

    • 这里的参照完整性规则,意思就是:如果选课表中的课程id,参照了课程表中的课程id,
    • 那么选课表中的课程id的取值,要么为空,要么就等于 课程表中的课程id中某个值。

    也是:Mysql错误1452 - Cannot add or update a child row: a foreign key constraint fails怎么办?中这个回答的理论依据。
    在这里插入图片描述

    1.3 用户定义完整性

    在这里插入图片描述

    1.4 ✅ 参照完整性的SQL实现

    还是王珊,萨师煊老师的教材,是后面的例子,截图贴上来
    在这里插入图片描述
    主要还是关于参照完整性(外键)这部分的内容

    可以看到,对于学生版Student(Sno)、课程表Course(Cno)和学生选课表SC(Sno,Cno)来说,按照上面的规定,
    在这里插入图片描述
    则,Sno是表SC的外码,SC表是参照关系,被参照表是Student;Cno也是表SC外码,SC表是参照关系,被参照表是Course。

    在这里插入图片描述

    1.5 ✅ MySQL数据库操作示例

    如果是用Navicat设计mysql数据库,那么可视化应该是这样:

    例如,有两个表,分别是poem(诗表)和poet_to_poem(诗人和诗对应表)
    在这里插入图片描述
    poem(诗表)数据
    在这里插入图片描述
    poet_to_poem(诗人和诗对应表)数据
    在这里插入图片描述
    poem(诗表)非空和主键约束在这里插入图片描述
    poet_to_poem(诗人和诗对应表)非空和主键约束

    很明显,poet_to_poem表中的poem_id是引用自poem表,所以可以设置一个外键(对poet_to_poem表设置)。
    在这里插入图片描述
    所以外键是设置在引用了其他表字段的表上!

    设置完之后,ER图显示就是这样,主键是钥匙,外键是个锁扣的形状
    在这里插入图片描述

    1.6 ✅ neo4j中的关系和mysql的外键

    之前在:图数据库初探——4. mysql数据导入neo4j(desktop界面导入)中,由于外键设置错误,所以导入的时候,只导入了节点,没有识别出关系。设置正确后,就可以正确识别关系了,如下:
    在这里插入图片描述
    在这里插入图片描述

    C:\shaiic_work\neo4j_data\relate-data\dbmss\dbms-54e8721d-3337-412a-8b54-d6ccd03b564e\bin\neo4j-admin.bat @C:\Users\HUANGS~1\AppData\Local\Temp\csv-001\neo4j-admin-import-params
    很奇怪,这个命令运行了两次,第一次报错了
    在这里插入图片描述
    另外,重启桌面版之后,这个新建的数据库在对应的DBMS界面没有显示,但是用命令行去看,是可以看到的。

    CALL db.schema.visualization()
    

    在这里插入图片描述
    可以看到,neo4j中的schema导入前mysql的schema是基本一致的(只是关系表,转为了relationship边)


    match (p:Poem)
    return p
    

    在这里插入图片描述
    一个表的主码就作为节点,其他的属性就作为节点的属性。

    2 MySQL中实现的规定

    根据参考,进行关键部分的摘录

    2.1 基本概念

    MySQL支持外键,允许跨表的交叉引用(外键可以是表内,也可以是表外,mysql都支持),外键约束可以帮助保持相关数据的一致性。(被参照表的主键字段删了,对应的参照表的外键也会删掉)

    外键关系包含拥有列的初始值的父表(例如:学生表),以及引用父表中列的值的子表(例如:学生成绩表引用学生表的student_id)。外键约束定义在子表上

    创建表或者修改表时进行外键约束的语法如下(只有这两种时候才可以加外键约束):

    [CONSTRAINT [symbol]] FOREIGN KEY
        [index_name] (col_name, ...)
        REFERENCES tbl_name (col_name,...)
        [ON DELETE reference_option]
        [ON UPDATE reference_option]
    
    reference_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
    

    2.2 ✅ 命名规则

    • 在外键约束的语法中,如果已经对外键命名,即上面的[CONSTRAINT [symbol]] FOREIGN KEYsymbol这个字段有值了,则直接使用这个值作为外键名称
    • 如果CONSTRAINT symbol子句未定义,或CONSTRAINT关键字后未包含符号,
      • 对于InnoDB表,会自动生成约束名称,ibfk是InnoDB Foreign Key的缩写
      • 例如:使用Navicat工具管理mysql数据库。外键的一种常用命名方式是表名_fk_序号,如下,poet表的第一个外键就是:poet_ibfk_1
        在这里插入图片描述
      • 对于NDB表,使用该 FOREIGN KEY index_name值(如果已定义)。否则,会自动生成约束名称。
    • 该值(如果已定义)在数据库中必须是唯一的。重复会 导致类似于以下内容的错误:ERROR 1005 (HY000): Can't create table 'test.fk1' (errno: 121)。 CONSTRAINT symbolsymbol(外键名称在一个数据库中必须唯一)

    这是Mysql错误1452 - Cannot add or update a child row: a foreign key constraint fails怎么办?这个错误下这个答案的依据,只是不太匹配这个报错信息
    在这里插入图片描述


    2.3 ✅ 条件和限制

    外键约束遵循以下条件和限制:

    • 父表和子表必须使用相同的存储引擎,同时子表和父表不能是临时表。

    • 创建外键需要从父表得到 REFERENCES 权限(需要有引用的权限)

    • 外键列和它引用的被参照列必须有相似的数据类型(最好是一模一样或者是可以兼容的),比如整数(INTEGER)和小数(DECIMAL)的符号以及固定精度必须一致;如果是字符串类型,则对长度的规定可以不一致,对于非二进制(字符)字符串列,字符集和排序规则必须相同。

      • 类似下面这样 在这里插入图片描述
    • MySQL支持外键引用同一个表中的另一列(主键),但是列不能对列自身有引用。在这种情况下,子表记录指的是同一个表中的依赖记录。

      • 比如,如果学生组,包含学生id属性,小组长/班长id属性,那么后者其实就会引用前者,所以支持同一个表中不同列的引用,但是不支持列对列自身的引用
    • MySQL要求外键和引用的列上都有索引,这样进行外键检查的时候就不需要扫描整个表,可以加快速度。在引用表中,外键引用的那列必须要用索引,如果没有,就会自动创建。

    • 对于InnoDB来说,允许外键引用含有索引的列或者列组(好几列),不过,在引用的数据表上,其中引用的第一列上必须有相同的索引。

      • 关于索引这部分,其实可以观察一下,在创建外键之后,会自动对外键的列添加索引。(确实是引用表的外键上有索引,被引用的则没有)
        在这里插入图片描述
    • 外键关系中的表不能更改为使用另一个存储引擎。要更改存储引擎,您必须首先删除所有外键约束。简单来说,还是建立外键关系的两个表,必须使用同一种存储引擎

    2.3.1 存储引擎查询

    • 关于存储引擎,其实就是这个:
      在这里插入图片描述
    • 也可以使用sql语句查询某个表的存储引擎
      # 查询某个数据库中所有表的存储引擎
      show table status from 库名;
      # 查询某个特定表的存储引擎
      show table status from 库名 where name='表名'
      在这里插入图片描述

    参考:

    ✅mysql5.7文档中文翻译(显示的是5.7 但是对应章节都不一样,参考对照着看,另外,有点像机翻,哈哈。)


    其他可能有用的信息

    mysql5.1文档的中文翻译


    实践的结果(从程序员的角度来看):

    展开全文
  • mysql外键约束的写法:【[CONSTRAINT ] FOREIGN KEY 字段名 REFERENCES 主键列1】。外键约束是表的一个特殊字段,经常与主键约束一起使用。在 CREATE TABLE 语句中,通过 FOREIGN KEY 关键字来指定外键。(推荐学习:...
  • 什么是数据库外键?

    千次阅读 2021-04-10 21:17:42
    外键就是一个表中的一个字段引用了另一个表中的主键,引用的表叫做子表,被引用的表叫做主表,外键是一种约束,描述的是表之间的关系。
  • 为什么禁用数据库外键外键带来的好处带来的不便 一带来的不便 二带来的不便 三带来的不便 四最后说下 外键带来的好处 数据一直性检查由数据库保证 带来的不便 一 每次增删改时都要考虑到外键约束,在调试接口的时候...
  • 2个表;人员表,订单表; 创建人员表,pid为主键;Sqlite的主键自增长必须为integer,不能为int; 创建订单表;字段: oid,orderno, pid;...订单表中的 pid 列指向人员表中的pid列;...sqlite外键的写法:.
  • SQL数据库外键代码

    千次阅读 2021-01-18 19:15:29
    子表(test_student)创建一个外键, alter表TEST_STUDENT 添加约束fk_class_id外键(CLASS_ID) 参考test_class(CLASS_ID); 扩展资料: 1.高可用性: 分布式组织的可扩展性,决策支持的数据仓库功能,与...
  • 你好,这是【一文一点】的第1篇文章,不拘泥于篇幅字数,用一篇文章说清一个知识点。有的SQL规约是这么说的:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。那先复习下是什么...
  • 外键作用: 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有客户号,客户名称 b表中存有每个客户的订单 ...
  • 1,由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的完整性,而用外键即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。 eg:数据库和应用是一...
  • Mysql数据库5.5以后默认的表类型就是INNOB的,默认支持外键设置,现以学生选课表为例说明外键的设置格式。第一张学生表:create table student(sid int primary key ,sname varchar(45) not null,ssex varchar(2) ...
  • qt数据库外键查询

    2022-02-04 19:23:29
    qt数据库外键查询 最近,开发qt数据库方面的信息管理系统,使用到了sqlite数据库,涉及到了外键查询。 查找了几个文章,没有找到合适的解决方案,阅读QSqlRelationalTableModel帮助文档,没有看懂其使用方法。 最后...
  • java获取数据库外键

    2014-02-19 14:56:01
    使用eclipse获取mysql数据库中的表结构以及主外键
  • 数据库设置外键

    千次阅读 2022-03-31 21:18:26
    数据库默认引擎是InnoDB,默认支持外键设置 e.g. 创建表1 create table 表1( 表1.主键 字段类型 primary key, 创建的一些字段。。。。 ) 创建表2 create table 表2( 表2.主键 字段类型 primary key, 创建...
  • Django 学习,数据库外键的设置 model.ForeignKey() TypeError: init() missing 1 required positional argument: ‘on_delete’ 建立外键的时候碰到上述报错 class Student(models.Model): s_name = models....
  • 数据库外键的使用以及优缺点

    千次阅读 2018-08-23 13:59:25
    1,由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的完整性,而用外键即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。 e...
  • 数据库外键的使用和原则

    万次阅读 多人点赞 2015-11-19 10:47:49
    外键作用: 保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有客户号,客户名称 b表中存有每个客户的订单 有了...
  • 为什么需要数据库外键

    千次阅读 2019-01-09 15:59:26
    MySQL数据库使用外键条件:两个表存储引擎必须是InnoDB,MyISAM暂时不支持外键外键列必须建立索引,MySQL4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显式建立;外键关系的两表的列的...
  • 数据库外键 附数据和代码

    千次阅读 2018-05-14 23:46:06
    数据库外键定义: 数据库外键作用: 数据库外键和主键的区别: 数据库外键demo; DROP schema IF EXISTS `demo`; CREATE schema demo;
  • 一、什么是主键、外键: 关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键 比如 学生表(学号,姓名,性别,班级) 其中每个学生的学号是唯一的...
  • 查看外键名称查看数据库外键名字

    千次阅读 2019-10-29 12:46:35
    我们要进行删除外键时,需要知道外键的名字,那么如何查看数据库外键呢?有2种方式查看: 1.过查看表的方式查看外键名字; 2.通过mysql自带的系统表查看外键。 更多精彩请访问本文源地址: ...
  • 数据库外键时,可能导致热更新后不能正常使用,无法运行,只有重启服务才正常,从而达不到热更新目的 3.耦合度 外键的使用物理关联,导致耦合度增加 4.难以分库分表 在大型互联网项目中,如果要做分库,当存在...
  • 阻止执行 ...主表修改主键值,连带从表相关行的外键值一起修改。两种方法提供给用户选择。无论选取哪种方法,从表里都* 不会有多余行。从另一个角度理解,用拒绝同一事物在从表中的标志与主表不一致来实现
  • 外键的好处:1减少重复数据在删除主表数据前先删除与之相关的子表的相关数据原则上主表的数据是不允许删除的2可以设置级联删除和更新,保证数据库的完整性3外键在一定程度上说明了业务逻辑,会使设计周到具体全面...
  • 数据库外键ForeignKey

    2021-03-11 22:33:23
    外键(foreign key)的使用及其优缺点 要不要使用外键(foreign key )? MYSQL外键的使用以及优缺点 外键是什么 如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键...
  • 使用过或者接触过数据库外键的开发者,有时候删数据就能够体会到一种欲生欲死的感觉,各种表关联,导致了要删某张表的数据就一定要先删除外键关联的那张表中对应的数据,一层层的删除下来,烦的一批。不过使用数据库...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 225,030
精华内容 90,012
关键字:

数据库外键的作用