2012-04-16 64 views
1

我在创建的网站上撰写电子邮件系统的简化版本。数据库效率/结构问题

基本前提是用户可以在网站上互相发送消息,最好的例子是易趣,您可以在网站上自己发送其他用户的消息,它基本上是一个电子邮件系统。

我所拥有的是信息本身,他们来自谁,以及文本。

我还想要基本的“读/不读”和“删除”,甚至可能是“发送”类别。

是这样的:

表结构:

ID,以从,主题,正文,日期时间

我想知道的是,如果它更有意义,只是增加一个“读取”和“删除”列到该表,并搜索这些特定的条件,当我需要他们在网站上,或者如果更有效率/最好的做法有另一个“类别”表,然后有一个连接表把一个消息ID与类别ID,然后使用该连接表来提供信息时,它的要求?

如果我的问题没有道理原谅我,我仍然是这个东西很新。

回答

3

我想补充两列:

read tinyint(1), 
deleted tinyint(1) 

,并把它们作为布尔值。

+0

我现在很倾向于这种方式,我主要关心的是用户群的潜在范围非常大,我正在成千上万的用户中谈论。我只是有点担心速度,以及这种方式的查询如何在可能非常高的负载上运行。 我到目前为止所做的其他每个站点都没有超过3个用户,所有管理员都是如此,这些问题对我来说都是新的。因此,第一次就把它做对了。 – 2012-04-16 13:59:23

+0

你可以像做一个specs表一样做,但这只会减慢查询速度,因为简单的1或0比简单的1或0以及对消息的引用要小。它也会更快,因为不需要连接。 – Manuel 2012-04-16 14:07:43

+0

我已经从每个人那里得到了一些很棒的建议,但是我想我会用这个,对于我来说这是迄今为止最简单也是最快的,尽管@ Pierre-Olivier的建议最终可能会在更长时间内变得更有用如果项目进一步发展,请继续运行。谢谢大家! – 2012-04-16 19:50:55

1

我会为这个系统创建三张表。一个用于你的线程(消息组),一个用于你的实际消息,另一个用于你的类别。

这样的事情,

MessagesThreads 
-------------------- 
id (int, serial) 
from (int, foreign: Users.id) 
to (int, foreign: Users.id) 
subject (varchar) 
category (foreign key: Categories.id) 

MessagesContent 
-------------------- 
id (int, serial) 
threadId (int, foreign: MessagesThreads.id) 
content (text) 
date (datetime) 
status (tinyint) (0 for unread, 1 for read, 2 for deleted, for instance) 

Categories 
-------------------- 
id (int, serial) 
name (varchar) 

这将是一个正确规范化的数据库。

由此,一个线程可以包含一对多消息(因为外键在MessagesContent),消息只附加到一个胎面,并且一个线程可以有一个类别。

我认为这是存储您的消息的最有效方式,根据您的规格。

+0

这是非常有帮助的,如果我正在做一个“论坛风格”的消息系统,这将是有意义的。我在这里与这个小家伙瞄准的是更多的e邮件风格,所以基本上我给你发消息,当你回复我时,它会成为另一个“电子邮件”,邮件的主体将包含已经发送给对方的文本,与回复类型相同的想法 – 2012-04-16 13:56:06

+0

@DavidMorin与数据的存储方式无关,以前的电子邮件是否显示取决于您是否查询以前的电子邮件,另外,具有该功能的电子邮件系统实际上会复制数据,小号结束它在一个新的电子邮件与附加的答复。 – Ozzy 2012-04-16 14:16:48

+0

我的模式旨在避免在每封电子邮件/消息中重复邮件内容。我将它设计成记录讨论/以前的消息。在我看来,每个回复中重复的邮件内容可能不是长期的最佳解决方案。你的数据库会很快变大。 – 2012-04-16 14:20:17

3

我刚刚实现了类似的东西。我把这列放在“消息”表中。我选择了以下内容:

ReadDate DATETIME DEFAULT NULL, 

如果消息还没有被读取,则ReadDate为NULL。当用户阅读它时,我填写它被阅读的日期。这允许发送者知道接收者何时读取它。

+0

当您将它移动到deletedMessages表时,您是否保留所有相同的信息,除了现在消息被“删除”?我长期以来的目标是,如果人们选择他们可以将其移回,或者他们意外删除了某些东西,他们仍然可以看到这些东西,如果他们仍然需要它。 – 2012-04-16 13:57:26

+0

@DavidMorin,我删除了我的那部分回答,因为我意识到你正在处理删除更像另一个文件夹(常见的执行意外删除)。在我的情况下,我正在谈论归档。我的归档消息移动到具有相同模式的DeletedMessages表加上一个“DeletedDate”列。它仍然可能适合您的使用,因为它可以提高阅读邮件时的性能,删除时速度会更慢。 – 2012-04-16 15:28:06

0

给定一个用户帐户表是这样的:

CREATE TABLE tbl_accounts(
    id INT NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY(id), 
    email_addr VARCHAR(50) NOT NULL, 
    passkey BLOB /* AES KEY */ 
) ENGINE = InnoDB; 

您将需要一个邮箱表中查找取决于用户帐户&他们正在检查的文件夹中的邮件(收件箱|发件箱)。我们分开这个表,保持数据库“正常化”。

CREATE TABLE tbl_email_box(
    account_id INT, /* owner|sender of mail */ 
    FOREIGN KEY (account_id) REFERENCES tbl_accounts(id) ON DELETE SET NULL, 
    email_id INT, 
    FOREIGN KEY (email_id) REFERENCES tbl_emails(id) ON DELETE SET NULL, 

    folder TINYINT(1), /* 0=inbox->account=owner; 1=outbox->account=sender; */ 

    status TINYINT(1) DEFAULT 0, /* 0=unread, 1=read */ 

    date TIMESTAMP  /* because the query executes when they check/send mail, */ 
         /* then record is created (date=sent|received date) */ 
) ENGINE = InnoDB; 

该表将存储实际的电子邮件数据

CREATE TABLE tbl_emails(
    id INT NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY(id), 
    subject VARCHAR(100), 
    message BLOB, 
    created TIMESTAMP 
) ENGINE = InnoDB; 

希望这有助于。