Articulo de referencia

Nulo (SQL)

El carácter griego omega (ω) minúscula se utiliza para representar Nulo en la teoría de bases de datos . En el lenguaje de consulta de bases de datos SQL , null o NULL es un mar...

El carácter griego omega (ω) minúscula se utiliza para representar Nulo en la teoría de bases de datos .

En el lenguaje de consulta de bases de datos SQL , null o NULL es un marcador especial que indica que un valor de datos no existe en la base de datos . Introducido por el creador del modelo de base de datos relacional , E. F. Codd , el valor null de SQL cumple con el requisito de que todos los sistemas de gestión de bases de datos relacionales ( RDBMS ) admitan una representación de "información faltante e información no aplicable". Codd también introdujo el uso del símbolo omega (ω) griego en minúscula para representar null en la teoría de bases de datos . En SQL, es una palabra reservada que se utiliza para identificar este marcador.NULL

Un valor nulo no debe confundirse con un valor de 0. Un valor nulo indica la ausencia de un valor, lo cual no es lo mismo que un valor cero. Por ejemplo, en la pregunta "¿Cuántos libros tiene Adam?", la respuesta puede ser "cero" (se sabe que tiene cero libros ) o "nulo" (se desconoce el número de libros ). En una tabla de base de datos, la columna que reporta esta respuesta comenzaría sin valor (marcada como nula) y no se actualizaría con el valor cero hasta que se confirme que Adam no tiene libros.

En SQL, null es un marcador, no un valor. Este uso difiere de la mayoría de los lenguajes de programación, donde un valor null de una referencia significa que no apunta a ningún objeto .

Historia

EF Codd mencionó los valores nulos como método para representar datos faltantes en el modelo relacional en un artículo de 1975 publicado en el FDT Bulletin de ACM - SIGMOD . El artículo de Codd más citado en relación con la semántica de Null (tal como se adoptó en SQL) es su artículo de 1979 en ACM Transactions on Database Systems , en el que también introdujo su Modelo Relacional/Tasmania , aunque gran parte de las demás propuestas de este último artículo han permanecido poco claras. La sección 2.3 de su artículo de 1979 detalla la semántica de la propagación de Null en operaciones aritméticas, así como en comparaciones que emplean una lógica ternaria (de tres valores) al comparar con valores nulos; también detalla el tratamiento de los valores nulos en otras operaciones de conjuntos (este último tema sigue siendo controvertido hoy en día). En los círculos de la teoría de bases de datos , la propuesta original de Codd (1975, 1979) se conoce ahora como "tablas de Codd". [ 1 ] Posteriormente, Codd reforzó su requisito de que todos los RDBMS admitan Null para indicar datos faltantes en un artículo de dos partes publicado en 1985 en la revista Computerworld . [ 2 ] [ 3 ]

El estándar SQL de 1986 adoptó básicamente la propuesta de Codd tras un prototipo de implementación en IBM System R. Aunque Don Chamberlin reconoció los valores nulos (junto con las filas duplicadas) como una de las características más controvertidas de SQL, defendió el diseño de los valores nulos en SQL invocando argumentos pragmáticos: era la forma menos costosa de soporte del sistema para la información faltante, lo que ahorraba al programador muchas comprobaciones duplicadas a nivel de aplicación (véase el problema del semipredicado ) y, al mismo tiempo, proporcionaba al diseñador de la base de datos la opción de no usar valores nulos si así lo deseaba; por ejemplo, para evitar anomalías bien conocidas (que se analizan en la sección de semántica de este artículo). Chamberlin también argumentó que, además de proporcionar cierta funcionalidad para valores faltantes, la experiencia práctica con los valores nulos también condujo a otras características del lenguaje que dependen de ellos, como ciertas construcciones de agrupación y uniones externas. Finalmente, argumentó que en la práctica los valores nulos también terminan usándose como una forma rápida de parchear un esquema existente cuando necesita evolucionar más allá de su propósito original, codificando no para información faltante sino para información inaplicable; por ejemplo, una base de datos que necesita rápidamente admitir autos eléctricos mientras tiene una columna de millas por galón. [ 4 ]

Codd indicó en su libro de 1990, The Relational Model for Database Management, Versión 2, que el único valor nulo exigido por el estándar SQL era inadecuado y debía reemplazarse por dos marcadores de tipo nulo separados para indicar por qué faltan datos. En el libro de Codd, estos dos marcadores de tipo nulo se denominan «Valores A» y «Valores I», que representan «Faltante pero aplicable» y «Faltante pero inaplicable», respectivamente. [ 5 ] La recomendación de Codd habría requerido que el sistema lógico de SQL se ampliara para admitir un sistema lógico de cuatro valores. Debido a esta complejidad adicional, la idea de múltiples valores nulos con diferentes definiciones no ha logrado una amplia aceptación en el ámbito de los profesionales de bases de datos. Sin embargo, sigue siendo un campo de investigación activo, con numerosos artículos que aún se publican.

Desafíos

El valor nulo ha sido objeto de controversia y debate debido a su lógica trivalente (3VL), los requisitos especiales para su uso en las uniones SQL y el tratamiento especial que requieren las funciones de agregación y los operadores de agrupación SQL. El profesor de informática Ron van der Meyden resumió los diversos problemas de la siguiente manera: «Las inconsistencias en el estándar SQL implican que no es posible atribuir ninguna semántica lógica intuitiva al tratamiento de los valores nulos en SQL». [ 1 ] Si bien se han presentado varias propuestas para resolver estos problemas, la complejidad de las alternativas ha impedido su adopción generalizada.

Propagación nula

Operaciones aritméticas

Dado que Null no es un valor de datos, sino un marcador de un valor ausente, el uso de operadores matemáticos en Null produce un resultado desconocido, que se representa mediante Null. [ 6 ] En el siguiente ejemplo, multiplicar 10 por Null da como resultado Null:

10 * NULL -- El resultado es NULL

Esto puede generar resultados inesperados. Por ejemplo, cuando se intenta dividir Null entre cero, las plataformas pueden devolver Null en lugar de generar la esperada "excepción de datos : división por cero ". [ 6 ] Aunque este comportamiento no está definido por el estándar ISO SQL, muchos proveedores de sistemas de gestión de bases de datos (DBMS) tratan esta operación de manera similar. Por ejemplo, las plataformas Oracle, PostgreSQL, MySQL Server y Microsoft SQL Server devuelven un resultado Null para lo siguiente: 

NULO / 0

concatenación de cadenas

Las operaciones de concatenación de cadenas , comunes en SQL, también devuelven Null cuando uno de los operandos es Null. [ 7 ] El siguiente ejemplo muestra el resultado Null que se obtiene al usar Null con el ||operador de concatenación de cadenas SQL.

'Pescado' || NULO || 'Patatas fritas' -- El resultado es NULO

Esto no es cierto para todas las implementaciones de bases de datos. En un sistema de gestión de bases de datos relacionales (RDBMS) de Oracle, por ejemplo, NULL y la cadena vacía se consideran lo mismo y, por lo tanto, 'Fish ' || NULL || 'Chips' da como resultado 'Fish Chips'. [ 8 ]

