Silné stránky prvního
První schéma se řídí lepšími normalizačními pravidly, a proto je ve většině případů pravděpodobně lepší.
S thread_id
, což je v podstatě přirozený klíč, který není FK k jinému stolu, si pravděpodobně koleduje o potíže. Bude velmi těžké prosadit, že je jedinečný, když chcete, aby byl, a stejný, když chcete, aby byl. Z tohoto důvodu bych doporučil první navrhované schéma.
Síla druhého
Vaše druhé schéma umožňuje změnit předmět pro každou zprávu ve vláknu. Pokud je to funkce, kterou chcete, nemůžete použít první možnost, jak jste ji napsali (ale viz níže).
Další možnosti
Message
- id
- parent (fk to Message.id)
- subject
- content
- timestamp
- sender (fk)
MessageRecipient
- message_id (fk)
- recipient (fk)
- status (read, unread, deleted)
Namísto thread_id
koncept, můžete mít místo toho parent
pojem. Pak bude každá odpověď ukazovat na záznam původní zprávy. To umožňuje vytváření vláken bez tabulky „vlákna“. Další možnou výhodou je to, že umožňuje stromy vláken také. Jednoduše řečeno, tímto způsobem můžete reprezentovat mnohem komplikovanější vztahy mezi zprávami a odpověďmi. Pokud vás to nezajímá, nebude to pro vaši aplikaci bonus.
Pokud vás nezajímají výhody vláken, které jsem právě zmínil, pravděpodobně bych doporučil hybrid vašich dvou schémat:
MessageThread(models.Model):
- id
Message(models.Model):
- thread (pk)
- subject
- content
- timestamp
- sender
MessageRecipient
- message_id (pk)
- recipient (pk)
- status (read, unread, deleted)
Toto je podobné prvnímu schématu, kromě toho, že jsem přesunul sloupec 'předmět' z MessageThread
do Message
tabulka, aby se předmět mohl měnit s postupem vlákna... Jednoduše používám tabulku MessageThread, aby fungovala jako omezení pro ID vlákna používané ve Zprávě (což překonává omezení, která jsem zmínil na začátku své odpovědi). Možná máte další metadata, která chcete zahrnout také do tabulky MessageThread, ale to nechám na vás a vaší aplikaci.