¿Razón para no usar números anulables en Oracle?


12

Nuestra compañía está interactuando con otra compañía de software para un proyecto conjunto, y nos dijeron que, si no se mostrara un valor particular, deberíamos pasar un -5000 (su valor arbitrario centinela); la razón es que ninguna columna de números en su base de datos Oracle admite valores nulos, por recomendación de su (ahora anterior) desarrollador de Oracle. Esta compañía también escribe la gran mayoría de su código en VB6 (haciendo una transición lenta a VB.NET, que es otro tema para otro día ...). Por pura curiosidad, ¿hay alguna razón válida para esta recomendación? No puedo pensar en ninguno de mi lado.

--- editar

Gracias por los comentarios a todos. Planteé la misma pregunta en CodeProject.com ( enlace ) y recibí comentarios muy similares. Parece que la única vez que uno podría comenzar a justificar esta práctica está relacionada con las claves externas, y puedo afirmar que no utilizan claves externas en ninguna parte del sistema. El desarrollador que hizo esta determinación (solía trabajar en esa compañía) tiene mucha más experiencia que yo, así que quería asegurarme de que no hubiera una razón válida para esto antes de que surja la burla.


2
¿Quiere decir, aparte de "eso es lo que especifica su API"?
Robert Harvey

Sí, tengo más curiosidad acerca de por qué su API lo especificaría en primer lugar; ¿Hay alguna razón para esta práctica, o es solo una locura?

3
¡Locura del más alto orden!
Philᵀᴹ

Respuestas:


17

Siendo realistas, el requisito es una locura. Sin embargo, como todas las grandes ideas locas, es probable que se base en una pepita de razonabilidad potencial que las personas que no entienden la lógica subyacente están fuera de contexto.

Puede ser razonable diseñar un esquema de base de datos de manera que no NULLse permitan valores. Sin embargo, si lo hace, se compromete a un nivel de normalización en el que cada elemento no requerido se divide en una tabla separada con una referencia de clave externa adecuada de nuevo al padre. No se hace a menudo en la práctica, pero en los casos en que tiene sentido hacerlo, puede haber beneficios.

Si va a diseñar un esquema de base de datos de manera que no NULLse permitan valores, no tiene sentido permitir, y mucho menos, requerir valores mágicos para indicar que algo es desconocido. Eso introduce todos los problemas que tiene permitir NULLvalores, además agrega un código adicional para verificar los valores mágicos que deben repetirse en todo el lugar. No tiene sentido desarrollar una API que requiera que se pasen valores mágicos independientemente del diseño de la base de datos; si va a obstaculizar su código con comprobaciones de valores mágicos, realmente no debe dejar que esa locura se propague a otros sistemas .


+1 y el código adicional para verificar los valores mágicos no pueden usar funciones conocidas como COALESCE(), por lo que se vuelve aún más complicado.
ypercubeᵀᴹ

Y los valores deben almacenarse en cualquier índice de esa columna. Los índices no tienen que almacenar valores nulos.
Tripp Kinetics

15

No hay razón válida para usar un valor mágico en lugar de NULL. Este podría ser el proceso de pensamiento de alguien creando este desastre. Escriben algo como esto:

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

Cuando esto no devuelve los resultados que esperan, se dan cuenta de que no incluye NULL y necesitarían escribir esto:

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

No quieren escribir u olvidar en el futuro escribir esto, por lo que se les ocurre la solución de hacer todos los NULLS -5000. Mágicamente, su consulta original maneja NULL sin ningún cambio. De lo que no se dan cuenta es que ahora alguien que quiere excluir estos valores tiene que escribir esto:

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

O si querían estos valores y están buscando un rango más alto:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

También pueden no darse cuenta de que lo siguiente ya no sería significativo:

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

En cambio, una persona tiene que recordar el valor mágico. Con cada tipo de datos utilizado, deben recordar más valores mágicos, por ejemplo, 1/1 // 1900, "Z", -5000. Además, cuando el valor mágico está en los datos, también deben recordar valores mágicos alternativos.

Entonces, para un caso específico, simplifica el código a expensas de otros casos, sin mencionar el espacio en disco, el tamaño del índice, el análisis de consultas, la coherencia, etc.


8

Es una locura absoluta y no hay justificación para ello. NULLfue creado para representar la ausencia de un valor y usar un valor real como -5000 es loco.

Por lo general, no escribiría una respuesta tan breve, pero la pregunta merece ser una de las más visibles en dba.se y cuantas más respuestas, mejor.


5

Pensé en esto por un momento tratando de ser positivo y justificar la necesidad de usar un valor arbitrario en lugar de un valor nulo y parece que (al menos para mí) no hay una razón válida para esto, excepto quizás en un conjunto de datos de minería de datos cerrado para mejorar y simplificar el rendimiento y las consultas, y solo en los casos en que los números no sean valores que puedan sesgar los datos. Incluso esto debería ser considerado cuidadosamente. En todas las situaciones del mundo real, dar un valor a nulo no es una buena práctica. Esto convierte una definición de columna NOT NULL de tu amigo a tu enemigo, ya que realmente no es cierto.