Comparaciones con NULL y la lógica trivalente (3VL)

Dado que Null no pertenece a ningún dominio de datos , no se considera un "valor", sino un marcador (o marcador de posición) que indica un valor indefinido . Por ello, las comparaciones con Null nunca pueden dar como resultado True ni False, sino siempre un tercer resultado lógico: Unknown. [ 9 ] El resultado lógico de la siguiente expresión, que compara el valor 10 con Null, es Unknown:

SELECT 10 = NULL -- Resultado desconocido

Sin embargo, ciertas operaciones con valores nulos pueden devolver valores si el valor ausente no es relevante para el resultado de la operación. Considere el siguiente ejemplo:

SELECCIONE NULO O VERDADERO -- El resultado es verdadero

En este caso, el hecho de que el valor a la izquierda de OR sea desconocido es irrelevante, porque el resultado de la operación OR sería verdadero independientemente del valor a la izquierda.

SQL implementa tres resultados lógicos, por lo que las implementaciones de SQL deben contemplar una lógica trivalente especializada (3VL) . Las reglas que rigen la lógica trivalente de SQL se muestran en las tablas siguientes ( p y q representan estados lógicos) [ 10 ]. Las tablas de verdad que SQL utiliza para AND, OR y NOT corresponden a un fragmento común de la lógica trivalente de Kleene y Łukasiewicz (que difieren en su definición de implicación; sin embargo, SQL no define tal operación). [ 11 ].

Efecto de lo desconocido en las cláusulas WHERE

La lógica trivalente de SQL se encuentra en el lenguaje de manipulación de datos (DML) en los predicados de comparación de las sentencias y consultas DML. La cláusula WHEREhace que la sentencia DML actúe solo sobre aquellas filas para las que el predicado se evalúa como verdadero. Las filas para las que el predicado se evalúa como falso o desconocido no son procesadas por INSERTlas sentencias DML, y son descartadas por las consultas. Interpretar desconocido y falso como el mismo resultado lógico es un error común que se encuentra al trabajar con valores nulos. [ 10 ] El siguiente ejemplo sencillo demuestra esta falacia:UPDATEDELETESELECT

SELECCIONAR * DE t DONDE i = NULL ;

La consulta de ejemplo anterior siempre devuelve lógicamente cero filas porque la comparación de la columna i con Null siempre devuelve Desconocido, incluso para aquellas filas donde i es Null. El resultado Desconocido provoca que la SELECTinstrucción descarte automáticamente todas las filas. (Sin embargo, en la práctica, algunas herramientas SQL recuperan filas mediante una comparación con Null).

Predicados de comparación específicos para valores nulos y específicos para 3VL

Los operadores de comparación SQL básicos siempre devuelven Desconocido al comparar cualquier cosa con Null, por lo que el estándar SQL proporciona dos predicados de comparación especiales específicos para Null. Los predicados IS NULLy IS NOT NULL(que utilizan una sintaxis posfija ) comprueban si los datos son o no son Null. [ 12 ]

El estándar SQL contiene la característica opcional F571 " Pruebas de valor de verdad " que introduce tres operadores lógicos unarios adicionales (seis de hecho, si contamos su negación, que forma parte de su sintaxis), que también utilizan notación posfija. Tienen las siguientes tablas de verdad: [ 13 ]

La característica F571 es independiente de la presencia del tipo de dato booleano en SQL (que se analiza más adelante en este artículo) y, a pesar de las similitudes sintácticas, F571 no introduce literales booleanos ni trivalentes en el lenguaje. De hecho , la característica F571 ya estaba presente en SQL92 [ 14 ] mucho antes de que el tipo de dato booleano se incorporara al estándar en 1999. Sin embargo, pocos sistemas implementan la característica F571; PostgreSQL es uno de ellos.

La adición de IS UNKNOWN a los demás operadores de la lógica trivalente de SQL hace que la lógica trivalente de SQL sea funcionalmente completa , [ 15 ] lo que significa que sus operadores lógicos pueden expresar (en combinación) cualquier función lógica trivalente imaginable.

En sistemas que no admiten la función F571, es posible emular IS UNKNOWN p recorriendo cada argumento que podría hacer que la expresión p sea desconocida y probando esos argumentos con IS NULL u otras funciones específicas para NULL, aunque esto puede ser más engorroso.

Ley del cuarto excluido (en cláusulas WHERE)

En la lógica trivalente de SQL, la ley del tercero excluido , p OR NOT p , ya no se evalúa como verdadera para todo p . Más precisamente, en la lógica trivalente de SQL, p OR NOT p es desconocido precisamente cuando p es desconocido y verdadero en caso contrario. Debido a que las comparaciones directas con Null dan como resultado el valor lógico desconocido, la siguiente consulta

SELECCIONAR * DE cosas DONDE ( x = 10 ) O NO ( x = 10 );

no es equivalente en SQL con

SELECCIONAR * DE cosas ;

Si la columna x contiene algún valor nulo, la segunda consulta devolvería algunas filas que la primera no devuelve, concretamente todas aquellas en las que x es nulo. En la lógica clásica de dos valores, la ley del tercero excluido permitiría simplificar el predicado de la cláusula WHERE, de hecho, eliminarlo. Intentar aplicar la ley del tercero excluido a la lógica de tres valores de SQL es, en efecto, una falsa dicotomía . La segunda consulta es en realidad equivalente a:

SELECT * FROM stuff ; -- es (debido a 3VL) equivalente a: SELECT * FROM stuff WHERE ( x = 10 ) OR NOT ( x = 10 ) OR x IS NULL ;

Por lo tanto, para simplificar correctamente la primera instrucción en SQL, es necesario que devolvamos todas las filas en las que x no sea nulo.

SELECCIONAR * DE stuff DONDE x NO ES NULO ;

En vista de lo anterior, observe que para la cláusula WHERE de SQL se puede escribir una tautología similar a la ley del tercero excluido. Suponiendo que el operador IS UNKNOWN está presente, p OR (NOT p ) OR ( p IS UNKNOWN) es verdadero para todo predicado p . Entre los lógicos, esto se conoce como la ley del cuarto excluido .

Hay algunas expresiones SQL en las que no es tan obvio dónde se produce el falso dilema, por ejemplo:

SELECCIONAR 'ok' DONDE 1 NO ESTÉ EN ( SELECCIONAR CONVERTIR ( NULL COMO ENTERO )) UNIÓN SELECCIONAR 'ok' DONDE 1 ESTÉ EN ( SELECCIONAR CONVERTIR ( NULL COMO ENTERO ));

no produce filas porque INse traduce en una versión iterada de igualdad sobre el conjunto de argumentos y 1<>NULL es Desconocido, al igual que 1=NULL es Desconocido. (El CAST en este ejemplo solo es necesario en algunas implementaciones de SQL como PostgreSQL, que de otro modo lo rechazarían con un error de comprobación de tipos. En muchos sistemas, el SELECT NULL simple funciona en la subconsulta). El caso que falta arriba es, por supuesto:

SELECCIONAR 'ok' DONDE ( 1 EN ( SELECCIONAR CONVERTIR ( NULL COMO ENTERO ))) ES DESCONOCIDO ;

