Cita:
Fuente: http://es.debugmodeon.com/articulo/herencia-en-una-base-de-datos-relacionalVoy a suponer que tengo una jerarquía de herencia con tres clases: Persona, Cliente, Empleado. La clase Persona es abstracta y las otras son clases concretas que extienden de la primera. De un Cliente vamos a saber su número de tarjeta de crédito y de un empleado vamos a saber la cuenta bancaria donde se domicilian sus nóminas.
Esta es la clase Persona (Java):
La clase Cliente sólo añade un campo más:
Y la clase Empleado:
Bien, vamos a ver que tenemos tres estrategias para persistir estas clases en una base de datos relacional:
Voy a explicar detenidamente cada estrategia.
Una tabla por cada clase
Cada tabla contendrá los campos de cada clase. Los únicos campos que se repetirán serán los relativos a las claves primarias. Estas serían las sentencias para crear las tablas:
Los beneficios de esta estrategia son:
En caso de que se añadan campos a la clase Persona, sólo hay que añadir columnas a la tabla personas.
Si en ciertas consultas sólo necesitamos los datos comunes de clientes y empleados, sólo necesitamos un SELECT.
Los inconvenientes son:
Cuando se inserta un cliente o un empleado, hay que insertar en dos tablas.
Cuando se consultan datos de un cliente o un empleado, hay que hacer un JOIN.
La integridad referencial (claves foráneas/ajenas) pueden influir en el rendimiento de la base de datos.
Una tabla por cada clase concreta
Con esta estrategia las sentencias para crear las tablas serían las siguientes:
Los beneficios de esta estrategia son:
Cuando se inserta un cliente o un empleado sólo se actualiza una tabla.
Cuando se consultan datos de un cliente o un empleado sólo se consulta una tabla.
No hay restricciones referenciales.
Los inconvenientes son:
En caso de que se añadan campos a la clase Persona habría que modificar varias tablas.
Si en alguna consulta necesitamos datos de clientes y empleados tendríamos que hacer dos SELECT y unir los resultados. O hacer un UNION.
Una tabla para la jerarquía de herencia
Con esta estrategia sólo tendríamos una tabla:
He añadido una columna "tipo". Esa columna permitirá saber si el registro se refiere a un cliente o a un empleado. También he eliminado las restricciones "NOT NULL" tanto de la columna tarjetacredito como de la columna domiciliacionbancaria debido a que ahora podrán ser NULL. Si una persona es cliente tendrá domiciliacionbancaria a NULL y viceversa con el campo tarjetacredito si es un empleado.
Los beneficios de esta estrategia son:
Cuando se inserta un cliente o un empleado sólo se actualiza una tabla.
Cuando se consultan datos de un cliente o un empleado sólo se consulta una tabla.
No hay restricciones referenciales.
En caso de que se añadan campos a la clase Persona sólo habría que cambiar una tabla.
Los inconvenientes son:
Deberemos utilizar características avanzadas de la base de datos si queremos mantener las restricciones NOT NULL de ciertas columnas.
Conclusiones
En conclusión lo más común desde mi experiencia es utilizar la segunda o la tercera estrategias. Elegir entre ellas dependerá de las consultas que se han de hacer a la base de datos. Si por ejemplo en ningún momento hacemos una consulta que involucre tanto a clientes y empleados, quizá lo mejor será tener una tabla por cada clase concreta. Si por el contrario es común hacer listados que involucren a ambas clases, entonces lo mejor será utilizar una sola tabla.
Esta es la clase Persona (Java):
Código PHP:
public abstract class Persona {
private String nif;
private String nombre;
private String apellidos;
/* métodos get y set */
}
Código PHP:
public class Cliente extends Persona {
private String tarjetaCredito;
/* métodos get y set */
}
Código PHP:
public class Empleado extends Persona {
private String domiciliacionBancaria;
/* métodos get y set */
}
- Una tabla por cada clase. Por tanto tres tablas: personas, clientes, empleados.
- Una tabla por cada clase concreta (no abstracta). Dos tablas: clientes y empleados.
- Una tabla para la jerarquía de herencia. Una tabla: personas.
Voy a explicar detenidamente cada estrategia.
Una tabla por cada clase
Cada tabla contendrá los campos de cada clase. Los únicos campos que se repetirán serán los relativos a las claves primarias. Estas serían las sentencias para crear las tablas:
Código PHP:
CREATE TABLE personas (nif CHAR(9) NOT NULL,
nombre VARCHAR(50),
apellidos VARCHAR(50),
PRIMARY KEY(nif));
CREATE TABLE clientes (nif CHAR(9) NOT NULL,
tarjeta_credito CHAR(16) NOT NULL,
PRIMARY KEY(nif));
CREATE TABLE empleados (nif CHAR(9) NOT NULL,
domiciliacion_bancaria CHAR(20) NOT NULL,
PRIMARY KEY(nif));
ALTER TABLE clientes ADD FOREIGN KEY (nif) REFERENCES personas (nif);
ALTER TABLE empleados ADD FOREIGN KEY (nif) REFERENCES personas (nif);
En caso de que se añadan campos a la clase Persona, sólo hay que añadir columnas a la tabla personas.
Si en ciertas consultas sólo necesitamos los datos comunes de clientes y empleados, sólo necesitamos un SELECT.
Los inconvenientes son:
Cuando se inserta un cliente o un empleado, hay que insertar en dos tablas.
Cuando se consultan datos de un cliente o un empleado, hay que hacer un JOIN.
La integridad referencial (claves foráneas/ajenas) pueden influir en el rendimiento de la base de datos.
Una tabla por cada clase concreta
Con esta estrategia las sentencias para crear las tablas serían las siguientes:
Código PHP:
CREATE TABLE clientes (nif CHAR(9) NOT NULL,
nombre VARCHAR(50),
apellidos VARCHAR(50),
tarjeta_credito CHAR(16) NOT NULL,
PRIMARY KEY(nif));
CREATE TABLE empleados (nif CHAR(9) NOT NULL,
nombre VARCHAR(50),
apellidos VARCHAR(50),
domiciliacion_bancaria CHAR(20) NOT NULL,
PRIMARY KEY(nif));
Cuando se inserta un cliente o un empleado sólo se actualiza una tabla.
Cuando se consultan datos de un cliente o un empleado sólo se consulta una tabla.
No hay restricciones referenciales.
Los inconvenientes son:
En caso de que se añadan campos a la clase Persona habría que modificar varias tablas.
Si en alguna consulta necesitamos datos de clientes y empleados tendríamos que hacer dos SELECT y unir los resultados. O hacer un UNION.
Una tabla para la jerarquía de herencia
Con esta estrategia sólo tendríamos una tabla:
Código PHP:
CREATE TABLE personas (nif CHAR(9) NOT NULL,
nombre VARCHAR(50),
apellidos VARCHAR(50),
tipo CHAR(1) NOT NULL,
tarjeta_credito CHAR(16),
domiciliacion_bancaria CHAR(20),
PRIMARY KEY(nif));
Los beneficios de esta estrategia son:
Cuando se inserta un cliente o un empleado sólo se actualiza una tabla.
Cuando se consultan datos de un cliente o un empleado sólo se consulta una tabla.
No hay restricciones referenciales.
En caso de que se añadan campos a la clase Persona sólo habría que cambiar una tabla.
Los inconvenientes son:
Deberemos utilizar características avanzadas de la base de datos si queremos mantener las restricciones NOT NULL de ciertas columnas.
Conclusiones
En conclusión lo más común desde mi experiencia es utilizar la segunda o la tercera estrategias. Elegir entre ellas dependerá de las consultas que se han de hacer a la base de datos. Si por ejemplo en ningún momento hacemos una consulta que involucre tanto a clientes y empleados, quizá lo mejor será tener una tabla por cada clase concreta. Si por el contrario es común hacer listados que involucren a ambas clases, entonces lo mejor será utilizar una sola tabla.
Autor: gimenete
Referencia del Autor:
Gimenete es un tipo al que le encanta programar y cada vez más el mundo de los negocios. Lleva media vida programando en Java, y últimamente le da bastante a Objective-C para iOS y también a Python. No le hace ascos a JavaScript y otras hierbas