No diseño esquemas todos los días, pero cuando lo hago, trato de configurar las actualizaciones / eliminaciones en cascada correctamente para facilitar la administración. Entiendo cómo funcionan las cascadas, pero nunca puedo recordar qué tabla es cuál.
Por ejemplo, si tengo dos tablas - Parent
y Child
- con una clave foránea en Child
esas referencias Parent
y has ON DELETE CASCADE
, ¿qué registros desencadenan una cascada y qué registros son eliminados por la cascada? Mi primera suposición sería que los Child
registros se eliminan cuando Parent
se eliminan, ya que los Child
registros dependen de los Parent
registros, pero ON DELETE
es ambiguo; podría significar eliminar el Parent
registro cuando Child
se elimine el registro, o podría significar eliminar el Child
registro cuando Parent
se elimine. Entonces, ¿cuál es?
Desearía que la sintaxis fuera ON PARENT DELETE, CASCADE
, ON FOREIGN DELETE, CASCADE
o algo similar para eliminar la ambigüedad. ¿Alguien tiene alguna mnemotecnia para recordar esto?
fuente
Order(custID, itemID, orderID)
donde secustID
refiere a una clave primaria en laCustomers
tabla y seitemID
refiere a una clave primaria en laItems
tabla. ¿NoOrder
tendrá dos padres?ON DELETE CASCADE es una cláusula opcional en una declaración de clave foránea. Entonces va con la declaración de clave extranjera. (Es decir, en la tabla "hijo").
Una forma de interpretar una declaración de clave externa es: "Todos los valores válidos para esta columna provienen de 'that_column' en 'that_table'". Cuando elimina una fila en la tabla "secundaria", a nadie le importa. No afecta la integridad de los datos.
Cuando elimina una fila de la tabla "primaria" - de "esa_tabla" - elimina un valor válido de los posibles valores para la tabla "secundaria". Para mantener la integridad de los datos, debe hacer algo en la tabla "secundaria". La eliminación en cascada es una cosa que puede hacer.
fuente
SQL: 2011 Spec
Hay cinco opciones para
ON DELETE
, yON UPDATE
eso puede aplicarse aFOREIGN KEY
. Estos se llaman<referential actions>
, directamente desde la especificación SQL: 2011La clave foránea establece la relación dependiente. El
<referential action>
determina lo que sucede cuando la relación se disuelve.Ejemplo / Metáfora / Explicación
Para este ejemplo, aceptaremos el modelo común de sociedad y economía: donde cada
business
una es una compañía que mantiene una relación abourgeoisie
través de afatcat_owner
.Si todos los
business
es afectados directamente porbourgeoisie
ellosfatcat_owner
, ¿qué haces después de la revolución obrera cuando purgas elfatcat_owner
s y tienes una sociedad sin clases?Tienes algunas opciones aquí,
RESTRICT
. Algunas personas creen que este es el mal menor, pero generalmente están equivocados.Permitir que continúe. Si es así cuando sucede la revolución, SQL te da cuatro opciones,
SET NULL
-- dejalo en blanco. Quién sabe, tal vez se restablezca el capitalismobourgeoisie
y surjan los oligarcasfatcat_owners
. Nota importante, la columna debe serNULLABLE
(noNOT NULL
) o esto nunca puede suceder.SET DEFAULT
- tal vez tuviste unDEFAULT
que manejó esto? ADEFAULT
puede llamar a una función. Quizás tu esquema ya esté listo para la revolución.CASCADE
- No hay control de daños. Si elbourgeoisie
va, también lo hace elbusiness
. Si una empresa debe tener unfatcat_pig
, entonces a veces tiene más sentido perder los datos en lugar de tener una no empresa en unabusiness
tabla.NO ACTION
- esto es esencialmente un método para retrasar la verificación, en MySQL no es diferenteRESTRICT
, pero en PostgreSQL, podría hacerEn dicho sistema, la restricción se valida solo antes de que se confirme la transacción. Esto puede resultar en detener la revolución, pero puede recuperarse en la transacción, hasta cierto punto de "recuperación".
fuente
referenced
Tabla significa tabla primaria yreferencing
tabla significa tabla secundaria?Una simple mnemónica sería
AL ELIMINAR la CASCADA principal [al eliminar] aquí
Eso le indica qué eliminaciones (eliminaciones del padre) se ponen en cascada, dónde va la instrucción ON DELETE CASCADE (en el hijo) y qué se elimina (el hijo).
fuente
bueno, quizás podamos racionalizar la sintaxis. Tomemos un ejemplo de Python:
lo que dice esta línea es on_delete del Parent (que se menciona accidentalmente en la declaración), por favor, elimine en cascada al niño. Es por eso que la declaración CASCADE se define en el nivel secundario, marca aquellos elementos secundarios que deben eliminarse
Por ejemplo si tuvieras otra clase
esta estructura mostraría claramente cuáles de los niños necesitan ser eliminados (Niño) y cuáles deben permanecer (GrownUpChild) aunque huérfanos
[Editar: dado el contexto de la discusión, específicamente en casos de on_delete = models.CASCADE, etc.,] de hecho, a menudo es un comportamiento deseado dejar a los hijos de un padre eliminado, debido a razones de auditoría e informes, así como a la recuperación accidental eliminaciones [por supuesto, el software de nivel empresarial se creará en torno a dicho comportamiento y marcará los registros eliminados como eliminados = 1 en lugar de eliminarlos realmente y tampoco los incluirá en ninguna consulta para el front-end, menos algunos informes especialmente diseñados. Además, tendrá la función de purgar los registros eliminados == 1 de la base de datos, que generalmente será ejecutado por el administrador de la interfaz de usuario, a menudo evitando cualquier participación del lado del administrador de la base de datos.]
fuente