Efecto de lo nulo y lo desconocido en otras construcciones

Se une

Las uniones se evalúan utilizando las mismas reglas de comparación que para las cláusulas WHERE. Por lo tanto, se debe tener cuidado al usar columnas que admiten valores nulos en los criterios de unión SQL. En particular, una tabla que contiene valores nulos no es igual a una auto-unión natural de sí misma, lo que significa que mientrasRR=R{\displaystyle R\bowtie R=R}Esto es cierto para cualquier relación R en álgebra relacional , una auto-unión SQL excluirá todas las filas que tengan un valor Null en cualquier parte. [ 16 ] Un ejemplo de este comportamiento se da en la sección que analiza la semántica de valores faltantes de Nulls.

Las COALESCEfunciones o CASEexpresiones SQL pueden utilizarse para "simular" la igualdad de valores nulos en los criterios de unión, y los predicados IS NULLAND IS NOT NULLtambién pueden utilizarse en dichos criterios. El siguiente predicado comprueba la igualdad de los valores A y B y trata los valores nulos como iguales.

( A = B ) O ( A ES NULO Y B ES NULO )

expresiones CASE

SQL proporciona dos tipos de expresiones condicionales . Una se llama "CASE simple" y funciona como una instrucción switch . La otra se llama "CASE con búsqueda" en el estándar y funciona como un if...elseif .

Las expresiones simples CASEutilizan comparaciones de igualdad implícitas que operan bajo las mismas reglas que las WHEREreglas de la cláusula DML para Null. Por lo tanto, una expresión simpleCASE no puede comprobar directamente la existencia de Null. Una comprobación de Null en una CASEexpresión simple siempre da como resultado Desconocido, como en el siguiente ejemplo:

SELECCIONAR CASO i CUANDO NULL ENTONCES 'Es nulo' -- Esto nunca se devolverá CUANDO 0 ENTONCES 'Es cero' -- Esto se devolverá cuando i = 0 CUANDO 1 ENTONCES 'Es uno' -- Esto se devolverá cuando i = 1 FIN DESDE t ;

Debido a que la expresión i = NULLse evalúa como Desconocido sin importar qué valor contenga la columna i (incluso si contiene Nulo), la cadena 'Is Null'nunca se devolverá.

Por otro lado, una CASEexpresión "buscada" puede usar predicados como " IS NULLand" IS NOT NULLen sus condiciones. El siguiente ejemplo muestra cómo usar una CASEexpresión buscada para comprobar correctamente si un valor es nulo:

SELECCIONAR CASO CUANDO i ES NULO ENTONCES 'Resultado nulo' -- Esto se devolverá cuando i sea NULO CUANDO i = 0 ENTONCES 'Cero' -- Esto se devolverá cuando i = 0 CUANDO i = 1 ENTONCES 'Uno' -- Esto se devolverá cuando i = 1 FIN DESDE t ;

En la CASEexpresión de búsqueda, la cadena 'Null Result'se devuelve para todas las filas en las que i es nulo.

El dialecto SQL de Oracle proporciona una función integrada DECODEque se puede utilizar en lugar de las expresiones CASE simples y que considera que dos valores nulos son iguales.

SELECCIONAR DECODIFICAR ( i , NULL , 'Resultado nulo' , 0 , 'Cero' , 1 , 'Uno' ) DE t ;

Finalmente, todas estas construcciones devuelven NULL si no se encuentra ninguna coincidencia; tienen una ELSE NULLcláusula predeterminada.

Sentencias IF en extensiones de procedimientos

SQL/PSM (Módulos Almacenados Persistentes SQL) define extensiones procedimentales para SQL, como la IFinstrucción `Null`. Sin embargo, los principales proveedores de SQL han incluido históricamente sus propias extensiones procedimentales propietarias. Las extensiones procedimentales para bucles y comparaciones operan bajo reglas de comparación de valores nulos similares a las de las instrucciones y consultas DML. El siguiente fragmento de código, en formato estándar ISO SQL, demuestra el uso de `Null 3VL` en una IFinstrucción `Null`.

SI i = NULL ENTONCES SELECCIONAR 'El resultado es verdadero' SINO SI NO ( i = NULL ) ENTONCES SELECCIONAR 'El resultado es falso' SINO SELECCIONAR 'El resultado es desconocido' ;

La IFinstrucción realiza acciones solo para aquellas comparaciones que se evalúan como verdaderas. Para las instrucciones que se evalúan como falsas o desconocidas, la IFinstrucción pasa el control a la ELSEIFcláusula y, finalmente, a la ELSEcláusula. El resultado del código anterior siempre será el mensaje, 'Result is Unknown'ya que las comparaciones con Null siempre se evalúan como desconocidas.

Análisis de la semántica de valores nulos faltantes en SQL

El trabajo pionero de T. Imieliński y W. Lipski Jr. (1984) [ 17 ] proporcionó un marco para evaluar la semántica prevista de varias propuestas para implementar la semántica de valores faltantes, que se conoce como álgebras de Imieliński-Lipski . Esta sección sigue aproximadamente el capítulo 19 del libro de texto "Alice". [ 18 ] Una presentación similar aparece en la reseña de Ron van der Meyden, §10.4. [ 1 ]

En selecciones y proyecciones: representación débil

Las construcciones que representan información faltante, como las tablas de Codd, en realidad están destinadas a representar un conjunto de relaciones, una para cada posible instanciación de sus parámetros; en el caso de las tablas de Codd, esto significa reemplazar los valores nulos con algún valor concreto. Por ejemplo,

 

La tabla Codd Emp puede representar la relación EmpH22 o EmpH37 , como se muestra en la imagen.

Se dice que una construcción (como una tabla de Codd) es un sistema de representación fuerte (de información faltante) si cualquier respuesta a una consulta realizada sobre la construcción puede particularizarse para obtener una respuesta para cualquier consulta correspondiente sobre las relaciones que representa, las cuales se consideran modelos de la construcción. Más precisamente, si q es una fórmula de consulta en el álgebra relacional (de relaciones "puras") y si q es su elevación a una construcción destinada a representar información faltante, una representación fuerte tiene la propiedad de que para cualquier consulta q y construcción (tabla) T , q eleva todas las respuestas a la construcción, es decir:

METROodmils(q¯(T))={q(R)|RMETROodmils(T)}{\displaystyle \mathop {\mathrm {Models} } ({\bar {q}}(T))=\{q(R)\,|R\in \mathop {\mathrm {Models} } (T)\}}

(Lo anterior debe cumplirse para consultas que tomen cualquier número de tablas como argumentos, pero la restricción a una tabla es suficiente para esta discusión). Claramente, las tablas de Codd no tienen esta fuerte propiedad si las selecciones y proyecciones se consideran parte del lenguaje de consulta. Por ejemplo, todas las respuestas a

SELECCIONAR * DE Emp DONDE Edad = 22 ;

Se debe incluir la posibilidad de que exista una relación como EmpH22. Sin embargo, las tablas de Codd no pueden representar la disyunción "resultado con posiblemente 0 o 1 filas". No obstante, un dispositivo, principalmente de interés teórico, llamado tabla condicional (o tabla c), sí puede representar dicha respuesta:

