我將在我的網站中添加評論,我想要一個樹結構,這樣每個評論都可以有一個父級。這在檢索評論時會產生問題,因為必須為孩子遍歷每個評論,這在資料庫存盤方面是不可接受的。
這個眾所周知的性能問題有多種解決方案,我想使用簡單、快速的路徑前綴 scan( SELECT * FROM comments WHERE path LIKE 'commentID/%') ,其中我將通過所有評論的所有父項和評論的 id 作為值獲得帶有路徑的索引。
在實踐中,它看起來像:
[comment id]/[comment id]/[comment id]/.. = [comment id]
通過這種方式,我可以一次找到某個路徑的所有評論,并在需要時立即洗掉子項。
評論 id 將是無符號整數,由資料庫指定為自動遞增鍵。
我正在研究的問題是如何使用最短的評論 id 表示,這樣路徑索引就不會太長。
我希望使用無符號的 64 位長整數,它以二進制格式占用 8 個位元組。在三個前驅的情況下,路徑值將為 24 個位元組 2 個位元組的分隔符。如果我使用字串表示,那么它取決于數字的大小。如果每個父代的 id 為 5 位長 (12345),則路徑值將是 17 個位元組長,這比用 9 個位元組表示數字的二進制表示更有效。但是一旦 id 超過 8 位,字串變體的效率就會降低,它比二進制格式更長。
所以我的問題是,是否有另一種方法可以對整數進行簡短表示?我在考慮雙射函式。
uj5u.com熱心網友回復:
一個顯而易見的答案是使用 32 位整數而不是 64 位整數。您真的認為您網站上的 2 32 條評論會更多嗎?無意冒犯,但我假設您沒有實施 Facebook。你甚至沒有實作 Stack Overflow,到目前為止它只有 8300 萬條評論。
如果你真的需要支持 2 64 個不同的值,我看不出雙射函式會有什么幫助。與雙射相關的兩個集合中的值每個至少需要 64 位,并且您不會保存任何內容。
另一個答案是改變你存盤分層資料的方式,這樣你就不必擔心注釋路徑的長度。您正在使用一種管理樹狀資料的方法,有時稱為物體化路徑,這自然會限制路徑的深度,這就是您的問題所在。
沒有物體化路徑的一種方法是只使用存盤層次結構的正常方式:每個評論都有一個對它自己的父級的參考。然后,您需要學習使用MySQL 8.0 支持的遞回 SQL 查詢。
或者您可以使用其他替代方法來存盤層次結構。我喜歡使用閉包表,請參閱我對將平面表決議為樹的最有效/最優雅的方法是什么的回答?
哪種設計最適合您的應用取決于您需要針對這些資料進行的查詢型別。您必須對每個解決方案進行試驗,看看它對您需要做的用途的效果如何,例如添加評論、搜索評論執行緒、洗掉評論或執行緒等。
uj5u.com熱心網友回復:
我希望 98% 的“路徑”不會超過 3 深:“123/456/789”。因此,通過使用VARCHAR,這將需要 2 11 個位元組(長度為 2;字串為 11)。換句話說,我不認為空間是一個大問題。
我看了一個有 71K 問題的論壇。有 185K 回應。忽略“執行緒”(對回應的回應),即 71K/185K (38%) 是單個數字(即“123”)。我沒有關于執行緒的統計資料,但我上面 98% 的宣告可能相當接近正確。
底線:我認為縮小代表“執行緒”的字串是一個小問題。
(我有一個經驗法則:如果提議的更改似乎沒有節省 10%,請繼續解決其他問題。)執行緒字串可能遠小于所有其他內容占用的磁盤空間的 10%——尤其是文本。在我的調查中,“元資訊”是 11MB;文本為 260MB。您的執行緒字串將是 11MB 的一小部分。
為了節省空間,我會將compress()文本(上面的 260MB)存盤到MEDIUMBLOB. 散文(或代碼或 XML 或 json)通常以 3:1 的比例縮小(只有 87MB)。在客戶端執行壓縮/解壓縮,從而卸載服務器和網路。
另一方面,您可能需要FULLTEXT評論的索引。所以不能壓縮。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/385368.html
上一篇:SQL-選擇具有最新日期的值
