Which of the following db design would be preferable for an internal messaging system.
Three tables:
MessageThread(models.Model):
- subject
- timestamp
- creator
Message(models.Model):
- thread (pk)
- content
- timestamp
- sender
MessageRecipient
- message_id (pk)
- recipient (pk)
- status (read, unread, deleted)
Two tables:
Message
- thread_id
- subject
- content
- timestamp
- sender (fk)
MessageRecipient
- message_id (fk)
- recipient (fk)
- status (read, unread, deleted)
What would be the advantages of one over another?
Strengths of the first
The first schema obeys better normalization rules, and so is probably better in most cases.
Having a
thread_id, which is basically a natural key, that isn’t a FK to another table is probably asking for trouble. It will be very difficult to enforce that it is unique when you want it to be, and the same when you want it to be. For this reason, I would encourage the first suggested schema.Strengths of the second
Your second schema allows the subject to be altered for each message in the thread. If this is a feature you want, you can’t use the first option, as you’ve written it (but see below).
Other options
Instead of having a
thread_idconcept, you can intead have aparentconcept. Then every reply will point to the original message’s record. This allows threading, without a ‘thread’ table. Another possible advantage of this, is it allows thread trees as well. Simply put, you can represent much more complicated relationships between messages and replies this way. If you don’t care about that, then this won’t be a bonus for your application.If you don’t care about the threading advantages I just mentioned, I would probably recommend a hybrid of your two schemas:
This is similar to first schema, except that I moved the ‘subject’ column from the
MessageThreadto theMessagetable, to allow the subject to change as the thread progresses… I’m simply using the MessageThread table to act as a constraint on the thread ID used in Message (which overcomes the limitations I mentioned at the beginning of my answer). You may have additional meta data you want to include in the MessageThread table as well, but I’ll leave that up to you and your application.