MySQL: NULL vs “”

¿Es mejor usar default null o default "" para campos de texto en MySQL?

¿Por qué?

Actualización: sé lo que significa cada uno de ellos. Me interesa qué es mejor usar teniendo en cuenta el espacio y el rendimiento del disco.

Actualización 2: Hola gente! La pregunta era “qué es mejor usar”, no “lo que significa cada uno” o “cómo verificarlos” …

Usar null predeterminado En SQL, null es muy diferente de la cadena vacía (“”). La cadena vacía significa específicamente que el valor se configuró como vacío; null significa que el valor no se estableció o se estableció en nulo. Diferentes significados, ves.

Los diferentes significados y sus diferentes usos explican por qué es importante usar cada uno de ellos según corresponda; la cantidad de espacio potencialmente guardado mediante el uso de default null en lugar de default "" es tan pequeño que se acerca a la insignificancia; sin embargo, el valor potencial de usar los valores predeterminados correctos como dicta la convención es bastante alto.

Para las tablas MyISAM, NULL crea un bit adicional para cada columna NULLABLE (el bit nulo) para cada fila. Si la columna no es NULLABLE, nunca se necesita la información adicional. Sin embargo, eso se rellena en bytes de 8 bits, por lo que siempre obtendrá 1 + mod 8 bytes para el recuento de columnas NULLABLE. 1

Las columnas de texto son un poco diferentes de otros tipos de datos. Primero, para “”, la entrada de la tabla contiene la longitud de dos bytes de la cadena seguida de los bytes de la cadena y es una estructura de longitud variante. En el caso de NULL, no hay necesidad de la información de longitud, pero se incluye de todos modos como parte de la estructura de la columna.

En InnoDB, NULLS no toma espacio: simplemente no existen en el conjunto de datos. Lo mismo es cierto para la cadena vacía ya que los offsets de datos tampoco existen. La única diferencia es que los NULL tendrán el bit NULL establecido mientras que las cadenas vacías no. 2

Cuando los datos se presentan realmente en el disco, NULL y ” ocupan EXACTAMENTE EL MISMO ESPACIO en ambos tipos de datos. Sin embargo, cuando se busca el valor, la comprobación de NULL es un poco más rápida que la comprobación de ”, ya que no tiene que considerar la longitud de los datos en sus cálculos: solo verifica el bit nulo.

Como resultado de NULL y ” diferencias de espacio, NULL y ” no tienen IMPACTO DE TAMAÑO a menos que la columna se especifique como NULLable o no. Si la columna NO ES NULA, solo verá en las tablas MyISAM cualquier diferencia de rendimiento (y luego, obviamente, el NULL predeterminado no se puede usar, por lo que es una pregunta discutible).

La verdadera pregunta se reduce a la interpretación de la aplicación de las columnas “sin valor establecido aquí”. Si “” es un valor válido que significa “el usuario no ingresó nada aquí” o algo así, entonces es preferible usar NULL por defecto, ya que quiere distinguir entre NULL y “” cuando se ingresa un registro que no tiene datos.

Sin embargo, en general, el valor predeterminado solo es útil para refacturar una base de datos, cuando los nuevos valores deben entrar en vigencia en los datos antiguos. En ese caso, nuevamente, la elección depende de cómo se interpretan los datos de la aplicación. Para algunos datos antiguos, NULL es perfectamente apropiado y el más adecuado (¡la columna no existía antes, por lo que ahora tiene valor NULL!). Para otros, “” es más apropiado (a menudo cuando las consultas usan SELECT * y NULL causa problemas de locking).

En los TÉRMINOS ULTRA-GENERALES (y desde un punto de vista filosófico) se prefiere el NULO predeterminado para las columnas NULLABLE, ya que ofrece la mejor interpretación semántica de “Sin valor especificado”.

