tags:

views:

59

answers:

3

Hi! I'm working on a db but i'm kinda new to this so i've bumped into a problem today. I've got some tables: OFFICE, ROOM, EMPLOYEE and DOCUMENT. Document must specify the sender, which can be a single employee, an entire room or an entire office so it must have a reference to the primary keys of those tables. Should I do a "parallel" table for handle it (for example i've done one for handle the multiple recipients documents) or there is another way? Thank you

+1  A: 

I would be inclined to have a foreign key to each of the three tables with a check constraint that ensures only one will have a value. In this way, you can still use standard referential integrity. Btw, this assumes that the business rule is that each document must have one and only one sender.

Create Table Document
(
    SenderEmployeeId ...
    , SenderRoomId ...
    , SenderOfficeId....
    , Constraint CK_Document_SingleSender Check ( Case 
                                                    When SenderEmployeeId Is Not Null And SenderRoomId Is Null And SenderOfficeId Is Null Then 1
                                                    When SenderRoomId Is Not Null And SenderEmployeeId Is Null And SenderOfficeId Is Null Then 1
                                                    When SenderOfficeId Is Not Null And SenderEmployeeId Is Null And  SenderRoomId Is Null Then 1
                                                    Else 0
                                                    End = 1)
)
Thomas
yes, a document can have only one sender, so probably i'm gonna use a check constraint solution. Thank you
AGarofoli
A: 

You are trying to create conditional foreign keys which you can't do in SQL Server. I think creating a table to hold the Document and the Sender is a good idea but you won't be able to create the foreign keys. You could implement a Check Constraint though to control the data.

Barry
I dont know the check contraint too well but it seems to be the best solution. Thanks for the link!
AGarofoli
A: 

I would implement this with parallel tables as you mentioned. The tables would be as such:

OfficeDocuments (OfficeID, DocumentID)

RoomDocuments (RoomID, DocumentID)

EmployeeDocuments (EmployeeID, DocumentID)

You can design more flexible queries with a design like this, such as joinin against the Room and Office tables to acquire a list of employees.

The method you choose should depend on how flexible you need to be. If you are designing only a query or two to go along with this table, it may make sense to have a denormalized table instead (using check constraints and multiple attributes for each type of table which can be a sender).

Eugarps
The only query I need to have is one that let me check who has written a document, a check constraint would make it easier than the "parallel tables" method but you are right, this is a more flexible solution. For now I dont need to be flexible I might need to switch solution soon.Probably i'm gonna try both and see which one works better, thank you!
AGarofoli