Cuando escuchamos el término "herencia", es común que nuestra mente viaje al mundo de la Programación Orientada a Objetos (OOP). Allí, la herencia es un pilar fundamental que nos permite construir nuevas clases basadas en otras existentes, reutilizando código y definiendo comportamientos especializados. Pero, ¿sabías que el concepto de herencia también tiene una aplicación en el ámbito de las bases de datos? Aunque similar en nombre, su propósito e implementación son distintos y se centran en la estructura y organización de los datos.

Este artículo desentrañará qué significa realmente la herencia cuando hablamos de bases de datos, cómo se implementa en algunos sistemas y en qué se diferencia de su prima de la programación. También abordaremos la confusión común entre la herencia de estructuras de datos y el término "base de datos heredada", que tiene un significado completamente diferente.

- ¿Qué es la Herencia en el Contexto de Bases de Datos?
- Implementación de la Herencia de Tablas en SQL (Ejemplo con PostgreSQL)
- Herencia en Bases de Datos vs. Herencia en Programación Orientada a Objetos (OOP)
- ¿Qué es una "Base de Datos Heredada"?
- Tipos de Herencia en Bases de Datos (según Implementación)
- Ventajas y Desventajas de la Herencia de Tablas
- Preguntas Frecuentes (FAQ)
- Conclusión
¿Qué es la Herencia en el Contexto de Bases de Datos?
A diferencia de la herencia en OOP, que se enfoca en la reutilización de código y comportamiento a través de clases, la herencia en bases de datos, específicamente la herencia de tablas, se trata de la reutilización de la *estructura* de datos. Permite definir una tabla (la tabla hija o derivada) que hereda las columnas y, a menudo, ciertas restricciones de otra tabla (la tabla padre o base).
Imagina que tienes diferentes tipos de entidades que comparten muchas características comunes pero también tienen algunas propias. Por ejemplo, podrías tener una tabla general para "Vehículos" con columnas como `marca`, `modelo`, `año`. Luego, podrías tener tablas más específicas como "Coches" y "Camiones". Un coche es un vehículo, y un camión también es un vehículo. En lugar de duplicar las columnas `marca`, `modelo` y `año` en las tablas `coches` y `camiones`, puedes hacer que estas últimas *hereden* esas columnas de la tabla `vehiculos`.
La herencia de tablas permite modelar relaciones jerárquicas de "es un tipo de" directamente en el esquema de la base de datos. La tabla hija obtiene implícitamente todas las columnas de la tabla padre, y puede añadir sus propias columnas adicionales para sus características específicas. Esto no solo ayuda a mantener el esquema organizado y a evitar la duplicación de definiciones de columnas, sino que también facilita la consulta de datos a través de toda la jerarquía.
Implementación de la Herencia de Tablas en SQL (Ejemplo con PostgreSQL)
Aunque el concepto de herencia de tipos existe en el estándar SQL (desde SQL:1999), la implementación más conocida y utilizada de la herencia de *tablas* se encuentra en sistemas como PostgreSQL. Veamos cómo funciona usando un ejemplo práctico, similar al proporcionado:
Supongamos que queremos modelar ciudades, donde algunas son capitales de estado.
Primero, creamos la tabla padre, `ciudades`:
CREATE TABLE ciudades (
nombre text,
poblacion float,
elevacion int -- en pies
);Luego, creamos la tabla hija, `capitales`, que hereda de `ciudades`. Añadimos una columna específica para las capitales:
CREATE TABLE capitales (
estado char(2)
) INHERITS (ciudades);La tabla `capitales` ahora tiene implícitamente las columnas `nombre`, `poblacion` y `elevacion` de `ciudades`, además de su propia columna `estado`.
Consultando Datos con Herencia
Una de las principales ventajas de la herencia de tablas en PostgreSQL es cómo maneja las consultas. Por defecto, una consulta `SELECT` sobre una tabla padre incluirá automáticamente las filas de todas sus tablas hijas (y descendientes).
Si insertamos datos (es importante notar que los `INSERT` se dirigen siempre a una tabla específica):
INSERT INTO ciudades (nombre, poblacion, elevacion) VALUES ('Las Vegas', 651319, 2174);
INSERT INTO ciudades (nombre, poblacion, elevacion) VALUES ('Mariposa', 1826, 1953);
INSERT INTO capitales (nombre, poblacion, elevacion, estado) VALUES ('Madison', 258054, 845, 'WI');Si consultamos la tabla `ciudades` para buscar ciudades con elevación mayor a 500 pies:
SELECT nombre, elevacion FROM ciudades WHERE elevacion > 500;Esto retornará filas tanto de `ciudades` como de `capitales`:
nombre | elevacion
-----------+-----------
Las Vegas | 2174
Mariposa | 1953
Madison | 845Si solo queremos consultar la tabla padre *sin* incluir las hijas, usamos la palabra clave `ONLY`:
SELECT nombre, elevacion FROM ONLY ciudades WHERE elevacion > 500;Esto solo retornará las filas que están *directamente* en la tabla `ciudades`:
nombre | elevacion
-----------+-----------
Las Vegas | 2174
Mariposa | 1953Identificando el Origen de la Fila
Para saber de qué tabla específica proviene una fila en una consulta que abarca la jerarquía, puedes usar la columna de sistema `tableoid`. Esta columna contiene el Identificador de Objeto (OID) de la tabla de origen. Puedes unirla con `pg_class` para obtener el nombre de la tabla, o usar el tipo `regclass` para una salida más legible:
SELECT c.tableoid::regclass, c.nombre, c.elevacion
FROM ciudades c
WHERE c.elevacion > 500;Esto podría mostrar:
tableoid | nombre | elevacion
----------+-----------+-----------
ciudades | Las Vegas | 2174
ciudades | Mariposa | 1953
capitales | Madison | 845Restricciones y Herencia
En PostgreSQL, las restricciones `CHECK` y `NOT NULL` definidas en una tabla padre se heredan automáticamente por las tablas hijas, a menos que se especifique lo contrario con `NO INHERIT`. Sin embargo, es crucial notar que otros tipos de restricciones, como las restricciones `UNIQUE`, `PRIMARY KEY` y `FOREIGN KEY`, no se heredan. Cada tabla hija debe definir sus propias claves primarias y foráneas si son necesarias.
Herencia Múltiple de Tablas
Una tabla en PostgreSQL puede heredar de más de una tabla padre. En este caso, la tabla hija tendrá la unión de todas las columnas definidas en las tablas padre, más cualquier columna definida directamente en la hija. Si una columna con el mismo nombre aparece en múltiples padres (o en un padre y la hija), se "fusionan" en una única columna en la hija, siempre y cuando tengan el mismo tipo de dato. Las restricciones `CHECK` y `NOT NULL` heredadas también se fusionan de manera similar.

