Перемещение схемы обмена сообщениями в MongoDB - PullRequest
1 голос
/ 03 мая 2011

У меня есть эта схема для поддержки обмена сообщениями на месте: enter image description here

Когда я отправляю сообщение другому участнику, оно сохраняется в таблице сообщений;запись добавляется в таблицу MessageSent, а запись для каждого получателя добавляется в таблицу MessageInbox.MessageCount используется для отслеживания количества сообщений в папках входящих / отправки и заполняется с помощью триггеров вставки / удаления в MessageInbox / MessageSent - таким образом, я всегда могу знать, сколько сообщений участник имеет, не делая дорогой "счетчик выбора (*) "query.

Также, когда я запрашиваю сообщения участника, я присоединяюсь к таблице Member, чтобы получить FirstName / LastName участника.

Теперь я перенесу приложение в MongoDB, и яЯ не совсем уверен, какой должна быть схема сбора.Поскольку в MongoDB нет доступных объединений, я должен полностью денормализовать их, поэтому у меня будут коллекции MessageInbox, MessageDraft и MessageSent с полной информацией о сообщениях, верно?

Тогда я не уверен в следующем:

  1. Что если пользователь изменит свое имя / фамилию?Он будет храниться денормализованным как отправитель в некоторых сообщениях, как часть Получателей в других сообщениях - как мне его оптимальным образом обновить?

  2. Как получить количество сообщений?Там будет множество запросов одновременно, поэтому он должен работать хорошо.

Любые идеи, комментарии и предложения высоко ценятся!

1 Ответ

1 голос
/ 03 мая 2011

Я могу предложить вам некоторое представление о том, что я сделал для имитации JOIN в MongoDB.

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

(я не предлагаю, чтобы это была ваша схема, просто использую ее в качестве примера моего подхода)

{
    _id: "msg1234",
    from: "user1234",
    to: "user5678",
    subject: "This is the subject",
    body: "This is the body"
} 

Я бы запросил базу данных, чтобы получить все нужные мне сообщения, затем в своем приложении я бы повторил результаты и создал массив идентификаторов пользователей. Я бы отфильтровал этот массив, чтобы он был уникальным, а затем запросил бы базу данных во второй раз, используя оператор $in, чтобы найти любого пользователя в данном массиве.

Затем в моем приложении я присоединю результаты к объекту.

Требуется два запроса к базе данных (или, возможно, больше, если вы хотите присоединиться к другим коллекциям), но это иллюстрирует то, что многие люди защищали в течение долгого времени: выполняйте свои СОЕДИНЕНИЯ на уровне приложений. Пусть база данных тратит свое время на запросы данных, а не на их обработку. Возможно, вы все равно сможете масштабировать свои серверы приложений быстрее и дешевле, чем база данных.

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

Кроме того, записи в MongoDB блокируются, поэтому, если произойдет сценарий, подобный тому, который я только что описал, все операции чтения и записи будут заблокированы до завершения операции записи. Я полагаю, что это будет решено в некоторой степени для серии 2.x, но все еще не будет идеальным.

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

...