请为我澄清两点:

外键可以为NULL吗? 外键可以被复制吗?

正如我所知道的那样,NULL不应该用于外键,但在我的一些应用程序中,我可以在Oracle和SQL Server中输入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 ) ;

创建表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表中。

其他回答

下面是一个使用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表中。

简单回答:是的,它可以是NULL或重复。

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

Let me give you a real life example. Suppose you have a database that stores sales proposals. Suppose further that each proposal only has one sales person assigned and one client. So your proposal table would have two foreign keys, one with the client ID and one with the sales rep ID. However, at the time the record is created, a sales rep is not always assigned (because no one is free to work on it yet), so the client ID is filled in but the sales rep ID might be null. In other words, usually you need the ability to have a null FK when you may not know its value at the time the data is entered, but you do know other values in the table that need to be entered. To allow nulls in an FK generally all you have to do is allow nulls on the field that has the FK. The null value is separate from the idea of it being an FK.

Whether it is unique or not unique relates to whether the table has a one-one or a one-many relationship to the parent table. Now if you have a one-one relationship, it is possible that you could have the data all in one table, but if the table is getting too wide or if the data is on a different topic (the employee - insurance example @tbone gave for instance), then you want separate tables with a FK. You would then want to make this FK either also the PK (which guarantees uniqueness) or put a unique constraint on it.

大多数FK是一对多关系,这就是你从FK中得到的,而不需要在字段上增加进一步的约束。例如,你有一个订单表和订单明细表。如果客户一次订购10件商品,那么他有一个订单和10个订单详细记录,其中包含与FK相同的orderID。

外键的思想是基于引用一个已经存在于主表中的值的概念。这就是为什么在另一个表中它被称为外键。这个概念被称为参考完整性。如果外键被声明为空字段,它将违反引用完整性的逻辑。它指的是什么?它只能引用主表中存在的内容。因此,我认为将外键字段声明为null是错误的。

简单地说,实体之间的“非识别”关系是ER-Model的一部分,在设计ER-Diagram时可以在Microsoft Visio中使用。这需要在类型为“0或大于0”或“0或1”的实体之间强制执行基数。注意基数中的“0”,而不是“一对多”中的“1”。

现在,一个非识别关系的例子,其中基数可能是“零”(非识别),当我们说一个实体- a中的记录/对象“可能”或“可能”有一个值作为对另一个实体- b中的记录/s的引用。

由于实体a的一条记录有可能向其他实体b的记录标识自己,因此实体b中应该有一列具有实体b记录的标识值。如果实体a中没有记录标识实体b中的记录或对象,则此列可能为“Null”。

在面向对象(现实世界)范式中,b类对象的存在不一定依赖于a类对象(强耦合),这意味着b类与a类是松散耦合的,因此a类可以“包含”a类对象(Containment),而不是b类对象必须有a类对象(Composition)的概念,才能创建b类对象。

从SQL Query的角度来看,可以查询实体b中所有“非空”的外键为实体b保留的记录。这将为实体a中的行带来具有特定对应值的所有记录,或者所有具有Null值的记录将是实体b中实体a中没有任何记录的记录。

1 -是的,因为至少SQL Server 2000。

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