2008-08-28 59 views
8

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

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 

回答

9

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

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

+2

..或需要超过SQL行长度限制。 Microsoft Dynamics CRM执行此操作可将内置列与用户添加的列分开。 – BlackWasp 2009-02-23 22:13:46

4

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

0

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

0

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

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

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

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

1

@bosnic:

您必须有1台客户:因为,例如,您的系统的逻辑是这样说的带表SALES_OFFICE 1的关系。

你的应用程序逻辑是什么意思,你的数据模型说的是两个不同的东西。与业务逻辑代码一起执行这种关系没有任何问题,但它在数据模型中没有地位。

您是否真的将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的实例(因此,更改1的ZIP_CODE不会影响另一个)。你不同意ZIP_CODE属于SALES_OFFICE中的一列吗?