1 [ http://forge.mysql.com/wiki/MySQL_Internals_MyISAM%5D

2 [ http://forge.mysql.com/wiki/MySQL_Internals_InnoDB%5D

Desde High Performance MySQL, 3ra Edición

Evite NULL si es posible. Muchas tablas incluyen columnas anulables incluso cuando la aplicación no necesita almacenar NULL (la ausencia de un valor), simplemente porque es la predeterminada. Por lo general, es mejor especificar las columnas como NOT NULL a menos que tenga la intención de almacenar NULL en ellas. Para MySQL es más difícil optimizar las consultas que se refieren a columnas que aceptan nulos, porque hacen que los índices, las estadísticas de índice y las comparaciones de valores sean más complicados. Una columna que admite nulos permite más espacio de almacenamiento y requiere un procesamiento especial dentro de MySQL. Cuando una columna anulable está indexada, requiere un byte adicional por entrada e incluso puede convertir un índice de tamaño fijo (como un índice en una única columna de enteros) en un tamaño variable en MyISAM. La mejora en el rendimiento desde cambiar las columnas NULL a NOT NULL suele ser pequeña, por lo que no debe priorizar su búsqueda y cambiarlas en un esquema existente a menos que sepa que están causando problemas. Sin embargo, si planea indexar columnas, evite que sean nulables si es posible. Hay excepciones, por supuesto. Por ejemplo, vale la pena mencionar que InnoDB almacena NULL con un solo bit, por lo que puede ser bastante eficiente en el uso del espacio para datos escasamente poblados. Esto no se aplica a MyISAM, sin embargo.

Mucha gente está respondiendo la diferencia entre null y '' , pero el OP ha solicitado lo que ocupa menos espacio / es más rápido, así que aquí está mi ataque:

La respuesta es que depende. Si su campo es un char(10) , siempre tomará 10 bytes si no se establece en null , y por lo tanto, null ocupará menos espacio. Minutos fila por fila, pero en millones y millones de filas, esto podría sumrse. Creo que incluso un varchar(10) almacenará un byte ( \0 ) como una cadena vacía, así que de nuevo podría sumrse en tablas enormes.

En términos de rendimiento en las consultas, null es, en teoría, más rápido de probar, pero no he podido encontrar ninguna diferencia apreciable en una tabla bien indexada. Sin embargo, tenga en cuenta que es posible que deba convertir null a '' en el lado de la aplicación si esta es la devolución deseada. De nuevo, fila por fila, la diferencia es mínima, pero podría sumrse potencialmente.

En general, es una micro-optimización, por lo que se reduce a las preferencias. Mi preferencia es usar null porque me gusta saber que no hay ningún valor allí y no adivinar si es una cadena en blanco ( '' ) o un grupo de espacios ( ' ' ). null es explícito en su naturaleza. '' no es. Por lo tanto, voy con null porque soy un tipo explícito de persona.

Descubrí que NULL vs “” es insignificante en términos de espacio de disco y rendimiento.

La única razón verdadera que puedo ver personalmente al usar NULL en lugar de ” es cuando tienes un campo marcado como ÚNICO pero necesitas la capacidad de permitir columnas múltiples “vacías”.

Por ejemplo, la columna de correo electrónico en mi tabla de usuarios solo se completa si alguien realmente tiene una dirección de correo electrónico. Cualquier persona sin una dirección de correo electrónico obtiene NULL. Todavía puedo hacer que este campo sea único porque NULL no se cuenta como un valor, mientras que la cadena vacía ” sí lo es.

Usa lo que tenga sentido. NULL significa “ningún valor disponible / especificado”, "" significa “cadena vacía”.

Si no permite cadenas vacías, pero el usuario no tiene que ingresar un valor, entonces NULL tiene sentido. Si necesita un valor, pero puede estar vacío, NOT NULL y un valor de "" tiene sentido.

Y, por supuesto, si no necesita un valor, pero se puede especificar un valor vacío, entonces NULL tiene sentido.

En cuanto al punto de vista de la eficiencia, se usa un bit adicional para determinar si el campo es NULL o no, pero no se preocupe por dicha microoptimización hasta que tenga millones de filas.

Prefiero nulo cuando es semánticamente correcto. Si hay un campo de dirección disponible y el usuario no completó, le doy un “”. Sin embargo, si hay un atributo de dirección en la tabla de usuarios pero no le ofrecí al usuario la oportunidad de completarlo, le doy un NULO.

Dudo (pero no puedo verificar) que NULL y “” marcan una gran diferencia.

"" es como una caja vacía … null es como ninguna caja en absoluto.

Es un concepto difícil de comprender inicialmente, pero como las respuestas aquí claramente indican, hay una gran diferencia.

En general, NULL debe indicar datos que no están presentes o que no se han proporcionado y, por lo tanto, es un valor predeterminado mejor que la cadena vacía.

A veces, la cadena vacía es lo que necesita como valor de datos, pero casi nunca debe ser un valor predeterminado.

NULL significa ‘no hay valor’ y es tratado especialmente por los RDBMS con respecto a cláusulas where y join.

“” significa ‘cadena vacía’ y no se trata especialmente.

Depende de qué representa el texto y cómo se usará realmente en las consultas.

Por ejemplo, puede tener un cuestionario con algunas preguntas obligatorias y algunas preguntas opcionales.

  • Las preguntas opcionales rechazadas deben tener un NULO en su columna correspondiente.
  • Las preguntas obligatorias deben tener una cadena vacía como predeterminada, porque TIENEN que ser respondidas. (Por supuesto, en una aplicación real le dices al usuario que ingrese algo, pero espero que entiendas la idea)

'' = '' produce TRUE que satisface la condición WHERE

NULL = NULL produce NULL que no satisface la condición WHERE

Lo que es mejor usar depende del resultado que desea obtener.

Si sus valores son por defecto NULL , ninguna consulta como esta:

 SELECT * FROM mytable WHERE col1 = ? 

alguna vez devolverá estos valores, incluso si pasa el valor NULL para el parámetro enlazado, mientras esta consulta:

 SELECT * FROM mytable WHERE col1 = '' 

le devolverá las filas que estableció en una cadena vacía.

Esto es cierto para MySQL , pero no para Oracle , que no distingue entre cadenas vacías y NULL .

En Oracle , la última consulta nunca devolverá nada.

Utilizar “”. Requiere menos esfuerzo de progtwigción si puede afirmar que las columnas no son nulas. La diferencia de espacio entre estos es trivial.