¿Cuándo usar NULL y cuándo usar una cadena vacía?


82

Estoy interesado principalmente en MySQL y PostgreSQL, pero podría responder lo siguiente en general:

  • ¿Existe un escenario lógico en el que sería útil distinguir una cadena vacía de NULL?
  • ¿Cuáles serían las implicaciones de almacenamiento físico para almacenar una cadena vacía como ...

    • ¿NULO?
    • ¿Cuerda vacía?
    • Otro campo?
    • ¿Cualquier otra manera?

Respuestas:


67

Digamos que el registro proviene de un formulario para recopilar información de nombre y dirección. La línea 2 de la dirección generalmente estará en blanco si el usuario no vive en el departamento. Una cadena vacía en este caso es perfectamente válida. Tiendo a preferir usar NULL para indicar que el valor es desconocido o no se da.

No creo que valga la pena preocuparse por la diferencia de almacenamiento físico en la práctica. Como administradores de bases de datos, ¡tenemos peces mucho más grandes para freír!


2
+1 muy pocos dba necesitan preocuparse por las diferencias de velocidad / tamaño de usar NULLo no
Patrick

28
De acuerdo ... Intento reservar NULL para 'no conocido' ... la cadena vacía es 'sabemos que debería estar vacía'. Es particularmente útil para cuando sus datos provienen de múltiples fuentes
Joe

66
Excepcional: no se conoce NULL, se especificó una cadena vacía.
ScottCher

@Larry, ¿cuál es el impacto en el rendimiento? ¿Cómo varía el rendimiento con tablas de muchos cols frente a tablas de muchas filas?
Shimmy

Estoy de acuerdo en que si hay una distinción entre ningún valor dado y una cadena vacía en su conjunto de datos, entonces debe usarlos apropiadamente, pero personalmente si no necesito esa distinción con mis datos, siempre uso una cadena vacía, simplemente porque yo encuentre que el resultado de la consulta de un cliente MySQL en la línea de comando puede ser más limpio para ver con cadenas vacías en lugar de muchos NULL
RTF

25

No sé acerca de MySQL y PostgreSQL, pero déjenme tratar esto un poco en general.

Hay un DBMS, a saber, Oracle, que no permite elegir sus usuarios entre NULL y ''. Esto demuestra claramente que no es necesario distinguir entre ambos. Hay algunas consecuencias molestas:

Establece un varchar2 en una cadena vacía como esta:

Update mytable set varchar_col = '';

lo siguiente lleva al mismo resultado

Update mytable set varchar_col = NULL;

Pero para seleccionar las columnas donde el valor está vacío o NULL, debe usar

select * from mytable where varchar_col is NULL;

Utilizando

select * from mytable where varchar_col = '';

es sintácticamente correcto, pero nunca devuelve una fila.

Por otro lado, al concatenar cadenas en Oracle. Los varchars NULL se tratan como cadenas vacías.

select NULL || 'abc' from DUAL;

rinde abc . Otros DBMS devolverían NULL en estos casos.

Cuando desee expresar explícitamente que se asigna un valor, debe usar algo como ''.

Y debe preocuparse si el recorte no está vacío da como resultado NULL

select case when ltrim(' ') is null then 'null' else 'not null' end from dual

Lo hace.

Ahora mirando DBMS donde '' no es idéntico a NULL (por ejemplo, SQL-Server)

Trabajar con '' es generalmente más fácil y, en la mayoría de los casos, no hay necesidad práctica de distinguir entre ambos. Una de las excepciones que conozco es cuando su columna representa alguna configuración y no tiene valores predeterminados vacíos para ellos. Cuando puede distinguir entre '' y NULL, puede expresar que su configuración está vacía y evitar que se aplique el valor predeterminado.



17

Depende del dominio en el que esté trabajando. NULLsignifica ausencia de valor (es decir, no hay valor ), mientras que una cadena vacía significa que hay un valor de cadena de longitud cero.

Por ejemplo, supongamos que tiene una tabla para almacenar los datos de una persona y que contiene una Gendercolumna. Puede guardar los valores como 'Masculino' o 'Femenino'. Si el usuario puede elegir no proporcionar los datos de género, debe guardarlos como NULL(es decir, el usuario no proporcionó el valor) y no una cadena vacía (ya que no hay género con valor '').


