¿Cómo funcionan las opciones de la clave foránea de Postgres 'en la actualización' y 'en la eliminación'?

StackOverflow https://stackoverflow.com/questions/225881

Pregunta

¿Puede alguien proporcionar una explicación / ejemplo claro de lo que hacen estas funciones y cuándo es apropiado usarlas?

¿Fue útil?

Solución

Directamente desde el manual ...

  

Sabemos que las claves externas no permiten la creación de pedidos que no estén relacionados con ningún producto. ¿Pero qué sucede si se elimina un producto después de crear un pedido que lo referencia? SQL te permite manejar eso también. Intuitivamente, tenemos algunas opciones:

     

No permitir eliminar un producto referenciado

     

Eliminar las órdenes también

     

¿Algo más?

CREATE TABLE order_items (
 product_no integer REFERENCES products ON DELETE RESTRICT,
 order_id integer REFERENCES orders ON DELETE CASCADE,
 quantity integer,
 PRIMARY KEY (product_no, order_id)
);
  

La restricción y las eliminaciones en cascada son las dos opciones más comunes. RESTRICT evita la eliminación de una fila referenciada. NO ACCIÓN significa que si alguna fila de referencia todavía existe cuando se comprueba la restricción, se genera un error; este es el comportamiento predeterminado si no especifica nada. (La diferencia esencial entre estas dos opciones es que NO ACTION permite que la verificación se aplace hasta más adelante en la transacción, mientras que RESTRICT no lo hace). también. Hay otras dos opciones: SET NULL y SET DEFAULT. Esto hace que las columnas de referencia se establezcan en valores nulos o valores predeterminados, respectivamente, cuando se elimina la fila de referencia. Tenga en cuenta que estos no le eximen de observar ninguna restricción. Por ejemplo, si una acción especifica SET DEFAULT pero el valor predeterminado no satisface la clave externa, la operación fallará.

     

De forma análoga a ON DELETE, también hay ON UPDATE que se invoca cuando se modifica (actualiza) una columna a la que se hace referencia. Las posibles acciones son las mismas.

editar: Es posible que desee consultar esta pregunta relacionada: ¿Cuándo / Por qué usar la conexión en cascada en SQL Server? . Los conceptos detrás de la pregunta / respuestas son los mismos.

Otros consejos

Tengo una base de datos PostGreSQL y uso On Delete cuando tengo un usuario que elimino de la base de datos y necesito eliminar su información de otra tabla. De esta manera, solo necesito hacer 1 eliminación y FK que tiene la función ON eliminar eliminará información de otra tabla.

Puedes hacer lo mismo con ON Update. Si actualiza la tabla y el campo tiene un FK con On Update, si se realiza un cambio en el FK, se notará en la tabla FK.

Lo que Daok dice es cierto ... puede ser bastante conveniente. Por otro lado, hacer que las cosas sucedan automáticamente en la base de datos puede ser un problema real, especialmente cuando se trata de eliminar datos. Es posible que en el futuro alguien cuente con el hecho de que los FK generalmente impiden la eliminación de los padres cuando hay hijos y no se dan cuenta de que el uso de On Delete Cascade no solo no evita la eliminación, sino que genera una gran cantidad de datos en docenas de Otras mesas desaparecen gracias a una cascada de eliminaciones en cascada.

@ el comentario de Arthur.

Cuanto más frecuentemente " oculto " las cosas suceden en la base de datos cuanto menos probable sea que alguien alguna vez tenga un buen control de lo que está sucediendo. Los desencadenadores (y esto es esencialmente un desencadenante) pueden hacer que mi simple acción de eliminar una fila tenga muchas consecuencias en toda mi base de datos. Emito una instrucción Delete y 17 tablas se ven afectadas por cascadas de desencadenantes y restricciones y nada de esto es inmediatamente evidente para el emisor del comando. OTOH, si coloco la eliminación del padre y de todos sus hijos en un procedimiento, es muy fácil y claro para cualquiera ver EXACTAMENTE lo que sucederá cuando emito el comando.

No tiene absolutamente nada que ver con lo bien que diseño una base de datos. Tiene todo que ver con los problemas operacionales introducidos por los activadores.

En lugar de escribir el método para hacer todo el trabajo, la eliminación en cascada o la actualización en cascada, simplemente podría escribir un mensaje de advertencia en su lugar. Es mucho más fácil que reinventar la rueda, y lo deja claro para el cliente (y los nuevos desarrolladores que toman el código)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top