Así como en la orientación a objetos, algunas clases se relacionan con otras, ya sea a través de la herencia o la composición, cuando nuestros objetos deben guardar un almacén de datos, esa relación, debe conservarse también en la base de datos de nuestra aplicación.
Si te fijas el siguiente esquema, puede entenderse como dos objetos con sus propiedades y a la vez, como dos tablas, relacionadas entre sí:
El objeto producto, se relaciona directamente con el objeto categoría. Esto significa que nuestros productos, pertenecen a una categoría determinada. Se relacionan a través del campo-propiedad, categoria_id
.
Para crear bases de datos relacionales, primero debemos crear nuestros modelos, a fin de obtener las relaciones que serán necesarias:
class Categoria(object):
categoria_id = 0;
categoria = ""
activa = True
class Producto(object):
producto_id = 0
categoria = Categoria()
producto = ""
precio = 0.0
descripcion = ""
Una vez que tenemos los modelos, podemos pasar a crear las tablas:
CREATE TABLE categoria(
categoria_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
categoria VARCHAR(25) NOT NULL,
activa BOOL
) ENGINE=InnoDB;
CREATE TABLE producto(
producto_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
categoria_id INT(11) NOT NULL,
producto VARCHAR(255) NOT NULL,
precio DECIMAL(7, 2) NOT NULL,
descripcion BLOB,
FOREIGN KEY (categoria_id)
REFERENCES categoria(categoria_id)
) ENGINE=InnoDB;
Nota Cuando el campo de una tabla hace referencia a la clave primaria de otra tabla, se denomina “+clave foránea o foreign key (en inglés). Para poder utilizar claves foráneas, MySQL necesita utilizar sí o sí, el motor InnoDB ya que es el único con soporte para éstas.
Como podrás observar, el campo de la tabla producto, que hace referencia a la clave primaria de la tabla categoría, se llama igual (categoria_id
). Podría tener un nombre diferente, pero más adelante lo veremos. Este campo, debe ser creado en la tabla, como cualquier campo común. La principal diferencia, radica en que debemos indicar que este campo, debe ser tratado como una clave foránea.
Para ello, utilizamos la siguiente sintaxis:
FOREIGN KEY (nombre_de_la_clave_foranea) REFERENCES tabla_relacionada(nombre_de_la_clave_primaria)
En lenguaje humano, esto se leería como sigue: la clave foránea es FK
(FOREIGN KEY (FK)
) que hace referencia a la tabla TABLA
a través del campo PK
(REFERENCES TABLA(PK)
).
Nota FK
es una Foreign Key (clave foránea) mientras que PK
es una Primary Key (clave primaria).
Esto significa que siempre que debamos relacionar un campo con otro, el campo relacionado deberá indicarse como Foreign Key mientras que el campo al cuál hace referencia, deberá indicarse como Primary Key.
Luego, podremos obtener, desde la base de datos, el objeto producto, incluyendo los datos a los cuáles hace referencia. Para ello, utilizaremos la siguiente consulta:
SELECT producto.*, categoria.*
FROM producto INNER JOIN categoria USING(categoria_id)
Con SELECT producto.*, categoria.*
estamos seleccionando todos los campos
de la tabla producto y todos los campos de la tabla categoria. Mientras que con FROM producto INNER JOIN categoria USING(categoria_id)
, estamos diciendo que: desde la tabla producto
unida internamente a la tabla categoria
(FROM producto INNER JOIN categoria
) utilizando el campo categoria_id
(USING(categoria_id)
).
Cómo comentamos anteriormente, una FK
no necesariamente debe llevar el mismo nombre que la clave primaria a la cuál hace referencia. Podríamos, por ejemplo, haber creado nuestra tabla producto de la siguiente manera:
CREATE TABLE producto(
producto_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
FK_categoria INT(11) NOT NULL,
producto VARCHAR(255) NOT NULL,
precio DECIMAL(7, 2) NOT NULL,
descripcion BLOB,
FOREIGN KEY (FK_categoria)
REFERENCES categoria(categoria_id)
) ENGINE=InnoDB;
Pero en este caso, deberíamos modificar la sintaxis de nuestra consulta:
SELECT producto.*, categoria.*
FROM producto INNER JOIN categoria
ON producto.FK_categoria = categoria.categoria_id
Es decir, que ya no podemos indicarle que utilice el campo homónimo en ambas tablas, sino, que para realizar esta unión interna se base en la condición de igualdad del valor de los mismo (campo foráneo y primario respectivamente).