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



我正在定义一个代表一个由一个或多个零件项目组成的页面。每个页面必须至少有一个部分定义。每个部分仅属于一个页面。部分项目之一将是页面上的"主"部分,所有其他项目都将依靠主人。除了这种区别,主人和从属部分的行为相同。

我正在寻找几种在SQL中表达这一点的不同方法。我可以想到几个选择,每个选择都有优势和缺点。我敢肯定没有一个"正确的答案",但是我正在寻找有关哪些方法具有隐藏复杂性的反馈,以稍后将我咬住我。限制和级联触发器是可取的,因此其他各方可以在需要时安全地修改表,但我想避免使用需要曲折,复杂逻辑的设计。

在配置时间,用户需要能够选择主的能力,而无需将0或多个部分标记为主要部分。在运行时,每个部分都需要识别它是主人还是需要依靠主获取信息。

我的目标平台是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
)

优点:在数据中易于理解;我正在增强的基本应用程序中使用的类似方法;零件记录知道它是主人,而无需查找页面记录上的数据。缺点:强迫一个和唯一的主人将要求触发器拒绝违反规则或应用程序层代码的更新,或两者兼而有之。

选项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的缺点是不正确的:可以使用调用UDF的检查约束来执行"一个和唯一的主"规则。这就是我要使用的。

最新更新