Conoce SQL – Restricciones – NOT NULL

1- B: Restricción NOT NULL

Algo que también he notado bastante es la ausencia del uso de los valores nulos y que muchas veces son sustituidos indebidamente por 0 en caso de valores numéricos o por cadenas vacías en caso de cadenas de texto.

Tanto a nivel conceptual como a nivel técnico es mucho más correcto usar el valor nulo para indicar que “no hay nada” en vez de un 0 o cadena vacía. Puede parecer algo semejante pero no es lo mismo.

Para un sistema gestor de bases de datos, tanto un 0 como una cadena vacía es contenido y como contenido que es se le reserva un espacio en disco, en memoria y se le trata igual que a un dato normal. Aquí ya tenemos la primera pérdida de eficiencia.

Si queremos trabajar con esos datos y por ejemplo obtener las filas que tengan como columna “nombre” la cadena de texto “” (vacío). Aquí el sistema gestor hace las búsquedas a nivel de cadena de texto (si duda los más duro para un ordenador) y ya tenemos más perdida de eficiencia.

Conceptualmente tampoco es válido porque un 0 o una cadena vacía es algo aunque nosotros no lo consideremos así en ciertos casos. Muchas veces estos problemas “coneptuales” no afectan al funcionamiento del programa pero dificultan en gran medida la comprensión y funcionamiento coherente del programa. Aunque también es cierto que fallos conceptuales terminan desembocando en bugs.
Recuerda que mientras escribes código sabes lo que hace ese código pero dentro de unos meses volverás a ese código y necesitaras horas hasta saber por qué haces tal cosa. Y ya no te cuento si le toca leer ese código a otra persona. Desde aquí aprovecho para decir que un buen diseño coneptual es lo que diferencia un buen software de un software chapucero así que si piensas hacer algo medianamente grande te recomendaría encarecidamente que antes de tocar el teclado pienses muy bien el funcionamiento del programa.

Pero una de las grandes ventajas de usar nulos es que, siguiendo una de las reglas de Codd, los sistemas gestores están preparados para usar valores nulos. Tenemos muchas funciones y utilidades proporcionadas por el sistema gestor para tratar con esos valores nulos que nos ayudan bastante para crear consultas. Aunque en esta sección me limitaré a explicar qué es NOT NULL y como usarlo.

Vamos con un ejemplo

Tenemos la tabla de envios con la descripcion del paquete y la fecha de entrega. En ciertas ocasiones he visto que en la tabla se añade una columna más llamada “entregado” cuyo valor puede suele ser o “si/no” o “0/1” (aquí entraria el problema de y si en vez de si/no pongo “jo” o vez de 0/1 pongo 7, esas validaciones las veremos más tarde, ahora solo quería exponer los chapucero que resulta eso jeje). Aquí volvemos a perder eficiencia ya que usamos otra columna. Me pongo pesadito con estas cosas porque con 4 datos ni se nota pero cuando tengas miles de registros y la base de datos te empieza a ir lenta pensarás “Ay si lo hubiera hecho bien desde el principio…”.

Otra manera sería poner la fecha como “0000-00-00” cuando no está entregado. Esta solución es mejor que la anterior pero tampoco es la ideal porque por ejemplo si quieremos mostrar todos los paquetes no entrados realizaría comparaciones comparando fechas, algo mucho más duro que si fueran nulos. Pero otro problema mayor es si queremos ver todos los paquetes entregados antes del 2009. Nos aparecerían además de los paquetes que queremos, todos los paquetes no entregados con lo que seria necesario que en la consulta se especificara que no queremos los de la fecha 0000-00-00 con lo que la consulta tardaría mínimo el doble de tiempo.

echo “Paquetes entregados antes del 2009″;
$sql=”SELECT descripcion,fecha FROM paquetes WHERE entrega<STR_TO_DATE(’01/01/2009′, ‘%m/%d/%Y’) and entrega!=STR_TO_DATE(’00/00/0000′, ‘%m/%d/%Y’);
while($paquete=mysql_fetch_array(mysql_query($sql),MYSQL_ASSOC))
{
echo $paquete[‘descripcion’].” entregado el día “.$paquete[‘fecha’].”<br>”;
}

La solución ideal sería usar valores nulos y así ademas de ganar en eficiencia evitamos sorpresas como la anterior, que quizá no nos daríamos cuenta hasta que veríamos por pantalla datos incorrectos.

echo “Paquetes entregados antes del 2009″;
$sql=”SELECT descripcion,fecha FROM paquetes WHERE entrega is not null and entrega<STR_TO_DATE(’01/01/2009′, ‘%m/%d/%Y’)
while($paquete=mysql_fetch_array(mysql_query($sql),MYSQL_ASSOC))
{
echo $paquete[‘descripcion’].” entregado el día “.$paquete[‘fecha’].”<br>”;
}

Esto es un caso donde sería correcto usar valores nulos pero hay otros en los que es necesario que haya información entonces para eso esta la restricción NOT NULL.

Por ejemplo vamos a suponer que identificamos cada paquete con un código de 5 letras por ejemplo para que el cliente pueda hacer desde la página web un seguimiento de dicho paquete. Es necesario que haya un código así que en este caso podríamos usar NOT NULL (realmente sería clave primaria pero eso ya lo veremos otro día).

create table paquetes(
codigo CHAR(5) NOT NULL,
descripcion VARCHAR(25) NOT NULL,
entrega DATE
);

insert into paquetes (descripcion) values (‘Un paquete muy bonito’);

Aquí MySQL no dará error porque en el código pondrá un codigo vacío pero sin embargo la fecha sí será nula. Personalmente no veo bien que mysql meta el campo vacío pero bueno, forcemos el error.

insert into paquetes (codigo,descripcion) values (null,’Un paquete muy bonito’);

Fíjate que cuando usamos null para indicar valor nulo no se ponen comillas.

Este tema este de los nulos es algo dificilillo de comprender si nunca has trabajado con ellos pero hazme caso cuando te digo que son realmente útiles. Quizá ahora pienses “nulos, pues vale” y no te culpo si todavía no les ves utilidad pero segun vayamos avanzando te irán gustando. Por hoy me conformo con que sepas que existen los valores nulos y que también podemos prohibir el uso de valores nulos (not null).

Nos vemos en el siguiente capítulo.

You may also like...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *