Mysql

在 CMS 中集成 MySql 全文搜尋

  • January 10, 2016

我正在開發自己的 CMS 並使用 MySql v5.5 DB 來保存內容項記錄。

由於技術限制,我無法將我的數據庫升級到支持對 InnoDB 表進行全文搜尋的更新版本。

當“真實”數據保存在InnoDB儲存引擎中時,使用MyISAM表進行文本搜尋是否是一個好習慣?

例子:

  1. 使用者創建內容項並將其保存到數據庫
  2. 所有內容項欄位都保存到InnoDB表中。
  3. 所有文本欄位都堆疊在一起並保存在MyISAM表內的單個欄位中,該表還包括參考原始內容項的附加 ID 欄位。

當使用者執行基於文本的搜尋時,我將使用全文搜尋查詢對MyISAM表進行查詢,這將為我提供對****InnoDB表中所有匹配記錄的引用。

底線 - 這是否被認為是一個很好的解決方案,性能方面並提高了我的 CMS 的搜尋能力,還是我應該堅持使用舊的LIKE運算符並僅使用 InnoDB 表進行查詢?

有用。它的表現相當不錯。

您有兩張表,一張是 InnoDB,其中包含實體的大部分屬性。另一個是MyISAM,和第一張表是1:1的,包含一個TEXT欄位,加上FULLTEXT索引。

相關查詢類似於:

SELECT ...
  FROM inno_tbl i
  JOIN ft_tbl f ON i.id = f.id
  WHERE i.stuff...
    AND MATCH (f.text) AGAINST (...);

我認為MATCH總是會首先發生,即使測試i可能更具選擇性。這就是 的性質FULLTEXT

jkavalik 提到了一些一致性問題;但是這些可以通過仔細選擇進入兩個表的順序以及INSERT是否使用REPLACEIODKU代替“插入INSERT”之一的純文字來避免這些。

(我相信我已經在一兩個項目中完成了你所描述的事情。我已經測量過 InnoDBFULLTEXT似乎更快。)

底線:繼續做吧。

附錄 如何對語句進行排序以最大程度地減少數據完整性問題。

BEGIN;
INSERT into InnoDB table
$id = SELECT LAST_INSERT_ID(); -- assuming you are using an AUTO_INCREMENT
INSERT INTO MyISAM_table
   (id, text)  VALUES  ($id, '$escaped_text')
   ON DUPLICATE KEY UPDATE
       text = '$escaped_text';
COMMIT;

案例…

  • 如果兩者都INSERTs成功或都失敗,則不存在完整性問題。
  • 如果 MyISAM 有錯誤INSERT,你應該抓住它而ROLLBACK不是COMMIT. 因此具有良好的完整性。
  • 如果 MyISAM 成功但COMMIT失敗,則 MyISAM 表中將有一個額外的行,其中沒有 InnoDB 行。兩種情況…

如果FULLTEXT搜尋命中該行,則JOIN對 InnoDB 表的搜尋將失敗,從而獲得“正確”答案(以較小的成本)。

如果您稍後出現並重用它id來重新插入行(或插入不同的行),那麼 IODKU 將“做正確的事”。一切都很好。

注意(針對其他讀者):這種將 InnoDB 表與非事務性表混合的技術INSERT在其他情況下有效。考慮將圖像 (.jpg) 放在文件中,同時將圖像的“元數據”放在 InnoDB 行中。在最壞的情況下,您可能會在文件系統中儲存額外或重複的圖像。

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