Обходной путь полнотекстового поиска MySQL для таблиц innoDB

Я разрабатываю внутреннее веб-приложение, использующее MySQL в качестве базы данных. Целостность данных имеет решающее значение, поэтому я использую механизм innoDB для его функций ограничения внешнего ключа.

Я хочу выполнить полнотекстовый поиск одного типа записей, который изначально не поддерживается таблицами innoDB. Я не хочу переходить к MyISAM таблицам из-за отсутствия в них поддержки внешнего ключа и из-за того, что их блокировка осуществляется по таблице, а не по строке.

Будет ли плохой практикой создавать зеркальную таблицу записей, которые мне нужно искать с помощью механизма MyISAM, и использовать ее для полнотекстового поиска? Таким образом, я просто ищу копию данных, и если что-то случится с этими данными, это не имеет большого значения, потому что их всегда можно воссоздать.

Или это неудобный способ сделать это, которого следует избегать?

Спасибо.


person Rob    schedule 14.04.2010    source источник
comment
Есть довольно неплохой набор опций от Percona: mysqlperformanceblog.com/2009/09/10/   -  person cce    schedule 14.01.2012


Ответы (5)


Возможно, вы сможете выполнить какую-то синхронизацию данных с помощью триггеров (если ваша версия 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.

person michael    schedule 01.06.2010
comment
Насколько мне известно, @Noona JDBC не имеет связи с триггерами, которые являются частью базы данных. По мнению Майкла, ваше решение на первый взгляд довольно грязное, но довольно эффективное (не будет ли оно повторно вставлять все данные после каждой вставки?) - person AsTeR; 06.08.2012
comment
@AsTeR, нет, last_insert_id() гарантирует, что он захватит только одну строку. - person Aaron Harun; 04.07.2013

Я думаю, это действительно неловко. Тем не менее, мой метод «быстрого прототипа, который, вероятно, случайно станет производственным кодом» выглядит примерно так:

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

person pcarter    schedule 14.04.2010
comment
Чем воссоздание всего индекса для каждого запроса лучше, чем поиск с LIKE? - person Chris Middleton; 08.03.2015

Вы можете создать зеркальный столик. Это, вероятно, менее чем идеально, поскольку таблица MyISAM не будет учитывать ваши транзакции (если транзакция завершилась неудачно в InnoDB, ваши изменения, внесенные в MyISAM в этой транзакции, все равно появятся).

Вы можете использовать специальную систему полнотекстового поиска, такую ​​как Sphinx, которую я использовал для полнотекстового поиска поиск (поскольку моя база данных - InnoDB).

person Mitch Dempsey    schedule 07.05.2010

Я считаю, что самым простым решением этой проблемы является создание индексной таблицы, которая будет использоваться для поиска, с указателем на таблицу, содержащую реальные данные. Я столкнулся с той же проблемой, и я не хочу использовать таблицы MyISAM для своей системы из-за спокойствия, предоставляемого таблицами InnoDB.

Итак, что я планирую сделать со своей проблемой, так это создать таблицу индексов с помощью MyISAM, чтобы у меня была только информация, которую нужно проиндексировать. Синхронизация будет осуществляться с помощью триггеров, что является самым простым способом сделать это. Я не хочу копировать всю таблицу, так как это будет стоить много места. Однако копирование только желаемых полей потребует места за счет средства поисковой системы.

Эту индексную таблицу можно понимать как индекс для средств поиска. Как и любой индекс, он будет стоить места. В качестве оптимизации вставленные данные в эту индексную таблицу могут быть только терминами, но в этом случае требуется дополнительная обработка, чтобы очистить бесполезное слово для поиска.

person Ronaldo Faria Lima    schedule 06.09.2010

Хорошие новости! В MySQL 5.6 и выше полнотекстовые индексы могут использоваться с таблицами InnoDB. Вам следует подумать об обновлении MySQL до версии 5.6 или выше, если вы еще этого не сделали.

В моем приложении полнотекстовый поиск был очень важен, поэтому я просто использовал MyISAM. Теперь я обновил MySQL до версии 5.6, преобразовал базу данных в InnoDB и добавил правильные ограничения. Лучшее из беспокойных миров.

Руководство по MySQL 5.6 - функции полнотекстового поиска

person Syclone    schedule 11.03.2014