请为我澄清两件事:
- 外键可以为NULL吗?
- 外键可以重复吗?
据我所知,NULL
不应该在外键中使用,但是在我的某些应用程序中,我可以NULL
在Oracle和SQL Server中进行输入,而且我也不知道为什么。
请为我澄清两件事:
据我所知,NULL
不应该在外键中使用,但是在我的某些应用程序中,我可以NULL
在Oracle和SQL Server中进行输入,而且我也不知道为什么。
Answers:
简短答案:是,可以为NULL或重复。
我想解释一下为什么外键可能需要为空,或者可能需要唯一或不唯一。首先要记住,外键仅要求该字段中的值必须首先存在于另一个表(父表)中。这就是FK的全部定义。根据定义,Null不是值。Null表示我们尚不知道该值是什么。
让我给你一个真实的例子。假设您有一个存储销售建议的数据库。进一步假设每个提案仅分配了一个销售人员和一个客户。因此,您的提案表将具有两个外键,一个具有客户ID,一个具有销售代表ID。但是,在创建记录时,并不总是分配销售代表(因为尚无人可以自由处理),因此填写了客户ID,但是销售代表ID可能为空。换句话说,当您在输入数据时可能不知道空FK的值,但是您确实知道表中需要输入的其他值时,通常需要具有空FK的能力。要在FK中允许空值,通常要做的就是在具有FK的字段上允许空值。空值与其作为FK的想法是分开的。
它是否唯一与表是否与父表具有一对一或一对多的关系有关。现在,如果您具有一对一关系,则可以将所有数据都放在一个表中,但是如果表太宽或数据涉及不同的主题(员工-保险示例@tbone给例如),那么您想要带有FK的单独表。然后,您可能想使此FK兼作PK(保证唯一性)或对其施加唯一约束。
大多数FK都是一对多的关系,这就是您从FK得到的,而无需在字段上增加其他约束。因此,您有一个订单表和一个订单详细信息表。如果客户一次订购十个项目,则他有一个订单和十个订单明细记录,这些记录包含与FK相同的orderID。
NULL
在一个表中用另一张表中的多个NULL
进行了交易。
从马口中:
即使没有匹配的PRIMARY或UNIQUE键,外键也允许所有键值为NULL
外键无约束
当在外键上没有定义其他约束时,子表中的任何数量的行都可以引用相同的父键值。此模型允许外键为空。...
外键上的NOT NULL约束
如果外键不允许使用空值,则子表中的每一行都必须显式引用父键中的值,因为外键不允许使用空值。
子表中的任何数量的行都可以引用相同的父键值,因此此模型在父键和外键之间建立了一对多关系。但是,子表中的每一行都必须引用一个父键值。不允许外键中没有值(空值)。上一节中的相同示例可用于说明这种关系。但是,在这种情况下,员工必须参考特定部门。
外键的唯一约束
当在外键上定义UNIQUE约束时,子表中只有一行可以引用给定的父键值。此模型允许外键为空。
此模型在父键和外键之间建立了一对一的关系,从而允许外键中的值不确定(空值)。例如,假设员工表中有一个名为MEMBERNO的列,它引用公司保险计划中的员工成员编号。此外,名为INSURANCE的表具有名为MEMBERNO的主键,并且该表的其他列保留与员工保险单有关的相应信息。员工表中的MEMBERNO必须既是外键又是唯一键:
在EMP_TAB和INSURANCE表之间强制执行引用完整性规则(FOREIGN KEY约束)
为了确保每个员工都有唯一的会员编号(UNIQUE键约束)
外键上的UNIQUE和NOT NULL约束
当在外键上同时定义UNIQUE和NOT NULL约束时,子表中只有一行可以引用给定的父键值,并且由于外键中不允许使用NULL值,因此子表中的每一行都必须显式引用父键中的值。
看到这个:
是的,外键可以为空,就像上面的高级程序员所说的那样...我将添加另一种情况,要求外键为空...。假设我们在允许对图片和图片进行注释的应用程序中有表格注释,图片和视频视频。在注释表中,我们可以有两个外键PicturesId和VideosId以及主键CommentId。因此,当您在视频上发表评论时,仅视频ID是必填项,而PictureId将为null ...,如果您在图片上发表评论,则仅需PictureId,而VideosId将为null ...
这是一个使用Oracle语法的示例:
首先让我们创建一个表COUNTRY
CREATE TABLE TBL_COUNTRY ( COUNTRY_ID VARCHAR2 (50) NOT NULL ) ;
ALTER TABLE TBL_COUNTRY ADD CONSTRAINT COUNTRY_PK PRIMARY KEY ( COUNTRY_ID ) ;
创建表省
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表中。
简而言之,实体之间的“非识别”关系是ER模型的一部分,并且在设计ER图时在Microsoft Visio中可用。这是强制实施“零或大于零”或“零或一”类型的实体之间的基数所必需的。注意基数为“零”,而不是“一对多”中的“一”。
现在,基数可能为“零”(非标识)的非标识关系的示例是当我们说一个实体中的记录/对象时,“可能”或“可能不会”具有一个值作为对记录的引用/ s在另一个实体B中。
由于实体A的一条记录有可能将自己标识为另一实体B的记录,因此实体B中应有一列,以具有实体B的记录的标识值。如果实体-A中没有记录标识实体-B中的记录(或对象),则此列可以为“ Null”。
在面向对象(现实世界)范式中,B类对象的存在并不一定依赖于(强烈耦合)A类对象,这意味着B类与B类松散耦合。这样,A类可以“包含”(包含)A类对象,而不是B类对象的概念必须具有(Composition)A类对象,因为其(Class-object对象) B)创作。
从SQL查询的角度来看,您可以查询实体B中为“实体B”保留的外键“不为空”的所有记录。这将为实体A中的行带来具有特定对应值的所有记录,或者所有具有Null值的记录将成为实体B中的实体A中没有任何记录的记录。