Comment fonctionnent les options de clé étrangère Postgres 'on update' et 'on delete'?
quelqu'un Peut-il fournir une explication claire de ce que ces fonctions ne, et quand il est approprié d'utiliser?
4 réponses
directement de le manuel ...
nous savons que les clés étrangères interdisent la création de commandes qui ne se rapportent à aucun produit. Mais que faire si un produit est retiré après la création d'une commande que des références? SQL vous permet de charger. Intuitivement, nous avons quelques options:
refuser la suppression d'un produit de référence
Supprimer aussi les commandes
autre chose?
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 restriction et la suppression en cascade sont les deux options les plus courantes. La restriction empêche la suppression d'une ligne référencée. Aucune ACTION signifie que si des lignes de référencement existent encore lorsque la contrainte est cochée, une erreur est soulevée; c'est le comportement par défaut si vous ne spécifiez rien. (La différence essentielle entre ces deux choix est QU'aucune ACTION ne permet de reporter le contrôle JUSQU'à plus tard dans la transaction, tandis que RESTRICT ne le fait pas.) En CASCADE précise que lorsqu'une ligne référencée est supprimée, ligne(s) de référencement, il sera automatiquement supprimé. Il y a deux autres options: SET NULL et SET DEFAULT. Cela fait que les colonnes de référence sont définies à nulls ou valeurs par défaut, respectivement, lorsque la ligne référencée est supprimée. Notez que cela ne vous dispense pas d'observer des contraintes. Par exemple, si une action spécifie SET DEFAULT mais la valeur par défaut ne satisferait pas les clés étrangères, l'opération échoue.
analogue à ON DELETE il y a aussi ON UPDATE qui est invoqué lorsqu'une colonne référencée est changée (mise à jour). Les actions possibles sont les mêmes.
edit: Vous voudrez peut-être jeter un oeil à cette question: Quand/Pourquoi pour utilisation en Cascade dans SQL Server? . Les concepts derrière les questions/réponses sont les mêmes.
j'ai une base de données PostGreSQL et je L'utilise sur Supprimer quand j'ai un utilisateur que je supprime de la base de données et je dois supprimer ses informations d'une autre table. De cette façon, je dois faire seulement 1 supprimer et FK qui a sur Supprimer supprimera les informations d'un autre tableau.
vous pouvez faire la même chose sur Update. Si vous mettez à jour la table et que le champ a un FK avec On Update, si un changement est fait sur le FK, vous serez remarqué sur la table FK.
ce que dit Daok est vrai... il peut être assez pratique. D'un autre côté, avoir des choses qui se passent automagiquement dans la base de données peut être un vrai problème, surtout quand il s'agit d'éliminer des données. Il est possible que dans le futur quelqu'un comptera sur le fait que FKs empêchent généralement la suppression des parents quand il ya des enfants et ne pas se rendre compte que votre utilisation de ON Delete Cascade non seulement n'empêche pas la suppression, il fait d'énormes quantités de données dans des douzaines d'autres tableaux vont grâce une cascade de suppressions en cascade.
commentaire de @Arthur.
plus les choses "cachées" sont fréquentes dans la base de données, moins il y a de chances que quelqu'un ait une bonne idée de ce qui se passe. Les déclencheurs (et c'est essentiellement un déclencheur) peuvent causer ma simple action de supprimer une rangée, pour avoir des conséquences très variées dans toute ma base de données. J'émets une déclaration de suppression et 17 tables sont affectées par des cascades de déclencheurs et contraintes et rien de cela n'apparaît immédiatement à l'émetteur de la commande. OTOH, si je place la suppression du parent et tous ses enfants dans une procédure, alors il est très facile et clair pour quiconque de voir exactement ce qui va se passer lorsque je donne la commande.
cela n'a absolument rien à voir avec la façon dont je conçois une base de données. Cela a tout à voir avec les problèmes opérationnels introduits par les déclencheurs.
au lieu d'écrire la méthode pour faire tout le travail, de la suppression en cascade ou de la mise à jour en cascade, vous pouvez simplement écrire un message d'avertissement à la place. Beaucoup plus facile que de réinventer la roue, et il est clair pour le client (et les nouveaux développeurs de ramasser le code)