2012-06-12 10 views
38

Ho una tabella con diverse colonne che costituiscono la chiave primaria. La natura dei dati memorizzati consente ad alcuni di questi campi di avere valori NULL. Ho progettato il mio tavolo in quanto tale:Valore NULL in chiave primaria a più colonne

CREATE TABLE `test` (
    `Field1` SMALLINT(5) UNSIGNED NOT NULL, 
    `Field2` DECIMAL(5,2) UNSIGNED NULL DEFAULT NULL, 
    PRIMARY KEY (`Field1`, `Field2`) 
) 
COLLATE='latin1_swedish_ci' 
ENGINE=InnoDB; 

Tuttavia, quando ho eseguito describe test lo dimostra in questo modo:

|| *Field* || *Type*    || *Null* || *Key* || *Default* || *Extra* 
|| Field1 || smallint(5) unsigned || NO  || PRI ||   ||   
|| Field2 || decimal(5,2) unsigned || NO  || PRI || 0.00  ||   

E Continuo a ricevere un errore quando si inserisce un valore NULL.

colonna 'Campo2' non può essere nullo

È questo a causa di un campo che è parte di una chiave primaria non può essere nulla? Quali sono le mie alternative oltre a usare, diciamo, '0' per NULL?

+2

Grazie al collegamento vj di Shah, @Tomalak rende il [punto eccellente] (http://stackoverflow.com/a/386061/673991) che questa restrizione Da quanto SQL base principio, dal momento che le parti di una chiave PRIMARIA devono essere confrontate da ogni riga a ogni altra, e "** NULL non può far parte di un confronto - il risultato di tale confronto sarebbe sempre NULL **" che impone l'unicità della chiave PRIMARIA richiede colonne non nulle. –

risposta

34

Dalla documentazione di MySQL:

Un PRIMARY KEY è un indice univoco in cui tutte le colonne chiave devono essere definite come NOT NULL. Se essi
non sono dichiarati esplicitamente come NOT NULL, MySQL li dichiara così implicitamente (e silenziosamente). Una tabella può avere solo un PRIMARY KEY. Il nome di un PRIMARY KEY è sempre PRIMARY, che quindi non può essere utilizzato come nome per qualsiasi altro tipo di indice.

http://dev.mysql.com/doc/refman/5.1/en/create-table.html

Se Campo2 può essere NULL, mi chiedo perché ne hai bisogno come parte della chiave primaria in quanto è quindi necessario Field1 essere distinta tra tutte le righe. Quindi Field1 di per sé dovrebbe essere sufficiente come chiave primaria. È possibile creare un diverso tipo di indice su Field2.

+12

Sorprendente che consente di creare una chiave primaria utilizzando una colonna definita come accetta null. – Marvo

+1

Questa è la definizione che stavo cercando ma che non ho trovato. Grazie. In effetti ho 12 colonne che compongono la chiave primaria in questo momento. 5 di questi valori sono annullabili. È una strategia di memorizzazione nella cache in cui non tutti i valori sono necessari nella richiesta incassata. La mia idea era che le chiavi primarie composte sarebbero state più economiche rispetto all'utilizzo di un valore di autoincremento come PK e aggiungendo un indice univoco rispetto agli altri. Sembra che io debba andare da quella parte. – simbabque

+7

@Girish Mi sono appena imbattuto in questo problema e voglio anche avere un campo nullable. Nel mio caso, il PK è di due campi, uno dei quali annullabile, ma mi piacerebbe al massimo una riga con il 2 ° campo NULL, quindi dovrebbe essere un PK valido. IMHO, questa è una specifica fallita da MySQL. – Seb

7

stati chiave primaria che colonna non deve avere NULL valori. Quindi le colonne utilizzate per la definizione della chiave primaria composita non saranno NULL.

Anche il server Oracle confronta la combinazione di tutte le colonne utilizzate in una definizione di chiave primaria composita. Se tutti i dati esistenti di tutte le colonne (ad esempio x, y) corrispondono alla riga aggiunta di recente, genererà l'errore di Vincolo univoco Violato.

Inoltre, guarda questa discussione: What's wrong with nullable columns in composite primary keys?.

Questo collegamento fornisce preziose informazioni sulla possibilità di colonne NULLABLE in chiave composita!

+3

Grazie per il tuo contributo. Non sono su Oracle ma su MySQL però. – simbabque

3

È possibile utilizzare chiave univoca in questo modo:

mysql> CREATE TABLE `test` (
    ->  `Field1` SMALLINT(5) UNSIGNED NOT NULL, 
    ->  `Field2` DECIMAL(5,2) UNSIGNED NULL DEFAULT NULL, 
    ->  UNIQUE KEY (`Field1`, `Field2`) 
    ->) 
    -> COLLATE='latin1_swedish_ci' 
    -> ENGINE=InnoDB; 
Query OK, 0 rows affected (0.03 sec) 

mysql> 
mysql> desc test 
    -> ; 
+--------+-----------------------+------+-----+---------+-------+ 
| Field | Type     | Null | Key | Default | Extra | 
+--------+-----------------------+------+-----+---------+-------+ 
| Field1 | smallint(5) unsigned | NO | MUL | NULL |  | 
| Field2 | decimal(5,2) unsigned | YES |  | NULL |  | 
+--------+-----------------------+------+-----+---------+-------+ 
2 rows in set (0.01 sec) 
18

chiavi primarie sono usati per fare la colonna sia unica e non nullo

Inorder per inserire inserire i valori nulli fanno field2 come Unico

Unico vincolo rende il campo rimuove i duplicati ma permettono nulli valori

+1

Questa risposta alla domanda, grazie. La risposta accettata era sbagliata. – singe3

+1

@ singe3 beh, la domanda non era _come faccio a creare un indice con un valore NULL_, ma _why non posso avere un valore NULL nella chiave primaria_. Sono contento che l'informazione che una chiave univoca ti consente di avere un campo NULL ti ha aiutato, ma non risponde alla domanda. La risposta accettata fa. – simbabque

Problemi correlati