Дизайн базы данных для системы обмена сообщениями электронной почты - PullRequest
21 голосов
/ 30 июля 2010

Я хочу создать систему обмена сообщениями электронной почты, подобную gmail.Я хотел бы иметь следующую опцию: Помечено, Корзина, Спам, Черновик, Чтение, Непрочитанное.Прямо сейчас у меня есть следующая структура в моей базе данных:

CREATE TABLE [MyInbox](
    [InboxID] [int] IDENTITY(1,1) NOT NULL,
    [FromUserID] [int] NOT NULL,
    [ToUserID] [int] NOT NULL,
    [Created] [datetime] NOT NULL,
    [Subject] [nvarchar](255) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [Body] [nvarchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [IsRead] [bit] NOT NULL,
    [IsReceived] [bit] NOT NULL,
    [IsSent] [bit] NOT NULL,
    [IsStar] [bit] NOT NULL CONSTRAINT [DF_MyInbox_IsStarred]  DEFAULT ((0)),
    [IsTrash] [bit] NOT NULL CONSTRAINT [DF_MyInbox_IsTrashed]  DEFAULT ((0)),
    [IsDraft] [bit] NOT NULL CONSTRAINT [DF_MyInbox_Isdrafted]  DEFAULT ((0))
) ON [PRIMARY]

Но я столкнулся с некоторыми проблемами с вышеуказанной структурой.Прямо сейчас, если пользователь A отправляет сообщение пользователю BI, я храню строку в этой таблице. Но если пользователь B удаляет это сообщение, он также удаляет отправленное сообщение от пользователя A.Это неправильно, я хочу точно так же, как обычная система обмена сообщениями электронной почты.Если A удаляет сообщение из отправленного им сообщения, то B не должен удаляться из своего почтового ящика.Я думаю о другой проблеме, которая возникнет, предположим, что пользователь А отправил письмо 500 пользователям одновременно, поэтому в соответствии с моим дизайном у меня будет 500 строк с дублированными телами, то есть не эффективный способ хранения.Не могли бы вы, ребята, помочь мне в разработке дизайна системы обмена сообщениями?

Ответы [ 8 ]

33 голосов
/ 30 июля 2010

Вам нужно разделить свой стол для этого.Вы можете иметь следующую схему и структуру

CREATE TABLE [Users]
    (
      [UserID] INT ,
      [UserName] NVARCHAR(50) ,
      [FirstName] NVARCHAR(50) ,
      [LastName] NVARCHAR(50)
    )

CREATE TABLE [Messages]
    (
      [MessageID] INT ,
      [Subject] NVARCHAR(MAX) ,
      [Body] NVARCHAR(MAX) ,
      [Date] DATETIME,
      [AuthorID] INT,
    )

CREATE TABLE [MessagePlaceHolders]
    (
      [PlaceHolderID] INT ,
      [PlaceHolder] NVARCHAR(255)--For example: InBox, SentItems, Draft, Trash, Spam 
    )

CREATE TABLE [Users_Messages_Mapped]
    (
      [MessageID] INT ,
      [UserID] INT ,
      [PlaceHolderID] INT,
      [IsRead] BIT ,
      [IsStarred] BIT 

    )

В таблице пользователей у вас могут быть пользователи. «Сообщения» обозначает таблицу для сообщений.«MessagePlaceHolders» обозначает таблицу для заполнителей для сообщений.Заполнителями могут быть входящие, отправленные элементы, черновик, спам или корзина.«Users_Messages_Mapped» обозначает таблицу сопоставления для пользователей и сообщений.«UserID» и «PlaceHolderID» являются внешними ключами. «IsRead» и «IsStarred» означают, что означает их имя.Если в таблице «Users_Messages_Mapped» не найдена запись для определенного сообщения, эта запись будет удалена из таблицы «Сообщения», поскольку она нам больше не нужна.

4 голосов
/ 30 июля 2010

Если вы работаете с документами, я советую взглянуть на CouchDB .Это без схемы, что означает, что такие проблемы исчезают.

Давайте рассмотрим пример: A отправляет сообщение B, и оно удаляется B.

У вас будет одинэкземпляр документа, с recipients в качестве атрибута электронного письма.Когда пользователи удаляют сообщения, вы либо удаляете их из списка получателей, либо добавляете их в список deleted_by или по своему усмотрению.

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

4 голосов
/ 30 июля 2010

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

2 голосов
/ 30 июля 2010

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

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

1 голос
/ 06 июля 2014
CREATE TABLE `mails` (  
  `message_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,  
  `message` varchar(10000) NOT NULL DEFAULT '',  
  `file` longblob,  
  `mailingdate` varchar(40) DEFAULT NULL,  
  `starred_status` int(10) unsigned NOT NULL DEFAULT '0',  
  `sender_email` varchar(200) NOT NULL DEFAULT '',  
  `reciever_email` varchar(200) NOT NULL DEFAULT '',  
  `inbox_status` int(10) unsigned NOT NULL DEFAULT '0',   
  `sent_status` int(10) unsigned NOT NULL DEFAULT '0',  
  `draft_status` int(10) unsigned NOT NULL DEFAULT '0',  
  `trash_status` int(10) unsigned NOT NULL DEFAULT '0',  
  `subject` varchar(200) DEFAULT NULL,  
  `read_status` int(10) unsigned NOT NULL DEFAULT '0',  
  `delete_status` int(10) unsigned NOT NULL DEFAULT '0',  
  PRIMARY KEY (`message_id`)  
)

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

1 голос
/ 30 июля 2010

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

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

0 голосов
/ 13 марта 2012

ПОЧЕМУ УДАЛИТЬ?Я думаю, что не нужно ничего удалять.Просто скрыть это от пользователей при удалении.Потому что будет сложно проверить обе стороны, когда отправитель отправляет одно и то же сообщение многим получателям.Затем вы должны проверить и пометить всех получателей.Если все в порядке, то удалите ... Я думаю, что удалять ничего не нужно.

0 голосов
/ 30 июля 2010

Сообщение может находиться только в одной папке за раз, поэтому вам нужна таблица папок (содержащая папки «Корзина», «Входящие», «Архив» и т. Д.) И внешний ключ для сообщений в папки. Для меток у вас есть отношение «многие ко многим», поэтому вам нужна таблица меток, а также таблица ссылок (messages_labels). Для ролей следует использовать простой битовый столбец, то же самое для «непрочитанного».

...