Postgresql
聊天/對話歷史,實體關係圖
完全意識到有非常相似的問題,每個問題都經過了,但這些都是非常簡單/基本的解決方案,我根據我的需要,從中獲取了一些東西和想法來創建下面的實體關係圖。我要做的是為聊天/對話歷史創建數據庫模式(postgresql),我需要支持一些棘手的事情,例如:
- 聊天有名稱和初始創建者 (
customer_id
)- 創建的聊天消息
customer_id
可以是純文字消息或文件,而這兩個共享一些列,但從某種意義上說,它們在文件可以具有的方式上有所不同,file_name
例如保存位置(例如文件系統),並且文件可以被對話中的任何人標記為存在或不存在。由於兩者之間的許多差異,至少對我來說,將兩者分開並擁有“共同父”表似乎更自然,. 其他方法是讓單個表具有許多 NULL 值左右。非常有興趣看到您對此的看法。file_mime_type``external_path``relevant``chat_lines
- 我最大的擔憂之一是聊天參與者能夠在
reply_to
現有的聊天線上或在現有的聊天線上啟動一個執行緒。我沒有比讓chat_lines
table 有兩個單獨的對其自身的引用更好的主意。我沒有看到任何更好的方法來建模執行緒和回复。- 每條消息都可以
seen
由討論中的任何人提出,因此引入了seens
表格。不太確定是seens
正確的英文單詞。- 最後,對話/聊天中的任何人都可以對每一個做出反應
chat line
,例如thumb up
,thumb down
,僅此而已,因此 ENUM 似乎是一種不錯的方法。經過幾個小時的思考,我得出了這個結論:
對我來說,這裡的一個擔憂是
chat lines
桌子已經變成了一個God table
,一切都集中在這張桌子周圍,可能未來的每張桌子都會與它相關。此外,為了重建聊天記錄,每個SELECT
查詢都必須逐字逐句。JOIN
非常擔心表演,預計chat_lines
隨著時間的推移,桌子會變得很大,試想一下,5 到 10 名參與者之間的一次聊天可以有大約 1k-5k 條聊天線,一路上傳文件很少。indexes
在那些桌子上尋找合適的。SELECT
我現在可以想像的每個查詢都可能會大量使用chat name
(customer ids
例如聊天的參與者)。所以想在這些上創造一些indexes
。當然,任何參與者都可以搜尋提到的東西。對於純文字消息,似乎要走的路是 postgresql
tsvector
針對錶中text
的列messages
。參與者將能夠在文件上傳時進行搜尋,因此在表file_name
中設置索引似乎是合理的。file_name``files
請對一些“有意見的問題”表示抱歉,對您對這個解決方案未來擴展程度的看法非常感興趣,非常感謝任何可以改變的建議。任何其他想法如何對回復和執行緒進行建模?你會在哪裡添加索引?無論我做什麼,我想當數據開始大量增長時,將來應該創建基於此模式中的某些內容的數據庫分區。
一些可能有用但可能完全不正確的鬆散意見:
- 該模型看起來不錯,據我所知應該是可擴展的。
- 關係模型 (3NF) 是儲存大小和數據一致性的王者。它不是“輕鬆查詢”之王。請參閱
customer_id
下面的註釋。- 在實際的長期業務中,可維護性通常比性能更重要。
- 不要擔心分區太快。您可能永遠不會在數據庫中看到前 0.5 TB 的客戶數據。但是
customer_id
,如果這將是一個多租戶應用程序,請考慮在所有表中製作 PK 部分。這將使擴大規模(想想:分片/分離租戶)更容易。thread
ID 也可能chat_lines
是.id
的頂級項目。- tsearch 是可以的,但對於大規模、花哨的全文搜尋,您可能需要使用一些外部工具,如 ElasticSearch / Sphinx / 等。