Postgresql

聊天/對話歷史,實體關係圖

  • June 2, 2020

完全意識到有非常相似的問題,每個問題都經過了,但這些都是非常簡單/基本的解決方案,我根據我的需要,從中獲取了一些東西和想法來創建下面的實體關係圖。我要做的是為聊天/對話歷史創建數據庫模式(postgresql),我需要支持一些棘手的事情,例如:

  1. 聊天有名稱和初始創建者 ( customer_id)
  2. 創建的聊天消息customer_id可以是純文字消息或文件,而這兩個共享一些列,但從某種意義上說,它們在文件可以具有的方式上有所不同, file_name例如保存位置(例如文件系統),並且文件可以被對話中的任何人標記為存在或不存在。由於兩者之間的許多差異,至少對我來說,將兩者分開並擁有“共同父”表似乎更自然,. 其他方法是讓單個表具有許多 NULL 值左右。非常有興趣看到您對此的看法。file_mime_type``external_path``relevant``chat_lines
  3. 我最大的擔憂之一是聊天參與者能夠在reply_to現有的聊天線上或在現有的聊天線上啟動一個執行緒。我沒有比讓chat_linestable 有兩個單獨的對其自身的引用更好的主意。我沒有看到任何更好的方法來建模執行緒和回复。
  4. 每條消息都可以seen由討論中的任何人提出,因此引入了seens表格。不太確定是seens正確的英文單詞。
  5. 最後,對話/聊天中的任何人都可以對每一個做出反應chat line,例如thumb up, thumb down,僅此而已,因此 ENUM 似乎是一種不錯的方法。

經過幾個小時的思考,我得出了這個結論:

在此處輸入圖像描述

對我來說,這裡的一個擔憂是chat lines桌子已經變成了一個God table,一切都集中在這張桌子周圍,可能未來的每張桌子都會與它相關。此外,為了重建聊天記錄,每個SELECT查詢都必須逐字逐句。JOIN非常擔心表演,預計chat_lines隨著時間的推移,桌子會變得很大,試想一下,5 到 10 名參與者之間的一次聊天可以有大約 1k-5k 條聊天線,一路上傳文件很少。indexes在那些桌子上尋找合適的。SELECT我現在可以想像的每個查詢都可能會大量使用chat namecustomer ids例如聊天的參與者)。所以想在這些上創造一些indexes

當然,任何參與者都可以搜尋提到的東西。對於純文字消息,似乎要走的路是 postgresqltsvector針對錶中text的列messages。參與者將能夠在文件上傳時進行搜尋,因此在表file_name中設置索引似乎是合理的。file_name``files

請對一些“有意見的問題”表示抱歉,對您對這個解決方案未來擴展程度的看法非常感興趣,非常感謝任何可以改變的建議。任何其他想法如何對回復和執行緒進行建模?你會在哪裡添加索引?無論我做什麼,我想當數據開始大量增長時,將來應該創建基於此模式中的某些內容的數據庫分區。

一些可能有用但可能完全不正確的鬆散意見:

  • 該模型看起來不錯,據我所知應該是可擴展的。
  • 關係模型 (3NF) 是儲存大小和數據一致性的王者。它不是“輕鬆查詢”之王。請參閱customer_id下面的註釋。
  • 在實際的長期業務中,可維護性通常比性能更重要。
  • 不要擔心分區太快。您可能永遠不會在數據庫中看到前 0.5 TB 的客戶數據。但是customer_id,如果這將是一個多租戶應用程序,請考慮在所有表中製作 PK 部分。這將使擴大規模(想想:分片/分離租戶)更容易。
  • threadID 也可能chat_lines是. id的頂級項目。
  • tsearch 是可以的,但對於大規模、花哨的全文搜尋,您可能需要使用一些外部工具,如 ElasticSearch / Sphinx / 等。

引用自:https://dba.stackexchange.com/questions/268388