映射复合主键表的父/子关系

时间:2011-09-12 23:07:34

标签: c# .net sql database winforms

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

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

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

表格维护程序
ProgramCode(主键)
ProgramDescription
其他专栏......

表维护项目(复合主键表)
ProgramCode(复合主键)
MaintenanceCode(复合主键)
MaintenanceDescription
其他专栏......

表格父/子维护项目(选项1)
的程序代码
ParentMaintenanceCode
ChildMaintenanceCode

表格父/子维护项目(选项2)
ParentProgramCode(与ChildProgramCode相同的值)
ParentMaintenanceCode
ChildProgramCode(与ParentProgramCode相同的值)
ChildMaintenanceCode

父/子表中没有其他列只是关系映射表。

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

3 个答案:

答案 0 :(得分: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个父项维护项目,这些项目必须与同一维护程序相关。

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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