Uno de los aspectos fundamentales de las bases de datos relacionales son precisamente las relaciones. En pocas palabras, una «relación» es una asociación que se crea entre tablas, con el fin de vincularlas y garantizar la integridad referencial de sus datos.

Para que una relación entre dos tablas exista, la tabla que deseas relacionar debe poseer una clave primaria, mientras que la tabla donde estará el lado dependiente de la relación debe poseer una clave foránea, pero:

¿Qué es una clave primaria y una clave foránea?

Una clave primaria es un campo cuyos valores identifican de forma única cada registro dentro de la tabla. Este campo tiene la cláusula PRIMARY KEY.

La clave foránea, por su parte, es un campo dentro de la tabla cuyos valores hacen referencia a «claves primarias» en otra tabla. Este campo viene acompañado de la cláusula FOREIGN KEY.

Tanto la clave primaria, como las claves foráneas que hagan referencia a ella, deben ser del mismo tipo de dato.

Tipos de relaciones

Las bases de datos relacionales tienen diversos «tipos de relaciones» que podemos utilizar para vincular nuestras tablas.

Este «vínculo» va a depender de la cantidad de ocurrencias que tiene «un registro» de una tabla dentro de otra tabla (esto se conoce como cardinalidad).

Veamos los tipos de vínculos o relaciones:

Relaciones uno a uno

Se presentan cuando «un registro» de una tabla sólo está relacionado con «un registro» de otra tabla, y viceversa.

Por ejemplo, supongamos que nuestros empleados deben almacenar su información de contacto. Para este caso, pudiésemos leer la relación de esta manera:

«Un empleado tiene una sola información de contacto»
y
«Una información de contacto pertenece a un solo empleado»

Esta última forma de leer la relación se denomina inverso de la relación.

Dado que la información de contacto es la que depende principalmente del empleado, es en ella donde existirá la clave foránea para representar el vínculo.

Relaciones uno a muchos / muchos a uno

Esta relación es un poco más compleja que la anterior, así que vamos a usar las tablas A y B para explicarla.

Una relación de uno a muchos se presentan cuando «un registro» de la tabla A está relacionado con «ninguno o muchos registros» de la tabla B, pero este registro en la tabla B  solo está relacionado con «un registro» de la tabla A. Veamos un ejemplo de esto.

Supongamos que tenemos sucursales en las cuales trabajan nuestros empleados, pero cada empleado solo puede pertenecer a una sucursal. Para este caso, pudiésemos leer la relación de esta manera:

«Una sucursal tiene muchos (o ningún) empleados»
y
«Un empleado trabaja en una sola sucursal»

Dado que el empleado es el que necesita de la sucursal, es en él donde existirá la clave foránea para representar el vínculo.

Una sucursal puede existir sin que nadie trabaje todavía en ella.

Relaciones muchos a muchos

Estas son las relaciones más complejas, se presentan cuando «muchos registros» de una tabla se relacionan con «muchos registros» de otra tabla. Vamos a verlo en un ejemplo.

Supongamos que nuestros empleados trabajan en muchos turnos (horarios laborales). Por ejemplo, Juan trabaja en el turno de la mañana y de la noche, pero en el turno de la mañana trabajan Juan, Pedro y María.

En este caso, pudiésemos leer la relación de esta manera:

«Un empleado trabaja en muchos turnos»
y
«Un turno tiene muchos empleados»

Para este tipo de relación se crea una tabla intermedia conocida como tabla asociativa (en frameworks como Laravel suelen referirse a ella como tabla pivote). Por convención, el nombre de esta tabla debe estar formado por el nombre de las tablas participantes (en singular y en orden alfabético) separados por un guion bajo (_). Además, debe contener una clave foránea por cada una de sus tablas participantes.

Para nuestro ejemplo anterior, la tabla asociativa resultante de la relación sería:

CREATE TABLE employee_shift (
    id BIGINT UNSIGNED AUTO_INCREMENT,
    employee_id BIGINT UNSIGNED NOT NULL,
    shift_id BIGINT UNSIGNED NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (employee_id) REFERENCES employees (id),
    FOREIGN KEY (shift_id) REFERENCES shifts (id)
);

Creando una nueva relación de ejemplo

Vamos a suponer que tenemos sucursales en las cuales trabajan nuestros empleados, pero éstos solo pueden ser asignados a una sucursal.

Para crear este vínculo, primero debemos crear una nueva tabla llamada branches que tendrá las sucursales. Para ello, copia y pega el siguiente código en tu terminal:

CREATE TABLE branches (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(150) UNIQUE NOT NULL,
    start_date DATE NULL,
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL
);

Una vez creada la tabla, vamos a definir la relación, tomando como premisa que:

«Una sucursal tiene muchos empleados»
y
«Un empleado trabaja en una sola sucursal»

¿La recuerdas?

Sí, estamos frente a la relación uno a muchos entre sucursales (branches)  y empleados  (employees).

Pero antes de comenzar, vamos a verificar que nuestra tabla employees tenga un campo branch_id para crear el vínculo, ejecutando el comando DESC employees en la terminal:

+------------+---------------------+------+-----+---------+----------------+
| Field      | Type                | Null | Key | Default | Extra          |
+------------+---------------------+------+-----+---------+----------------+
| id         | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| branch_id  | bigint(20) unsigned | YES  |     | NULL    |                |
| dni        | varchar(20)         | YES  | UNI | NULL    |                |
| first_name | varchar(100)        | YES  |     | NULL    |                |
| last_name  | varchar(100)        | YES  |     | NULL    |                |
| birth_date | date                | YES  |     | NULL    |                |
| created_at | timestamp           | YES  |     | NULL    |                |
| updated_at | timestamp           | YES  |     | NULL    |                |
+------------+---------------------+------+-----+---------+----------------+
8 rows in set (0.006 sec)

Ahora sí, una vez que estemos seguros que el campo para la clave foránea existe, vamos a crear el índice sobre él:

MariaDB [storage]> CREATE INDEX branch_id ON employees (branch_id);

Sobre los índices, su uso e importancia te hemos hablado en nuestro libro Aprende SQL con MySQL y MariaDB, si deseas conocer más sobre este tema, te invito a leerlo.

Finalmente, creamos la clave foránea de esta manera:

MariaDB [storage]> ALTER TABLE employees ADD FOREIGN KEY (branch_id) REFERENCES branches (id);

El vínculo creado entre la clave primaria y foránea de las tablas nos permite tenerlas relacionadas.

El comando ALTER TABLE usa la cláusula ADD FOREIGN KEY seguida del campo que servirá de clave foránea. Luego se agrega la palabra reservada REFERENCES, seguida de la tabla a la que se hará referencia y el nombre del campo que será relacionado.

En otras palabras, el campo branch_id de la tabla employees tendrá valores que son «claves primarias» dentro de la tabla branches en su campo id.

En la siguiente lección siguiente aprenderemos a insertar y consultar los datos de estas tablas, además, veremos cómo con el uso de la clave foránea podemos acceder a la información relacionada.

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.

Lección anterior Modificar tablas en MySQL / MariaDB Lección siguiente Insertar y Consultar datos en MySQL / MariaDB