在CMS中集成MySql全文搜索

Alo*_*tan 5 mysql innodb myisam full-text-search like

我正在开发自己的 CMS 并使用 MySql v5.5 DB 来保存内容项记录。

由于技术限制,我无法将我的数据库升级到支持 InnoDB 表全文搜索的较新版本。

当“真实”数据保存在InnoDB存储引擎中时,使用MyISAM表进行文本搜索是否是一个好习惯?

例子:

  1. 用户创建内容项并将其保存到数据库
  2. 所有内容项字段都保存到InnoDB表中。
  3. 所有文本字段都堆叠在一起并保存在MyISAM表内的单个字段中,该表还包括参考原始内容项的附加 ID 字段。

当用户执行基于文本的搜索时,我将使用全文搜索查询对MyISAM表进行查询,该查询将为我提供对InnoDB表中所有匹配记录的引用。

底线 - 这被认为是一个很好的解决方案,性能方面和提高我的 CMS 的搜索能力,还是我应该坚持使用旧的LIKE运算符并仅使用 InnoDB 表进行查询?

Ric*_*mes 3

有用。它的性能相当不错。

您有两张表,一张是 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 (...);
Run Code Online (Sandbox Code Playgroud)

我认为,MATCH尽管测试i可能更具选择性,但总会先发生。这就是 的本质FULLTEXT

jkavalik提到了一些一致性问题;但是,通过仔细选择插入两个表的顺序,以及是否使用或代替“INSERT”之一的纯文本,这些大多可以避免。INSERTREPLACEIODKUINSERT

(我相信我已经在一两个项目中完成了你所描述的事情。此后我发现 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;
Run Code Online (Sandbox Code Playgroud)

案例...

  • 如果两者都成功或都失败,则不存在完整性问题INSERTs
  • 如果 MyISAM 上有错误INSERT,您应该捕获它,而ROLLBACK不是COMMIT. 因此具有良好的诚信。
  • 如果MyISAM成功但COMMIT失败,MyISAM表中会多出一行,而InnoDB表中没有该行。两个案例...

如果FULLTEXT搜索命中该行,则JOINInnoDB 表的搜索将失败,从而获得“正确”答案(花费较小的成本)。

如果您稍后再使用它id来重新插入行(或插入不同的行),那么 IODKU 将“做正确的事情”。一切都很好。

注意(针对其他读者):这种将 InnoDB 表与非事务INSERT表混合的技术在其他情况下也有效。考虑将图像 (.jpg) 放入文件中,同时将图像的“元数据”放入 InnoDB 行中。最坏的情况是,文件系统中可能存储有额外或重复的图像。