¿Cómo un apellido de nulo causa problemas en muchas bases de datos?

71

Leí un artículo en la BBC. Uno de los ejemplos que dijeron fue que las personas con el apellido 'Null' están teniendo problemas para ingresar sus datos en algunos sitios web.

No se da ninguna explicación sobre el error al que se enfrentan.

Pero hasta donde yo sé, la cadena 'Nulo' y el valor Nulo real es completamente diferente (desde el punto de vista de la base de datos).

¿Por qué esto causaría problemas en una base de datos?

Nitish
fuente
2
Este es un artículo de blog algo famoso sobre los supuestos que los programadores hacen sobre los nombres, escrito por una de las personas citadas en ese artículo de la BBC: kalzumeus.com/2010/06/17/…
Jörg W Mittag
12
Relevante xkcd
Restablecer Monica
44
La primera vez que vi a este tipo en la televisión supuse que era un error de la base de datos. Entonces descubrí que en realidad es su nombre.
Nate Eldredge
3
@JarrodRoberson ¿Cómo puede decir que "toda la premisa es falsa", dada la descripción de los problemas que enfrenta "Jennifer Null" y los nombres similares en el enlace que publicó el OP? Es un problema real que enfrentan los usuarios finales reales.
Gort the Robot

Respuestas:

102

No causa problemas en la base de datos. Causa problemas en las aplicaciones escritas por desarrolladores que no entienden las bases de datos. La raíz del problema es que gran parte del software relacionado con la base de datos muestra un registro NULL como la cadena NULL. Cuando una aplicación se basa en la forma de cadena de un registro NULL (probablemente también utilizando operaciones de comparación que no distinguen entre mayúsculas y minúsculas), dicha aplicación considerará que cualquier "null"cadena es NULL. Por consiguiente, esa aplicación consideraría que un nombre Nulo no existe.

La solución es declarar columnas no nulas como NOT NULLen la base de datos y no aplicar operaciones de cadena a los registros de la base de datos. La mayoría de los idiomas tienen excelentes API de bases de datos que hacen innecesarias las interfaces de nivel de cadena. Siempre deben preferirse, ya que cometen otros errores, como la inyección de SQL, menos probable.

amon
fuente
30
Sin embargo, en este caso, si lee el artículo en cuestión, crear un campo de apellido NOT NULLcausará un conjunto completo de problemas para otras personas. "Algunas personas solo tienen un único nombre, no un nombre y apellido".
MikeTheLiar
41
@Darkhogg mucha gente no está de acuerdo conmigo sobre esto, pero creo que los nombres son como direcciones de correo electrónico: no se moleste en validarlos, déle al usuario un único cuadro de texto y permítale poner lo que quiera. Esta es información que si realmente la necesito, la obtendré de una manera que seguramente será correcta.
MikeTheLiar
8
@mikeTheLiar No sé el nombre de esto, pero hay toda una clase de errores que surgen al crear reglas demasiado restrictivas sobre los datos. A menudo verá códigos postales y números de teléfono definidos como numéricos en aplicaciones y bases de datos. Realmente no son números porque no tiene sentido hacer operaciones matemáticas con ellos. Entonces, cuando alguien intenta ingresar una dirección canadiense, está atascado.
JimmyJames
19
@JimmyJames, sí, los códigos postales almacenados como números y, de repente, cualquiera que viva aquí tiene un código postal de base 8. "Si no estás haciendo matemáticas con él, es una cuerda, punto final".
MikeTheLiar
8
@mikeTheLiar. El problema con el tratamiento de nombres como una sola cadena (generalmente preferible, estoy de acuerdo) es cuando hay un requisito para la ordenación alfabética por apellido.
TRiG
13

Para responder a su pregunta específica, hay muchos pasos a lo largo de la cadena de eventos entre un formulario web y la base de datos. Si el apellido Nullse interpreta erróneamente como un NULLvalor, entonces el sistema puede rechazar un nombre perfectamente válido como no válido. Esto puede suceder en la capa de la base de datos como lo explica amon . Por cierto, si este es el problema específico, entonces la base de datos probablemente también esté abierta a la inyección SQL, también conocida como el ataque Bobby Tables . Otro paso en la cadena que podría estar causando problemas es el proceso de serialización .

En general, el artículo trataba sobre un problema mayor. El mundo es un gran lugar desordenado que no siempre se ajusta a nuestras suposiciones. Esto es especialmente evidente cuando intentas internacionalizar tu aplicación. Al final del día, debemos asegurarnos de que nuestras aplicaciones manejen y codifiquen nuestros datos correctamente . Depende de la empresa decidir cuántos recursos dedicamos a respaldar casos extremos cada vez más complicados. Si bien apoyo totalmente ser inclusivo, entenderé si la empresa decide que "el artista conocido formalmente como Príncipe" necesita usar un personaje Unicode para representar su nombre en nuestra base de datos.

Erik
fuente
Es difícil imaginar que esto sea causado por el tipo de interpolación de cadenas inseguras que puede conducir a la inyección de SQL. Si olvida citar la entrada del usuario en una consulta SQL (por ejemplo, INSERT INTO users (first, last) VALUES($first, $last)evalúa a INSERT INTO users (first, last) VALUES(Jennifer, Null)) todos los nombres cuyos nombres no son palabras clave SQL válidas o nombres de columna simplemente arrojarán errores y tampoco tendrán sus registros insertados. La causa debe ser más compleja.
Andrew Medico
@AndrewMedico en su ejemplo de hombre de paja sí, pero hay muchas maneras de hacer las cosas mal. Nunca subestimes el poder de <strike> estupidez <\ strike> ignorancia. La conclusión es que no tenemos idea de cuál es el problema real porque no podemos revisar el código en cuestión
Erik
7

