如何在保持参照完整性的父记录上识别 "preferred" 子项?

How to identify a "preferred" child on a parent record maintaining referential integrity?

我正在定义一个实体,它代表一个由一个或多个部分项目组成的页面。每个 Page 必须至少定义一个 Part。每个 Part 只属于一个 Page。部分项目之一将是页面上的 "master" 部分,所有其他部分将依赖于主。除了这个差异,主从部分的行为完全相同。

我正在研究在 SQL 中表达这一点的几种不同方式。我可以想到几个选项,每个选项都有优点和缺点。我确定没有人 "right answer,",但我正在寻找有关哪些方法具有隐藏的复杂性的反馈,这些复杂性稍后会咬我的屁股。约束和 CASCADE 触发器是可取的,这样其他方可以在需要时安全地修改表,但我想避免需要曲折、复杂逻辑的设计。

在配置时,用户需要能够选择主节点,而不允许将 0 个或多个部分标记为主节点。在运行时,每个部分都需要识别自己是master,还是需要依赖master获取信息。

我的目标平台是 Microsoft SQL Server 2008 或更高版本。下面的示例使用 int 键只是因为它使示例更小——我倾向于在实现时使用 GUID 键。

选项 1 - 主零件上的标志

create table [Page] (
  PageKey int identity primary key,
  PageName varchar(30) not NULL
)
go
create table [Part] (
  PartKey int identity primary key,
  PartName varchar(30) not NULL,
  PageKey int not null,
  constraint fkPage foreign key (PageKey) references [Page](PageKey),
  IsMasterPart bit not NULL default 0
)

优点:数据简单易懂;我正在增强的基础应用程序中使用的类似方法; Part 记录知道它是 master,而无需在 Page 记录上查找数据。 缺点:强制使用一个且唯一的master,需要触发器拒绝违反规则和/或应用层代码的更新。

选项 2 - 页面上的外键

create table [Page] (
  PageKey int identity primary key,
  PageName varchar(30) not NULL,
  MasterPartKey int not NULL
)
go
create table [Part] (
  PartKey int identity primary key,
  PartName varchar(30) not NULL,
  PageKey int not null,
  constraint fkPage foreign key (PageKey) references [Page](PageKey),
  IsMasterPart bit not NULL default 0
)
go
alter table [Page] 
  add constraint fkMasterPart 
  foreign key (MasterPartKey) references [Part](PartKey)

优点:DRI防止删除主零件;只能有一个主零件;不能有没有主部件的页面 缺点:分配 PK/FK 值

时可能存在先有鸡还是先有蛋的问题

我怀疑我错过了一两个提供良好答案所必需的细节。请提问,我会更新。

我会选择选项 1。选项 1 的缺点是不正确的:"one and only one master" 规则可以通过调用 UDF 的 CHECK CONSTRAINT 来强制执行。这就是我要使用的。