Se eu tiver uma tabela que se parece com isso
CREATE TABLE foo (
id INT NOT NULL AUTO_INCREMENT,
aa INT NOT NULL,
bb INT NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (aa, bb),
CONSTRAINT aa_ref FOREIGN KEY (aa) REFERENCES bar (id),
CONSTRAINT bb_ref FOREIGN KEY (bb) REFERENCES bar (id)
)
Existe uma maneira de garantir que, aa != bb
além de usar a lógica no nível do aplicativo ou forçar um gatilho a falhar em BEFORE INSERT?
Não, você não pode. Na maioria dos DBMS (Postgres, SQL-Server, Oracle, DB2 e muitos outros), você pode apenas adicionar uma
CHECK
restrição:Não vejo como fazer isso no MySQL, usando apenas restrições referenciais. Além dos gatilhos, você poderia deixar as duas colunas com valores iguais e simplesmente ignorar as linhas acessando a tabela sempre através de uma view:
Como alternativa, você pode restringir as operações de inserção e atualização por meio de procedimentos (armazenados) que cuidam da restrição e não permitem que dados sejam inseridos (ou alterados) que não a satisfaçam.
O MySQL não suporta
CHECK
contrsaints diretamente, embora se você tiver uma versão recente o suficiente, ele suporta gatilhos e geração de erros viaSIGNAL
, portanto, você pode definirBEFORE INSERT
eBEFORE UPDATE
disparar que verificam os dados e geram erros se a restrição pretendida não for satisfeita.Isso será menos eficiente do que o suporte nativo para restrições de verificação, é claro, portanto, se você estiver executando um alto volume de gravações nessa estrutura, certifique-se de analisar a diferença de desempenho causada pelo gatilho, caso isso prejudique muito seu aplicativo.
Boas notícias!!
Mysql suporta CHECK CONSTRAINT
https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html
As duas colunas em questão referem-se à mesma tabela Bar. Você poderia dividir a tabela Bar em duas para que contenham id com os diferentes conjuntos de valores?