77
Si el usuario elige no proporcionar un género, seguramente debe almacenar "Rechazado para proporcionar". NULL es ambiguo; también podría significar "al cliente no se le ha preguntado", "el cliente se identifica con un género que no está en nuestra lista", etc.
Jon of All Trades

9

Una cosa que vale la pena tener en cuenta es que cuando tiene un campo que no es obligatorio, pero cualquier valor que esté presente debe ser único, deberá almacenar valores vacíos como NULL. De lo contrario, solo podrá tener una tupla con un valor vacío en ese campo.

También hay algunas diferencias con el álgebra relacional y los valores NULL: NULL! = NULL, por ejemplo.


44
En realidad no es el caso que NULL! = NULL, porque eso es NULL. ;-)
Peter Eisentraut

1
Tenga en cuenta que MS SQL no sigue esta regla: varios valores NULL violarán una UNIQUErestricción. Afortunadamente, a partir de 2008 puede usar un índice filtrado para obtener un comportamiento adecuado.
Jon of All Trades


4

Un nuevo pensamiento, una gran influencia en su elección de NULL/ NOT NULLes si está utilizando un marco. Utilizo mucho Symfony y el uso de NULLcampos de permiso simplifica parte del código y la verificación de datos al manipular los datos.

Si no está utilizando un marco o si está utilizando declaraciones y procesamiento simples de SQL, elegiría la opción que considere más fácil de seguir. Generalmente prefiero NULL de manera que haciendo INSERTdeclaraciones no resultar tedioso con el olvido para establecer los campos vacíos a NULL.


la pregunta es sobre NULL vs. cadena vacía (en una columna anulable, IMO), no NULL vs NOT NULL, ¿no es así?
Gan

la parte de la pregunta sobre el almacenamiento me llevó a pensar que él también podría estar pensando en Null / Not Null
Patrick

o @todos los demás con respecto a la implicación de NULL vs NOT NULL, puede referirse a esto: dba.stackexchange.com/q/63/107
Gan

2

Habiendo tenido que trabajar con Oracle ( que no te permite diferenciar ), he llegado a la siguiente conclusión:

  • Desde un punto de vista lógico no importa. Realmente no puedo pensar en un ejemplo convincente donde la diferenciación entre NULL y cadena de longitud cero agregue algún valor en el DBMS.

  • De lo que sigue: Usted tiene una NULLcolumna capaz que no permite cero len ''(solución Oracle-ish) o una NOT NULLcolumna que permite cero len.

  • Y desde mi experiencia, ''tiene mucho más sentido al procesar los datos, ya que normalmente le gustaría procesar la ausencia de una cadena como la cadena vacía: concatenación, comparación, etc.

Nota: Para volver a mi experiencia con Oracle: supongamos que desea generar una consulta para una solicitud de búsqueda. Si lo usa '', puede generar WHERE columnX = <searchvalue>y funcionará para búsquedas de igualdad. Si usas NULLtienes que hacer WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). ¡Bah! :-)


2

También son diferentes desde una perspectiva de diseño:

p.ej

CREATE TABLE t (
    id INTEGER  NOT NULL,
    name CHARACTER(40),
    CONSTRAINT t_PK PRIMARY KEY (id)
);

CREATE UNIQUE INDEX t_AK1 ON t (name);

Parece:

 \d t
          Table "public.t"
 Column |     Type      | Modifiers
--------+---------------+-----------
 id     | integer       | not null
 name   | character(40) |
Indexes:
    "t_pk" PRIMARY KEY, btree (id)
    "t_ak1" UNIQUE, btree (name)

Vamos a insertar algunos datos:

op=# insert into t(id, name ) values ( 1, 'Hello');
INSERT 0 1

op=# insert into t( id, name) values ( 2, '');
INSERT 0 1

op=# insert into t( id, name) values ( 3, '');

ERROR:  duplicate key value violates unique constraint "t_ak1"

Ahora intentemos con nulo:

op=# insert into t( id, name) values (4, null );

INSERT 0 1

op=# insert into t( id, name) values (5, null);

INSERT 0 1

Esto esta permitido.

Soooooo: los nulos no son cadenas triviales ni al revés.

Salud


1

Si hablamos de teoría, entonces las reglas de Codd dicen que RDBMS debe tratar los NULLvalores de una manera especial.

La forma exacta en que se usa depende de los arquitectos de bases de datos, dependiendo del dominio real - tarea - proyecto - aplicación - área.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.