donde la columna de condición se interpreta como que la fila no existe si la condición es falsa. Resulta que, debido a que las fórmulas en la columna de condición de una tabla c pueden ser fórmulas de lógica proposicional arbitrarias , un algoritmo para el problema de si una tabla c representa alguna relación concreta tiene una complejidad co-NP-completa , por lo que tiene poca utilidad práctica.

Por lo tanto, es deseable una noción más débil de representación. Imielinski y Lipski introdujeron la noción de representación débil , que esencialmente permite que las consultas (elevadas) sobre una construcción devuelvan una representación solo para información segura , es decir, si es válida para todas las instanciaciones (modelos) de " mundo posible " de la construcción. Concretamente, una construcción es un sistema de representación débil si

METROodmils(q¯(T))={q(R)|RMETROodmils(T)}{\displaystyle \bigcap \mathop {\mathrm {Models} } ({\bar {q}}(T))=\bigcap \{q(R)\,|R\in \mathop {\mathrm {Models} } (T)\}}

El lado derecho de la ecuación anterior es la información segura , es decir, la información que se puede extraer con certeza de la base de datos, independientemente de los valores que se utilicen para reemplazar los valores nulos. En el ejemplo anterior, es fácil ver que la intersección de todos los modelos posibles (es decir, la información segura) de la consulta de selección está vacía porque, por ejemplo, la consulta (sin elevar) no devuelve filas para la relación EmpH37. De forma más general, Imielinski y Lipski demostraron que las tablas de Codd son un sistema de representación débil si el lenguaje de consulta se limita a proyecciones, selecciones (y cambio de nombre de columnas). Sin embargo, en cuanto añadimos uniones o combinaciones al lenguaje de consulta, incluso esta propiedad débil se pierde, como se evidencia en la siguiente sección.WHEREAge=22

Si se consideran las uniones o los sindicatos: ni siquiera una representación débil.

Considere la siguiente consulta sobre la misma tabla Codd Emp de la sección anterior:

SELECCIONAR Nombre DE Empleado DONDE Edad = 22 UNIÓN SELECCIONAR Nombre DE Empleado DONDE Edad < > 22 ;

Cualquier valor concreto que se elija para la NULLedad de Harriet, la consulta anterior devolverá la columna completa de nombres de cualquier modelo de Emp , pero cuando la consulta (elevada) se ejecuta en Emp mismo, Harriet siempre faltará, es decir, tenemos:

Por lo tanto, cuando se agregan uniones al lenguaje de consulta, las tablas Codd ni siquiera constituyen un sistema de representación débil de la información faltante, lo que significa que las consultas sobre ellas ni siquiera informan toda la información segura . La semántica de UNION en valores nulos no entró en juego en esta consulta. La naturaleza "olvidada" de las dos subconsultas fue suficiente para garantizar que cierta información segura no se informara cuando se ejecutó la consulta anterior en la tabla Codd Emp.

Para las uniones naturales , el ejemplo necesario para demostrar que cierta información puede no ser reportada por alguna consulta es un poco más complicado. Considere la tabla

y la consulta

SELECCIONAR F1 , F3 DE ( SELECCIONAR F1 , F2 DE J ) COMO F12 UNIÓN NATURAL ( SELECCIONAR F2 , F3 DE J ) COMO F23 ;

La intuición de lo que sucede arriba es que las tablas Codd que representan las proyecciones en las subconsultas pierden el rastro del hecho de que los valores nulos en las columnas F12.F2 y F23.F2 son en realidad copias de los originales en la tabla J. Esta observación sugiere que una mejora relativamente simple de las tablas Codd (que funciona correctamente para este ejemplo) sería usar constantes de Skolem (es decir, funciones de Skolem que también son funciones constantes ), por ejemplo ω 12 y ω 22 en lugar de un solo símbolo NULL. Este enfoque, llamado tablas v o tablas ingenuas, es computacionalmente menos costoso que las tablas c discutidas anteriormente. Sin embargo, todavía no es una solución completa para la información incompleta en el sentido de que las tablas v son solo una representación débil para consultas que no usan ninguna negación en la selección (y tampoco usan ninguna diferencia de conjuntos). El primer ejemplo considerado en esta sección usa una cláusula de selección negativa, por lo que también es un ejemplo donde las consultas de tablas v no reportarían información segura.WHEREAge<>22

Verifique las restricciones y las claves foráneas.

El punto principal donde la lógica trivalente de SQL se cruza con el lenguaje de definición de datos (DDL) de SQL es en forma de restricciones de verificación . Una restricción de verificación aplicada a una columna opera bajo un conjunto de reglas ligeramente diferente al de la WHEREcláusula DML. Mientras que una WHEREcláusula DML debe evaluarse como verdadera para una fila, una restricción de verificación no debe evaluarse como falsa. (Desde una perspectiva lógica, los valores designados son verdadero y desconocido). Esto significa que una restricción de verificación tendrá éxito si el resultado de la verificación es verdadero o desconocido. La siguiente tabla de ejemplo con una restricción de verificación impedirá que se inserten valores enteros en la columna i , pero permitirá la inserción de valores nulos, ya que el resultado de la verificación siempre se evaluará como desconocido para los valores nulos. [ 19 ]

CREATE TABLE t ( i INTEGER , CONSTRAINT ck_i CHECK ( i < 0 AND i = 0 AND i > 0 ) );

Debido al cambio en los valores designados con respecto a la cláusula WHERE , desde una perspectiva lógica, la ley del tercero excluido es una tautología para las restricciones CHECK , lo que significa que siempre se cumple. Además, suponiendo que los valores nulos se interpreten como valores existentes pero desconocidos, algunas comprobaciones problemáticas como la anterior permiten la inserción de valores nulos que nunca podrían ser reemplazados por ningún valor no nulo.CHECK (p OR NOT p)

Para restringir una columna y evitar valores nulos, NOT NULLse puede aplicar la restricción, como se muestra en el ejemplo siguiente. Esta NOT NULLrestricción es semánticamente equivalente a una restricción de verificación con un IS NOT NULLpredicado.

CREATE TABLE t ( i INTEGER NOT NULL );

Por defecto, las restricciones de comprobación contra claves foráneas tienen éxito si alguno de los campos de dichas claves es nulo. Por ejemplo, la tabla

CREATE TABLE Books ( title VARCHAR ( 100 ), author_last VARCHAR ( 20 ), author_first VARCHAR ( 20 ), FOREIGN KEY ( author_last , author_first ) REFERENCES Authors ( last_name , first_name ));

permitiría la inserción de filas donde author_last o author_first sean NULLindependientemente de cómo se defina la tabla Authors o lo que contenga. Más precisamente, un valor nulo en cualquiera de estos campos permitiría cualquier valor en el otro, incluso en uno que no se encuentre en la tabla Authors. Por ejemplo, si Authors contuviera solo ('Doe', 'John'), entonces ('Smith', NULL)cumpliría la restricción de clave externa. SQL-92 agregó dos opciones adicionales para reducir las coincidencias en tales casos. Si MATCH PARTIALse agrega después de la REFERENCESdeclaración, entonces cualquier valor no nulo debe coincidir con la clave externa, por ejemplo, ('Doe', NULL)seguiría coincidiendo, pero ('Smith', NULL)no. Finalmente, si MATCH FULLse agrega, entonces ('Doe', NULL)tampoco coincidiría con la restricción, pero (NULL, NULL)aún la cumpliría.

