Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I am modelling a database for an application I am developing and I am in front of a choice for which I would like to know what the best practice is.

Let's say I have a Documents table and a Users Table. Documents can be generic or related to a user in three ways:

Created by the user, in which case he has access to the document; About the user, in which case access to the document may or may not have been granted to him; Tailored for that user, in which case access to the document may or may not have been granted to him yet;

I could model a Many-to-Many relationship with a table containing a DocumentId field, a UserId field, and a bit telling whether the user has access to the document:

First appoach

Another approach would be to have a Many-to-Many table with a UserId field and a DocumentId field to link Documents to Users that have access to them, and to also have a UserId field in the Documents table that is Null if the document is generic or that contains the ID of the user it is related to.

Second approach

The first approach looks tidier because there is only one UserId FK. The second approach however allows to filter Documents by user without the need to join a table.

What is the best practice here?

share|improve this question
2  
Databases are optimized for joins if you index correctly. In the second approach, you can't have multiple users per document. –  HLGEM Aug 16 '12 at 20:47

2 Answers 2

up vote 3 down vote accepted

The first method is cleaner. I would make a few suggestions, however. You don't need the UserDocumentID surrogate Primary Key. A composite key of UserID and DocumentID would suffice, while also provide a unique constraint for the junction table. Also, is HasAccess really necessary? I believe the existence of the record in the junction table is enough to indiciate that access is granted.

Do you have different levels of access? Read-only, read/write, delete?

Hope this helps,

Matt

share|improve this answer
    
@Matt_M HasAccess is necessary, since a document may be related to a user without him having access to it. It could be a confidential document that an Admin user can see but not the user himself. Or it could be a document tailored for the user, but access has not been granted to him yet. –  Jean-François Beauchamp Aug 16 '12 at 20:49
    
@Jean-François_Beauchamp That makes sense. In that case, I would leave HasAccess in the junction table. –  Matt M Aug 16 '12 at 20:54
    
@Matt_M A while ago, I had noticed that some people put a surrogate PK in Many-to-Many relationship tables, ant that others don't, so I asked a DBA I know whether I should put one or not, and his answer was to put one, although I don't remember if he gave me any reason justifying his answer. So I always put one since then, but without understanding what the pros and cons are of doing so or not. Of course, if I put one, I also have to make the paire DocumentId, UserId a Unique Key. –  Jean-François Beauchamp Aug 16 '12 at 20:57
    
@Matt_M Concerning the different level of access, there are two: ReadAccess, and NoReadAccess. A document can be related to a user without the user having access to the document. –  Jean-François Beauchamp Aug 16 '12 at 23:28
    
@Jean-François_Beauchamp The surrogate PK issue is, and will continue to be, very divisive. It really boils down to storage efficiency, which is functionally equivalent to memory efficiency. Why add an additional key, when the combination of UserID and DocumentID both satisfies uniqueness AND is sufficiently narrow? I can see the argument for a surrogate key in this scenario, when you are going to subsequently join this junction table against something else enough to justify shaving off those 4 extra bytes per row. –  Matt M Aug 17 '12 at 14:06

It seems to me as though the access property should be at the document level. Therefore, I would do the following. The constraint on UserId in Document could be NULL if it does not belong to a user.

User (UserId PK, Firstname, Lastname, Email, UserTypeId)
Document (DocumentId PK, UserId FK, Name, Path, AccessTypeId FK)
DocumentAccess (AccessTypeId PK)
share|improve this answer
    
The thing is that if the document is generic, it may be shared with multiple users. In this case, I need a Many-to-Many relationship. –  Jean-François Beauchamp Aug 16 '12 at 20:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.