【问题标题】:Database design SQL Server数据库设计 SQL Server
【发布时间】:2011-09-02 22:44:28
【问题描述】:

假设我有一个包含多个权利的数据库,例如 person, company, conference,您必须跟踪 addresses。同一个实体(人)可以有多个地址。一种方法是为每个实体(person_address 等)创建一个单独的地址表。另一种方法是拥有一个具有主键 (Entity,id,address_type) 的地址表。在这种方法中,我们不能使用从地址表到实体的外键。

那么更好的方法是什么。还有其他方法吗?

谢谢

【问题讨论】:

  • 在 2000 年的代表中,您已经有足够长的时间知道最好不要标记问题 sqlserver

标签: sql-server


【解决方案1】:

在逻辑建模 POV 中,您的描述强调了 personcompanyconference 等实体具有一个共同特征:它们有零个、一个或多个地址。如果您将其建模为类层次结构,也许您会创建一个Addressable 类并让个人、公司和会议从这个可寻址类继承。您可以将相同的推理应用于您的数据模型,并拥有一个带有addressable_entity_idaddresable 表。 personcompanyconference 实体将“继承”该表。实现表继承的既定方法有以下三种:

所以你可以像这样为你的表建模:

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

【讨论】:

    【解决方案2】:

    从技术上讲,如果两个人住在同一个地址,如果TBLPerson 中的行只有一个名为TBLAddress 的一对多详细信息表,那么您将不会完全标准化。但是,如果您只想要一个实例每个物理地址都会产生TBLPersonAddresses 的多对多关系表的开销,FK 是TBLAddress

    我会说,除非您希望多个人在同一个地址成为常态,否则我只会将 TBLAddress 和列 personID 作为 TBLPerson 的详细信息

    编辑:而且我倾向于总是使用代理键,除非我有特定的理由不这样做。

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 2011-05-09
      • 2010-12-12
      • 1970-01-01
      • 2011-01-06
      • 2021-07-03
      相关资源
      最近更新 更多