Uniones externas

Ejemplo de consulta SQL de unión externa con marcadores de posición nulos en el conjunto de resultados. Los marcadores nulos se representan mediante la palabra NULLen lugar de datos en los resultados. Los resultados provienen de Microsoft SQL Server , tal como se muestra en SQL Server Management Studio.

Las uniones externas SQL , incluidas las uniones externas izquierdas, derechas y completas, generan automáticamente valores nulos como marcadores de posición para los valores faltantes en las tablas relacionadas. Por ejemplo, en las uniones externas izquierdas, se generan valores nulos en lugar de las filas que faltan en la tabla que aparece a la derecha del LEFT OUTER JOINoperador. El siguiente ejemplo sencillo utiliza dos tablas para demostrar la generación de marcadores de posición nulos en una unión externa izquierda.

La primera tabla ( Employee ) contiene los números de identificación y los nombres de los empleados, mientras que la segunda tabla ( PhoneNumber ) contiene los números de identificación y los números de teléfono de los empleados relacionados , como se muestra a continuación.

La siguiente consulta SQL de ejemplo realiza una unión externa izquierda en estas dos tablas.

SELECT e . ID , e . LastName , e . FirstName , pn . Number FROM Employee e LEFT OUTER JOIN PhoneNumber pn ON e . ID = pn . ID ;

El conjunto de resultados generado por esta consulta demuestra cómo SQL utiliza Null como marcador de posición para los valores que faltan en la tabla de la derecha ( PhoneNumber ), como se muestra a continuación.

Funciones agregadas

SQL define funciones de agregación para simplificar los cálculos de agregación en el servidor sobre los datos. Excepto por la COUNT(*)función, todas las funciones de agregación realizan un paso de eliminación de valores nulos, de modo que los valores nulos no se incluyan en el resultado final del cálculo. [ 20 ]

Tenga en cuenta que la eliminación de Null no es equivalente a reemplazar Null por cero. Por ejemplo, en la siguiente tabla, AVG(i)(el promedio de los valores de i) dará un resultado diferente al de AVG(j):

Aquí AVG(i)está 200 (el promedio de 150, 200 y 250), mientras que AVG(j)es 150 (el promedio de 150, 200, 250 y 0). Un efecto secundario bien conocido de esto es que en SQL, AVG(z)no es equivalente a SUM(z)/COUNT(*)sino a SUM(z)/COUNT(z). [ 4 ]

El resultado de una función de agregación también puede ser nulo. He aquí un ejemplo:

SELECCIONAR CONTAR ( * ), MÍN ( e . Salario ), MÁX ( e . Salario ) DE Empleado e DONDE e . Apellido LIKE '%Jones%' ;

Esta consulta siempre arrojará exactamente una fila, contando el número de empleados cuyo apellido contiene "Jones" y proporcionando el salario mínimo y máximo encontrado para esos empleados. Sin embargo, ¿qué sucede si ninguno de los empleados cumple con los criterios dados? Calcular el valor mínimo o máximo de un conjunto vacío es imposible, por lo que esos resultados deben ser NULL, lo que indica que no hay respuesta. Este no es un valor desconocido, sino un valor nulo que representa la ausencia de un valor. El resultado sería:

Cuando dos valores nulos son iguales: agrupación, ordenación y algunas operaciones de conjuntos.

Debido a que SQL:2003 define todos los marcadores Null como distintos entre sí, se requirió una definición especial para agrupar los Nulls al realizar ciertas operaciones. SQL define "cualquier par de valores que sean iguales entre sí, o cualquier par de Nulls", como "no distintos". [ 21 ] Esta definición de no distintos permite a SQL agrupar y ordenar los Nulls cuando GROUP BYse utiliza la cláusula (u otra característica del lenguaje SQL que realiza agrupaciones).

Otras operaciones, cláusulas y palabras clave de SQL que utilizan la definición "not distinct" en su tratamiento de valores nulos incluyen:

  • La PARTITION BYcláusula de las funciones de clasificación y ventanas, tales comoROW_NUMBER
  • Los operadores UNION, INTERSECT, y EXCEPT, que tratan los valores NULL como iguales a efectos de comparación/eliminación de filas.
  • La DISTINCTpalabra clave utilizada en SELECTlas consultas

El principio de que los valores nulos no son iguales entre sí (sino que el resultado es desconocido) se viola efectivamente en la especificación SQL para el UNIONoperador, que sí identifica los valores nulos entre sí. [ 1 ] En consecuencia, algunas operaciones de conjuntos en SQL, como la unión y la diferencia, pueden producir resultados que no representan información certera, a diferencia de las operaciones que implican comparaciones explícitas con NULL (por ejemplo, las de una WHEREcláusula analizada anteriormente). En la propuesta de Codd de 1979 (que fue adoptada por SQL92), esta inconsistencia semántica se justifica argumentando que la eliminación de duplicados en las operaciones de conjuntos ocurre "a un nivel de detalle inferior al de la prueba de igualdad en la evaluación de las operaciones de recuperación". [ 11 ]

El estándar SQL no define explícitamente un orden de clasificación predeterminado para los valores nulos. En cambio, en los sistemas que cumplen con el estándar, los valores nulos se pueden clasificar antes o después de todos los valores de datos utilizando las cláusulas NULLS FIRSTOR NULLS LASTde la ORDER BYlista, respectivamente. Sin embargo, no todos los proveedores de sistemas de gestión de bases de datos (DBMS) implementan esta funcionalidad. Los proveedores que no la implementan pueden especificar diferentes tratamientos para la clasificación de valores nulos en el DBMS. [ 19 ]

Efecto en la operación de índice

Algunos productos SQL no indexan claves que contienen NULL. Por ejemplo, las versiones de PostgreSQL anteriores a la 8.3 no lo hacían, y la documentación para un índice B-tree indica que [ 22 ]

Los árboles B pueden manejar consultas de igualdad y de rango en datos que se pueden ordenar de alguna manera. En particular, el planificador de consultas de PostgreSQL considerará usar un índice de árbol B siempre que una columna indexada esté involucrada en una comparación usando uno de estos operadores: < ≤ = ≥ >

También se pueden implementar construcciones equivalentes a combinaciones de estos operadores, como BETWEEN e IN, mediante una búsqueda en un índice de árbol B. (Cabe destacar que IS NULL no es equivalente a = y no es indexable).

En los casos en que el índice exige unicidad, los valores NULL se excluyen del índice y no se exige unicidad entre los valores NULL. Nuevamente, citando la documentación de PostgreSQL: [ 23 ]

Cuando se declara un índice único, no se permiten varias filas de la tabla con valores indexados iguales. Los valores nulos no se consideran iguales. Un índice único de varias columnas solo rechazará los casos en los que todas las columnas indexadas sean iguales en dos filas.

