在 CMS 中集成 MySql 全文搜尋
我正在開發自己的 CMS 並使用 MySql v5.5 DB 來保存內容項記錄。
由於技術限制,我無法將我的數據庫升級到支持對 InnoDB 表進行全文搜尋的更新版本。
當“真實”數據保存在InnoDB儲存引擎中時,使用MyISAM表進行文本搜尋是否是一個好習慣?
例子:
- 使用者創建內容項並將其保存到數據庫
- 所有內容項欄位都保存到InnoDB表中。
- 所有文本欄位都堆疊在一起並保存在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
是否使用REPLACE
或IODKU
代替“插入INSERT
”之一的純文字來避免這些。(我相信我已經在一兩個項目中完成了你所描述的事情。我已經測量過 InnoDB
FULLTEXT
似乎更快。)底線:繼續做吧。
附錄 如何對語句進行排序以最大程度地減少數據完整性問題。
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 行中。在最壞的情況下,您可能會在文件系統中儲存額外或重複的圖像。