MySQL – Contraintes de clés étrangères conditionnelles

J’ai le tableau suivant de commentaires dans mon application:

comments -------- id INT foreign_id INT model TEXT comment_text TEXT ... 

l’idée de cette table est de stocker des commentaires pour différentes parties de mon application – elle peut stocker des commentaires pour un article de blog, par exemple:

 1|34|blogpost|lorem ipsum... 

image d’utilisateur:

 2|12|picture|lorem ipsum... 

etc.

Maintenant, existe-t-il un moyen de forcer la contrainte FOREIGN KEY sur de telles données?

c’est-à-dire quelque chose comme ça dans le tableau des commentaires:

 FOREIGN KEY (`foreign_id`) REFERENCES blogposts (`id`) //but only when model='blogpost' 

Vous essayez de faire une conception appelée Associations Polymorphiques . C’est-à-dire que la clé étrangère peut faire référence à des lignes dans l’une des tables associées.

Mais une contrainte de clé étrangère doit référencer exactement une table. Vous ne pouvez pas déclarer une clé étrangère qui référence différentes tables en fonction de la valeur dans une autre colonne de votre table Comments . Cela violerait plusieurs règles de conception de firebase database relationnelle.

Une meilleure solution consiste à créer une sorte de “supertable” référencée par les commentaires.

 CREATE TABLE Commentable ( id SERIAL PRIMARY KEY ); CREATE TABLE Comments ( comment_id SERIAL PRIMARY KEY, foreign_id INT NOT NULL, ... FOREIGN KEY (foreign_id) REFERENCES Commentable(id) ); 

Chacun de vos types de contenu serait considéré comme un sous-type de cette supertable. Ceci est analogue au concept orienté object d’une interface .

 CREATE TABLE BlogPosts ( blogpost_id INT PRIMARY KEY, -- notice this is not auto-generated ... FOREIGN KEY (blogpost_id) REFERENCES Commentable(id) ); CREATE TABLE UserPictures ( userpicture_id INT PRIMARY KEY, -- notice this is not auto-generated ... FOREIGN KEY (userpicture_id) REFERENCES Commentable(id) ); 

Avant de pouvoir insérer une ligne dans BlogPosts ou UserPictures , vous devez insérer une nouvelle ligne dans Commentable pour générer un nouvel identifiant pseudokey. Ensuite, vous pouvez utiliser cet identifiant généré lorsque vous insérez le contenu dans la table de sous-types correspondante.

Une fois que vous faites tout cela, vous pouvez vous fier aux contraintes d’intégrité référentielle.