Esto concuerda con el comportamiento de las comparaciones escalares nulas definido en SQL:2003 .

Otro método para indexar valores nulos implica tratarlos como no distintos de acuerdo con el comportamiento definido en SQL:2003. Por ejemplo, la documentación de Microsoft SQL Server indica lo siguiente: [ 24 ]

Para fines de indexación, los valores NULL se consideran iguales. Por lo tanto, no se puede crear un índice único ni una restricción UNIQUE si las claves son NULL en más de una fila. Al seleccionar columnas para un índice único o una restricción UNIQUE, elija columnas definidas como NOT NULL.

Ambas estrategias de indexación son coherentes con el comportamiento de los valores nulos definido en SQL:2003. Dado que las metodologías de indexación no están definidas explícitamente en el estándar SQL:2003, el diseño e implementación de las estrategias de indexación para los valores nulos queda totalmente a cargo de los proveedores.

Funciones de manejo de valores nulos

SQL define dos funciones para manejar explícitamente los valores nulos: NULLIFy COALESCE. Ambas funciones son abreviaturas de expresiones de búsquedaCASE . [ 25 ]

NULLIF

La NULLIFfunción acepta dos parámetros. Si el primer parámetro es igual al segundo, NULLIFdevuelve Null. En caso contrario, devuelve el valor del primer parámetro.

NULLIF ( valor1 , valor2 )

Por lo tanto, NULLIFes una abreviatura de la siguiente CASEexpresión:

CASE WHEN value1 = value2 THEN NULL ELSE value1 END

JUNTARSE

La COALESCEfunción acepta una lista de parámetros y devuelve el primer valor no nulo de la lista:

COALESCE ( valor1 , valor2 , valor3 , ...)

COALESCEse define como una forma abreviada de la siguiente CASEexpresión SQL:

CASE WHEN value1 IS NOT NULL THEN value1 WHEN value2 IS NOT NULL THEN value2 WHEN value3 IS NOT NULL THEN value3 ... END

Algunos sistemas de gestión de bases de datos SQL implementan funciones específicas del proveedor similares a COALESCE. Algunos sistemas (por ejemplo, Transact-SQL ) implementan una ISNULLfunción u otras funciones similares que son funcionalmente parecidas a COALESCE. (Consulte Islas funciones para obtener más información sobre las ISfunciones en Transact-SQL).

NVL

La NVLfunción de Oracle acepta dos parámetros. Devuelve el primer parámetro que no sea nulo o nulo si todos los parámetros son nulos.

Una COALESCEexpresión se puede convertir en una NVLexpresión equivalente de la siguiente manera:

COALESCE ( val1 , ... , val { n } )

se convierte en:

NVL ( val1 , NVL ( val2 , NVL ( val3 , , NVL ( val { n - 1 } , val { n } ) )))

Un caso de uso de esta función es reemplazar en una expresión un valor NULL por un valor como en NVL(SALARY, 0)que dice, 'si SALARYes NULL, reemplácelo con el valor 0'.

Sin embargo, existe una excepción notable. En la mayoría de las implementaciones, COALESCEevalúa sus parámetros hasta encontrar el primero que no sea nulo, mientras que NVLevalúa todos sus parámetros. Esto es importante por varias razones. Un parámetro posterior al primero que no sea nulo podría ser una función, lo cual podría resultar computacionalmente costoso, inválido o generar efectos secundarios inesperados.

Tipos de datos Nulos y Desconocidos

En SQL, el NULLliteral no tiene tipo, lo que significa que no se designa como un entero, un carácter ni ningún otro tipo de dato específico . [ 26 ] Por este motivo, a veces es obligatorio (o deseable) convertir explícitamente los valores nulos a un tipo de dato específico. Por ejemplo, si el sistema de gestión de bases de datos relacionales (RDBMS) admite funciones sobrecargadas , SQL podría no ser capaz de resolver automáticamente la función correcta sin conocer los tipos de datos de todos los parámetros, incluidos aquellos para los que se pasa un valor nulo.

La conversión de un NULLliteral a un valor nulo de un tipo específico es posible utilizando la CASTfunción introducida en SQL-92 . Por ejemplo:

CONVERTIR ( NULO COMO ENTERO )

representa un valor ausente de tipo ENTERO.

El tipo real de Desconocido (distinto o no de NULL) varía entre las implementaciones de SQL. Por ejemplo, lo siguiente:

SELECCIONAR 'ok' DONDE ( NULL <> 1 ) ES NULL ;

Analiza y se ejecuta correctamente en algunos entornos (por ejemplo , SQLite o PostgreSQL ) que unifican un booleano NULL con Desconocido, pero falla al analizar en otros (por ejemplo, en SQL Server Compact ). MySQL se comporta de manera similar a PostgreSQL en este sentido (con la pequeña excepción de que MySQL considera TRUE y FALSE como iguales a los enteros ordinarios 1 y 0). PostgreSQL implementa además un IS UNKNOWNpredicado, que se puede usar para comprobar si un resultado lógico de tres valores es Desconocido, aunque esto es simplemente azúcar sintáctico .

tipo de datos BOOLEAN

El estándar ISO SQL:1999 introdujo el tipo de datos BOOLEAN en SQL; sin embargo, sigue siendo solo una característica opcional, no esencial, codificada como T031. [ 27 ]

Cuando se restringe mediante una NOT NULLrestricción, el tipo de dato SQL BOOLEAN funciona como el tipo booleano de otros lenguajes. Sin embargo, sin restricciones, el tipo de dato BOOLEAN, a pesar de su nombre, puede contener los valores de verdad TRUE, FALSE y UNKNOWN, todos definidos como literales booleanos según el estándar. El estándar también afirma que NULL y UNKNOWN "pueden usarse indistintamente para significar exactamente lo mismo". [ 28 ] [ 29 ]

El tipo booleano ha sido objeto de críticas, particularmente debido al comportamiento obligatorio del literal DESCONOCIDO, que nunca es igual a sí mismo debido a la identificación con NULO. [ 30 ]

Como se mencionó anteriormente, en la implementación de SQL de PostgreSQL , Null se usa para representar todos los resultados DESCONOCIDOS, incluido el BOOLEAN DESCONOCIDO. PostgreSQL no implementa el literal DESCONOCIDO (aunque sí implementa el operador IS DESCONOCIDO, que es una característica independiente). La mayoría de los demás proveedores importantes no admiten el tipo Boolean (tal como se define en T031) a partir de 2012. [ 31 ] Sin embargo, la parte procedimental de PL/SQL de Oracle admite variables BOOLEAN; a estas también se les puede asignar NULL y el valor se considera el mismo que DESCONOCIDO. [ 32 ]

Controversia

Errores comunes

La falta de comprensión del funcionamiento de Null es la causa de numerosos errores en el código SQL, tanto en las sentencias SQL estándar ISO como en los dialectos SQL específicos compatibles con los sistemas de gestión de bases de datos reales. Estos errores suelen deberse a la confusión entre Null y 0 (cero) o una cadena vacía (un valor de cadena con longitud cero, representado en SQL como ''). Sin embargo, el estándar SQL define Null como distinto tanto de una cadena vacía como del valor numérico 00. Mientras que Null indica la ausencia de cualquier valor, tanto la cadena vacía como el cero numérico representan valores reales.

