Posso garantir que duas colunas não tenham o mesmo valor

11

Se eu tiver uma tabela assim

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 != bbalém de usar a lógica no nível do aplicativo ou forçar a falha de um gatilho no ANTES DE INSERIR?

Nifle
fonte

Respostas:

3

O MySQL não suporta CHECKcontrsaints diretamente, mas se você tem uma versão recente o suficiente ele suporta gatilhos e erro levantando via SIGNAL, para que você possa definir BEFORE INSERTe BEFORE UPDATEgatilhos que verificam os erros de dados e aumentar se a restrição destina-se não está satisfeito.

Isso será menos eficiente que o suporte nativo a restrições de verificação, é claro, portanto, se você estiver executando um alto volume de gravações nessa estrutura, analise a diferença de desempenho causada pelo gatilho, caso isso prejudique muito o seu aplicativo.

David Spillett
fonte
8

Não, você não pode. Na maioria dos DBMS (Postgres, SQL-Server, Oracle, DB2 e muitos outros), você pode simplesmente adicionar uma CHECKrestrição:

ALTER TABLE foo 
  ADD CONSTRAINT aa_cannot_be_equal_to_bb_CHK
    CHECK (aa <> bb) ;

Não vejo nenhuma maneira de ter isso no MySQL, usando apenas restrições referenciais. Além dos gatilhos, você pode permitir que as duas colunas tenham valores iguais e simplesmente ignorar as linhas acessando a tabela sempre por meio de uma exibição:

CREATE VIEW foo_correct AS
SELECT id, aa, bb
FROM foo
WHERE aa <> bb ;

Como alternativa, você pode restringir as operações de Inserção e Atualização através de procedimentos (armazenados) que cuidam da restrição e não permitem que dados sejam inseridos (ou alterados) que não a satisfazem.

ypercubeᵀᴹ
fonte
-1

As duas colunas em questão fazem referência à mesma tabela Bar. Você pode dividir a tabela Bar em duas para que elas contenham ID com os diferentes conjuntos de valores?

msi77
fonte
11
Então, digamos que temos três casais na Footabela: (1,2) (2,3) (3,1). Como devemos dividir os três valores?
precisa saber é o seguinte
11
Concordo, sugestão equivocada.
msi77