2011-02-10 4 views
11

Sto provando a creare un vincolo UNICO INDICE per due colonne, ma solo quando un'altra colonna contiene il valore 1. Ad esempio, column_1 e column_2 devono essere UNICI solo quando active = 1 . Qualsiasi riga che contiene active = 0 può condividere valori per column_1 e column_2 con un'altra riga, indipendentemente da quale sia il valore dell'altra riga per active. Ma righe dove active = 1 non possono condividere valori di column_1 o column_2 con un'altra riga che ha active = 1.Vincolo UNICO, solo quando un campo contiene un valore specifico

Quello che intendo per "condivisione" è due righe con lo stesso valore (s) nella stessa colonna (s). Esempio: row1.a = row2.a AND row1.b = row2.b. I valori sarebbero condivisi solo se entrambe le colonne nella riga 1 corrispondessero alle altre due colonne nella riga2.

Spero di essere stato chiaro. : \

risposta

0
Gli indici

sono indipendenti da influssi esterni. Questo tipo di vincolo dovrebbe essere implementato al di fuori del database.

0

In SQL Server questo potrebbe essere eseguito con i vincoli di controllo, tuttavia non so se MySQL supporti qualcosa di simile.

Ciò che funzionerà su qualsiasi database, è che è possibile dividere il tavolo in due. Se i record dove active = 0 sono solo record di cronologia e non saranno mai più attivi, è possibile spostarli in un'altra tabella e impostare un semplice vincolo univoco sulla tabella originale.

+0

Ho ricevuto un suggerimento simile su IRC; crea una tabella attiva e una tabella inattiva. Ma il modo in cui lo metti ha più senso; avere una tabella storica e una tabella attiva. Tuttavia, questa tabella ha molti campi e sembrerebbe che duplicare quei campi in due tabelle sarebbe la cosa sbagliata da fare. Come suggeriresti di evitare questo tipo di ridondanza? – Sam

+0

Una piccola denormalizzazione può fare molto, quindi non preoccuparti delle definizioni duplicate. Ovviamente, dovrai apportare eventuali modifiche alla tabella originale anche alla tabella storica, quindi è un po 'eccessivo, ma, IMHO, vale la pena di pulire i dati. – SWeko

+0

Hmm, e se dovessi separare solo i dati che necessitano di indicizzazione univoca? Le tabelle: mydata, mydata_active, mydata_inactive. In questo modo mydata contiene la chiave primaria e le colonne di dati.E mydata_active e mydata_inactive conterranno solo le colonne che devono essere indicizzate in modo univoco e una chiave esterna che fa riferimento a mydata. Questo è un altro modo, ma richiede un extra (terzo) tavolo. – Sam

11

Si può provare a creare un indice UNIQUE multi colonna con column_1, column_2 e active, quindi impostare active = NULL per le righe in cui non è richiesta l'univocità. In alternativa, puoi utilizzare i trigger (see MySQL trigger syntax) e controllare per ogni riga inserita/aggiornata se tali valori sono già presenti nella tabella, ma penso che sarebbe piuttosto lento.

+0

Suggerirei la soluzione NULL: è facile, NULL è uguale a FALSE (non dirlo a un fondamentalista di SQLer) e, soprattutto, fa in modo che il database faccia tutto il lavoro per voi. –

+0

Nella soluzione NULL, in che modo il database distingue l'unicità di 2 righe nella situazione quando sono identiche? Mysql evita il controllo dei vincoli in quel momento? –

2

Sto cercando di creare un vincolo indice univoco per due colonne, ma solo quando un'altra colonna contiene il valore 1

è possibile impostare il valore di "un'altra colonna" su un valore unico che non uguale a 1. ad esempio l'id di un record.

Quindi il vincolo di indice univoco può essere applicato a tutte e tre le colonne inclusa "un'altra colonna". Chiamiamo la colonna "un'altra colonna" X. Impostare il valore di columnX su 1 se si desidera applicare il vincolo univoco a un record. Impostare il valore di columnX su un valore univoco se non si desidera applicare il vincolo univoco.

Quindi non sono necessari ulteriori interventi/trigger. L'indice univoco di tutte e tre le colonne potrebbe risolvere il tuo problema.