如何识别"首选"保持参照完整性的父记录上的孩子?

时间:2017-10-04 16:39:33

标签: sql-server referential-integrity

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

我正在研究几种不同的方式来在SQL中表达这一点。我可以想到几个选项,每个选项都有优点和缺点。我确定没有人正确的答案,"但是我正在寻找关于哪些方法隐藏了复杂性的反馈,这些复杂性会让我陷入困境。需要约束和CASCADE触发器,以便其他方可以在需要时安全地修改表格,但我希望避免设计需要扭曲,复杂的逻辑。

在配置时,用户需要能够选择主设备而不允许将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
)

优点:数据简单易懂;我正在增强的基础应用程序中使用的类似方法; Part记录知道它是master而没有在Page记录上查找数据。 缺点:强制一对一的主服务器需要触发器来拒绝违反规则或应用程序层代码或两者的更新。

选项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 个答案:

答案 0 :(得分:0)

我会选择选项1.您对选项1的不利之处是不正确的:"一个且只有一个主人"可以使用调用UDF的CHECK CONSTRAINT强制执行规则。这就是我要用的东西。