Posso assicurarmi che due colonne non abbiano lo stesso valore?


11

Se ho un tavolo che assomiglia a questo

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)
)

C'è un modo per assicurarsi che aa != bboltre a utilizzare la logica a livello di applicazione o forzare un trigger a fallire PRIMA DI INSERIRE?

Risposte:


3

MySQL non supporta CHECKdirettamente i controsain, sebbene se si dispone di una versione abbastanza recente supporta trigger e raccolta di errori tramite SIGNAL, quindi è possibile definire BEFORE INSERTe BEFORE UPDATEtrigger che controllano i dati e generano errori se il vincolo previsto non è soddisfatto.

Questo sarà meno efficiente del supporto nativo per i vincoli di controllo, quindi, se stai eseguendo un volume elevato di scritture su quella struttura, assicurati di analizzare la differenza di prestazioni causata dal trigger nel caso in cui danneggi troppo l'applicazione.


8

No, non puoi. Nella maggior parte dei DBMS (Postgres, SQL-Server, Oracle, DB2 e molti altri), puoi semplicemente aggiungere un CHECKvincolo:

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

Non vedo alcun modo per avere questo in MySQL, usando solo vincoli referenziali. Oltre ai trigger, è possibile consentire alle due colonne di avere valori uguali e semplicemente ignorare le righe accedendo alla tabella sempre tramite una vista:

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

In alternativa, è possibile limitare le operazioni di inserimento e aggiornamento tramite procedure (memorizzate) che gestiscono il vincolo e non consentono l'inserimento (o la modifica) di dati che non lo soddisfano.



-1

Entrambe le colonne in questione fanno riferimento alla stessa tabella Bar. Potresti dividere la tabella Bar in due in modo che contengano id con i diversi set di valori?


1
Poi, dire che abbiamo tre coppie nella Footabella: (1,2) (2,3) (3,1). Come dovremmo dividere i tre valori?
ypercubeᵀᴹ

1
Sono d'accordo, suggerimento errato.
msi77,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.