1:1外键约束

时间:2008-08-28 14:16:16

标签: sql sql-server

如何在transact sql中指定外键约束应该是1:1的关系?是否足够声明列UNIQUE?以下是我现有的代码。!

CREATE TABLE [dbo].MyTable(
    [MyTablekey] INT IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
    [OtherTableKey] INT NOT NULL UNIQUE
        CONSTRAINT [FK_MyTable_OtherTable] FOREIGN KEY REFERENCES [dbo].[OtherTable]([OtherTableKey]),
    ...
    CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
    (
        [MyTableKey] ASC
    ) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

5 个答案:

答案 0 :(得分:9)

具有引用另一个表中的UNIQUE,NOT NULL列的UNIQUE和NOT NULL约束的外键列会创建1:(0 | 1)关系,这可能是您想要的。

如果存在真正的1:1关系,则第一个表中的每个记录在第二个表中都有相应的记录,反之亦然。在这种情况下,您可能只想制作一个表(除非您需要一些奇怪的存储优化)。

答案 1 :(得分:4)

您可以将列声明为主键和外键。这是“扩展”表的一个很好的策略,用于避免将可为空的列放入主表。

答案 2 :(得分:1)

@bosnic:

  

您有一个与表SALES_OFFICE具有1:1关系的表CLIENT,因为,例如,系统的逻辑就是这样。

您的应用逻辑说的是什么,以及您的数据模型所说的是两个不同的东西。使用业务逻辑代码强制执行该关系没有任何问题,但它在数据模型中没有任何地位。

  

您是否真的将SALES_OFFICE的数据合并到CLIENT表中?

如果每个CLIENT都有一个唯一的SALES_OFFICE,并且每个SALES_OFFICE都有一个单一的,唯一的客户端 - 那么是的,它们应该在同一个表中。我们只需要一个更好的名字。 ;)

  

如果其他表需要将自己与SALES_OFFICE联系起来?

没有理由。将您的其他表与CLIENT相关联,因为CLIENT具有唯一的SALES_OFFICE。

  

那么数据库规范化最佳实践和模式呢?

规范化。

公平地说,SALES_OFFICE和CLIENT显然不是1:1的关系 - 它是1:N。希望您的SALES_OFFICE能够为超过1个客户提供服务,并且在没有任何客户的情况下将继续存在(至少一段时间)。

一个更现实的例子是SALES_OFFICE和ZIP_CODE。 SALES_OFFICE必须具有1个ZIP_CODE和2个SALES_OFFICE - 即使它们具有等效的ZIP_CODE - 不共享ZIP_CODE的实例(因此,更改ZIP_CODE为1不会影响另一个)。你不同意ZIP_CODE属于SALES_OFFICE中的一列吗?

答案 3 :(得分:0)

根据上面的代码,只要表中的每个主键,唯一约束列也是唯一的,唯一约束就足够了。此外,这假设在[OtherTable]中,[OtherTableKey]列是该表的主键。

答案 4 :(得分:0)

  

如果存在真正的1:1关系,则第一个表中的每个记录在第二个表中都有相应的记录,反之亦然。在这种情况下,您可能只想制作一个表(除非您需要一些奇怪的存储优化)。

这是非常不正确的。让我给你举个例子。您有一个与表SALES_OFFICE具有1:1关系的表CLIENT,因为,例如,系统的逻辑就是这样。您真的会将SALES_OFFICE的数据合并到CLIENT表中吗?如果另一个表需要将自己与SALES_OFFICE联系起来?那么数据库规范化最佳实践和模式呢?

  

具有引用另一个表中的UNIQUE,NOT NULL列的UNIQUE和NOT NULL约束的外键列会创建1:(0 | 1)关系,这可能是您想要的。

你的答案的第一部分是正确的答案,没有第二部分,除非第二张表中的数据真的是一种属于第一张表的信息,永远不会被其他表使用。