Como estudiante de CS, he aprendido un buen número de lenguajes de programación a lo largo de los años, la mayoría de los cuales han tenido algún concepto de tipo "anulable" u "opcional". Tenga en cuenta que estoy no hablar de punteros nulos o referencias, o lenguajes de tipo débilmente como JavaScript donde todo puede ser null
. Los ejemplos de lo que estoy hablando incluyen boost::optional
(C ++), java.util.Optional
(Java 8.0), prelude.Maybe
(Haskell) y todos los '?' tipos (por ejemplo int?
, float?
C # y Kotlin). Estas son construcciones que agregan nulabilidad a un tipo previamente no anulable dentro de un sistema de tipo estricto y estático.
SQL tiene un concepto similar: un tipo como INTEGER
puede ser anulable o no anulable, pero hay un giro. En SQL, INTEGER
es anulable de forma predeterminada y debe escribirse explícitamente INTEGER NOT NULL
para que no sea anulable.
Me parece extremadamente contra-intuitivo y potencialmente peligroso por permitir que los NULL sean el comportamiento predeterminado. Obviamente, SQL ha existido durante tanto tiempo en este punto que (la mayoría) de los desarrolladores de SQL han desarrollado una conciencia saludable de las trampas de NULL. Pero no puedo evitar imaginar que en los primeros días, NULL a menudo se arrastraba en lugares inesperados y problemáticos.
SQL es anterior a todos los ejemplos que he proporcionado, por lo que es posible que esto sea simplemente una cuestión de evolución histórica. Aún así, tengo que preguntar, ¿hay alguna buena razón para que el lenguaje se diseñe de esta manera, con tipos que se anulan por defecto?
Si es así, ¿es solo una razón histórica, o la lógica se mantiene hoy en día para el diseño de la base de datos?
Editar: no estoy preguntando por qué NULL es parte de SQL o por qué las columnas anulables son útiles. Solo estoy preguntando por qué las columnas son anulables por defecto . Por ejemplo, por qué escribimos:
column1 FLOAT,
column2 FLOAT NOT NULL
Más bien que:
column1 FLOAT NULLABLE,
column2 FLOAT
fuente
Respuestas:
En Uni me enseñaron que lo contrario es cierto. Es mucho más peligroso hacer algo
not null
sin razón. Con un campo anulable, lo peor que puede suceder es que se tropiece con la aplicación para acceder a los datos. Oh querido, vuelve y arregla la aplicación ...Con un campo no nulo, hace que sea imposible agregar un registro porque algún campo arbitrario no está disponible. Ahora necesita cambiar el modelo de datos y potencialmente corregir el resultado en MUCHOS lugares diferentes ...
Es bueno pensar que
null
es "desconocido". Si hay alguna razón plausible por la que desee ingresar un registro sin saber algo, entonces debe ser anulable.Uno de mis profesores universitarios lo describió así:
En la práctica, reserve
not null
para los campos que deben tener sentido para el registro. Por ejemplo:Una tabla de lugares con campos (ID, Nombre del lugar, País, Longitud, Latitud) ... "longitud" "latitud" debe ser anulable para que pueda almacenar la existencia de un lugar antes de saber dónde está.
Pero si tiene una tabla cuyo único propósito es almacenar coordenadas geográficas con campos (Item_id, longitud, latitud), el registro completo no tiene sentido si la longitud y la latitud son nulas. Por lo tanto, en este caso no deberían ser nulos
En mi experiencia profesional desde la universidad, hay muchos más campos que pueden ser opcionales que obligatorios.
fuente
La intuición está en el ojo del espectador y su opinión al respecto está determinada por las cosas a las que ha estado expuesto. Saludo de una época en que ese tipo de seguridad no era estándar y las herramientas no señalaban cuándo te burlabas. He estado usando la motosierra sin un protector de cuchilla el tiempo suficiente para que mi primer instinto sea evitar por completo la intuición, volver al DDL y descubrir exactamente qué suposiciones me permitirá hacer el esquema sobre sus datos.
Creo que estás exagerando los peligros relativos.
NOT NULL
tiene su propio conjunto de trampas que pueden conducir a errores igualmente insidiosos. (Enumerarlos sería un forraje para una pregunta diferente).El diseñador de una mesa siempre tiene la opción de restringir una columna
NULL
oNOT NULL
y hará uno o el otro para moverse por la omisión, lo que sea. No restringir una columna correctamente es una falla del desarrollador en seguir las reglas de negocio. No hacer lo correcto en otra parte según la definición de la columna es la incapacidad del desarrollador de comprender los datos que le están entregando. No hay solución técnica para ninguno de los dos.No, no hay Debido a que ambos tienen riesgos, tampoco hay una buena razón para que el lenguaje se diseñe de otra manera. Se reduce a recoger tu veneno.
fuente
Las columnas anulables son necesarias en SQL debido a las combinaciones externas (también conocidas como combinaciones izquierdas o derechas). Cuando la fila en un lado de la unión no tiene coincidencia en el otro lado, los campos para el otro lado deben tener NULL. Dado que la salida de una combinación puede tener columnas anulables, las tablas base también deberían admitirlas debido al principio de cierre relacional (que básicamente indica que el resultado de una consulta o vista no se puede distinguir de una tabla base).
Dado esto, SQL debe admitir columnas anulables. Por otro lado, las columnas no anulables son una característica secundaria: SQL aún podría funcionar sin ellas.
fuente
Vamos a darle la vuelta y decir que tienes razón. Digamos que su número entero no es nulo por defecto.
Lo que significa que tiene que tener un valor por defecto. Incluso cuando no se sabe.
Entonces, cuando actualiza su tabla de personas y tiene dos opciones: es imposible actualizar la tabla porque no ingresó el peso. O cuando no proporcionó el argumento del peso, lo puso en el estándar "-1 kilos" cuando se desconoce.
Ambas situaciones son indeseables. Desea poder agregar clientes, incluso si no conoce su peso. Pero tampoco quiere tener valores "proxy". Valores que son marcadores de posición pero que pueden tener un significado real, por ejemplo: se pueden usar en funciones matemáticas como "promedio" pero no son valores reales.
Quiero decir que al calcular un peso promedio, -1 es un valor válido en su función promedio de matemáticas, pero no como el peso de una persona. Utiliza nulo y ahora su función promedio sabe ignorar ese valor.
Además, realmente no compararía SQL con los lenguajes de programación cuando se discuten los nulos, son inherentemente diferentes, nulo en SQL es en gran parte parte de la teoría del diseño de bases de datos relacionales.
fuente
No. No hay una razón convincente por la que SQL se predetermina a nula De hecho, muchos investigadores prominentes en la teoría de bases de datos relacionales no están de acuerdo con esta decisión de diseño, quizás especialmente Chris Date , un colaborador frecuente con el diseñador original de la base de datos relacional, Edgar Codd . Date (junto con el coautor Hugh Darwen) publicó un conocido libro sobre teoría relacional (" The Third Manifesto ") que describe los principios para diseños alternativos para una familia de lenguajes relacionales que llaman "D", junto con un ejemplo de lenguaje llamado " Tutorial D ".
Los lenguajes D se prohíben explícitamente de admitir valores NULL ("D no incluirá ningún concepto de una" relación "en la que alguna" tupla "incluya algún" atributo "que no tenga un valor"). En cambio, los valores opcionales son compatibles al tener tipos de datos alternativos que incluyen marcadores de posición "no presentes" o valores similares. Los lenguajes D proporcionan un modelo rico para tipos definidos por el usuario que permitiría ampliar cualquier tipo nativo con tales valores adicionales.
Hay razones teóricas convincentes por las cuales esta es una buena idea, y Date & Darwen han escrito mucho sobre esto, así como sobre las otras decisiones que tomaron en su diseño. Recomiendo leer su trabajo sobre este tema.
fuente
Representing x with null is a bad idea
no infiere esoallowing x by default is bad
. Ergo, eso no implica esoallowing null by default is bad where null is the only available representation of x
Not Present = Not Present
donde ni en SQLnull = null
onull != null
son verdaderas.No estoy en desacuerdo con su premisa sobre cuál debería ser el valor predeterminado, pero es una buena práctica no asumir nada como desarrollador. Verificar las especificaciones en una tabla de base de datos no debería ser demasiado difícil.
Más desde una perspectiva de DBA donde se le pedirá que cargue datos en masa, especialmente cuando se fusiona desde otros sistemas, es mejor que conozca la configuración de cada campo, ya sea que tenga algún dato que agregar o no.
Las empresas y las aplicaciones están a cargo de personas. Si no son programadores, la definición de "nunca" y "siempre" no es exactamente la misma y cambiará con el tiempo. La configuración nula actual en un campo dado no debe ser difusa.
fuente
Las bases de datos son diferentes bestias de los lenguajes de programación normales.
Debido a que el esquema de una tabla está configurado, todos los datos deben estar presentes al guardar la información en una fila. Sin embargo, muchos de estos datos pueden no ser necesarios para crear una representación válida de un objeto modelo una vez cargado en su código. Exigir que todos los datos no sean nulos y estén llenos significará que estos campos no obligatorios tendrán que contener un valor y aún no tienen uno, son "desconocidos".
Imagine tener que llenar TODOS los campos en los formularios web TODO el tiempo, ya que no pueden ser nulos en la base de datos, deben recibir un valor ... ¡una receta para la locura!
Puede establecer algunos valores reservados para representar la ausencia de datos, una cadena vacía, un número específico, una fecha específica, etc., dependiendo del tipo de datos, pero ¿qué valor elegir? Luego debe asegurarse de que todos estén de acuerdo en que estos valores arbitrarios en realidad significan "desconocido" y no "1 de enero de 1970", por ejemplo. La aversión nula puede tomar muchas formas y llevarte a desvíos largos y complicados solo porque alguien dijo que los nulos eran malos. ¿Qué tan complejo estás listo para ser solo para evitar tratar con nulos?
Tener un único valor universal para todo lo que se desconoce me parece mucho más preferible que usar algún conjunto de valores constantes arbitrarios. No digo que los valores constantes sean malos y nulo es mejor, si su modelo está bien servido por una constante para representar esta información, entonces utilícela por todos los medios, pero hay muchas situaciones en las que un nulo es lo que mejor se ajusta. Para todos los que odian a los nulos, ¡esta es una situación en la que si se niega la nulidad, tendría que inventarse!
Al ver cuán generalizado es el concepto de "desconocido" en una base de datos, entonces sí, diría que hacer que los valores sean anulables por defecto tiene mucho sentido.
Profundizando y mirando otras respuestas aquí, no me sorprendería saber que los nulos no son solo una "característica del lenguaje" sino una parte integral de la teoría subyacente en la que se basa SQL. Uno puede eliminar C (la velocidad de la luz) de la relatividad, pero el concepto de velocidad máxima absoluta permanece y aún debe expresarse para que regrese de alguna forma.
fuente
Respuesta corta: compatibilidad con versiones anteriores.
Respuesta larga:
En una base de datos totalmente normalizada, NULL no está permitido en ninguna columna. Por ejemplo, suponga que hay una tabla llamada MailingAddress que tiene una columna PostOfficeBox, que es un número entero. Como no todos tienen un apartado postal, hay dos formas de implementarlo.
Primero, NULL podría permitirse en la columna.
En segundo lugar, PostOfficeBox se elimina de MailingAddress y se crea una nueva tabla, PostOfficeBox con un número de columna y su PK es el FK de MailingAddress. Pero ahora se necesitan dos consultas para obtener direcciones de correo: una para aquellos que no tienen apartados de correos y otra para aquellos con.
SQL permite NULL en columnas para fines prácticos.
fuente