15

我正在设计一个使用 MySQL 作为其后端数据库的内部 Web 应用程序。数据的完整性至关重要,因此我将innoDB引擎用于其外键约束功能。

我想对一种记录进行全文搜索,而 innoDB 表本身不支持这种搜索。MyISAM由于缺乏外键支持以及它们的锁定是按表而不是按行的事实,我不愿意移至表。

创建一个我需要使用 MyISAM 引擎搜索的记录的镜像表并将其用于全文搜索是否是不好的做法?这样,我只是在搜索数据的副本,如果该数据发生任何事情,这没什么大不了的,因为它总是可以重新创建。

或者这是一种应该避免的尴尬方式?

谢谢。

4

5 回答 5

10

您也许可以使用触发器进行某种数据同步(如果您的 mysql 版本支持它们)。它们允许您在某些点(例如在将数据插入表或从表中删除之后)运行 SQL 的小片段。

例如...

create trigger TRIGGER_NAME after insert on INNODB_TABLE
insert into MYISAM_TABLE select * from INNODB_TABLE
where id = last_insert_id();

... 每当数据插入 INNODB 表时,相同的数据会自动插入到 MISAM 表中。

于 2010-06-01T07:52:30.080 回答
7

我觉得真的很尴尬。也就是说,我的“可能会意外成为生产代码的快速原型”的方法是这样的:

CREATE TEMPORARY TABLE search_mirror (FULLTEXT INDEX (col1, col2, ...)) Engine=MyISAM SELECT * FROM original_innodb_table;

SELECT * FROM search_mirror WHERE MATCH(col1, col2, ...) AGAINST ('foo');

DROP TEMPORARY TABLE search_mirror;

对于奖励积分,您可以在符合您要求的事务中完成所有这些操作(如果您使用非持久连接并且每次连接仅搜索一次,则可以双倍奖励,因为您可以消除 drop 语句)。

是的,我意识到这不是真正的镜像/复制。是的,我意识到复制表格可能很昂贵(这里的数据集相对较小)。就像我说的,快速而肮脏的原型。YMMV

于 2010-04-14T20:11:36.177 回答
2

您可以创建一个镜像表。这可能不太理想,因为 MyISAM 表不会尊重您的事务(如果事务在 InnoDB 上失败,您在该事务中对 MyISAM 所做的更改仍会出现)。

您可以使用像Sphinx这样的专用全文搜索系统,这是我用于全文搜索的系统(因为我的数据库是 InnoDB)。

于 2010-05-07T00:34:15.307 回答
1

我觉得这个问题最简单的解决方案是创建一个用于搜索的索引表,并带有一个指向包含真实数据的表的指针。我面临着完全相同的问题,我不想在我的系统中使用 MyISAM 表,因为 InnoDB 表让我高枕无忧。

所以,我打算解决我的问题是使用 MyISAM 创建一个索引表,所以我只能拥有要在其上编制索引的信息。同步将使用触发器完成,这是最简单的方法。我不想复制整个表,因为它会占用大量空间。但是,仅复制所需的字段会以牺牲搜索引擎设施为代价来消耗空间。

这个索引表可以理解为搜索设施的索引。与任何索引一样,它会占用空间。作为优化,这个索引表上插入的数据只能是词条,但是这种方式需要额外的处理,以便清理无用词进行搜索。

于 2010-09-06T15:17:29.800 回答
1

好消息!在 MySQL 5.6 及更高版本中,全文索引可以与 InnoDB 表一起使用。如果您还没有,您应该考虑将您的 MySQL 更新到 5.6 或更高版本。

在我的应用程序中,全文搜索非常重要,所以我只使用了 MyISAM。现在,我已将 MySQL 更新到 5.6,将数据库转换为 InnoDB 并添加了正确的约束。最好的麻烦世界。

MySQL 5.6 手册 - 全文搜索功能

于 2014-03-11T19:15:35.343 回答