2010-04-14 24 views
15

Estoy diseñando una aplicación web interna que utiliza MySQL como su base de datos back-end. La integridad de los datos es crucial, así que estoy usando el motor innoDB para sus características de restricción de clave externa.MySQL Búsqueda de texto completo Solución para las tablas innoDB

Quiero hacer una búsqueda de texto completo de un tipo de registros, y eso no es compatible de forma nativa con las tablas de innoDB. No estoy dispuesto a pasar a las tablas MyISAM debido a su falta de soporte de clave externa y debido a que su bloqueo es por tabla, no por fila.

¿Sería una mala práctica crear una tabla reflejada de los registros que necesito buscar usando el motor MyISAM y usar eso para la búsqueda de texto completo? De esta manera, estoy buscando una copia de los datos y si algo le sucede a esos datos, no es tan importante porque siempre se puede volver a crear.

¿O es una forma incómoda de hacer esto que debería evitarse?

Gracias.

+0

Hay una muy buena carrera hacia abajo de opciones entre las Percona: http://www.mysqlperformanceblog.com/2009/09/10/what-to-do-with-mysql-full-text- search-while-migrating-to-innodb/ – cce

Respuesta

7

Creo que es realmente incómodo. Dicho esto, mi "prototipo rápido que se convertirá probablemente accidentalmente el código de producción" método de hacer esto es algo como esto:

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; 

Y para los puntos de bonificación que podría hacer todo esto dentro de una transacción debe ese traje a su fantasía (doble bonificación si está utilizando conexiones no persistentes y solo busca una vez por cada conexión, ya que puede eliminar la declaración desplegable).

Sí, me doy cuenta de que esto no es verdadero reflejo/replicación. Sí, me doy cuenta que duplicar la tabla puede ser costoso (conjuntos de datos relativamente pequeños aquí). Como dije, prototipo rápido y sucio. YMMV

+4

De acuerdo. Es realmente incomodo. – Abinadi

+0

Lo único mejor que el código fueron las advertencias. : P –

+0

¿Cómo sería la recreación de todo el índice en cada consulta mejor que una búsqueda con 'LIKE'? –

2

Puede crear una tabla duplicada. Probablemente sea menos que ideal, ya que la tabla MyISAM no respetará sus transacciones (si una transacción falla en InnoDB, sus cambios realizados en MyISAM en esa transacción seguirán apareciendo).

Puede utilizar un sistema dedicado de búsqueda de texto completo como Sphinx, que es lo que he usado para la búsqueda de texto completo (dado que mi base de datos es InnoDB).

9

Es posible que pueda hacer algún tipo de sincronización de datos utilizando desencadenadores (si su versión de mysql los admite). Le permiten ejecutar pequeños fragmentos de SQL en ciertos puntos, como después de insertar o eliminar datos de una tabla.

Por ejemplo ...

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

... Cada vez que se inserta datos en la tabla InnoDB, los mismos datos se inserta automáticamente en la tabla MYISAM.

+0

¿funcionaría esta solución con jdbc y mysql 5.1? – Noona

+0

sí desencadenantes son compatibles en 5.1 – michael

+0

@Noona JDBC no tienen ningún vínculo con los desencadenadores que son base de datos hasta donde yo sé. Para Michael su solución está bastante sucia a primera vista, pero bastante eficiente (¿no volverá a insertar todos los datos después de cada inserción?) – AsTeR

1

Creo que la solución más simple para este problema es la creación de una tabla de índice que se utilizará para las búsquedas, con un puntero a la tabla que contiene los datos reales. Estoy enfrentando exactamente el mismo problema y no quiero usar tablas MyISAM para mi sistema debido a la tranquilidad que brindan las tablas InnoDB.

Entonces, lo que planeo hacer con mi problema es crear una tabla de índice usando MyISAM, por lo que solo puedo indexar la información en él. La sincronización se realizará mediante desencadenadores, que es la forma más sencilla de hacerlo. No quiero replicar toda la tabla, ya que costará mucho espacio. Sin embargo, replicar solo los campos deseados costará espacio a expensas del servicio del motor de búsqueda.

Esta tabla de índice se puede entender como un índice para las funciones de búsqueda. Como cualquier índice, costará espacio. Como optimización, los datos insertados en esta tabla de índice pueden ser solo términos, pero de esta forma se necesita un procesamiento adicional para limpiar la palabra inútil para la búsqueda.

1

¡Buenas noticias! En MySQL 5.6 y versiones posteriores, los índices de texto completo se pueden usar con tablas InnoDB. Debería considerar actualizar su MySQL a 5.6 o superior si aún no lo ha hecho.

Con mi aplicación de búsqueda de texto completo fue muy importante, así que acabo de utilizar MyISAM. Ahora, he actualizado MySQL a 5.6, convertí la base de datos a InnoDB y agregué las restricciones correctas. Lo mejor de los mundos molestos.

MySQL 5.6 Manual - Full-Text Search Functions

Cuestiones relacionadas