2011-09-02 131 views
1

说我有一个数据库有多个权利,如person, company, conference,你必须跟踪说addresses。我们可以为同一个实体(人)提供多个地址。一种方法是为每个实体分配一个单独的地址表(person_address等)。另一种方法是拥有一个包含主键的地址表(Entity,id,address_type)。在这种方法中,我们不能使用地址表中的外键到实体。数据库设计SQL Server

那么有什么更好的方法。有没有另一种方法来做到这一点?

感谢

+2

at 2000 rep,你已经足够长时间知道比标记一个问题'sql'和'server' –

回答

3

在逻辑建模POV中,您的描述强调了像person,company,conference等实体具有共同特征的事实:它们具有零个,一个或多个地址。如果您将此类建模为类层次结构,那么您可能会创建一个Addressable类,并且会从此Addressable类继承人员,公司和会议。您可以将相同的推理应用于您的数据模型,并将addresable表与addressable_entity_id配合使用。 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)); 

当然你必须找到绝对之间的平衡e关系正常形式和实际可用性。在这个方案中,我建议例如为了插入一个新的人,必须先在Addressable中获得一行,然后获取AddressableId,然后继续插入该人。这可能或可能也不起作用。顺便说一句,有的方式在一个单独的语句来完成这样的插入使用OUTPUT子句链两个插件:

insert into Addressable (AddressableType) 
output inserted.AddressableId, @FirstName, @LastName 
into Person (AddressableId, FirstName, LastName) 
values (AddressableTypePerson); 

但现在很难获取新插入的PersonId

1

从技术上讲,如果两个人住在同一个地址,你不会是完全标准化的,如果根本就在TBLPerson行称为TBLAddress但是单一个一对多的详细表,如果你只想每个物理地址一个实例,你将招致一个多对多关系表TBLPersonAddresses的开销,其中FK的对TBLAddress

我会说,除非你希望在同一个地址的多个人是我的标准将TBLAddresspersonID列作为01的详细信息

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