Es una cosa muy diferente decir que nuestra aplicación no debería aceptar un valor NULO para algunas (o incluso todas) columnas. Esta es una práctica sensata y buena, y existen beneficios bien documentados al no permitir nulos (claves e índices y cálculos estadísticos, por ejemplo). Sin embargo, asignar un valor para "sentarse en el lugar" de un valor nulo no es lo mismo. Es la barra para su propia espalda, ya que primero debe seleccionar un valor que nunca se usará, filtre este valor como lo haría con el valor nulo y recuerde no usarlo en cálculos y resúmenes y eliminarlo de los datos externos. . Esto es al menos tan malo como usar un valor nulo para representar un valor real, que es lo que te dices a ti mismo que estás evitando, pero no lo eres.

La mayoría de los problemas que causan los nulos, una vez entendidos, pueden tratarse (mejor normalización, índices basados ​​en funciones o mapas de bits o con un simple DONDE x NO ES NULO). ¿Crees que en alguna Telco grande o en Amazon en la reunión de rendimiento mensual algún DBA está delineando este gran plan para acelerar un poco las consultas en sus enormes conjuntos de datos "al reemplazar nulo con un valor arbitrario, algo como -5000, o lo que sea? Estoy abierto al valor ... ". ¿O cree que pasan su tiempo dividido entre un mejor diseño de la aplicación para filtrar los nulos no deseados y la optimización de consultas en función de los datos reales que reciben ? De acuerdo, bien, tal vez una reunión mensual sea un poco optimista, pero cada vez que suceden, puedo asegurarle que "Reemplazar nulos con -5000 (o lo que sea) para una mejor API" no es un tema de la agenda.

Para mí está bien decir que no aceptaré datos faltantes (debe tener una edad o un precio o un código de región o lo que sea) y, a veces, incluso está bien decir que para esta columna hay un valor predeterminado que se ingresará si No pones otra cosa. No está bien dejar de lado un valor que significa nulo. Piense en los campos de segundo nombre como ejemplo. A veces, esto no existirá ya que los padres son demasiado vagos para completar todos los cuadros. ¿Agregamos "ninguno" o "falta" o "desconocido" a nuestros datos para mejorar nuestras búsquedas? No, porque puede haber personas extrañas que cambien sus nombres a estos valores, por lo que cuando imprimimos los datos no sabemos si debemos incluirlos o no. Es un ejemplo simple, pero de largo alcance. Sabemos acerca de NULL y tenemos funciones predecibles incorporadas para manejarlo. No puedes codificar esto mejor.

Si ninguna respuesta (o NULL) no es una respuesta válida a su solicitud de entrada, entonces no la permita en la aplicación o en la base de datos, si es una buena respuesta, debe permitirla tanto en su aplicación como en su base de datos y tratar con Es una respuesta válida. Si es parte de un conjunto de respuestas válidas, su base de datos debe estar diseñada para almacenarla. Después de todo lo que no dices, los campos numéricos son tan aburridos que permite almacenar números en blobs y usar imágenes de animales salvajes para representar cada número, porque eso es loco (genial pero loco). Tampoco decidimos que no nos gusta la letra B, y al igual que una cruel pesadilla de Sesame Street, reemplácela con un # en nuestros datos. Si B no es una respuesta, queremos decirle al usuario "Oye, no puedes poner una B aquí". Entonces, ¿por qué tratar nulo de manera diferente?

Por lo tanto, evite los valores nulos que no desea a nivel de aplicación y trátelos en su base de datos donde los acepte, de lo contrario, tan seguro como giraffe + giraffe = hipopótamo, su disputa de datos sin sentido lo meterá en problemas.


2
Mis padres no eran flojos y, por cierto, no tengo segundo nombre. No todas las personas viven en los Estados Unidos.
ypercubeᵀᴹ

1
Estaba destinado a ser un ejemplo alegre, sin ofender. Por supuesto, hay muchas personas sin segundo nombre (el primer punto) por muchas razones bastante válidas (el punto principal). Nulo en esta columna no le dice nada acerca de por qué faltaba. No estoy seguro acerca de su ángulo geopolítico: no vivo en los Estados Unidos, pero de hecho tengo un segundo nombre. Supongo que es difícil hacer suposiciones basadas en datos faltantes.

No se ofende. Voté tu respuesta en realidad. Creo que has dado en el clavo con tu punto principal de que hay una diferencia entre no aceptar / permitir Nulos en la base de datos y reemplazar Nulos con un valor mágico.
ypercubeᵀᴹ

55
¡Me encantaría que mi segundo nombre fuera "-5000"! : D
Philᵀᴹ
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.