Vous essayez de faire une conception qui s'appelle Associations polymorphes . C'est-à-dire que la clé étrangère peut référencer des lignes dans n'importe laquelle de plusieurs tables lié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 fait référence à différentes tables en fonction de la valeur dans une autre colonne de votre Comments
table. Cela violerait plusieurs règles de conception de bases de données relationnelles.
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é objet 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 de pseudo-clé. Ensuite, vous pouvez utiliser cet identifiant généré lorsque vous insérez le contenu dans la table de sous-types respective.
Une fois que vous avez fait tout cela, vous pouvez compter sur des contraintes d'intégrité référentielle.