Les relations de base de données impliquent souvent des scénarios complexes qui nécessitent des contraintes supplémentaires pour garantir l'intégrité des données. Cet article explore un défi spécifique : implémenter une contrainte de clé étrangère qui garantit la validité d'un choix tout en considérant les relations circulaires potentielles.
Considérez deux tableaux : SystemVariables et VariableOptions. SystemVariables représente des variables système personnalisables, tandis que VariableOptions contient les choix disponibles pour ces variables. Chaque SystemVariable a une option choisie représentée par le champ Choice_id, tandis que chaque VariableOption a un variable_id indiquant la variable à laquelle elle appartient.
Le but est d'ajouter une contrainte supplémentaire qui garantit :
VariableOptions[sysVar.choice_id].variable_id == sysVar.id
où sysVar est une ligne dans la table SystemVariables.
Une solution simple consiste à étendre la clé étrangère faisant référence à l'option choisie pour inclure à la fois Choice_id et variable_id :
ALTER TABLE systemvariables ADD CONSTRAINT systemvariables_choice_id_fk FOREIGN KEY (choice_id, variable_id) REFERENCES variableoptions(option_id, variable_id);
Cela garantit que l'option sélectionnée est valide et renvoie à la bonne variable dans les deux sens.
L'approche précédente nécessite toutes les colonnes clés être non NULL, ce qui peut introduire des restrictions lors de l'utilisation de nouvelles insertions. Une meilleure solution consiste à exploiter les contraintes de clé étrangère reportables.
CREATE TABLE systemvariables ( variable_id int PRIMARY KEY , variable text , choice_id int NOT NULL ); CREATE TABLE variableoptions ( option_id int PRIMARY KEY , option text , variable_id int NOT NULL REFERENCES systemvariables ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED , UNIQUE (option_id, variable_id) -- needed for the foreign key ); ALTER TABLE systemvariables ADD CONSTRAINT systemvariables_choice_id_fk FOREIGN KEY (choice_id, variable_id) REFERENCES variableoptions(option_id, variable_id) DEFERRABLE INITIALLY DEFERRED;
Cette approche permet l'insertion de nouvelles variables et options dans la même transaction, même lorsqu'elles dépendent les unes des autres, en différant les vérifications de clé étrangère jusqu'à la fin de la transaction.
En utilisant des contraintes de clé étrangère différables et en étendant les clés étrangères pour inclure plusieurs colonnes, on peut obtenir des clés étrangères complexes contraintes clés qui maintiennent l’intégrité des données tout en permettant une flexibilité dans la manipulation des données.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!