首页 文章

外键可以为NULL和/或重复吗?

提问于
浏览
216

请为我澄清两件事:

  • 外键可以为NULL吗?

  • 外键可以重复吗?

据我所知, NULL 不应该't be used in foreign keys, but in some application of mine I'能够在Oracle和SQL Server中输入 NULL ,我不知道为什么 .

10 回答

  • -6

    这取决于这个 foreign key 在你的关系中起什么作用 .

    • 如果 foreign key 在您的关系中也是 key attribute ,则它不能为NULL

    • 如果此 foreign key 是关系中的普通属性,则它可以为NULL .

  • 3

    简答:是的,它可以是NULL或重复 .

    我想解释为什么外键可能需要为null或者可能需要唯一或不唯一 . 首先要记住,外键只需要该字段中的值必须首先存在于另一个表(父表)中 . 根据定义,这就是FK . 根据定义,空值不是值 . Null意味着我们还不知道它的 Value .

    让我给你一个真实的例子 . 假设您有一个存储销售提案的数据库 . 进一步假设每个提案仅分配了一个销售人员和一个客户 . 因此,您的提议表将有两个外键,一个具有客户端ID,另一个具有销售代表ID . 但是,在创建记录时,并不总是分配销售代表(因为没有人可以自由处理它),因此填写了客户端ID,但销售代表ID可能为空 . 换句话说,当您在输入数据时可能不知道其值时,通常需要具有空FK的能力,但您确实知道表中需要输入的其他值 . 要允许FK中的空值,通常您只需要在具有FK的字段上允许空值 . null值与它是FK的想法是分开的 .

    它是唯一的还是不唯一的,与表是否与父表具有一对一或一对多的关系有关 . 现在,如果你有一对一的关系,你有可能将数据全部放在一个表中,但如果表格太宽或者数据是在另一个主题上(员工 - 保险示例@tbone给出了)例如),那么你想要一个带有FK的单独表 . 然后你想要使这个FK也是PK(它保证唯一性)或对它施加一个独特的约束 .

    大多数FK用于一对多的关系,这是你从FK获得的,而不在场上添加进一步的约束 . 所以你有一个订单表和订单详情表 . 如果客户一次订购十件商品,他有一个订单和十个订单明细记录,其中包含与FK相同的订单ID .

  • -1

    1 - Yes, since at least SQL Server 2000.

    2 - 是,只要它不是 UNIQUE 约束或链接到唯一索引 .

  • 12

    从马的嘴里:

    外键允许全部为NULL的键值,即使没有匹配的PRIMARY或UNIQUE键外键上没有约束当外键上没有定义其他约束时,子表中的任何行数都可以引用相同的值父键值 . 此模型允许外键中的空值 . ...外键上的NOT NULL约束当外键中不允许空值时,子表中的每一行都必须显式引用父键中的值,因为外键中不允许使用空值 . 子表中的任意数量的行都可以引用相同的父键值,因此该模型在父键和外键之间 Build 一对多关系 . 但是,子表中的每一行都必须引用父键值;不允许在外键中缺少值(null) . 可以使用上一节中的相同示例来说明这种关系 . 但是,在这种情况下,员工必须具有对特定部门的引用 . 外键上的UNIQUE约束当在外键上定义UNIQUE约束时,子表中只有一行可以引用给定的父键值 . 此模型允许外键中的空值 . 此模型在父键和外键之间 Build 一对一关系,允许外键中的未确定值(空值) . 例如,假设employee表有一个名为MEMBERNO的列,指的是公司保险计划中的员工成员编号 . 此外,名为INSURANCE的表具有名为MEMBERNO的主键,该表的其他列保留与员工保险单相关的相应信息 . employee表中的MEMBERNO必须是外键和唯一键:在EMP_TAB和INSURANCE表之间强制执行参照完整性规则(FOREIGN KEY约束)保证每个员工都有唯一的成员编号(UNIQUE键约束)外键上的UNIQUE和NOT NULL约束如果在外键上定义了UNIQUE和NOT NULL约束,则子表中只有一行可以引用给定的父键值,并且因为不允许使用NULL值外键,子表中的每一行必须显式引用父键中的值 .

    看到这个:

    Oracle 11g link

  • 45

    是的,外键可以为null,如上面高级程序员所说...我会添加另一个场景,其中外键需要为null ....假设我们在应用程序中有表评论,图片和视频,允许对图片和视频 . 在注释表中,我们可以有两个外键PicturesId,以及VideosId和主键CommentId . 因此,当您对视频发表评论时,只需要VideosId并且pictureId将为null ...如果您对图片发表评论,则只需要PictureId,而且VideosId将为null ...

  • 36

    以下是使用Oracle语法的示例:
    首先让我们创建一个表COUNTRY

    CREATE TABLE TBL_COUNTRY ( COUNTRY_ID VARCHAR2 (50) NOT NULL ) ;
    ALTER TABLE TBL_COUNTRY ADD CONSTRAINT COUNTRY_PK PRIMARY KEY ( COUNTRY_ID ) ;
    

    创建表PROVINCE

    CREATE TABLE TBL_PROVINCE(
    PROVINCE_ID VARCHAR2 (50) NOT NULL ,
    COUNTRY_ID  VARCHAR2 (50)
    );
    ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_PK PRIMARY KEY ( PROVINCE_ID ) ;
    ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_COUNTRY_FK FOREIGN KEY ( COUNTRY_ID ) REFERENCES TBL_COUNTRY ( COUNTRY_ID ) ;
    

    这在Oracle中运行得非常好 . 请注意,第二个表中的COUNTRY_ID外键没有“NOT NULL” .

    现在要在PROVINCE表中插入一行,仅指定PROVINCE_ID就足够了 . 但是,如果您也选择指定COUNTRY_ID,则它必须已存在于COUNTRY表中 .

  • 5

    默认情况下,外键没有约束,外键可以为null和重复 .

    在创建表/更改表时,如果添加任何唯一性约束或不为null,则只有它不允许空/重复值 .

  • 1

    简而言之,实体之间的“非识别”关系是ER-Model的一部分,在设计ER-Diagram时可以在Microsoft Visio中使用 . 这需要在“零或大于零”或“零或一”类型的实体之间强制实现基数 . 注意基数中的这个“零”而不是“一对多”中的“一” .

    现在,基数可能为“零”(非识别)的非识别关系的例子是当我们说一个实体中的记录/对象时 - “可能”或“可能不”具有作为记录参考的值/ s在另一个实体-B中 .

    因为,实体-A的一个记录有可能将自己标识为其他实体-B的记录,因此实体-B中应该有一列具有实体-B记录的标识值 . 如果实体-A中的记录没有标识实体-B中的记录/或(对象/ s),则该列可以是“空” .

    在面向对象(真实世界)范例中,有些情况下,类B的对象不一定依赖于(强耦合)在类A的对象上它的存在,这意味着类B与类的松散耦合 - A类可以“包含”(包含)A类对象,而B类对象的概念必须具有(组成)A类对象,因为它(类的对象) B)创作 .

    从SQL Query的角度来看,您可以查询entity-B中为Entity-B保留的外键的“非null”的所有记录 . 这将为实体-A中的行带来具有特定对应值的所有记录,或者具有Null值的所有记录将是在实体-B中的实体-A中没有任何记录的记录 .

  • 385

    我认为最好考虑表格中可能的基数 . 我们可以有最小基数为零 . 当它是可选的时,相关表中元组的最小参与可能为零,现在您面临允许外键值为null的必要性 .

    但答案是这一切都取决于业务 .

  • 0

    我认为一个表的外键也是其他表的主键 . 所以它不会允许null . 所以在外键中没有空值的问题 .

相关问题