Многопользовательский поиск MySQL для обходных путей для таблиц innoDB
Я разрабатываю внутреннее веб-приложение, которое использует MySQL в качестве базовой базы данных. Целостность данных имеет решающее значение, поэтому я использую механизм innoDB
для его ограничений внешнего ключа.
Я хочу выполнить полнотекстовый поиск записей одного типа, и это не поддерживается на основе таблиц innoDB. Я не хочу переходить на таблицы MyISAM
из-за отсутствия поддержки внешнего ключа и из-за того, что их блокировка выполняется за таблицу, а не за строку.
Было бы плохой практикой создавать зеркальную таблицу записей, которые мне нужно искать с помощью механизма MyISAM, и использовать их для полнотекстового поиска? Таким образом, я просто ищу копию данных, и если что-то случится с этими данными, это не так дорого, потому что оно всегда может быть воссоздано.
Или это неудобный способ сделать это, которого следует избегать?
Спасибо.
Ответы
Ответ 1
Возможно, вы сможете выполнить некоторую синхронизацию данных с помощью триггеров (если ваша версия 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.
Ответ 2
Я думаю, что это действительно неудобно. Тем не менее, мой "быстрый прототип, который, вероятно, случайно станет производственным кодом", способ сделать это примерно так:
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
Ответ 3
Вы можете создать зеркальную таблицу. Это, вероятно, меньше, чем идеально, поскольку таблица MyISAM не будет уважать ваши транзакции (если транзакция не удалась в InnoDB, ваши изменения, внесенные в MyISAM в этой транзакции, все равно появятся).
Вы можете использовать специальную полнотекстовую поисковую систему, такую как Sphinx, что я использовал для полнотекстового поиска ( Поскольку моя база данных - InnoDB).
Ответ 4
Я считаю, что простейшим решением этой проблемы является создание таблицы индексов, которая будет использоваться для поиска, с указателем обратно в таблицу, которая содержит реальные данные. Я столкнулся с одной и той же проблемой, и я не хочу использовать таблицы MyISAM для своей системы из-за спокойствия, данных таблицами InnoDB.
Итак, то, что я планирую сделать с моей проблемой, - создать таблицу индексов с помощью MyISAM, чтобы я мог проиндексировать только информацию. Синхронизация будет выполнена с использованием триггеров, что является самым простым способом сделать это. Я не хочу реплицировать всю таблицу, так как она будет стоить много места. Однако репликация только желаемых полей будет стоить места за счет средства поисковой системы.
Эта индексная таблица может быть указана как индекс для поиска объектов. Как любой индекс, это будет стоить места. В качестве оптимизации вставленные данные в этой индексной таблице могут быть только терминами, но при этом необходима дополнительная обработка, чтобы очистить бесполезное слово для поиска.
Ответ 5
Хорошие новости! В MySQL 5.6 и выше полнотекстовые индексы могут использоваться с таблицами InnoDB. Вы должны рассмотреть возможность обновления вашего MySQL до 5.6 или вверх, если вы еще этого не сделали.
В моем приложении полнотекстовый поиск был очень важным, поэтому я просто использовал MyISAM. Теперь я обновил MySQL до 5.6, преобразовал базу данных в InnoDB и добавил правильные ограничения. Лучше всего беспокоиться о мире.
MySQL 5.6 Руководство - Функции полнотекстового поиска