外键可以为空吗?

not*_*d90 11 sql oracle database-design foreign-keys data-integrity

在我们的数据库项目中,我们有一个Sale包含主键和两个独占外键的表: Vehicle_IDPiece_ID.例如,如果我们出售车辆,我们需要Vehicle_ID作为外键但不是Piece_ID.我们可以将NULL放入Piece_ID,外键是否可以为空?或者有办法做这个工作吗?

谢谢.

APC*_*APC 14

主键的列(或列)必须为NOT NULL.无法通过NULL唯一标识记录.因此,外键引用末尾的ID列必须定义为NOT NULL.

但是,外键关系是可选的合法设计决策,表示方式的方法是使键的引用结束是可选的,即允许NULL.

在数据建模术语中,你所描述的是一个(独占)弧:"一个表......有两个或多个外键,其中一个且只有一个非空." 在逻辑建模中,弧是完全可以接受的,但是有一大堆意见支持将它们作为单独的表来实现.在您的场景中,这将是一个通用Sale表加上两个子类型表,VehicleSalePieceSale.

单独的表实现的优点是:

  • 更容易执行外键约束;
  • 更容易添加与(例如)车辆销售相关的其他不适用于销售的列;
  • 更容易使用其他子类型扩展模型;
  • 更清晰的数据模型,可以简化应用程序开发.

然而,优点并非都是单向的.虽然这是很容易确保Sale适用于任何一个VehicleSale或一个PieceSale而不是两个,执行一个规则Sale 必须有一个孩子记录实际上得到相当粗糙.

因此,流行的建议是,专属弧是错误的,这通常是好建议.但它并不像有些人那样明确.

  • @BrankoDimitrijevic - 我以为我很清楚替代实现是一个带有子类表的通用表,即三表解决方案.通用表将强制实现唯一性. (2认同)

Bra*_*vic 6

回答:

是的,您可以这样做 - 使FK本身可以为空,但添加一个CHECK以确保其中一个包含非NULL值.

阐述:

FK可以是NULL,可以建立1..0:N关系.换句话说,"子"行可以(但不是必须)具有"父"行.

NOT NULL外键模拟1:N关系.换句话说,每个孩子都必须有父母.

当FK为复合1且其至少一个字段为NULL时,将以特殊方式处理NULL和非NULL值的混合:

  • 如果FK为MATCH FULL,则所有值必须为NULL或所有值必须为非NULL且与某些父行匹配.
  • 如果FK是MATCH PARTIAL,则只有那些非NULL的值必须与某个父行匹配(忽略NULL).
  • 如果FK是MATCH SIMPLE,则所有值都是非NULL并且必须与某个父行匹配,或者至少有一个NULL值(在这种情况下,非NULL不需要匹配).

大多数DBMS默认为MATCH SIMPLE(除了MS Access之外),大多数DBMS默认不支持任何内容.


1你没有这里 - 只是提到完整性.


And*_*ers 0

如果您的外键为空,Oracle 不应该抱怨。

您遇到过一些错误吗?

  • null 是指没有值。在您的情况下,值将是引用其他地方的主键的外键。空值表示不存在值,就像往常一样。在下一个抽象层次上,外键代表关系。可为空的外键表示可选关系。没问题。 (3认同)