【问题标题】:Mapping a Parent/Child Relationship of a Composite Primary Key Table映射复合主键表的父/子关系
【发布时间】:2011-11-15 17:48:00
【问题描述】:

我有一个复合主键表(维护项目)。我想创建另一个表来映射该表中项目之间的父子关系。

我不确定如何创建父子关系表,请参见下面的选项 1 或选项 2。

注意:我们的业务规则规定父子关系只能在共享相同维护程序的维护项目之间存在。这永远不会改变!

餐桌维护计划
程序代码(主键)
节目说明
其他栏目...

表维护项目(复合主键表)
ProgramCode(复合主键)
维护代码(复合主键)
维护说明
其他栏目...

表父/子维​​护项目(选项 1)
程序代码
父维护代码
子维护代码

表父/子维​​护项目(选项 2)
ParentProgramCode(与 ChildProgramCode 值相同)
父维护代码
ChildProgramCode(与 ParentProgramCode 值相同)
子维护代码

父/子表中不会有其他列,它只是一个关系映射表。

哪个是更好的选择?选项 2 似乎适合最佳实践,但鉴于我们的业务规则意味着我们基本上有两列具有完全相同的数据(程序代码)。

【问题讨论】:

    标签: c# .net sql database winforms


    【解决方案1】:

    选项 1 是最佳答案,您可以将子项引用到父项(并强制执行参照完整性)。此外,如果您使用的是 SQL Server 2005 或更高版本,如果需要菜单、下拉菜单等,您可以使用递归 CTE 来构建父/子的层次结构。

    【讨论】:

    • 谢谢威尔,递归 CTE 可能是我的下一个障碍。
    【解决方案2】:

    使用您所建议的关联实体的唯一原因是您是否希望维护项目之间存在多对多关系。如果这就是你所追求的,那么选项 1 就是你要做的。架构看起来像

    create table MaintenanceProgram
    (
      ProgramCode int not null ,
    
      ... -- other non-key attributes here
    
      primary key ( ProgramCode ) ,
    
    )
    create table MaintenanceItem
    (
      ProgramCode     int not null ,
      MaintenanceCode int not null ,
    
      ... -- other non-key attributes here
    
      primary key ( ProgramCode , MaintenanceCode ) ,
    
      foreign key                     ( ProgramCode )
        references MaintenanceProgram ( ProgramCode ) ,
    
    )
    create table MaintenanceItemMap
    (
      ProgramCode           int not null , 
      ParentMaintenanceCode int not null ,
      ChildMaintenanceCode  int not null ,
    
      primary key ( ProgramCode , ParentMaintenanceCode , ChildMaintenanceCode ) ,
    
      foreign key                  ( ProgramCode , ParentMaintenanceCode )
        references MaintenanceItem ( ProgramCode , MaintenanceCode       ) ,
      foreign key                  ( ProgramCode , ChildMaintenanceCode  )
        references MaintenanceItem ( ProgramCode , MaintenanceCode       ) ,
    
      check ( ParentMaintenanceCode != ChildMaintenanceCode ) ,
    
    )
    

    这确保所有相关的维护项目共享相同的 ProgramCode,并且维护项目不能映射到自身(检查约束)。

    但是,您的问题陈述是指父/子关系,这听起来更像是层次结构/树。在这种情况下,您想要的架构如下所示:

    create table MaintenanceProgram
    (
      ProgramCode int not null ,
    
      ... -- other non-key attributes here
    
      primary key ( ProgramCode ) ,
    
    )
    create table MaintenanceItem
    (
      ProgramCode           int not null ,
      MaintenanceCode       int not null ,
      ParentMaintenanceCode int     null ,
    
      ... -- other non-key attributes here
    
      primary key ( ProgramCode , MaintenanceCode ) ,
    
      foreign key                     ( ProgramCode  )
        references MaintenanceProgram (  ProgramCode ) ,
      foreign key                     ( ProgramCode , ParentMaintenanceCode )
        references MaintenanceItem    ( ProgramCode , MaintenanceCode       ) ,
    
      check ( MaintenanceCode != ParentMaintenanceCode or ParentMaintenanceCode is null ) ,
    
    )
    

    上面说每个维护项目都与一个维护程序相关;相反,每个维护程序都有零个或多个维护项目。

    进一步,每个维护项目有零个或1个父维护项目,必须与同一个维护程序相关。

    检查约束表示给定的维护项目可能不是它自己的父项。

    【讨论】:

    • 绝对是你的顶级架构是我所追求的。需要是多对多的关系。谢谢!
    【解决方案3】:

    为什么您认为选项 2 是最佳做法?如果它们必须相同,那么将它们放在不同的列中是没有意义的。选项 1 优于 2。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-29
      • 1970-01-01
      • 2013-05-26
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 2019-04-22
      • 2012-11-23
      相关资源
      最近更新 更多