2010-04-14 17 views
15

Projektuję wewnętrzną aplikację internetową, która wykorzystuje bazę danych MySQL jako bazę danych. Integralność danych ma kluczowe znaczenie, więc korzystam z silnika innoDB dla jego funkcji ograniczenia klucza obcego.Przetwarzanie pełnotekstowe MySQL Obejście tabel innoDB

Chcę wykonać wyszukiwanie pełnotekstowe jednego typu rekordów, a to nie jest obsługiwane natywnie z tabelami innoDB. Nie chcę przenosić się do tabel MyISAM ze względu na brak obsługi klucza obcego i ze względu na fakt, że ich blokowanie odbywa się według tabeli, a nie wiersza.

Czy nie byłoby dobrze wytworzyć lustrzaną tabelę rekordów, które muszę przeszukać za pomocą silnika MyISAM i użyć tego do wyszukiwania pełnotekstowego? W ten sposób po prostu przeszukuję kopię danych i jeśli cokolwiek stanie się z tymi danymi, nie jest to tak duża oferta, ponieważ zawsze można ją odtworzyć.

Czy jest to niezręczny sposób robienia tego, czego należy unikać?

Dzięki.

+0

Jest to całkiem dobry zaniedbany opcji z Percona: http://www.mysqlperformanceblog.com/2009/09/10/what-to-do-with-mysql-full-text- search-while-migrating-to-innodb/ – cce

Odpowiedz

7

Myślę, że to naprawdę niezręczne. Powiedział, że moja „szybki prototyp, który będzie prawdopodobnie przypadkowo stają kod produkcji” Sposób na to jest coś takiego:

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; 

A dla punktów bonusowych można zrobić wszystko to wewnątrz transakcji powinny w zależności od fantazji (podwójny bonus, jeśli używasz nietrwałych połączeń i wyszukujesz tylko raz na każde połączenie, ponieważ możesz wtedy wyeliminować instrukcję drop).

Tak, zdaję sobie sprawę, że to nie jest prawdziwe odzwierciedlenie/replikacja. Tak, zdaję sobie sprawę, że oszukanie tabeli może być kosztowne (tutaj stosunkowo małe zbiory danych). Tak jak powiedziałem, szybki i brudny prototyp. YMMV

+4

Zgoda. To naprawdę niezręczne. – Abinadi

+0

Jedyną rzeczą lepszą od kodu były zastrzeżenia. : P –

+0

Jak odtworzenie całego indeksu przy każdym zapytaniu byłoby lepsze niż wyszukiwanie z 'LIKE'? –

2

Można utworzyć tabelę lustrzaną. To chyba mniej niż idealne, ponieważ tabela MyISAM nie będzie respektować twoich transakcji (jeśli transakcja nie powiodła się na InnoDB, twoje zmiany wprowadzone do MyISAM w tej transakcji będą nadal widoczne).

Można użyć dedykowanego systemu wyszukiwania pełnotekstowego, takiego jak Sphinx, który został użyty do wyszukiwania pełnotekstowego (Ponieważ moja baza danych to InnoDB).

9

Możliwe, że będziesz w stanie przeprowadzić synchronizację danych za pomocą wyzwalaczy (jeśli obsługuje je twoja wersja mysql). Pozwalają one uruchamiać małe fragmenty kodu SQL w niektórych punktach, np. Po wstawieniu danych do tabeli lub usunięciu z niej.

Na przykład ...

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

... Gdy dane są wstawiane do tabeli InnoDB, te same dane są automatycznie wstawiane do tabeli MyISAM.

+0

czy to rozwiązanie działa z jdbc i mysql 5.1? – Noona

+0

yes triggers są obsługiwane w 5.1 – michael

+0

@Noona JDBC nie mają łącza z wyzwalaczami, które są stroną bazy danych, o ile wiem. Na michaela twoje rozwiązanie jest dość brudne na pierwszy rzut oka, ale dość wydajne (czy nie wstawi ponownie wszystkich danych po każdym wstawieniu?) – AsTeR

1

Uważam, że najprostszym rozwiązaniem tego problemu jest utworzenie tabeli indeksu, która będzie używana do wyszukiwania, z wskaźnikiem z powrotem do tabeli zawierającej prawdziwe dane. Mam dokładnie ten sam problem i nie chcę używać tabel MyISAM dla mojego systemu ze względu na spokój ducha oferowany przez tabele InnoDB.

Tak więc, planuję zrobić z moim problemem, aby utworzyć tabelę indeksu za pomocą MyISAM, więc mogę mieć tylko informacje do indeksowania na nim. Synchronizacja zostanie wykonana za pomocą wyzwalaczy, co jest najprostszym sposobem na zrobienie tego. Nie chcę replikować całej tabeli, ponieważ będzie to kosztowało dużo miejsca. Jednak replikacja tylko pożądanych pól będzie kosztować przestrzeń kosztem mechanizmu wyszukiwarki.

Ta tabela indeksu może być rozumiana jako indeks do wyszukiwania obiektów. Jak każdy indeks, będzie kosztować miejsce. Jako optymalizację wstawione dane w tej tabeli indeksów mogą być tylko terminami, ale w ten sposób potrzebne jest dodatkowe przetwarzanie w celu wyczyszczenia niepotrzebnego słowa do wyszukiwania.

1

Dobra wiadomość! W MySQL 5.6 i nowszych indeksy pełnotekstowe mogą być używane z tabelami InnoDB. Powinieneś rozważyć aktualizację MySQL do wersji 5.6 lub wyższej, jeśli jeszcze tego nie zrobiłeś.

Z mojego wniosku wyszukiwanie pełnotekstowe było bardzo ważne, więc po prostu użyłem MyISAM. Teraz zaktualizowałem MySQL do wersji 5.6, przekonwertowałem bazę danych na InnoDB i dodałem poprawne ograniczenia. Najlepsze z kłopotliwych światów.

MySQL 5.6 Manual - Full-Text Search Functions