Bueno, antes de que se ingrese en la base de datos, es un elemento DOM, luego una variable de JavaScript que se pasa, se valida y se manipula, luego un valor JSON, luego una variable en cualquier biblioteca JSON de back-end que esté usando, luego se pasa una variable, validado y manipulado en su lenguaje de programación de back-end, luego un elemento de algún tipo de DAO, luego parte de una cadena SQL. Luego, para recuperar el valor, lo hace todo a la inversa. Esos son muchos lugares para que los programadores cometan errores, y generalmente muchos de ellos sin el beneficio de la escritura estática.

Karl Bielefeldt
fuente
2

Lo más probable es que sea un problema de programación. Si observa esta respuesta aquí sobre cómo se pasan los NULL, podría causar fácilmente un comportamiento no deseado si fuera "Mr. Null".

https://stackoverflow.com/questions/4620391/mysql-and-php-insert-null-rather-than-empty-string

Puede ver que si algún elemento de datos se pasó como NULL, los datos se interpolarían como una base de datos nula en la base de datos.

"NULL"! = Base de datos nula

Algunos casos de uso y comportamientos relacionados ...

Digamos que el apellido se marcó en la base de datos como no nulo, ahora cuando se insertan los datos, se interpretará como NULL y fallará la inserción.

Otro caso es digamos que el apellido era anulable en la base de datos. El Sr. NULL se inserta y se transforma en DBNull.Value, que no es lo mismo que "NULL". Después de la inserción no podemos encontrar al Sr. Null porque su apellido no es "NULL" sino que en realidad es un valor nulo de la base de datos.

Entonces, esos serían 2 casos de problemas. Como señala @Amon, las bases de datos en sí mismas no tienen problemas con los nulos, aunque uno debe entender cómo se manejan los nulos en cada instancia de RDMS, ya que habrá diferencias entre los diferentes proveedores.

Jon Raynor
fuente
"Puede ver que si algún elemento de datos se pasó como NULL, los datos se interpolarían como una base de datos nula en la base de datos". - la pregunta SO / respuesta aceptada vinculada no parece mostrar esto?
MrWhite
2

Atribuiría el problema a la programación descuidada y al diseño deficiente de algunas implementaciones de SQL. "Nulo" el nombre siempre debe presentarse e interpretarse con comillas. nulo, el valor de la base de datos, siempre debe presentarse sin comillas; pero al escribir código ad-hoc, es fácil pasar al paradigma de "cualquier cosa servirá" y aceptar cosas que se consideran una cadena en forma sin comillas.

Esto se agrava por el hecho de que otros tipos de datos; los números, por ejemplo, pueden y son aceptados en cualquier forma porque la interpretación es inequívoca.

ddyer
fuente
¿Te refieres a implementaciones deficientes de aplicaciones que usan SQL, seguramente? Ninguna implementación seria de un RDBMS en sí sería vulnerable a esto (¡así como ninguna aplicación seria lo es!)
subrayado_d
0

Un problema, fundamentalmente, es que el término "nulo" se aplica a dos conceptos diferentes de la base de datos, a veces usando el contexto para distinguirlos:

  1. Algo no tiene un valor conocido.
  2. Se sabe que algo no tiene valor

Si bien el contexto a veces puede ser suficiente para distinguir entre esos conceptos, hay momentos en que realmente no lo hace. Si uno usa un registro para contener una consulta de búsqueda, por ejemplo, debería haber una diferencia entre decir "Quiero a alguien por el nombre de [lo que sea], sin apellido", versus "Quiero a alguien cuyo nombre sea [ lo que sea] pero cuyo apellido es desconocido ". Muchos motores de bases de datos tienen un sesgo hacia un significado u otro, pero no son todos iguales. El código que espera que un motor de base de datos funcione de una manera puede funcionar mal si se ejecuta en un motor diferente que funciona de manera diferente.

Super gato
fuente
Si se sabe que una cadena no tiene ningún valor, entonces el valor debe ser una cadena vacía, no una cadena nula.
Byron Jones
0

La mayoría de las respuestas existentes se centran en las partes no SQL de una aplicación, pero también puede haber un problema en SQL:

Si se le indica que filtre los registros donde el apellido de un usuario no está disponible, alguien que no entienda muy bien SQL puede escribir un filtro WHERE u.lastname != 'NULL'. Debido a la forma en que funciona SQL, aparecerá para verificar si u.lastname IS NOT NULL: todos los NULLregistros se filtran. Todos los no NULLregistros permanecen.

Excepto, por supuesto, los registros donde u.lastname == 'NULL', pero puede que no haya habido ningún registro disponible durante la prueba.

Esto se vuelve más probable si el SQL es generado por algún tipo de marco, donde ese marco no expone una forma fácilmente accesible de verificar la no- NULLnodad con los parámetros, y alguien nota "oye, si paso la cadena NULL, hace exactamente lo que quiero! "

hvd
fuente