Manejo de Datos (INSERT, UPDATE, DELETE)
Como mencionamos, las sentencias `INSERT` siempre insertan datos solo en la tabla especificada. No hay un mecanismo automático para "enrutar" una inserción a una tabla hija adecuada basándose en los datos proporcionados. Si necesitas este comportamiento, tendrías que implementarlo usando reglas (`RULES`) o disparadores (`TRIGGERS`), aunque esto puede añadir complejidad.
Las sentencias `UPDATE` y `DELETE` que se ejecutan sobre una tabla padre (sin `ONLY`) afectarán a las filas correspondientes en las tablas hijas. Por ejemplo, un `UPDATE` en `ciudades` podría modificar filas en `capitales` si cumplen las condiciones de la cláusula `WHERE`.
Modificando la Jerarquía
Puedes modificar una jerarquía de herencia existente. Es posible añadir o eliminar una relación de herencia a una tabla ya definida utilizando `ALTER TABLE INHERIT` y `ALTER TABLE NO INHERIT`, respectivamente. La tabla que se convierte en hija debe tener previamente una estructura compatible (mismas columnas y restricciones heredables) con la tabla padre.
Eliminar una tabla padre que tiene hijas requerirá el uso de la opción `CASCADE`, lo que eliminará también a todas las tablas hijas. De manera similar, no puedes eliminar o modificar columnas o restricciones en una tabla hija si son heredadas de un padre, a menos que uses `CASCADE` en el padre.
Herencia en Bases de Datos vs. Herencia en Programación Orientada a Objetos (OOP)
Es vital distinguir claramente la herencia en bases de datos de la herencia en OOP, ya que, a pesar del nombre, sirven a propósitos diferentes:
- Propósito: En bases de datos, el objetivo principal es la reutilización de la estructura del esquema (columnas, algunas restricciones) y facilitar consultas unificadas sobre datos jerárquicos. En OOP, el objetivo es la reutilización de código y comportamiento, la extensibilidad y el polimorfismo.
- Qué se Hereda: En bases de datos (ej. PG), se heredan definiciones de columnas y ciertas restricciones. Los datos residen en las tablas concretas. En OOP, se heredan miembros (propiedades, métodos) y la clase hija puede extender o modificar el comportamiento del padre (polimorfismo).
- Manejo de Datos/Objetos: Las operaciones sobre datos en bases de datos (INSERT, UPDATE, DELETE) tienen comportamientos específicos en jerarquías. En OOP, se crean instancias de clases específicas, y los métodos llamados dependen del tipo real del objeto (polimorfismo).
- Soporte: La herencia de tablas no es una característica estándar en todos los sistemas de gestión de bases de datos relacionales (SGBDR). Es una característica específica de algunos, como PostgreSQL. La herencia es una característica fundamental y ampliamente soportada en la mayoría de los lenguajes de programación orientada a objetos.
Una tabla comparativa puede ayudar a visualizar estas diferencias:
| Característica | Herencia en Bases de Datos (ej. PostgreSQL) | Herencia en Programación Orientada a Objetos (OOP) |
|---|---|---|
| Concepto Principal | Reuso de estructura (columnas, constraints) y consultas jerárquicas de datos. | Reuso de código, comportamiento y polimorfismo. |
| Aplicado a | Tablas (esquema y datos). | Clases (código y objetos). |
| Qué se Hereda | Columnas, restricciones CHECK/NOT NULL. | Miembros (propiedades, métodos). |
| Relación Típica | "Es un tipo de" (ej. Capital *es una* Ciudad). | "Es un" o "Tiene un comportamiento de". |
| Manejo de Datos/Objetos | Datos residen en tablas específicas; consultas pueden abarcar la jerarquía. | Objetos son instancias de clases específicas. |
| Polimorfismo | Limitado a cómo las consultas tratan la jerarquía. | Clave para redefinir métodos en clases derivadas. |
| Constraints (PG) | CHECK, NOT NULL heredados; PK, FK, UNIQUE no. | N/A directamente (se maneja en lógica de negocio). |
| Implementación | Varia según el SGBD (ej. INHERITS en PostgreSQL). | Característica fundamental en lenguajes OOP. |
¿Qué es una "Base de Datos Heredada"?
Otro punto de confusión que surge es el término "base de datos heredada". Este término no tiene relación alguna con el concepto de herencia de tablas o esquemas que hemos descrito. Una "base de datos heredada" (o legacy database en inglés) se refiere a un sistema de base de datos antiguo, a menudo crítico para las operaciones de una organización, que sigue en uso pero que puede ser difícil de mantener, actualizar o integrar con tecnologías modernas.
Estas bases de datos heredadas suelen ser sistemas que se implementaron hace muchos años, a menudo en tecnologías que ya no son las predominantes (por ejemplo, sistemas jerárquicos, de red o versiones muy antiguas de bases de datos relacionales). Pueden tener esquemas complejos y poco documentados, depender de hardware obsoleto, y requerir personal con habilidades específicas difíciles de encontrar.
El hecho de que se les llame "heredadas" viene de que han sido *heredadas* del pasado, no porque implementen algún tipo de herencia en su diseño de esquema. El desafío con las bases de datos heredadas es a menudo la necesidad de modernizar, migrar o coexistir con sistemas más nuevos, lo cual puede ser un proceso costoso y arriesgado.
La razón por la que las organizaciones a menudo se enfrentan a este desafío es que las bases de datos relacionales tradicionales, aunque robustas en cuanto a consistencia (ACID), a veces no pueden satisfacer las demandas de escalabilidad y disponibilidad de las aplicaciones web modernas con millones de usuarios concurrentes y altos volúmenes de datos. Esto llevó al surgimiento de nuevas arquitecturas como NoSQL y NewSQL. Las bases de datos heredadas son, típicamente, esos sistemas relacionales tradicionales que luchan por adaptarse a las nuevas exigencias de rendimiento y escalabilidad, o simplemente sistemas antiguos que necesitan ser reemplazados.