Un error clásico es intentar usar el operador de igualdad =en combinación con la palabra clave NULLpara encontrar filas con valores nulos. Según el estándar SQL, esta sintaxis no es válida y debería generar un mensaje de error o una excepción. Sin embargo, la mayoría de las implementaciones aceptan la sintaxis y evalúan dichas expresiones como nulas UNKNOWN. La consecuencia es que no se encuentran filas, independientemente de si existen o no filas con valores nulos. La forma propuesta de recuperar filas con valores nulos es usar el predicado IS NULLen lugar de = NULL.

SELECT * FROM sometable WHERE num = NULL ; -- Debería ser "WHERE num IS NULL"

En un ejemplo relacionado, pero más sutil, una WHEREcláusula o instrucción condicional podría comparar el valor de una columna con una constante. A menudo se asume erróneamente que un valor faltante sería "menor que" o "distinto de" una constante si ese campo contiene Null, pero, de hecho, dichas expresiones devuelven Unknown. A continuación se muestra un ejemplo:

SELECT * FROM sometable WHERE num <> 1 ; -- Las filas donde num sea NULL no se devolverán, -- contrariamente a las expectativas de muchos usuarios.

Estas confusiones surgen porque la Ley de Identidad está restringida en la lógica de SQL. Al tratar con comparaciones de igualdad usando el NULLliteral o el UNKNOWNvalor de verdad, SQL siempre devolverá UNKNOWNcomo resultado de la expresión. Esta es una relación de equivalencia parcial y convierte a SQL en un ejemplo de lógica no reflexiva . [ 33 ]

De forma similar, los valores nulos suelen confundirse con cadenas vacías. Consideremos la LENGTHfunción que devuelve el número de caracteres de una cadena. Si se le pasa un valor nulo, la función devuelve nulo. Esto puede generar resultados inesperados si los usuarios no están familiarizados con la lógica de tres valores. A continuación, se muestra un ejemplo:

SELECT * FROM sometable WHERE LENGTH ( string ) < 20 ; -- Las filas donde string sea NULL no se devolverán.

Esto se complica por el hecho de que en algunos programas de interfaz de bases de datos (o incluso en implementaciones de bases de datos como la de Oracle), NULL se informa como una cadena vacía, y las cadenas vacías pueden almacenarse incorrectamente como NULL.

Críticas

La implementación de Null en ISO SQL es objeto de críticas, debates y peticiones de cambio. En The Relational Model for Database Management: Version 2 , Codd sugirió que la implementación de Null en SQL era defectuosa y debería reemplazarse por dos marcadores distintos de tipo Null. Los marcadores que propuso representarían "Faltante pero aplicable" y "Faltante pero inaplicable" , conocidos como valores A y valores I , respectivamente. La recomendación de Codd, de haber sido aceptada, habría requerido la implementación de una lógica de cuatro valores en SQL. [ 5 ] Otros han sugerido añadir marcadores adicionales de tipo Null a la recomendación de Codd para indicar aún más razones por las que un valor de datos podría ser "Faltante", aumentando la complejidad del sistema lógico de SQL. En varias ocasiones, también se han presentado propuestas para implementar múltiples marcadores Null definidos por el usuario en SQL. Debido a la complejidad del manejo de Null y los sistemas lógicos necesarios para admitir múltiples marcadores Null, ninguna de estas propuestas ha obtenido una aceptación generalizada.

Chris Date y Hugh Darwen , autores de The Third Manifesto , han sugerido que la implementación de SQL Null es inherentemente defectuosa y debería eliminarse por completo, [ 34 ] señalando inconsistencias y fallos en la implementación del manejo de SQL Null (particularmente en funciones de agregación) como prueba de que todo el concepto de Null es defectuoso y debería eliminarse del modelo relacional. [ 35 ] Otros, como el autor Fabian Pascal , han afirmado que "la forma en que el cálculo de la función debe tratar los valores faltantes no está regida por el modelo relacional".

Suposición de mundo cerrado

Otro punto de conflicto con respecto a los valores nulos es que violan el modelo de supuesto de mundo cerrado de las bases de datos relacionales al introducir un supuesto de mundo abierto . [ 36 ] El supuesto de mundo cerrado, en lo que respecta a las bases de datos, establece que "Todo lo que la base de datos afirma, ya sea explícita o implícitamente, es verdadero; todo lo demás es falso". [ 37 ] Esta visión supone que el conocimiento del mundo almacenado en una base de datos es completo. Sin embargo, los valores nulos operan bajo el supuesto de mundo abierto, en el que algunos elementos almacenados en la base de datos se consideran desconocidos, lo que hace que el conocimiento del mundo almacenado en la base de datos sea incompleto.

Véase también

