簡體   English   中英

創建一個像facebook和gmail這樣的線程化私人消息系統

[英]Creating a threaded private messaging system like facebook and gmail

我正在創建一個類似於gmail和facebook的線程消息系統,其中收件箱列出顯示主題的最新線程,發件人的姓名和最新消息的時間戳。

這是我的表格如何設置:

users:
    user_id
    user_name

thread:
    thread_id
    title
    to_id
    to_keep
    to_read
    from_id
    from_keep
    date

message:
    message_id
    thread_id
    to_id
    from_id
    message_text
    date

我現在正在做的是當用戶創建新消息時,它在線程表中創建一個新線程,然后在消息表中創建一個新消息,如果用戶響應一個線程,它會復制當前線程。除了它之外的線程表交換to_idfrom_id ,然后根據它創建一條新消息。

此外,對於收件箱視圖,我只能基於user_id查詢所有線程。 所以像SELECT * FROM thread WHERE to_id = 2 and to_keep = TRUE ORDER BY date DESC或者如果我想查看發件箱中的消息,它將類似SELECT * FROM thread WHERE from_id = 2 and from_keep = TRUE ORDER BY date DESC

如果用戶在有新消息時打開一個線程,則to_read更新為true UPDATE thread SET to_read = TRUE WHERE thread_id = 4

我覺得我過度復雜化這個過程,應該有更好的方法來做到這一點。

任何幫助或想法將不勝感激。

這樣我就可以從線程表中選擇所有內容,然后使用user表進行連接,以顯示我需要的所有內容。 但是我覺得應該有更好的方法來做到這一點。

為什么不從用戶對每條消息的視圖中分離出消息關系?

我會通過消息上的自引用關系來進行線程化。 換句話說,該消息具有“respond_to_message_id”列。

我不確定我理解為什么你有“to_id”。 郵件是針對個人用戶的嗎? 這似乎非常有限。 我認為你要么沒有收件人(即收件人是任何人都可以閱讀的留言板),要么你可以指定多個收件人,就像電子郵件一樣。 也許您可以解釋有關系統如何使用的更多信息。

假設(為簡單起見)你要發布到一個板上,所以只有“from”很重要,那么你就有了你的消息表,具有線程的自引用關系,用戶表,然后是用戶和消息之間的交集表存儲每個用戶已讀取的消息。

這樣,如果您想知道用戶是否已閱讀消息,只需嘗試在交集表中讀取給定消息的用戶ID。 如果存在,那么該用戶將讀取該消息。

請注意,如果您希望擁有此設計的單個收件人,並且您希望擁有多個收件人,則可以使用交叉表來保存每封郵件的收件人列表。 如果您有一個收件人交叉表,它可以作為您的讀狀態表執行雙重任務。

編輯:ERD草圖:

這是我正在談論的快速草圖......

ERD草圖

發件人是否已選擇保留郵件在郵件本身上標記。 如果消息是新線程的開始,則reply_to_message_id列為NULL,否則為父消息的message_id。 可以有多個收件人,每個收件人都有自己保留郵件的能力,以及跟蹤收件人閱讀郵件的日期和時間的能力。

編輯2:替代ERD和查詢最近的消息

@OP詢問如何查詢線程中的最新消息。 答案取決於線程的形式。 你可以有一個扁平線程,其中每條消息都到達線性消息流的末尾,或者你可以有一個樹形線程,其中每條消息都有一個特定的父節點,除非它是線程的根。 在上面的ERD中,可以以任一方式使用reply_to_message_id字段。 如果線程是平的,則FK始終是根MESSAGE。 如果線程是樹形的,那么FK就是回復MESSAGE的直接父級。

如果要運行的典型查詢是“線程中最新消息是什么?” 並且您的線程是平的,那么您可以像這樣使用SQL:

select top 1
  M.message_id
, M.sent_datetime
, M.title
, M.message_text
, S.user_id
, S.user_name
-- and anything else you want...
from MESSAGE M inner join USER S
  on M.sender_user_id = U.user_id
where M.reply_to_message_id = @ThreadRootMessageID
order by
  M.sent_datetime desc

另一方面,如果您的線程是樹形的,並且這是一個您希望能夠快速輕松地運行的查詢,那么上面的ERD中的模式不是很容易使用。 SQL不擅長樹木。 您可以通過一點非規范化來解決問題。 請參閱下面的ERD:

樹線程ERD

請注意,現在有一個FK顯示直接父級,一個FK顯示根。 由於線程不受編輯 - 至少對於消息的根被更改為指向不同線程的編輯,這帶來的非規范化並不意味着更新異常的風險,因此冗余不會太成問題。

如果您使用此ERD,則查詢“線程X中的最新消息”與上面相同,但在where子句中使用M.thread_root_message_id而不是M.reply_to_message_id。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM