2012-06-12 11 views
38

Tengo una tabla con varias columnas que constituyen la clave principal. La naturaleza de los datos almacenados permite que algunos de estos campos tengan valores de NULL. He diseñado mi mesa como tal:Valor NULL en clave primaria de varias columnas

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; 

Sin embargo, cuando corro describe test se muestra así:

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

Y Me aparece un error al insertar un valor NULL.

Columna 'Campo2' no puede ser nulo

Se debe esto a un campo que es parte de una clave principal no puede ser nulo? ¿Cuáles son mis alternativas además de usar, digamos, '0' para NULL?

+2

Gracias a enlace vj de Shah, @Tomalak hace que el [excelente punto] (http://stackoverflow.com/a/386061/673991) que esta restricción se sigue de la SQL básico principio de que, como las partes de una clave PRIMARIA deben compararse de cada fila a cada otra fila, y "** NULL no puede ser parte de una comparación, el resultado de dicha comparación siempre será NULO **" que obliga a aplicar la singularidad PRIMARY columnas no nulas. –

Respuesta

34

De la documentación de MySQL:

Una PRIMARY KEY es un índice único en el que todas las columnas clave deben definirse como NOT NULL. Si ellos
no están explícitamente declarados como NOT NULL, MySQL los declara de manera implícita (y silenciosa). Una tabla puede tener solo una LLAVE PRIMARIA. El nombre de una LLAVE PRINCIPAL es siempre PRIMARIO, por lo que no se puede usar como nombre para ningún otro tipo de índice.

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

Si Campo2 puede ser NULL, me pregunta por qué lo necesita como parte de la clave principal ya que este caso es necesario Campo1 a ser distinto en todas las filas. Por lo tanto, Field1 por sí solo debería ser suficiente como la clave principal. Puede crear un tipo diferente de índice en Field2.

+12

Sorprende que le permita a uno crear una clave principal usando una columna que se define como aceptar nulos. – Marvo

+1

Esa es la definición que estaba buscando pero que no encontré. Gracias. De hecho, tengo 12 columnas que componen la clave principal en este momento. 5 de estos valores son anulables. Es una estrategia de almacenamiento en caché donde no se necesitan todos los valores en la solicitud cobrada. Mi idea era que las claves primarias compuestas serían más baratas que usar un valor de autoincrementación como PK y agregar un índice único sobre todos los demás. Parece que tengo que ir por ese camino. – simbabque

+7

@Girish Acabo de encontrarme con este problema y también quiero tener un campo que pueda contener nulos. En mi caso, el PK es de dos campos, uno de ellos con capacidad para anularse, pero me gustaría como máximo una fila con el segundo campo NULL, por lo que debería ser un PK válido. En mi humilde opinión, esta es una especificación fallida de MySQL. – Seb

7

estados clave principal que la columna no debe tener NULL valores. Por lo tanto, las columnas utilizadas para definir la clave primaria compuesta no van a ser NULL.

También el servidor Oracle compara la combinación de todas las columnas utilizadas en una definición de clave primaria compuesta. Si todos los datos existentes de las columnas (por ejemplo, x, y) coinciden con la fila de nueva adición, se generará un error de Violación única violada.

Además, mira este hilo: What's wrong with nullable columns in composite primary keys?.

Este enlace proporciona información valiosa sobre la posibilidad de columnas NULLABLE en la clave compuesta.

+3

Gracias por su contribución. No estoy en Oracle, pero en MySQL sin embargo. – simbabque

3

Puede usar clave única de esta manera:

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

Las claves primarias se utilizan para hacer la columna a la vez único y no nulo

finde para insertar valores nulos de inserción hacen campo2 como Único

Restricción única en el campo elimina duplicados pero permiten nulos valores

+1

Responde a la pregunta, gracias. La respuesta aceptada fue incorrecta. – singe3

+1

@ singe3, bueno, la pregunta no era: ¿cómo creo un índice con un valor NULO ?, sino ¿por qué no puedo tener un valor NULO en la clave principal? Me complace saber que la información de que una clave única le permite tener un campo NULO lo ayudó, pero no responde la pregunta. La respuesta aceptada sí. – simbabque

Cuestiones relacionadas