2012-05-15 10 views
6

Estoy almacenando las jerarquías del sistema de archivos de directorios y archivos.Eliminación en cascada de la tabla de datos y la tabla de búsqueda al mismo tiempo

En una tabla innodb, almaceno los detalles de cada directorio/archivo y mantengo la relación padre-hijo con una restricción de clave foránea que se aplicará en cascada en la eliminación.

Una tabla myisam se utiliza para buscar estos directorios/archivos con una búsqueda de texto completo. Contiene los nombres y los id de cada fila.

Cualquier fila en la tabla de datos (tabla innodb) tendrá una fila correspondiente en la tabla de búsqueda (tabla myisam) y agregar o eliminar filas de la tabla de datos debe reflejarse en la tabla de búsqueda.

Estoy tratando de encontrar la mejor solución para mantener la coherencia de datos entre las dos tablas al eliminar un directorio principal. La mesa innodb está bien. Elimino el elemento primario, eliminé las cascadas a través de los elementos secundarios hasta que todos se eliminaron. Eliminar las filas correspondientes de la tabla myisam es más difícil.

Lo primero que pensé fue utilizar un desencadenador on-delete en la tabla innodb. Cuando se elimina una fila, borra la fila correspondiente de la tabla myisam. Sin embargo, dado que MySQL no activa los desencadenantes durante una eliminación en cascada (un error conocido durante 7 años que se solucionó mencionando la falta de soporte en el manual), esa no es una opción.

Mi segundo pensamiento fue poner una relación padre-hijo en la tabla de búsqueda, pero es una tabla myisam para admitir la funcionalidad de búsqueda de texto completo, y por lo tanto no admite restricciones de clave externa.

Me enteré de que innodb ahora es compatible con búsquedas de texto completo, así que pensé que tal vez podría cambiar el motor de la tabla de búsqueda, pero solo está disponible en la versión de laboratorio.

Mi última idea fue abandonar las restricciones de clave externa y usar solo activadores para mantener la consistencia de los datos. En delete, elimine de ambas tablas innodb y myisam donde parent = OLD.id. Sin embargo, para evitar bucles infinitos que podrían dañar todos los datos de la tabla, MySQL no admite manipular los datos en la misma tabla que activó el desencadenador.

He recurrido a recuperar programáticamente todos los elementos secundarios del directorio padre a través de un bucle de solicitudes; sin embargo, creo que tiene que haber una mejor opción. ¿Hay algún otro trabajo que sería más eficiente? En este punto, las dos únicas opciones en las que puedo pensar están esperando que uno de los enfoques anteriores se solucione o cambie a un RDBMS diferente como PostgreSQL que admita desencadenantes de disparo a partir de una eliminación en cascada.

Cualquier otra idea sería muy apreciada.

+0

No estoy seguro de si lo entiendo, estoy bastante confundido acerca de la relación entre dos tablas, lo que entiendo es que define una relación entre 2 tablas que tienen un tipo diferente el uno del otro. Lo he intentado antes y he tenido problemas al mantener la coherencia de los datos, si desea mantener la coherencia de los datos a través de la relación de tabla con el usuario de claves externas y principales, use innodb en todas las tablas donde definirá su relación. –

+0

la tabla de búsqueda (myisam) se utiliza como mi motor de búsqueda para la tabla de datos (innodb). Pero a medida que los directorios con subdirectorios y archivos se eliminan, los cambios deben reflejarse tanto en la tabla de datos como en la tabla de búsqueda. No puedo usar innodb para el motor de búsqueda debido a la falta de soporte de búsqueda de texto completo (al menos, en ese momento). La relación se define bien en la tabla de datos, pero las eliminaciones no se reflejan en la tabla de búsqueda. – JayceTDE

+0

+1 para una pregunta bien escrita; desafortunadamente no veo ninguna alternativa a su enfoque actual, pero tal vez alguien más proponga algo – Daan

Respuesta

1

Este tipo de dolores de cabeza son exactamente lo que me hizo alejarme de mysql cuando sea posible.

... Siento que tiene que ser una opción mejor ...

Lamentablemente no es. El problema simple es que no puedes eliminar cascada y no sé lo que acaba de eliminar. Por lo tanto, su única opción es averiguar qué está por eliminar antes de hacerlo (este es el algoritmo que sugirió al final).

Dado que la conexión en cascada romperá sus datos, no debe usar una clave on update cascade para que el intento de eliminar un directorio principal sin borrar el elemento secundario falle.

Le aconsejaría que cree un procedimiento para realizar el levantamiento pesado (eliminación) por usted. Esto evitará un IO grande entre su aplicación y la base de datos, ya que recurre a través de todos los directorios. Iy también proporcionará un código común para hacerlo si alguna vez tiene acceso a la misma base de datos a través de una aplicación diferente (o si simplemente desea hacer algo manualmente).

Como dije antes, utilizo postgresql principalmente estos días. Este es un ejemplo de por qué.

Cuestiones relacionadas