自引用表上的复合键

时间:2009-08-26 14:35:27

标签: sql foreign-keys composite-key self-reference dbo

我们为下面定义的站点表提供了一个复合主键。从功能上讲,这完全符合我们的意愿。每个站点都应具有同一区域的父站点。以这种方式定义表格可以专门用于此。

    CREATE TABLE [dbo].[site](
        [site_number] [nvarchar](50) NOT NULL,
        [district_id] [bigint] NOT NULL,
        [partner_site_number] [nvarchar](50) NULL,
     CONSTRAINT [PK_site] PRIMARY KEY CLUSTERED 
    (
        [site_number] ASC,
        [district_id] ASC
    )

    ALTER TABLE [dbo].[site]  WITH CHECK ADD  CONSTRAINT [FK_site_site] FOREIGN KEY([partner_site_number], [district_id])

我的具体问题是关于在复合PK上定义的自引用FK。我听过一些关于这个特定设计的意见,但它们往往是相互矛盾的。有些人喜欢它,特别是因为它在复合键的一般理解中起作用。其他人坚持认为它在理论上是不正确的,并且还应该有一个[partner_district_id]字段包含在FK而不是[district_id]中。此设计需要验证以强制执行[district_id] = [partner_district_id],这可以使用检查约束或应用程序级逻辑来完成。

对这些解决方案或任何其他解决方案的进一步意见将不胜感激。

2 个答案:

答案 0 :(得分:2)

我建议将SiteId作为主键。 DistrictId可能应该是外键吗?

编辑 - 在这种情况下,我建议将额外的PartnerDistrictId添加到外键;你永远不会知道,你可能以后想要在另一个地区与另一个网站合作。但就个人而言,我在这里赞成代理钥匙。在大多数情况下;)

答案 1 :(得分:0)

命名评论...... Site_Id本身不是唯一的吗?因为名称Site_id暗示iut是。如果它只与Region_Id结合使用,那么它可能是错误名称......如果它是site_Sequence,或者是Region_site_No,或者其他更清楚的东西,它可能会更清楚。

如果我理解你的域模型,那么一个区域中的所有站点都来自同一个根父站点,并且不同地区的站点之间不会有重叠......如果是这样,那么相同的功能可以通过以下方式实现:使ZoneID可以为空,并且仅为根站点填充它。然后,Site_Id可以是单个字段PK,而ParentSiteId可以是单个字段FK。所有“子”网站都“属于”其根父网站记录中指定的区域。