如何在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
答案 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)关系,这可能是您想要的。
你的答案的第一部分是正确的答案,没有第二部分,除非第二张表中的数据真的是一种属于第一张表的信息,永远不会被其他表使用。