powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Проектирование почтового ящика в социальной сети
11 сообщений из 11, страница 1 из 1
Проектирование почтового ящика в социальной сети
    #36183056
goodw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

Условия задачи :
1. Высоконагруженный сервис (социальная сеть)

2. Пользователи могут обмениваться сообщениями
2.1. У каждого пользователя есть папка ВХОДЯЩИЕ
2.2. И папка ОТПРАВЛЕННЫЕ.
2.3. В списках 2.1. и 2.2. выделяются НЕПРОЧИТАННЫЕ сообщения.

3. Сообщение имеет формат -автор [Заголовок][Текст][Отправитель][Получатель][Дата][Прочтено\Нет]


Вопрос: какая структура была бы оптимальна для хранения и работы с сообщениями?

Планируемые запросы:
1. Вывод списка ВХОДЯЩИХ сообщений (постранично)
2. Вывод списка ОТПРАВЛЕННЫХ сообщений (постранично)
3. ПОИСК сообщений среди ВХОДЯЩИХ и ОТПРАВЛЕННЫХ по ЗАГОЛОВКУ и ТЕКСТУ
4. Отметка выбранных как прочитанных и непрочитанных.
5. Удаление выбранных.
6. Отправка сообщения.


Первое, что приходит на ум:

1. Таблица сообщений - Message

id subject body senderid receiverid sendate isread

2. Таблица почтового ящика - Mailbox

id messageid userid

Соответственно при отправке сообщения мы создаем 2 записи: 1 в Message, другую в Mailbox на userid-владельца ящика.

При удалении сообщения мы удаляем сначала запись в Mailbox, затем, если у сообщения не лежит в ящике отправителя - удаляем его из Message.

При выводе списков делаем join - Mailbox->Message

Вопрос: можно ли это реализовать как-то более удачно, с наименьшей избыточностью и потерей производительности?
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36184719
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а если нескольким юзерам послали одно сообщение?
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36184727
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну и соответственно is_read он для каждого пользователя свой, т.е. надо как-то разность кому послали сообщения и кто их прочитал.

т.е. в message лежит только от кого сообщение, дата сообщения и тело. далее должны быть таблицы прочтения сообщений пользователями соответственно с датой установки is_read (надеюсь без истории) и таблица кому из пользователей выслано данное соообщение.
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36185226
Konstantin~
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в свое время делали нечто похожее, "лобби для движка онлаин игры

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

при отравке сообщения создается три записи:
1. сообственно само сообщение, запись в таблице msg
2. для отправителя о том что сообщение отправлено: запись в таблице mailbox (отправитель,ид сообщения, ид папки Sent, flag: unread)
3. для получателя о том что сообщение доставлено: запись в таблице mailbox (получатель, ид сообщения, ид
папки Inbox, flag: unread).

После прочтения сообщения отправитель и/или получатель меняют unread|read флаг на соответсвующей записи в mailbox.
На удаление запись "переносится" в папку Deleted.

Записи в mailbox и в msg никогда не удаляются. Планировалось отдельно прикрутить систему удаления через триггер и таблицу заданий на удаление сообщений, но на этапе разработки решили не делать, т.к. было полно другой работы.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
-- messages
CREATE TABLE msg (
    id serial NOT NULL, -- id of the msg
    from_user_id integer NOT NULL, -- from whom the msg was sent
    to_user_id integer NOT NULL, -- id, to whom the msg was sent
    inreplyto_id integer NOT NULL DEFAULT currval('msg_id_seq'::regclass), -- msg threads feature.     
    ...
    ... -- subject, body, flags (urgent, normal, bulk), other message attributes
    ...
    timestamp timestamp without time zone NOT NULL DEFAULT now(),
);

-- mailboxes
CREATE TABLE mailbox
(
  owner_id integer NOT NULL, -- owner of the mailbox
  msg_id integer NOT NULL, -- 
  folder_id integer NOT NULL, -- msg folder in the mailbox, like inbox, sent, deleted
  status_id integer NOT NULL, -- msg status in the mailbox, like new, read, etc
  ...  
  ... -- other flags and attributes
  ...
  CONSTRAINT mailbox_pkey PRIMARY KEY (owner_id, msg_id), 
  ...
) 
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36185334
goodw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что скажете насчет такого варианта?

Message :
id subject body


Mailbox
авторid, message_id, sender_id, receiver_id, is_del_for_sender, is_del_for_receiver, send_date, is_read


is_del_for_sender - bit(1)
is_del_for_receiver - bit(1)


Таким образом, если автор отправляет сообщение одному пользователю, в Mailbox - 1 запись. Если отправка 2-м адресатам - 2 записи.

Если получатель удаляет сообщение в своем ящике - is_del_for_receiver = 0
Если отправитель удаляет сообщение в своем ящике - is_del_for_sender = 0

Если у оба нуля - удаляется запись из Mailbox и запись из Message


Список сообщений в ящике у меня выводится в таком виде:

Отправитель Получатель Заголовок Кусочек сообщения (например 15 символов) дата отправки


Имеет ли смысл для повышения производительности задублировать subject и body_small (обрезаный текст) в Mailbox?
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36186353
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а зачем дублировать sender_id в mail_box если он ясен из message? для скорости?
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36187205
goodw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, наоборот, предлагаю sender_id хранить в Mailbox, а не в Message.

В Message хранить только:

id subject body


Все операции вывода списков производить с Mailbox без присоединения Message.

Избыточно, но планируются миллионы таких записей.
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36187531
Konstantin~
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goodwЯ, наоборот, предлагаю sender_id хранить в Mailbox, а не в Message.

В Message хранить только:

id subject body
...
...


если сообщения посылаются от групп или к группе юзеров то желательно иметь sender_id, receiver_id в таблице Message.


qoodw
Имеет ли смысл для повышения производительности задублировать subject и body_small (обрезаный текст) в Mailbox?


уверены что будет повышение производительности? потестите, и заодно прикиньте на сколько увеличится
размер таблицы Mailbox если каждая запись будет иметь varchar subject, varchar body_small.
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36187587
goodw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сообщения одного пользователя другому пользователю или группе пользователей.
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36187717
goodw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как по быстродействию такой вариант?

Т.к. отправка идет от одного ко многим.

Message
id subject body sender_id send_date

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


Mailbox
id, message_id, receiver_id, id_read, is_delete_for_sender, is_delete_for_receiver
...
Рейтинг: 0 / 0
Проектирование почтового ящика в социальной сети
    #36189964
Konstantin~
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
idsubjectbodysender_idsend_date

т.к. сообщение идет от одного ко многим, получателем сообщения реално является группа, например в лобби сервере у каждого "клана" (команда геймеров) был свой user_id.

Message
idsubjectbodysender_idreceiver_idsend_date01testtest msg007(moderator)666(kill_all_humans_clan)2010-01-01


goodw
Mailbox
id message_id receiver_id id_read is_delete_for_sender is_delete_for_receiver


1. в Mailbox id это фактически receiver_id, т.е. ид юзера - владельца маилбокса. Сам по себе номер маилбокса смысла не имеет, если только у одного юзера не будет несколько разных маилбоксов (маловероятно)

mailbox_owner_id message_id is_read is_deleted ... other flags


... Вообще от кого и кому (sender_id, receiver_id) это свойства конкретного сообщения, т.е. должны быть в таблице Мessage.

У каждого юзера есть почтовый ящик, в котом лежит список сообщений с флагами которые определяют свойства сообщения относительно конкретного юзера, типа удалено,прочитано,послано,был написан ответ, и тд.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Проектирование почтового ящика в социальной сети
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]