2010-04-14 15 views
15

Sto progettando un'applicazione Web interna che utilizza MySQL come database di back-end. L'integrità dei dati è fondamentale, quindi sto utilizzando il motore innoDB per le sue caratteristiche di vincolo di chiave esterna.MySQL Ricerca testo completo Soluzione alternativa per tabelle innoDB

Voglio eseguire una ricerca full-text di un tipo di record e non è supportato in modo nativo con le tabelle innoDB. Non sono disposto a passare alle tabelle MyISAM a causa della mancanza di supporto per le chiavi esterne e perché il loro blocco è per tabella, non per riga.

Sarebbe una cattiva pratica creare una tabella con mirroring dei record che devo cercare usando il motore MyISAM e usarla per la ricerca full-text? In questo modo sto solo cercando una copia dei dati e se succede qualcosa a quei dati non è un grosso problema perché può sempre essere ricreato.

O è un modo imbarazzante di fare ciò che dovrebbe essere evitato?

Grazie.

+0

C'è un buon run-down di opzioni da Percona: http://www.mysqlperformanceblog.com/2009/09/10/what-to-do-with-mysql-full-text- search-while-migrating-to-innodb/ – cce

risposta

7

Penso che sia davvero imbarazzante. Detto questo, il mio "prototipo rapido che probabilmente accidentalmente diventerà codice di produzione" metodo di fare questo è qualcosa di simile:

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; 

E per i punti bonus si potrebbe fare tutto questo all'interno di una transazione dovrebbe che si adattano la vostra fantasia (doppio bonus se si utilizzano connessioni non persistenti e si esegue una sola ricerca per connessione, in quanto è possibile eliminare l'istruzione di rilascio).

Sì. Mi rendo conto che questo non è il vero mirroring/replica. Sì, mi rendo conto che abbaiare il tavolo può essere costoso (dataset relativamente piccoli qui). Come ho detto, prototipo veloce e sporco. YMMV

+4

concordato. È veramente imbarazzante. – Abinadi

+0

L'unica cosa migliore del codice erano le avvertenze. : P –

+0

In che modo ricreare l'intero indice su ogni query è meglio di una ricerca con 'LIKE'? –

2

È possibile creare una tabella speculare. Probabilmente non è l'ideale, dato che la tabella MyISAM non rispetterà le tue transazioni (se una transazione fallisce su InnoDB, le tue modifiche apportate a MyISAM in quella transazione verranno comunque visualizzate).

È possibile utilizzare un sistema di ricerca full-text dedicato come Sphinx, che è quello che ho usato per la ricerca full-text (Poiché il mio database è InnoDB).

9

Si potrebbe essere in grado di eseguire una sorta di sincronizzazione dei dati utilizzando i trigger (se la propria versione di mysql li supporta). Ti consentono di eseguire piccoli snippet di SQL in determinati punti, ad esempio dopo che i dati sono stati inseriti o eliminati da una tabella.

Ad esempio ...

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

... Quando i dati vengono inseriti nella tabella INNODB, gli stessi dati viene inserito automaticamente nella tabella MYISAM.

+0

questa soluzione funziona con jdbc e mysql 5.1? I trigger – Noona

+0

yes sono supportati in 5.1 – michael

+0

@Noona JDBC non ha collegamenti con i trigger che sono lato database per quanto ne so. Per Michael la tua soluzione è abbastanza sporca come prima occhiata ma abbastanza efficiente (non reinserirà tutti i dati dopo ogni inserimento?) – AsTeR

1

Ritengo che la soluzione più semplice per questo problema sia la creazione di una tabella di indici che verrà utilizzata per le ricerche, con un puntatore alla tabella che contiene i dati reali. Sto affrontando esattamente lo stesso problema e non voglio usare le tabelle MyISAM per il mio sistema a causa della tranquillità offerta dalle tabelle InnoDB.

Quindi, quello che sto pensando di fare con il mio problema è creare una tabella degli indici usando MyISAM, così posso avere solo le informazioni da indicizzare su di esso. La sincronizzazione verrà eseguita utilizzando i trigger, che è il modo più semplice per farlo. Non voglio replicare l'intera tabella, poiché costerà molto spazio. Tuttavia, la replica dei soli campi desiderati avrà un costo a discapito della struttura del motore di ricerca.

Questa tabella indice può essere intesa come un indice per le strutture di ricerca. Come qualsiasi indice, costerà spazio. Come ottimizzazione, i dati inseriti in questa tabella indice possono essere solo termini, ma in questo modo è necessaria un'ulteriore elaborazione per pulire parole inutili per la ricerca.

1

Buone notizie! In MySQL 5.6 e versioni successive, gli indici full-text possono essere utilizzati con le tabelle InnoDB. Dovresti considerare di aggiornare MySQL a 5.6 o versioni successive se non lo hai ancora fatto.

Con la mia applicazione la ricerca full-text era molto importante quindi ho usato MyISAM. Ora, ho aggiornato MySQL a 5.6, convertito il database in InnoDB e aggiunto i vincoli corretti. Meglio dei mondi fastidiosi.

MySQL 5.6 Manual - Full-Text Search Functions

Problemi correlati