电子邮件系统的数据库设计

时间:2010-07-30 10:33:34

标签: sql sql-server database-design email

我想制作像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向用户B发送msessage,我将在此表中存储一行但是如果用户B删除了该消息,则它也会被用户的A发送消息删除。这是错误的,我想要像正常的电子邮件消息系统那样。如果A从他发送的项目中删除了消息,那么B不应该从他的收件箱中删除。我在考虑其他问题,假设用户A一次向500个用户发送邮件,因此根据我的设计,我将有500行具有重复的主体,即不是存储效率的存储方式。你们能帮我制作一个消息系统的设计吗?

9 个答案:

答案 0 :(得分:33)

你需要拆分你的桌子。您可以拥有以下架构和结构

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 

    )

在users表中,您可以拥有用户。“Messages”表示消息表。 “MessagePlaceHolders”表示消息占位符的表。占位符可以是收件箱,已发送项目,草稿,垃圾邮件或垃圾箱。 “Users_Messages_Mapped”表示用户和消息的映射表。 “UserID”和“PlaceHolderID”是外键。“IsRead”和“IsStarred”表示他们的名字代表什么。 如果在“Users_Messages_Mapped”表中找不到特定messageid的记录,则该记录将从Messages表中删除,因为我们不再需要它。

答案 1 :(得分:4)

我认为您需要再分解您的架构。单独存储电子邮件,并将收件箱映射到它们包含的邮件。

答案 2 :(得分:4)

如果您正在进行以文档为导向的工作,我建议您查看CouchDB。它没有模式,意味着这样的问题消失了。

让我们看一下这个例子:A向B发送消息,然后由B删除。

您将拥有该文档的单个实例,并将recipients列为电子邮件的属性。当用户删除邮件时,您可以从收件人列表中删除邮件,也可以将其添加到deleted_by列表或您选择的任何邮件中。

这是一种与您习惯的数据截然不同的数据方法,但可能非常有利于花一些时间来考虑。

答案 3 :(得分:2)

如果我是你,我会为发送者设置一个标志,为接收者设置另一个标志,如果两个标志都为真,则应从数据库中删除消息,否则将其保留在数据库中,但将其与删除它的人隐藏起来。

对垃圾做同样的事情。如果发件人和收件人都删除了邮件,然后将其从数据库中删除,您可能需要手动运行cron或手动检查。

答案 4 :(得分:1)

您可以为MessageContacts创建一个表,该表将每条消息连接到在其邮箱中拥有它的人。当用户删除邮件时,会从MessageContacts中删除一行,但会保留原始邮件。

你可以这样做......但我建议你不要这样做。除非是您的导师设定的学术练习,否则开发您自己的消息系统肯定是完全浪费时间。如果是家庭作业那么你应该这么说。如果没有,那就去做一些更有用的事情。

答案 5 :(得分:1)

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`)  
)

您可以使用此表存储邮件并根据邮箱操作查询。我正在避开其他表,如用户详细信息和登录详细信息表。你可以根据自己的需要制作它们。

答案 6 :(得分:0)

邮件一次只能放在一个文件夹中,因此您需要一个文件夹表(包含文件夹“垃圾箱”,“收件箱”,“存档”等)和从邮件到文件夹的外键。 对于标签,您具有多对多关系,因此您需要标签表和链接表(messages_labels)。 对于主演,一个简单的位列应该做,“未读”也是如此。

答案 7 :(得分:0)

为什么要删除?我认为没有必要删除任何东西。只需在删除时将其隐藏起来。因为,当发件人向许多收件人发送相同的邮件时,检查双方都会出现问题。然后你必须检查并标记所有收件人。如果一切正常,则删除... 我认为没有必要删除任何内容。

答案 8 :(得分:-1)

在我的结构中,我设置了“ deleted:bool”标志,并取决于其值显示消息或隐藏。