2012-04-16 63 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; 

希望這有助於。