2010-04-14 17 views
15

Ich entwerfe eine interne Web-Anwendung, die MySQL als Backend-Datenbank verwendet. Die Integrität der Daten ist entscheidend, daher verwende ich die Engine innoDB für ihre Fremdschlüssel-Constraint-Funktionen.MySQL Volltext-Suche Workaround für innoDB Tabellen

Ich möchte eine Volltextsuche für einen Datensatztyp durchführen, der nicht nativ mit innoDB -Tabellen unterstützt wird. Ich bin nicht bereit, zu MyISAM Tabellen aufgrund ihrer fehlenden Fremdschlüsselunterstützung und aufgrund der Tatsache, dass ihre Sperrung pro Tabelle ist, nicht pro Zeile.

Wäre es nicht ratsam, eine gespiegelte Tabelle der Datensätze zu erstellen, die ich mit der MyISAM-Engine suchen muss, und diese für die Volltextsuche zu verwenden? Auf diese Weise suche ich nur eine Kopie der Daten und wenn etwas mit diesen Daten passiert, ist es nicht so ein großer Deal, weil es immer neu erstellt werden kann.

Oder ist dies eine unangenehme Vorgehensweise, die vermieden werden sollte?

Danke.

+0

Es gibt eine ziemlich gute heruntergekommenen von Optionen aus Percona: http://www.mysqlperformanceblog.com/2009/09/10/what-to-do-with-mysql-full-text- search-while-migrating-to-innodb/ – cce

Antwort

7

Ich denke, es ist wirklich peinlich. Das heißt, meine „Quick Prototyp, der wahrscheinlich aus Versehen Produktionscode werden wird“ Methode, dies zu tun ist so etwas wie dieses:

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; 

Und für Bonuspunkte könnten Sie all das innerhalb einer Transaktion sollten diesen Anzug Ihre Lust haben (doppelter Bonus, wenn Sie nicht persistente Verbindungen verwenden und nur einmal pro Verbindung suchen, da Sie dann die Drop-Anweisung löschen können.

Ja, ich weiß, dass dies nicht die richtige Spiegelung/Replikation ist. Ja, mir ist klar, dass die Tabelle teuer sein kann (relativ kleine Datensätze hier). Wie ich schon sagte, schneller und dreckiger Prototyp. YMMV

+4

Einverstanden. Es ist wirklich peinlich. – Abinadi

+0

Einzig besser als der Code waren die Vorbehalte. : P –

+0

Wie wäre es besser, den gesamten Index für jede Abfrage neu zu erstellen, als eine Suche mit 'LIKE'? –

2

Sie können eine Spiegeltabelle erstellen. Dies ist wahrscheinlich weniger als ideal, da die MyISAM-Tabelle Ihre Transaktionen nicht berücksichtigt (wenn eine Transaktion bei InnoDB fehlgeschlagen ist, werden Ihre Änderungen an MyISAM in dieser Transaktion weiterhin angezeigt).

Sie könnten ein dediziertes Volltextsuchsystem wie Sphinx verwenden, was ich für die Volltextsuche verwendet habe (Da meine Datenbank InnoDB ist).

9

Sie können möglicherweise eine Art Datensynchronisierung mit Triggern durchführen (wenn Ihre Version von MySQL diese unterstützt). Sie ermöglichen es Ihnen, zu bestimmten Zeitpunkten kleine SQL-Snippets auszuführen, beispielsweise nachdem Daten in eine Tabelle eingefügt oder aus einer Tabelle gelöscht wurden.

Zum Beispiel ...

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

... Jedes Mal, wenn Daten in die INNODB Tabelle eingefügt wird, werden die gleichen Daten automatisch in die MYISAM Tabelle eingefügt.

+0

würde diese Lösung mit jdbc und mysql 5.1 funktionieren? – Noona

+0

ja Trigger werden unterstützt in 5.1 – michael

+0

@Noona JDBC haben keine Verbindung mit den Triggern, die Datenbank-Seite, soweit ich weiß. Zu Michael ist deine Lösung auf den ersten Blick ziemlich dreckig, aber ziemlich effizient (werden nicht alle Daten nach jedem Einfügen wieder eingefügt?) – AsTeR

1

Ich denke, dass die einfachste Lösung für dieses Problem die Erstellung einer Indextabelle ist, die für Suchen verwendet wird, mit einem Zeiger zurück auf die Tabelle, die die echten Daten enthält. Ich stehe genau vor dem gleichen Problem, und ich möchte keine MyISAM-Tabellen für mein System verwenden, da die InnoDB-Tabellen keine Sorgen machen.

Also, was ich mit meinem Problem tun möchte, ist eine Indextabelle mit MyISAM zu erstellen, damit ich nur die Informationen haben kann, die darauf indiziert werden. Die Synchronisation erfolgt über Trigger, was der einfachste Weg ist. Ich möchte nicht die gesamte Tabelle replizieren, da dies viel Platz kostet. Das Replizieren nur der gewünschten Felder kostet jedoch Platz auf Kosten der Suchmaschineneinrichtung.

Diese Indextabelle kann als Index für Suchfunktionen verstanden werden. Wie jeder Index kostet es Platz. Als eine Optimierung können die eingefügten Daten in dieser Indextabelle nur Terme sein, aber auf diese Weise wird eine zusätzliche Verarbeitung benötigt, um nutzloses Wort für die Suche zu bereinigen.

1

Gute Nachrichten! Ab MySQL 5.6 können Volltextindizes mit InnoDB-Tabellen verwendet werden. Sie sollten in Betracht ziehen, MySQL auf 5.6 oder höher zu aktualisieren, falls Sie dies noch nicht getan haben.

Mit meiner Anwendung war die Volltextsuche sehr wichtig, also habe ich MyISAM verwendet. Jetzt habe ich MySQL auf 5.6 aktualisiert, die Datenbank in InnoDB konvertiert und die richtigen Einschränkungen hinzugefügt. Das Beste von Ärgerwelten.

MySQL 5.6 Manual - Full-Text Search Functions