1

Say I have a database with multiple entitles like person, company, conference for which you have to keep track of say addresses. We can have multiple addresses for the same entity (person). One approach is to have a separate address table for each entity (person_address etc). Another approach is to have an address table which has primary key (Entity,id,address_type). In this approach we cannot use foreign keys from address table to entities .

So what is the better approach. Is there another way to do this ?

thanks

1
  • 2
    at 2000 rep, you've been around long enough to know better than to tag a question sql and server Commented Sep 2, 2011 at 23:19

2 Answers 2

3

At a logical modeling POV your descriptions highlights the fact that the entities like person, company, conference etc have a common trait: they have zero, one or more addresses. If you would model this as a class hierarchy, perhaps you would create an Addressable class and have person, company and conference inherit from this Addressable class. You can apply the same reasoning to your data model and have an addresable table with an addressable_entity_id. The person, company, conference entities would 'inherit' this table. There are three established ways to implement table inheritance:

So you could model your tables like this:

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));

Of course you have to find the right balance between absolute relational normal form and actual usability. In this scheme I propose for instance in order to insert a new Person one has to first a row in Addressable, get the AddressableId and then proceed and insert the person. This may or may nor work. BTW, there is a way to do such an insert in one single statement using the OUTPUT clause to chain two inserts:

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

But now is difficult to retrieve the newly inserted PersonId.

Sign up to request clarification or add additional context in comments.

Comments

1

Technically if two people live at the same address you would not be completely normalized if there was simply a single one-to-many detail table for the row in TBLPerson called TBLAddress However, if you want just one instance per physical address you will incur the overhead of a many-to-many relation table of TBLPersonAddresses which FK's to TBLAddress

I would say that unless you expect multiple people at the same address to be the norm that I would simply have the TBLAddress with column personID as a detail to the TBLPerson

EDIT: And I tend to always use surrogate keys unless I have a specific reason not to do so.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.