【问题标题】:1:1 Foreign Key Constraints1:1 外键约束
【发布时间】:2010-09-07 03:17:24
【问题描述】:

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

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    @bosnic:

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

    您的应用逻辑所说的和您的数据模型所说的是两件不同的事情。用您的业务逻辑代码强制执行这种关系并没有错,但它在数据模型中没有位置。

    您真的会将 SALES_OFFICE 的数据合并到 CLIENT 表中吗?

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

    如果其他表需要将它们与 SALES_OFFICE 关联起来?

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

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

    这个标准化。

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • ..或需要超出 SQL 行长度限制。 Microsoft Dynamics CRM 这样做是为了将内置列与用户添加的列分开。
        • 或者如果出于功能原因将其拆分,例如仅在频繁引用主表的少数情况下引用的字段。
        • 或用于多态关联
        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            猜你喜欢
            • 2020-07-29
            • 1970-01-01
            • 1970-01-01
            • 2013-07-10
            • 1970-01-01
            • 2014-01-17
            • 2017-04-20
            • 2018-03-05
            • 2013-01-30
            相关资源
            最近更新 更多