Solución:
Bien por ti, por eliminar Nulls. Nunca he permitido Nulls en ninguna de mis bases de datos.
Por supuesto, si se prohíben los nulos, la información faltante tendrá que manejarse por otros medios. Desafortunadamente, esos otros medios son demasiado complejos para ser discutidos en detalle aquí.
En realidad, no es tan difícil. Hay tres alternativas.
-
Aquí hay un artículo sobre Cómo manejar la información faltante sin usar NULL por H Darwen, eso puede ayudar a entender el problema.
1.1. Sexta Forma Normal es la respuesta. Pero no tienes que normalizar tu completo base de datos a 6NF. Para cada columna que es opcional, necesita una tabla secundaria fuera de la tabla principal, con solo el PK, que también es el FK, porque es una relación 1 :: 0-1. Aparte del PK, la única columna es la columna opcional.
Mira esto Modelo de datos;
AssetSerial
en la página 4 es un caso clásico: no todosAssets
tengoSerialNumbers
; pero cuando lo hagan, quiero que los almacenen; más importante, quiero asegurarme de que sean únicos.(Para la gente de OO, dicho sea de paso, es un diagrama de clases de tres niveles en notación relacional, una “herencia de tabla concreta”, no es gran cosa, lo hemos tenido durante 30 años).
1.2. Para cada una de estas tablas, use una Vista para proporcionar la forma 5NF de la tabla. Claro, use Nulo (o cualquier valor que sea apropiado para la columna) para identificar la ausencia de la columna para cualquier fila. Pero no actualice a través de la vista.
1.3 No utilice juntas rectas para agarrar la columna 6NF. Tampoco use combinaciones externas (y haga que el servidor complete un Nulo para las filas que faltan). Use una subconsulta para completar la columna y especifique el valor que desea que se devuelva para un valor faltante (excepto si tiene Oracle, porque su procesamiento de subconsultas es incluso peor que su procesamiento establecido). P.ej. y solo un eg. puede convertir una columna numérica en una cadena y usar “Falta” para las filas que faltan.
Cuando no quieras llegar tan lejos (6NF), tienes dos opciones más.
-
Puede utilizar sustitutos nulos. Yo uso CHAR (0) para columnas de caracteres y 0 para numérico. Pero no lo permito para los FK. Obviamente, necesita un valor que esté fuera del rango normal de datos. Esto no permite la lógica de tres valores.
-
Además de (2), para cada columna que acepta valores NULL, necesita un indicador booleano. Para el ejemplo de la
Sex
columna, el indicador sería algo así comoSexIsMissing
oSexLess
(perdón). Esto permite una lógica de tres valores muy ajustada. A muchas personas en ese 5% les gusta porque la base de datos permanece en 5NF (y menos tablas); las columnas con información faltante se cargan con valores que nunca se utilizan; solo se utilizan si el indicador es falso. Si tiene una base de datos empresarial, puede envolverla en una función y usar siempre la UDF, no la columna sin formato.
Por supuesto, en todos los casos, nunca puede dejar de escribir el código necesario para manejar la información que falta. Si se trata de ISNULL()
, o una subconsulta para la columna 6NF, o un indicador para verificar antes de usar el valor, o una UDF.
Si Nulo tiene un significado específico … ¡entonces no es un Nulo! Por definición, Nulo es el valor desconocido.
Entonces, ¿cómo se diseña sin NULLS? Esa fue la pregunta original.
De hecho, es bastante fácil. Usted diseña de tal manera que siempre que tenga que dejar algunos datos faltantes, puede hacerlo dejando una fila completa. Si una fila no está allí, no es una fila llena de NULL. Simplemente no está ahí.
Entonces, en el caso de “DateOfDeath”, tenemos una tabla con dos columnas, a saber, PersonId y DateOfDeath. PersonId hace referencia al Id en la tabla Personas. Si no hay DateOfDeath para almacenar, no almacenamos la fila. Fin de la discusión.
Si realiza un OUTER JOIN entre esto y la tabla de Personas, obtendrá un NULL para DateOfDeath donde no haya una fila. Y si usa esto en una cláusula where, obtendrá el comportamiento desconcertante habitual con respecto a la lógica de 3 valores. Si realiza una INNER JOIN, las filas para las que no hay DateOfDeath simplemente desaparecerán de la combinación.
Un diseño que permite que todas las columnas se apliquen NOT NULL se ha denominado sexta forma normal.
Habiendo dicho todo eso, a menudo permito NULL en columnas no críticas. Y no tengo una manera sucinta de decirles cómo puedo determinar que una columna es crítica.
Simplemente almacenando solo la información conocida, en otras palabras, el supuesto del mundo cerrado. Trate de estar al menos en Boyce Codd / Fifth Normal Form y no se equivocará mucho.