Mysql

100 萬個字元串和完全匹配搜尋

  • October 27, 2014

我需要選擇最好的解決方案(軟體和算法)來解決我的問題。我需要儲存多達數百萬個字元串和與之關聯的數據。字元串是搜尋查詢,數據是記憶體的搜尋結果。所以我要執行的操作是:

  • 獲取使用者的查詢
  • 在數據庫中查找記憶體結果(完全匹配)
  • 如果找到 - 歸還
  • 如果不是 - 執行搜尋並儲存結果

其他一些事實:

  • 因為它是記憶體行將隨著時間的推移而過期。
  • 查找和插入速度是重中之重。
  • 這個字元串欄位很可能是唯一要搜尋的欄位。
  • 我正在使用 PHP

看起來散列字元串是個好主意,衝突不是問題,如果我明白了,我會假設它是記憶體未命中並執行新的搜尋。所以我正在考慮以下選項:

  • 雜湊儲存在二進製欄位中的 MySQL
  • MySQL 將雜湊作為帶索引的字元串
  • MongoDB(可能有上限集合而不是過期時間欄位)
  • 其他一些解決方案(專門的鍵值儲存或其他東西)我沒有經驗,如果它足夠好並且值得為項目學習

當我需要幾乎相同的東西但也有部分匹配時,我也使用了 Sphinx 搜尋。對於精確搜尋,這似乎是一種矯枉過正。

那麼散列是一個好主意嗎?你會推薦哪種雜湊算法?哪個選項更好,為什麼?如果我需要儲存 500 萬行,答案會改變嗎?如果我hits不時添加欄位以獲取最受歡迎的行怎麼辦?

PostgreSQL 非常適合這個。你有幾個選擇來完成這項工作。

首先:PostgreSQL 有一個特殊的索引類型,稱為 GIN ( http://www.cybertec.at/gin-just-an-index-type/ )。一般來說,它非常適合全文搜尋。

很酷的是:在最新版本的 PostgreSQL 中,支持一個叫做 jsonb 的東西。您可以將字元串放入 JSON 文件並使用 GIN 和幾個很酷的運算符以一種很好的方式搜尋 JSON 中的每個欄位(請參閱http://www.postgresql.org/docs/9.4/static/datatype-json .html)。JSONB 真的非常快,非常強大,它在性能方面肯定會殺死 MongoDB。除此之外,幾百萬行對 PostgreSQL 來說也沒什麼大不了的。還有一件很酷的事情:PostgreSQL 可以對字元串進行模糊搜尋(通過最近鄰搜尋)。

我不建議使用上限集合:它們的擴展性很差,因為在撰寫本文時它們不能被分片,也許永遠不會。請參閱MongoDB 的 JIRA 上的相應功能請求

我會使用不同的方法。

  1. 將使用者查詢字元串用作_id. 由於確切的查詢是標識您的記錄的內容,因此無需在客戶端對其進行雜湊處理。另外,_id無論如何都會創建。
  2. 使用該字元串的散列版本作為您的分片鍵,如MongoDB 文件中的“創建散列索引”中所述。這樣做的原因是您的查詢字元串可能具有較低的基數,並且使用 MongoDB 進行擴展的方式是,選擇具有低基數的分片鍵是一個非常糟糕的主意™。然而,另一個分片鍵可能是一個可行的解決方案。
  3. 在查詢數據庫以獲取該字元串之前,在傳入查詢字元串標識的文件上發出一個 upsert 遞增命中計數器,寫入關注“未確認” 。雖然不能保證查詢的結果會包含命中計數器的增量,但它最終會被添加。這種方法的優點是該命令不會阻塞,因此會延遲您在數據庫中的搜尋。如果搜尋已經儲存在數據庫中,您可以簡單地返回結果。如果您必須執行搜尋,您可以使用命中計數器 1 更新現有文件。

遵循這些步驟應該會給你你想要的。您可以通過確切的查詢字元串找到文件,該解決方案是可擴展的(取決於您的資源到數十億個查詢字元串),您可以使用 TTL 索引使數據過期,這使得由您維護和触發過期邏輯已經過時。

您可以使用幾種不同的方法,例如使用文本索引實現元搜尋。但所描述的方法是最容易實現的方法。

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