Сравнение двух конструкций БД для внутреннего обмена сообщениями - PullRequest
4 голосов
/ 28 октября 2011

Какая из следующих схем БД будет предпочтительнее для внутренней системы обмена сообщениями.

Три стола:

MessageThread(models.Model):
    - subject
    - timestamp
    - creator

Message(models.Model):
    - thread (pk)
    - content
    - timestamp
    - sender

MessageRecipient
    - message_id (pk)
    - recipient (pk)
    - status (read, unread, deleted)

Два стола:

Message
    - thread_id
    - subject
    - content
    - timestamp
    - sender (fk)

MessageRecipient
    - message_id (fk)
    - recipient (fk)
    - status (read, unread, deleted)

Каковы были бы преимущества одного над другим? Спасибо.

Ответы [ 2 ]

4 голосов
/ 28 октября 2011

сильные стороны первого

Первая схема подчиняется лучшим правилам нормализации, и поэтому, вероятно, лучше в большинстве случаев.

Наличие thread_id, который является в основном естественным ключом, который не является FK для другой таблицы, вероятно, вызывает проблемы. Будет очень трудно добиться того, чтобы он был уникальным, когда вы хотите, чтобы он был, и таким же, когда вы хотите, чтобы он был. По этой причине я бы рекомендовал первую предложенную схему.

Сильные стороны второго

Ваша вторая схема позволяет изменять тему для каждого сообщения в ветке. Если вам нужна эта функция, вы не можете использовать первый вариант, как вы его написали (но см. Ниже).

Другие опции

Message
    - id
    - parent (fk to Message.id)
    - subject
    - content
    - timestamp
    - sender (fk)

MessageRecipient
    - message_id (fk)
    - recipient (fk)
    - status (read, unread, deleted)

Вместо концепции thread_id вы можете иметь концепцию parent. Тогда каждый ответ будет указывать на запись исходного сообщения. Это позволяет создавать потоки без таблицы «thread». Еще одним возможным преимуществом этого является то, что он также позволяет деревья потоков . Проще говоря, вы можете представить гораздо более сложные отношения между сообщениями и ответами таким образом. Если вас это не волнует, это не будет бонусом для вашего приложения.

Если вы не заботитесь о преимуществах многопоточности, о которых я только что упомянул, я бы порекомендовал гибрид двух ваших схем:

MessageThread(models.Model):
    - id

Message(models.Model):
    - thread (pk)
    - subject
    - content
    - timestamp
    - sender

MessageRecipient
    - message_id (pk)
    - recipient (pk)
    - status (read, unread, deleted)

Это похоже на первую схему, за исключением того, что я переместил столбец 'subject' из таблицы MessageThread в Message, чтобы позволить субъекту изменяться по мере продвижения потока ... Я просто использую Таблица MessageThread, действующая как ограничение идентификатора потока, используемого в сообщении (которое преодолевает ограничения, о которых я упоминал в начале моего ответа). У вас могут быть дополнительные метаданные, которые вы также хотите включить в таблицу MessageThread, но я оставлю это на ваше усмотрение.

0 голосов
/ 28 октября 2011

Отдельная таблица MesageThread может пригодиться, если позже вы захотите добавить некоторые дополнительные свойства потока, такие как «заблокирован», «закреплен» или «важен». Однако выбор более сложной модели только ради возможного добавления дополнительных функций в будущем, как правило, не очень хорошая идея.

Первая модель (модель с таблицей MessageThread) гарантирует, что все сообщения в потоке имеют одинаковую тему, во второй модели каждое сообщение в потоке может иметь разную тему. Это может быть хорошо или плохо, в зависимости от того, как вы хотите, чтобы обмен сообщениями работал.

Первая модель позволяет объявить столбец message.thread_id как внешний ключ, поэтому вы не можете вставить сообщение без действительной ссылки на поток. Со второй моделью у вас нет такой гарантии. Это может вызвать некоторые ошибки позже.

Я не думаю, что столбцы MessageThread.timestamp и MessageThread.creator в первой модели действительно необходимы; не совпадают ли они с отметкой времени и создателем первого сообщения в теме? Такая избыточность может иметь негативные последствия.

Я бы пошел с первой моделью, но я бы удалил поля создателя и метки времени из MessageThread.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...