Tipos de Herencia en Bases de Datos (según Implementación)
En el contexto de la herencia de tablas, podemos identificar principalmente dos tipos, basados en la estructura de la jerarquía:
- Herencia Simple: Una tabla hija hereda de una única tabla padre. Este es el caso más común y sencillo (ej. `capitales` heredando de `ciudades`).
- Herencia Múltiple: Una tabla hija hereda de dos o más tablas padre. La hija combina las columnas y restricciones heredables de todos sus padres. Esto permite modelar entidades que son especializaciones de múltiples categorías base.
Es importante recordar que esta clasificación se basa en la implementación específica de la herencia de tablas en SGBDR como PostgreSQL, y no en un estándar SQL universal para este tipo de herencia.
Ventajas y Desventajas de la Herencia de Tablas
Ventajas:
- Reutilización de Estructura: Evita la duplicación de definiciones de columnas y restricciones comunes en múltiples tablas.
- Organización Lógica: Permite modelar jerarquías "es un tipo de" de manera intuitiva en el esquema.
- Consultas Simplificadas: Facilita la consulta de datos que residen en diferentes tablas de la jerarquía con una sola sentencia `SELECT` sobre la tabla padre.
- Mantenimiento: Los cambios en la estructura de la tabla padre (ej. añadir una columna) pueden propagarse automáticamente a las tablas hijas en algunos sistemas (como PostgreSQL con `ALTER TABLE`).
Desventajas:
- Soporte Limitado: No es una característica estándar y su implementación varía entre SGBDRs.
- Complejidad en Operaciones de Datos: La inserción de datos requiere dirigir la sentencia `INSERT` a la tabla hija específica, y no hay enrutamiento automático. Las operaciones `UPDATE` y `DELETE` sobre la tabla padre afectan a las hijas, lo que requiere cuidado.
- Restricciones no Heredadas: En implementaciones como la de PostgreSQL, las restricciones clave como `PRIMARY KEY`, `UNIQUE` y `FOREIGN KEY` no se heredan, lo que significa que deben definirse explícitamente en cada tabla hija, añadiendo complejidad al diseño y mantenimiento de la integridad referencial.
- Posible Impacto en el Rendimiento: Consultar jerarquías muy grandes o profundas puede tener implicaciones en el rendimiento, aunque los SGBDRs optimizados para esta característica intentan minimizar esto.
Preguntas Frecuentes (FAQ)
¿La herencia de tablas es parte del estándar SQL?
El estándar SQL (desde SQL:1999) define la herencia de *tipos*, que es un concepto relacionado pero diferente a la herencia de *tablas* implementada en sistemas como PostgreSQL. La herencia de tablas como la describe este artículo no es una característica universalmente estandarizada en todos los SGBDRs.
¿Todos los sistemas de bases de datos relacionales soportan la herencia de tablas?
No. Es una característica específica de algunos SGBDRs, siendo PostgreSQL el ejemplo más prominente. Otros sistemas populares como MySQL, SQL Server u Oracle no la soportan de la misma manera nativa, aunque pueden ofrecer soluciones alternativas para modelar estructuras jerárquicas (como tablas únicas con columnas de tipo, o tablas separadas gestionadas por lógica de aplicación).
¿Cómo inserto datos en una tabla que participa en una jerarquía de herencia?
Las sentencias `INSERT` deben dirigirse a la tabla específica donde residirá la fila (la tabla hija o la tabla padre si la fila solo es de ese tipo). No hay un mecanismo automático para insertar en la tabla padre y que la base de datos decida en qué tabla hija debe ir la fila.
¿Se heredan automáticamente las claves primarias y foráneas?
En la implementación de PostgreSQL, las restricciones `PRIMARY KEY`, `UNIQUE` y `FOREIGN KEY` NO se heredan. Debes definir estas restricciones explícitamente en cada tabla hija si son necesarias para mantener la integridad de los datos en esa tabla.
¿Una consulta a una tabla padre siempre incluye las filas de las tablas hijas?
Sí, por defecto, una consulta `SELECT` a una tabla padre incluirá las filas de todas sus tablas descendientes. Para limitar la consulta solo a la tabla padre, debes usar la palabra clave `ONLY` antes del nombre de la tabla.
¿Puedo añadir o eliminar herencia a una tabla existente?
Sí, en PostgreSQL puedes usar `ALTER TABLE ... INHERIT ...` para añadir una relación de herencia y `ALTER TABLE ... NO INHERIT ...` para eliminarla. La tabla hija debe ser estructuralmente compatible con el padre.
Conclusión
La herencia en bases de datos, específicamente la herencia de tablas como la encontramos en PostgreSQL, es una herramienta poderosa para modelar relaciones jerárquicas y reutilizar la estructura del esquema. Permite organizar la información de manera lógica y simplifica las consultas sobre conjuntos de datos relacionados distribuidos en varias tablas. Sin embargo, es fundamental entender que este concepto es distinto de la herencia en la programación orientada a objetos y no debe confundirse con el término "base de datos heredada", que se refiere a sistemas antiguos en producción. Aunque no es una característica universal en todos los SGBDRs, cuando está disponible, puede ser una opción de diseño muy útil para ciertos escenarios.
Si quieres conocer otros artículos parecidos a Herencia en Bases de Datos: Más Allá de OOP puedes visitar la categoría Bases de datos.

Aprende mas sobre MySQL