Você está tentando fazer um design chamado Associações Polimórficas . Ou seja, a chave estrangeira pode fazer referência a linhas em qualquer uma das várias tabelas relacionadas.
Mas uma restrição de chave estrangeira deve referenciar exatamente uma tabela. Você não pode declarar uma chave estrangeira que faça referência a diferentes tabelas dependendo do valor em outra coluna de seus
Comments
tabela. Isso violaria várias regras de design de banco de dados relacional. Uma solução melhor é fazer uma espécie de "supertabela" que seja referenciada pelos comentários.
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)
);
Cada um de seus tipos de conteúdo seria considerado um subtipo desta supertabela. Isso é análogo ao conceito orientado a objeto de uma 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)
);
Antes de inserir uma linha em
BlogPosts
ou UserPictures
, você deve inserir uma nova linha em Commentable
para gerar um novo ID de pseudochave. Em seguida, você pode usar esse id gerado ao inserir o conteúdo na respectiva tabela de subtipos. Depois de fazer tudo isso, você pode confiar nas restrições de integridade referencial.