我想制作像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行具有重复的主体,即不是存储效率的存储方式。你们能帮我制作一个消息系统的设计吗?
答案 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”标志,并取决于其值显示消息或隐藏。