Tengo una tabla en la que almaceno todos los mensajes del foro publicados por los usuarios en mi sitio web. La estructura de la jerarquía de mensajes se implementa utilizando un modelo de conjunto anidado .
La siguiente es una estructura simplificada de la tabla:
- Id (CLAVE PRIMARIA)
- Owner_Id (REFERENCIAS CLAVE EXTRANJERAS A Id )
- Parent_Id (REFERENCIAS CLAVE EXTRANJERAS A Id )
- nleft
- bien
- nivel
Ahora, la mesa se ve así:
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| Id | Owner_Id | Parent_Id | nleft | nright | nlevel |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
| 1 | 1 | NULL | 1 | 8 | 1 |
| 2 | 1 | 1 | 2 | 5 | 2 |
| 3 | 1 | 2 | 3 | 4 | 3 |
| 4 | 1 | 1 | 6 | 7 | 2 |
+ ------- + ------------- + -------------- + ---------- + ----------- + ----------- +
Tenga en cuenta que la primera fila es el mensaje raíz, y el árbol de esta publicación se puede mostrar como:
-- SELECT * FROM forumTbl WHERE Owner_Id = 1 ORDER BY nleft;
MESSAGE (Id = 1)
MESSAGE (Id = 2)
Message (Id = 3)
Message (Id = 4)
Mi problema ocurre cuando intento eliminar todas las filas debajo de la misma Owner_Id
en una sola consulta. Ejemplo:
DELETE FROM forumTbl WHERE Owner_Id = 1 ORDER BY nright;
La consulta anterior falla con el siguiente error:
Código de error: 1451. No se puede eliminar o actualizar una fila principal: falla una restricción de clave foránea (
forumTbl
,Owner_Id_frgn
LLAVE EXTRANJERA CONSTRAINT (Owner_Id
) REFERENCIASforumTbl
(Id
) AL BORRAR SIN ACCIÓN AL ACTUALIZAR SIN ACCIÓN)
La razón es que la primera fila , que es el nodo raíz ( Id=1
), también tiene el mismo valor en su Owner_Id
campo ( Owner_Id=1
), y hace que la consulta falle debido a la restricción de clave externa.
Mi pregunta es: ¿cómo puedo evitar esta circularidad de restricción de clave externa y eliminar una fila que hace referencia a sí misma? ¿Hay alguna manera de hacerlo sin tener que actualizar primero el Owner_Id
de la fila raíz NULL
?
Creé una demostración de este escenario: http://sqlfiddle.com/#!9/fd1b1
Gracias.
fuente