Referencias

  1. 1 2 3 4 Ron van der Meyden, " Enfoques lógicos para la información incompleta: una revisión " en Chomicki, Jan; Saake, Gunter (Eds.) Lógica para bases de datos y sistemas de información , Kluwer Academic Publishers ISBN 978-0-7923-8129-7pág. 344; preimpresión de PS (nota: la numeración de las páginas difiere en la preimpresión de la versión publicada)
  2. Codd, EF (14 de octubre de 1985). "¿Es realmente relacional su base de datos?". Computerworld .
  3. Codd, EF (21 de octubre de 1985). "¿Su DBMS funciona según las reglas?". Computerworld .
  4. 1 2 Chamberlin, Don (1998). Guía completa de la base de datos universal DB2 . Morgan Kaufmann. págs. 28–32 . ISBN  978-1-55860-482-7.
  5. 1 2 Codd, EF (1990). El modelo relacional para la gestión de bases de datos (2.ª ed.). Addison Wesley Publishing Company . ISBN  978-0-201-14192-4.
  6. 1 2 ISO/IEC (2003). ISO/IEC 9075-2:2003, "SQL/Foundation" . ISO/IEC. Sección 6.2.6: expresiones de valor numérico ..
  7. ISO/IEC (2003). ISO/IEC 9075-2:2003, "SQL/Foundation" . ISO/IEC. Sección 6.2.8: expresión de valor de cadena .
  8. "Manejar cadenas vacías al migrar de Oracle a PostgreSQL | Blog de bases de datos de AWS" . aws.amazon.com . 23/05/2022 . Consultado el 30/12/2023 .
  9. ISO/IEC (2003). ISO/IEC 9075-1:2003, "SQL/Framework" . ISO/IEC. Sección 4.4.2: El valor nulo .
  10. 1 2 Coles, Michael (27 de junio de 2005). "Cuatro reglas para valores nulos" . SQL Server Central . Red Gate Software.
  11. 1 2 Hans-Joachim, K. (2003). "Valores nulos en bases de datos relacionales y respuestas de información segura" . Semántica en bases de datos. Segundo taller internacional, Castillo de Dagstuhl, Alemania, 7-12 de enero de 2001. Artículos revisados . Lecture Notes in Computer Science. Vol. 2582. pp. 119-138 . doi : 10.1007/3-540-36596-6_7 . ISBN   978-3-540-00957-3Archivado del original el 7 de julio de 2018. Consultado el 28 de agosto de 2015 .
  12. ISO/IEC (2003). ISO/IEC 9075-2:2003, "SQL/Foundation" . ISO/IEC. Sección 8.7: predicado nulo .
  13. CJ Date (2004), Introducción a los sistemas de bases de datos , 8.ª ed., Pearson Education, pág. 594
  14. Melton, Jim; Simon, Alan R. (1993). Understanding The New SQL: A Complete Guide . Morgan Kaufmann. pp. 145–147 . ISBN  978-1-55860-245-8.
  15. CJ Date, Escritos sobre bases de datos relacionales, 1991-1994 , Addison-Wesley, 1995, pág. 371
  16. CJ Date (2004), Introducción a los sistemas de bases de datos , 8.ª ed., Pearson Education, pág. 584
  17. Imieliński, T. ; Lipski, W. Jr. (1984). "Información incompleta en bases de datos relacionales" . Journal of the ACM . 31 (4): 761– 791. doi : 10.1145/1634.1886 . S2CID 288040 . 
  18. Abiteboul, Serge ; Hull, Richard B .; Vianu, Victor (1995). Fundamentos de las bases de datos . Addison-Wesley. ISBN 978-0-201-53771-0.
  19. 1 2 Coles, Michael (26 de febrero de 2007). "¿Nulo versus nulo?" . SQL Server Central . Red Gate Software.
  20. ISO/IEC (2003). ISO/IEC 9075-2:2003, "SQL/Foundation" . ISO/IEC. Sección 4.15.4: Funciones de agregación .
  21. ISO/IEC (2003). ISO/IEC 9075-2:2003, "SQL/Foundation" . ISO/IEC. Sección 3.1.6.8: Definiciones: distinct .
  22. "Documentación de PostgreSQL 8.0.14: Tipos de índice" . PostgreSQL . Consultado el 6 de noviembre de 2008 .
  23. "Documentación de PostgreSQL 8.0.14: Índices únicos" . PostgreSQL . Consultado el 6 de noviembre de 2008 .
  24. "Creación de índices únicos" . PostfreSQL. Septiembre de 2007. Consultado el 6 de noviembre de 2008 .
  25. ISO/IEC (2003). ISO/IEC 9075-2:2003, "SQL/Foundation" . ISO/IEC. Sección 6.11: expresión case .
  26. Melton, Jim; Simon, Alan R. (2002). SQL:1999: Comprensión de los componentes del lenguaje relacional . Morgan Kaufmann. pág . 53. ISBN  978-1-55860-456-8.
  27. "Estándar SQL ISO/IEC 9075-1:1999". ISO. 1999.{{cite web}}: Falta o está vacío |url=( ayuda )
  28. Date, C. (2011). SQL y la teoría relacional: Cómo escribir código SQL preciso . O'Reilly Media, Inc. pág. 83. ISBN  978-1-4493-1640-2.
  29. ISO/IEC 9075-2:2011 §4.5
  30. Prigmore, Martyn (2007). Introducción a las bases de datos con aplicaciones web . Pearson Education Canada. pág. 197. ISBN  978-0-321-26359-9.
  31. Troels Arvin, Estudio de la implementación del tipo de datos BOOLEAN
  32. Feuerstein, Steven; Pribyl, Bill (2009). Oracle PL/SQL Programming . O'Reilly Media, Inc. págs. 74, 91. ISBN  978-0-596-51446-4.
  33. Arenhart, Krause (2012), "¿Lógica clásica o lógica no reflexiva? Un caso de subdeterminación semántica", Revista Portuguesa de Filosofia , 68 (1/2): 73– 86, doi : 10.17990/RPF/2012_68_1_0073 , JSTOR 41955624 .
  34. Darwen, Hugh ; Date, Chris . "El Tercer Manifiesto" . thethirdmanifesto.com . Consultado el 29 de mayo de 2007 .
  35. Darwen, Hugh . "The Askew Wall" (PDF) . dcs.warwick.ac.uk . Consultado el 29 de mayo de 2007 .
  36. Date, Chris (mayo de 2005). Database in Depth: Relational Theory for Practitioners . O'Reilly Media, Inc. p. 73. ISBN  978-0-596-10012-4.
  37. Date, Chris . "Resumen: La suposición del mundo cerrado" . Asociación de Gestión de Datos , Capítulo del Área de la Bahía de San Francisco. Archivado del original el 19 de mayo de 2007. Consultado el 29 de mayo de 2007 .

Lecturas adicionales

  • EF Codd. Comprensión de las relaciones (entrega n.° 7). Boletín FDT de ACM-SIGMOD, 7(3-4):23–28, 1975.
  • Codd, EF (1979). "Extending the database relational model to capture more meaning". ACM Transactions on Database Systems . 4 (4): 397– 434. CiteSeerX 10.1.1.508.5701 . doi : 10.1145/320107.320109 . S2CID 17517212 .  Especialmente el §2.3.
  • Date, CJ (2000). El modelo relacional de bases de datos: una revisión y análisis retrospectivos: un relato histórico y una evaluación de la contribución de E.F. Codd al campo de la tecnología de bases de datos . Addison Wesley Longman . ISBN 978-0-201-61294-3.
  • Klein, Hans-Joachim (1994). "Cómo modificar consultas SQL para garantizar respuestas seguras" . ACM SIGMOD Record . 23 (3): 14– 20. doi : 10.1145/187436.187445 . S2CID 17354724 . 
  • Claude Rubinson, Nulos, lógica trivalente y ambigüedad en SQL: crítica de la crítica de Date, archivado el 5 de marzo de 2016 en Wayback Machine , SIGMOD Record, diciembre de 2007 (Vol. 36, n.º 4).
  • John Grant, Valores nulos en SQL . SIGMOD Record, septiembre de 2008 (Vol. 37, No. 3)
  • Waraporn, Narongrit y Kriengkrai Porkaew. " Semántica nula para subconsultas y predicados atómicos ". IAENG International Journal of Computer Science 35.3 (2008): 305-313.
  • Thalheim, Bernhard; Schewe, Klaus-Dieter (2011). "Álgebras y lógicas de 'valor' NULL" . Frontiers in Artificial Intelligence and Applications . 225 (Modelado de información y bases de conocimiento XXII). doi : 10.3233/978-1-60750-690-4-354 .
  • Enrico Franconi y Sergio Tessaris, Sobre la lógica de los valores nulos SQL , Actas del 6.º Taller Internacional Alberto Mendelzon sobre Fundamentos de la Gestión de Datos, Ouro Preto, Brasil, 27-30 de junio de 2012, págs.  114-128 .
  • Valores NULL de Oracle archivados el 12/04/2013 en Wayback Machine.
  • El tercer manifiesto
  • Implicaciones de los valores NULL en la secuenciación de datos
  • Informe de error de Java sobre jdbc que no distingue entre cadena nula y vacía, que Sun cerró como "no es un error".