martes, 29 de marzo de 2011

De las claves ajenas, foráneas, externas…

El modelo relacional no sería nada sin claves ajenas. Foreign key, lo encontraréis traducido de todas las formas posibles: ajena, externa, aliena, alienígena…

El modelo relacional no usa el tradicional e imprescindible puntero. Los punteros son para programadores, no para usuarios “normales”, y el modelo relacional tiene vocación de “llegar a las masas”. El puntero apunta a un dato concreto y sólo a uno, de hecho es una dirección física de memoria. En el modelo relacional, un valor “apunta” a todos los sitios donde se utilice ese mismo valor. La referencia se consigue por comparación, por igualdad.


Entonces, ¿para qué queremos las claves ajenas? SQL, por ejemplo, hace como que no conoce ni claves ajenas ni primarias para resolver las consultas, somos nosotros los que de forma explícita debemos comparar los valores de esas columnas. Dos son, realmente, las funciones de las claves ajenas, no necesariamente en este orden:
  1. asegurar la integridad referencial y
  2. permitirnos modelar nuestro sistema de información a nuestro gusto.
    Hablemos de esto último. La palabra clave es “simultaneidad”: ¿de cuántas asignaturas puede estar matriculado un alumno en un momento dado? Y el marco temporal en el que responder a esta pregunta es “en cada estado de la base de datos”. Si entendemos un estado de base de datos como una fotografía que le hacemos a la base de datos cada vez que se produce un cambio en ésta, estos cambios consisten en que habrá una fila más o una fila menos, o que un dato ha cambiado de valor, pero las columnas de cada tabla son siempre las mismas, y las reglas impuestas a cada una también.

    La estructura de base de datos —el esquema— que diseñemos determinará la forma en que un usuario va a poder manejar la información. Si he matriculado al alumno A en la asignatura B, ¿puedo matricular a A también en C, o debo desmatricularlo antes de B? ¿Puedo dar de alta a un alumno sin matricularlo de ninguna asignatura? La respuesta a estas preguntas determinará dónde debo colocar la clave ajena —o claves— y decidir si esa clave ajena permite o no nulos y duplicados.
    Supongamos la siguiente tabla ALUMNO —se supone que también existe una tabla ASIGNATURAS; en este estado de base de datos, tanto Pepe como Juan y Manolo, están matriculados de una asignatura:

    21 Pepe BD1
    34 Juan BD1
    55 Manolo AESI


    En este otro estado de base de datos, aunque Pepe ha cambiado, todos siguen matriculados de una única asignatura:

    21 Pepe FP2
    34 Juan BD1
    55 Manolo AESI


    Y siempre será así, la clave ajena, que se supone que es la columna con los acrónimos de asignaturas, está colocada ahí, en la propia tabla alumno, y nunca veremos a Pepe —en realidad, a “21″ que no lo hemos dicho, pero es su valor de clave primaria— con dos asignaturas al mismo tiempo.
    Pero, ¿y si quiero que mis alumnos se puedan matricular de todas las asignaturas que quiera? Una solución sería una tabla adicional donde irían las claves ajenas.


    ALUMNOS
    21 Pepe
    34 Juan
    55 Manolo


    MATRICULAS
    21 BD1
    21 FP2
    34 BD1
    55 AESI


    Pepe, en este estado de base de datos y en cualquier otro, puede matricularse de tantas asignaturas como quiera. Y como él, cualquier alumno. Hemos cambiado el esquema de base de datos, hemos cambiado de sitio las claves ajenas. Tenemos otra base de datos, con otras reglas.