我正在设计一个使用MySQL作为后端数据库的内部Web应用程序。数据的完整性至关重要,因此我使用innoDB
引擎作为其外键约束功能。
我想对一种类型的记录进行全文搜索,而innoDB表本身不支持这种记录。我不愿意转移到MyISAM
表,因为它们缺少外键支持,并且由于它们的锁定是每个表而不是每行。
使用MyISAM引擎创建我需要搜索的记录的镜像表并将其用于全文搜索是不是不好的做法?这样我就只是在搜索数据的副本,如果这些数据发生任何变化,那么它就不会那么重要了,因为它总是可以重新创建。
或者这是一种应该避免的尴尬方式吗?
感谢。
答案 0 :(得分: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表,相同的数据都会自动插入到MYISAM表中。
答案 1 :(得分: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;
对于奖励积分,您可以在交易中完成所有这些以适合您的想象(如果您使用非持久性连接并且每次连接仅搜索一次,则可获得双倍奖励,因为您可以消除掉落声明)。
是的,我意识到这不是真正的镜像/复制。是的,我意识到重复表可能很昂贵(这里的数据集相对较小)。就像我说的那样,快速而肮脏的原型。 YMMV
答案 2 :(得分:2)
您可以创建镜像表。这可能不太理想,因为MyISAM表不会尊重您的交易(如果InnoDB上的交易失败,您在该交易中对MyISAM所做的更改仍会出现)。
您可以使用像Sphinx这样的专用全文搜索系统,这是我用于全文搜索的(因为我的数据库是InnoDB)。
答案 3 :(得分:1)
我觉得这个问题最简单的解决方案是创建一个索引表,用于搜索,指针返回包含真实数据的表。我面临完全相同的问题,我不想在我的系统中使用MyISAM表,因为InnoDB表给出了安心。
所以,我打算用我的问题做的是使用MyISAM创建索引表,所以我只能在其上编制索引信息。将使用触发器完成同步,这是最简单的方法。我不想复制整个表格,因为它会花费很多空间。但是,仅复制所需字段将占用搜索引擎设施的费用空间。
此索引表可以理解为搜索工具的索引。作为任何索引,它将花费空间。作为优化,此索引表上的插入数据只能是术语,但这样需要额外的处理才能清理无用的单词以进行搜索。
答案 4 :(得分:1)
使用我的应用程序全文搜索非常重要,所以我只使用了MyISAM。现在,我已将MySQL更新为5.6,将数据库转换为InnoDB并添加了正确的约束。最好的烦恼世界。