sql - significa - ¿Debo permitir valores nulos en un esquema db?
sql campo not null (15)
¿Qué buena razón hay para tener / permitir nulos en un esquema de base de datos?
Desde el punto de vista de la teoría, tener un NULL
significa que el valor no está definido para una columna.
Úselo donde sea que necesite decir " No sé / no me importa " para responder la pregunta " ¿Cuál es el valor de esta columna? "
Y aquí hay algunos consejos desde el punto de vista de la performance:
- En
Oracle
, losNULL
no están indexados. Puede guardar el espacio de índice y acelerar las consultas utilizandoNULL
para los valores que no necesita indexar. - En
Oracle
, losNULL
posteriores no ocupan espacio. - A diferencia de los ceros, los
NULL
se pueden dividir de forma segura por. -
NULL
contribuyen enCOUNT(*)
, pero no contribuyen enCOUNT(column)
Sé que, lógicamente, hay algunos casos en los que los valores NULL tienen sentido en un esquema DB, por ejemplo, si no se han especificado algunos valores simples. Dicho esto, trabajar alrededor de DBNull en código tiende a ser un dolor real. Por ejemplo, si estoy renderizando una vista, y quiero ver una cadena, no esperaría que ningún valor fuera una cadena en blanco, no "Nulo", y odio tener que codificar en ese escenario.
Además, facilita las consultas. Es cierto que puede hacer "foo no es nulo" muy fácilmente, pero para los desarrolladores SQL menores, es contrario a la intuición no poder usar "foo! = Null" (y sí, sé sobre las opciones para desactivar ANSI nulos, etc. , pero definitivamente NO es más simple, y no me gusta trabajar fuera del estándar).
¿Qué buena razón hay para tener / permitir nulos en un esquema de base de datos?
Además de las grandes razones mencionadas en otras respuestas, NULL puede ser muy importante para las nuevas versiones de productos existentes.
Agregar una nueva columna Nullable a una tabla ya existente tiene un impacto relativamente bajo. Agregar una nueva columna no anulable es un proceso mucho más complicado debido a la migración de datos. Si usted o sus clientes tienen muchos datos, el tiempo y la complejidad de la migración pueden convertirse en un problema importante.
CJ Date en su libro "SQL and Relational Theory" (2009: O''Reilly; ISBN 978-0-596-52306-0) toma una posición muy fuerte contra Nulls. Demuestra que la presencia de NULL en SQL da respuestas incorrectas a ciertas consultas. (El argumento no se aplica al modelo relacional en sí porque el modelo relacional no permite valores NULL).
Trataré de resumir su ejemplo en palabras. Presenta una tabla S con atributos SNO (Número de proveedor) y Ciudad (Ciudad donde se encuentra el proveedor) y una fila: (S1, Londres). También una tabla P con atributos PNO (Número de parte) y Ciudad (Ciudad donde se produce la parte) y una fila: (P1, NULO). Ahora hace la consulta "Obtener (SNO, PNO) pares donde el proveedor y las ciudades de la parte son diferentes o la parte de la ciudad no es París (o ambas)".
En el mundo real, P1 se produce en una ciudad que es o no es París, por lo que la consulta debe regresar (S1, P1) porque la ciudad de la parte es París o no es París. (La mera presencia de P1 en la tabla P significa que la parte tiene una ciudad asociada, incluso si no se conoce). Si es París, entonces las ciudades proveedoras y las ciudades parciales son diferentes. Si no es París, entonces la parte de la ciudad no es París. Sin embargo, según las reglas de la lógica de tres valores, (''London'' <> NULL) se evalúa como UNKNOWN, (NULL <> ''Paris'') se evalúa como UNKNOWN, y UNKNOWN o UNKNOWN se reduce a UNKNOWN, que no es TRUE (y no FALSO tampoco), por lo que la fila no se devuelve. El resultado de la consulta "SELECT S.SNO, P.PNO FROM S, P WHERE S.CITY <> P.CITY O P.CITY <> ''Paris''" es una tabla vacía, que es la respuesta incorrecta.
No soy un experto y no estoy actualmente equipado para tomar el pro o el contra aquí. Considero que CJ Date es una de las principales autoridades en teoría relacional.
PS También es cierto que puede usar SQL como algo más que una base de datos relacional. Puede hacer muchas cosas.
Cuando hay una entidad que no tiene ningún valor para su atributo, entonces usamos un valor nulo. Un valor nulo no es 0, pero no tiene valor. Un ejemplo es que la mayoría de los nombres coreanos no tienen segundo nombre. Si hay un atributo de nombre con nombre, medio y apellido, se debe dar un valor especial nulo.
En teoría, no hay diferencia entre la teoría y la práctica. En la práctica, existe.
En teoría, puede diseñar una base de datos que nunca necesite un NULL, porque está completamente normalizada. Siempre que se omita un valor, se puede omitir toda la fila que lo contiene, por lo que no es necesario ningún NULL.
Sin embargo, el grado de descomposición de la tabla que debe atravesar para obtener este resultado simplemente no vale la pena desde el aspecto de la estética teórica. A menudo es mejor dejar que algunas columnas contengan NULLS.
Los buenos candidatos para columnas que aceptan nulos son aquellos en los que, además de los datos que son opcionales, nunca se usa la columna en una condición de comparación en una cláusula WHERE o HAVING. Créalo o no, las claves externas a menudo funcionan bien con NULLS en ellas, para indicar una instancia de una relación que no está presente. INNER JOINS soltará los NULLS junto con las filas que los contienen.
Cuando un valor se usa a menudo en condiciones booleanas, es mejor diseñar para que no ocurra NULLS. De lo contrario, es probable que termine con el misterioso resultado de que, en SQL, el valor de "NO DESCONOCIDO" es "DESCONOCIDO". Esto ha causado errores para un número de personas antes que usted.
Estoy de acuerdo con la mayoría de las respuestas aquí, pero para darle una nueva forma, "no puedes tener un valor que signifique dos cosas". Es simplemente confuso. ¿0 significa realmente 0? o significa que aún no lo sabemos? etc.
Generalmente, si permite NULL para una columna en una base de datos, ese valor NULL tiene un significado separado con respecto a la estructura de la base de datos. Por ejemplo, en el esquema de base de datos de , NULL para la columna ParentId o etiquetas en la tabla Publicar indica si la publicación es una pregunta o una respuesta. Solo asegúrate de que, en cada caso, el significado esté bien documentado.
Ahora su queja particular es sobre el manejo de estos valores en el código del cliente. Hay dos formas de mitigar el problema:
La mayoría de los casos con un significado como el descrito anteriormente nunca deberían volver al cliente en primer lugar. Use NULL en sus consultas para recopilar los resultados correctos, pero no devuelva la columna NULL.
Para los casos restantes, generalmente puede usar funciones como COALESCE () o ISNULL () para devolver algo que es más fácil de procesar.
La razón más importante para permitir NULLS es que no hay una alternativa razonable. Lógicamente, un valor NULL representa "indefinido". Por falta de NULLS, terminará tratando de especificar un valor "ficticio" siempre que el resultado no esté definido, y luego deberá contabilizar dicho valor "ficticio" en TODA la lógica de su aplicación.
Escribí un artículo de blog sobre los motivos para incluir valores NULL en su base de datos. Puedes encontrarlo here . En resumen, ESTOY creyendo que los valores NULL son una parte integral del diseño de la base de datos, y deben usarse cuando corresponda .
Los nulos deben y deben usarse cada vez que la información no esté disponible en el momento en que se ingresan los datos originales (Ejemplo, fecha de envío en un pedido).
Ciertamente hay situaciones en las que los nulos pueden indicar la necesidad de rediseñar (una tabla que consiste principalmente en entradas nulas en la mayoría de los campos probablemente no esté normalizada correctamente, probablemente no se necesite un archivo que contenga todos los valores nulos).
No utilizar nulos porque los desarrolladores de jr no los entienden correctamente indica que tiene un problema mayor que los nulos. Cualquier desarrollador que no entienda cómo acceder a los datos que incluyen nulos, debe recibir capacitación básica en SQL. Esto es tan tonto como no usar disparadores para imponer reglas de integridad de datos porque los desarrolladores se olvidan de mirarlos cuando hay un problema o no usan combinaciones porque los desarrolladores no los entienden o usan select * porque los desarrolladores son demasiado perezosos para agregar los nombres de los campos.
Los nulos son buenos cuando su columna realmente puede tener un valor desconocido que no tiene valor predeterminado. No podemos responder si su columna se aplica a esa regla.
por ejemplo, si tiene una fecha de finalización y puede estar tentado de poner en datetime.maxvalue como el valor predeterminado isntead de null. es completamente válido, pero debes tener en cuenta los informes que se realizan sobre eso y cosas por el estilo.
NUNCA hay un caso donde NULL tenga sentido lógicamente. NULL no es parte del modelo relacional, y la teoría relacional no tiene un concepto como NULL.
NULL es "útil", en el sentido de que los malos DBMS no le dejan más remedio que usarlo, en el nivel FÍSICO, que esos mismísimos DBMS mismos confunden gravemente con el nivel lógico y obligan más o menos a sus usuarios a hacer lo mismo.
Por lo que vale, SQL-99 define un predicado IS [NOT] DISTINCT FROM
que devuelve verdadero o falso, incluso si los operandos son NULL.
foo IS DISTINCT FROM 1234
Es equivalente a:
foo <> 1234 OR foo IS NULL
Soporte de PostgreSQL, IBM DB2 y Firebird IS DISTINCT FROM
.
Oracle y Microsoft SQL Server no (todavía).
MySQL tiene su propio operador <=>
, que funciona como IS NOT DISTINCT FROM
.
Razones para tener nulos
- Es una práctica aceptada, y todos los que trabajan en la base de datos saben cómo funcionan los nulos.
- Muestra claramente que hay una ausencia de un valor.
Un nulo es útil siempre que necesite especificar que no hay ningún valor.
En su lugar, podría usar un número mágico, pero es más intuitivo manejar nulos que manejar valores mágicos, y es más fácil recordar qué valor manejar. (Hm ... ¿fue -1 o 99999 o 999999 ese fue el valor mágico ...?)
Además, los valores mágicos no tienen ninguna magia real, de todos modos no hay falla para evitar que uses el valor. La computadora no sabe que no se puede multiplicar 42 por -1 porque -1 resulta ser un valor irrazonable en esta situación, pero sabe que no se puede multiplicar 42 por nulo.
Para un valor de texto, una cadena vacía puede funcionar como "sin valor", pero hay algunos inconvenientes incluso allí. Si, por ejemplo, tiene tres espacios en un campo, no siempre es posible distinguir visualmente de la cadena vacía, pero son valores diferentes.