2010-07-30 16 views
20

Chcę utworzyć system wiadomości e-mail, taki jak Gmail. Chciałbym mieć następującą opcję: Starred, Trash, Spam, Draft, Read, Unread. Obecnie mam poniższą strukturę w mojej bazie danych:Projektowanie bazy danych dla systemu wiadomości e-mail

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] 

Ale mam pewne problemy z powyższą strukturą. W tej chwili, jeśli użytkownik A wyśle ​​misaż do użytkownika B, przechowuję wiersz w tej tabeli, ale jeśli użytkownik B usunie tę wiadomość, to zostanie ona również usunięta. To jest złe, chcę dokładnie tak, jak robi to normalny system wiadomości e-mail. Jeśli A usunie wiadomość z wysłanego przedmiotu, B nie powinno zostać usunięte ze swojej skrzynki odbiorczej. Zastanawiam się nad innym problemem, który przyjdzie, przypuśćmy, że użytkownik A wysłał pocztę do 500 użytkowników naraz, tak jak na mój projekt będę miał 500 wierszy z duplikatami ciał, tj. Nie jest to skuteczny sposób przechowywania pamięci. Czy moglibyście mi pomóc w zaprojektowaniu systemu komunikacyjnego?

Odpowiedz

29

Musisz podzielić swój stół na to.Można mieć następujący schemat i struktura

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 

    ) 

Database Diagram:. alt text http://codeasp.net/Assets/Uploaded-CMS-Files/13f15882-7ed9-4e22-8e2c-20c6527522317-31-2010%2012-51-50%20AM.png

użytkownicy tabeli można mieć użytkowników „Wiadomości” oznacza tabelę komunikatów. "MessagePlaceHolders" oznacza tabelę dla symboli zastępczych dla wiadomości. Elementami zastępczymi mogą być: skrzynka odbiorcza, wysłany element, wersja robocza, spam lub kosz. "Users_Messages_Mapped" oznacza tablicę mapowania dla użytkowników i wiadomości. "UserID" i "PlaceHolderID" są kluczami obcymi. "IsRead" i "IsStarred" oznaczają to, co oznacza ich nazwa. Jeśli nie znaleziono rekordu dla konkretnego komunikatu w tabeli "Users_Messages_Mapped", ten rekord zostanie usunięty z tabeli Wiadomości, ponieważ nie jest już potrzebny.

+0

Czy możesz opisać, skąd możemy wiedzieć w tym projekcie, że jest od użytkownika i do użytkownika, którego wiadomość jest wysyłana. – zarpio

+0

@ zarpio the authorID w tabeli komunikatów jest identyfikatorem nadawcy. –

+0

Jeśli nie masz klucza złożonego w tabeli Users_Messages_Mapped? – user3308043

3

Myślę, że trzeba nieco rozłożyć swój schemat. Przechowuj wiadomości e-mail oddzielnie i mapuj skrzynki odbiorcze do wiadomości, które zawierają.

4

Jeśli wykonujesz pracę zorientowaną na dokument, proponuję przejrzeć CouchDB. Jest to mniej schematyczne, co oznacza, że ​​takie problemy znikają.

Rzućmy okiem na przykład: A wysyła wiadomość do B, a jest ona usuwana przez B.

Trzeba pojedynczą instancję dokumentu, z recipients wymienionego jako atrybut email. Gdy użytkownicy usuwają wiadomości, usuniesz je z listy odbiorców lub dodasz do listy deleted_by lub cokolwiek innego.

Jest to znacznie inne podejście do danych niż to, do czego jesteś przyzwyczajony, ale może być bardzo korzystne, aby poświęcić trochę czasu na rozważenie.

0

Wiadomość może znajdować się tylko w jednym folderze na raz, dlatego chcesz utworzyć tabelę folderów (zawierającą foldery "Kosz", "Skrzynka odbiorcza", "Archiwum" itd.) I klucz obcy z wiadomości do folderów. W przypadku etykiet masz relację wiele do wielu, więc potrzebujesz tabeli etykiet, a także tabeli łączy (messages_labels). Dla gwiazdozbioru powinna być prosta kolumna bitowa, taka sama dla "nieprzeczytanej".

2

Gdybym był tobą, ustawiłbym dwie flagi dla nadawcy i dla odbiornika, jeśli obie flagi są prawdziwe, to wiadomość powinna zostać usunięta z bazy danych, w przeciwnym razie pozostaw to w bazie danych, ale ukryj ją przed tym, kto ją usunął.

To samo dotyczy kosza. Możesz uruchomić crona lub sprawdzić ręcznie, jeśli zarówno nadawca, jak i odbiorca usuwają wiadomość, a następnie usuwają ją z bazy danych.

1

Można utworzyć tabelę dla wiadomości, która łączy każdą wiadomość z osobami, które mają ją w swoich skrzynkach pocztowych. Gdy użytkownik usunie wiadomość, wiersz zostanie usunięty z wiadomości, ale oryginalna wiadomość zostanie zachowana.

Możesz to zrobić ... ale sugeruję, żebyś tego nie robił. O ile nie jest to akademickie ćwiczenie ustalone przez twojego nauczyciela, z pewnością jest to kompletna strata czasu na rozwój własnego systemu komunikacyjnego. Jeśli to zadanie domowe, powinieneś tak powiedzieć. Jeśli nie, użyj zamiast tego czegoś bardziej użytecznego.

0

DLACZEGO USUŃ? Myślę, że nie trzeba niczego usuwać. Po prostu ukryj, od użytkowników po usunięciu. Ponieważ sprawdzenie obu stron będzie problematyczne, gdy nadawca wyśle ​​tę samą wiadomość do wielu odbiorców. Następnie musisz sprawdzić i oznaczyć wszystkich odbiorców. Jeśli wszystko OK, a następnie usuń ... Myślę, że nie ma potrzeby usuwania czegokolwiek.

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

Możesz użyć tej tabeli do przechowywania wiadomości e-mail i manipulowania zapytaniami według skrzynek pocztowych. Unikałem pozostałych tabel, takich jak szczegóły dotyczące użytkownika i tabela szczegółów logowania. Możesz je wykonać zgodnie ze swoimi potrzebami.

Powiązane problemy