在逻辑建模 POV 中,您的描述强调了 person、company、conference 等实体具有一个共同特征:它们有零个、一个或多个地址。如果您将其建模为类层次结构,也许您会创建一个Addressable 类并让个人、公司和会议从这个可寻址类继承。您可以将相同的推理应用于您的数据模型,并拥有一个带有addressable_entity_id 的addresable 表。 person、company、conference 实体将“继承”该表。实现表继承的既定方法有以下三种:
所以你可以像这样为你的表建模:
create table Addresses (AddressId int not null identity(1,1) primary key, ...);
create table Addressable (AddressableId int not null identity (1,1) primary key, ...);
create table AddressableAddress (
AddressId int not null,
AddressableId int not null,
constraint AddressableAddressAddressId
foreign key (AddressId) references Addresses(AddressId),
constraint AddressableAddressAddressableId
foreign key (AddressableId) references Addressable(AddressableId));
create table Person (PersonId int not null identity(1,1) primary key,
AddressableId int not null,
...,
constraint PersonAddressableAddressableId
foreign key AddressableId references Addressable (AddressableId));
create table Company (CompanyId int not null identity(1,1) primary key,
AddressableId int not null,
...,
constraint CompanyAddressableAddressableId
foreign key AddressableId references Addressable (AddressableId));
当然,您必须在绝对关系范式和实际可用性之间找到适当的平衡。例如,在这个方案中,我建议为了插入一个新的人,必须首先在 Addressable 中的一行,获取 AddressableId,然后继续插入这个人。这可能会或可能不会奏效。顺便说一句,有一种方法可以在一个语句中使用 OUTPUT 子句链接两个插入:
insert into Addressable (AddressableType)
output inserted.AddressableId, @FirstName, @LastName
into Person (AddressableId, FirstName, LastName)
values (AddressableTypePerson);
但是现在很难找回新插入的PersonId。