¿Hay alguna razón convincente por la cual las columnas en SQL son anulables por defecto?

8

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 INTEGERpuede ser anulable o no anulable, pero hay un giro. En SQL, INTEGERes anulable de forma predeterminada y debe escribirse explícitamente INTEGER NOT NULLpara 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
Acercarse Oscuridad Peces
fuente
2
Aprenda a aceptar esta respuesta: "No hay razón, es solo nuestra política".
2
Porque a veces el concepto de "No sé" debe representarse en la base de datos de manera clara
Newtopian
@Newtopian que explica por qué NULL está en el idioma. Me pregunto por qué NULL tiene columnas permitidas de manera predeterminada.
ApproachingDarknessFish
44
Porque "No sé" es sorprendentemente común en la información de la base de datos. Para ilustrar este punto con un ejemplo. Imagine formularios web donde TODOS los campos son obligatorios de forma predeterminada y lo molesto que sería. En una base de datos, DEBE completar CADA campo con algo, siempre. Sin embargo, en su representación de dominio es muy probable que mucha de esta información no sea esencial y pueda quedar "desconocida" sin efectos negativos (siempre que proteja su código correctamente). De hecho, apostaría a que, en la mayoría de las aplicaciones, la mayor parte de la información cae en esta categoría no esencial, de ahí el valor predeterminado visto
Newtopian,
@Newtopian bien. Haz esa respuesta.
ApproachingDarknessFish

Respuestas:

24

En Uni me enseñaron que lo contrario es cierto. Es mucho más peligroso hacer algo not nullsin 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 nulles "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í:

Apocryphally He oído hablar de un sistema de ventas en los EE. UU. Que requería el número de seguro social del cliente para realizar una venta. Todos los operadores de cajas registradoras cuando un extranjero acudía a la caja registradora ingresaba 000-00-0000. Pero luego otros entrarían 123-45-6789. Esto hace que sea imposible identificar basura. Es mucho mejor permitir que un campo esté en blanco que forzarlo a contener basura.

U otra historia. Realmente me negaron el seguro de automóvil porque no tengo dos números de teléfono. Absolutamente no me darían seguro a menos que les diera dos. El vendedor me sugirió que diera uno falso. Al final me negué a mentirle a una aseguradora y simplemente fui con otra compañía.

En la práctica, reserve not nullpara 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.

Philip Couling
fuente
¿A quién estás citando en el bloque de cotizaciones anterior?
Robert Harvey
Profesor universitario.
Philip Couling
8

Me parece extremadamente contra-intuitivo ...

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.

... y potencialmente peligroso por permitir que los NULL sean el comportamiento predeterminado.

Creo que estás exagerando los peligros relativos. NOT NULLtiene 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 NULLo NOT NULLy 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.

Aún así, tengo que preguntar, ¿hay alguna buena razón para que el lenguaje se diseñe de esta manera, y los tipos se anulan de forma predeterminada?

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.

Blrfl
fuente
6

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.

JacquesB
fuente
4

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.

Pieter B
fuente
3

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.

Jules
fuente
1
No sigo / no estoy de acuerdo con tu lógica. Creo que estás combinando dos cuestiones separadas. Problema a) ¿ debería un lenguaje representar nulo? Problema b) en un lenguaje que usa nulo para significar "no presente", ¿deberían los campos permitir nulo (no presente) por defecto? Quizás haya omitido un paso en su respuesta ... ¿Hay un elemento c) en D, los atributos no deben permitir la
ausencia
2
Mi primer comentario es difícil de seguir, así que lo diré simplemente: Representing x with null is a bad ideano infiere eso allowing x by default is bad. Ergo, eso no implica esoallowing null by default is bad where null is the only available representation of x
Philip Couling
1
@jules ¿cuál es la diferencia conceptual entre un campo int que puede ser anulado y un campo int que tiene un tipo de datos alternativo: 'no presente'? ¿No es lo mismo con un nombre diferente? Null también es un tipo de datos alternativo a int.
Pieter B
1
@PieterB Sí y no. El problema fundamental de nulo es que se usa para significar muchas cosas diferentes. En SQL podría significar "no existe" o podría significar "desconocido". El argumento D es que todos estos deberían estar claramente definidos y nunca debería usarse un "nulo" general. No haber estudiado en detalle, sospecho que los defensores de D abogaríamos Not Present = Not Presentdonde ni en SQL null = nullo null != nullson verdaderas.
Philip Couling
Codd dijo que debería haber más tipos de Null, creo que propuso 4 inicialmente y luego se amplió a 17. Los programadores dijeron: ¿Por qué estamos desperdiciando esfuerzos para distinguir las formas de decir "No sé"? Claro, hay incógnitas conocidas e incógnitas desconocidas, pero en realidad, los datos son conocidos, y no mucho más.
1

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.

JeffO
fuente
Correcto, la carga masiva, la migración, etc. eventualmente superan todas las demás preocupaciones, porque los datos son lo que es real y de valor, y los programas son solo herramientas temporales que le dan forma. ¿Alguien ha visto una tarjeta perforada o las máquinas de grabación del censo de 1900? No, pero los datos aún están disponibles. ¿Cuántas veces se ha movido de un sistema a otro, incluso en el último año? Cada vez que alguien lo usa, supongo.
0

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.

Newtopian
fuente
0

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.

Shawnhcorey
fuente