jueves, 22 de septiembre de 2011

Bases de datos (3ra parte)

En el pasado post escribí acerca de la importancia de una buena estructura en una base de datos, así que hoy toca escribir acerca de dicha estructura pero para protegernos de un posible un tanto común pero con escasa información de como resolverlo.

A este error le llamo "Ruptura de interrelación" y se origina cuando en un par de tablas relacionadas, a través del primary key, para accesar a los campos de una de otra se elimina un registro. Un ejemplo sería el siguiente, donde la tabla notas se interrelaciona con la tabla usuarios:

Tabla1: usuarios
Campos: id, nombre, edad
Fila1: 1, juan, 15
Fila2: 2, pedro, 20

Tabla 2: notas
Campos: id, id_usuario, nota
Fila1: 1, 2, hola
Fila2: 2, 1, como

La consulta de selección (select query) empleado para este ejemplo es (ansi):

SELECT DISTINCT notas.id, usuarios.nombre, usuarios.edad, notas.nota FROM notas, usuarios WHERE notas.id_usuario=usuarios.id

Con esta consulta el resultado sería:

1, pedro, 20, hola
2, juan, 15, como

Pero que pasaría sí se eliminara el registro 1 de la tabla usuarios con una consulta como:

DELETE FROM usuarios WHERE id=1

Al volver a ejecutar la consulta de selección sólo retornaría un resultado, siendo éste:

1, pedro, 20, hola

Ésto sucede por el error que denominé "Ruptura de interrelación" porque en la consulta sólo se seleccionan los registros cuyo campo notas.id_usuario = usuario.id ignorando aquellos que son notas.usuario = null.

Hay varias soluciones:

1.- Usar una cláusula como ésta: WHERE (notas.id_usuario=usuario.id OR notas.usarios=NULL).
2.- Usar los equivalentes a cada lenguaje sql de IF NOT EXISTS(usuario.id, 'algo',usuario.nombre)

Otra opción más es hacer uso de triggers y funciones para cambiar el campo notas.id_usuario a 0 cuando dicho id de usuario es eliminado y luego usar consultas como IF(notas.id_usuario=0, 'sinregistro', usuario.nombre).

En fin, como podrán leer existen varias formas, aparte de las mencionadas (como el if not null), para evitar esas rupturas de interrelación que pueden finalizar en registros innaccesibles por consultas de selección como la primera expuesta.

Así que les recomiendo por mucho que lean a fondo los manuales de consultas selección, triggers, funciones y reserved keywords propias del sql que esten usando.

No hay comentarios:

Publicar un comentario