Saltar al contenido

¿Cómo se puede representar la herencia en una base de datos?

El tutorial o código que verás en este artículo es la solución más sencilla y efectiva que hallamos a tu duda o problema.

Solución:

@Bill Karwin describe tres modelos de herencia en su libro SQL Antipatterns, al proponer soluciones para el antipatrón SQL Entity-Attribute-Value. Esta es una breve descripción general:

Herencia de tabla única (también conocida como herencia de tabla por jerarquía):

Usar una sola tabla como en su primera opción es probablemente el diseño más simple. Como mencionaste, muchos attributes que son específicos de subtipo deberán recibir una NULL valor en filas donde estos attributes no apliques. Con este modelo, tendría una tabla de políticas, que se vería así:

+------+---------------------+----------+----------------+------------------+
| id   | date_issued         | type     | vehicle_reg_no | property_address |
+------+---------------------+----------+----------------+------------------+
|    1 | 2010-08-20 12:00:00 | MOTOR    | 01-A-04004     | NULL             |
|    2 | 2010-08-20 13:00:00 | MOTOR    | 02-B-01010     | NULL             |
|    3 | 2010-08-20 14:00:00 | PROPERTY | NULL           | Oxford Street    |
|    4 | 2010-08-20 15:00:00 | MOTOR    | 03-C-02020     | NULL             |
+------+---------------------+----------+----------------+------------------+

------ COMMON FIELDS -------/          ----- SUBTYPE SPECIFIC FIELDS -----/

Mantener el diseño simple es una ventaja, pero los principales problemas con este enfoque son los siguientes:

  • Cuando se trata de agregar nuevos subtipos, tendría que modificar la tabla para acomodar la attributes que describen estos nuevos objetos. Esto puede volverse problemático rápidamente cuando tiene muchos subtipos o si planea agregar subtipos de forma regular.

  • La base de datos no podrá hacer cumplir attributes se aplican y cuáles no, ya que no hay metadatos para definir qué attributes pertenecen a qué subtipos.

  • Tampoco puedes hacer cumplir NOT NULL sobre attributes de un subtipo que debería ser obligatorio. Tendría que manejar esto en su aplicación, lo que en general no es ideal.

Herencia de la mesa de hormigón:

Otro enfoque para abordar la herencia es crear una nueva tabla para cada subtipo, repitiendo todos los attributes en cada mesa. Por ejemplo:

--// Table: policies_motor
+------+---------------------+----------------+
| id   | date_issued         | vehicle_reg_no |
+------+---------------------+----------------+
|    1 | 2010-08-20 12:00:00 | 01-A-04004     |
|    2 | 2010-08-20 13:00:00 | 02-B-01010     |
|    3 | 2010-08-20 15:00:00 | 03-C-02020     |
+------+---------------------+----------------+
                          
--// Table: policies_property    
+------+---------------------+------------------+
| id   | date_issued         | property_address |
+------+---------------------+------------------+
|    1 | 2010-08-20 14:00:00 | Oxford Street    |   
+------+---------------------+------------------+

Este diseño básicamente resolverá los problemas identificados para el método de tabla única:

  • Obligatorio attributes ahora se puede hacer cumplir con NOT NULL.

  • Agregar un nuevo subtipo requiere agregar una nueva tabla en lugar de agregar columnas a una existente.

  • Tampoco hay riesgo de que una attribute se establece para un subtipo particular, como el vehicle_reg_no campo para una política de propiedad.

  • No hay necesidad de type attribute como en el método de tabla única. El tipo ahora está definido por los metadatos: el nombre de la tabla.

Sin embargo, este modelo también tiene algunas desventajas:

  • Lo común attributes están mixed con el subtipo específico attributesy no existe una forma sencilla de identificarlos. La base de datos tampoco lo sabrá.

  • Al definir las tablas, tendría que repetir el común attributes para cada tabla de subtipos. Eso definitivamente no es SECO.

  • La búsqueda de todas las políticas independientemente del subtipo se vuelve difícil y requeriría un montón de UNIONs.

Así es como tendría que consultar todas las políticas independientemente del tipo:

SELECT     date_issued, other_common_fields, 'MOTOR' AS type
FROM       policies_motor
UNION ALL
SELECT     date_issued, other_common_fields, 'PROPERTY' AS type
FROM       policies_property;

Tenga en cuenta que agregar nuevos subtipos requeriría que la consulta anterior se modifique con un adicional UNION ALL para cada subtipo. Esto puede generar fácilmente errores en su aplicación si se olvida esta operación.

Herencia de tabla de clases (también conocida como herencia de tabla por tipo):

Esta es la solución que @David menciona en la otra respuesta. Creas una sola tabla para tu clase base, que incluye todas las attributes. Luego, crearía tablas específicas para cada subtipo, cuyo principal key también sirve como extranjero key a la mesa base. Ejemplo:

CREATE TABLE policies (
   policy_id          int,
   date_issued        datetime,

   -- // other common attributes ...
);

CREATE TABLE policy_motor (
    policy_id         int,
    vehicle_reg_no    varchar(20),

   -- // other attributes specific to motor insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

CREATE TABLE policy_property (
    policy_id         int,
    property_address  varchar(20),

   -- // other attributes specific to property insurance ...

   FOREIGN KEY (policy_id) REFERENCES policies (policy_id)
);

Esta solución resuelve los problemas identificados en los otros dos diseños:

  • Obligatorio attributes se puede hacer cumplir con NOT NULL.

  • Agregar un nuevo subtipo requiere agregar una nueva tabla en lugar de agregar columnas a una existente.

  • No hay riesgo de que una inapropiada attribute está configurado para un subtipo particular.

  • No es necesario el type attribute.

  • Ahora el comun attributes no son mixed con el subtipo específico attributes ya no.

  • Podemos permanecer SECOS, finalmente. No es necesario repetir lo común attributes para cada tabla de subtipo al crear las tablas.

  • Gestionar un incremento automático id para las políticas se vuelve más fácil, porque esto puede ser manejado por la tabla base, en lugar de que cada tabla de subtipo las genere de forma independiente.

  • La búsqueda de todas las políticas independientemente del subtipo ahora se vuelve muy fácil: No UNIONse necesita – solo un SELECT * FROM policies.

Considero que el enfoque de la tabla de clases es el más adecuado en la mayoría de situaciones.


Los nombres de estos tres modelos provienen del libro de Martin Fowler Patrones de arquitectura de aplicaciones empresariales.

La tercera opción es crear una tabla “Política”, luego una tabla “SectionsMain” que almacena todos los campos que son comunes entre los tipos de secciones. Luego, cree otras tablas para cada tipo de sección que solo contengan los campos que no son comunes.

Decidir cuál es mejor depende principalmente de cuántos campos tiene y cómo desea escribir su SQL. Todos trabajarían. Si tiene solo unos pocos campos, probablemente iría con el n. ° 1. Con “muchos” campos, me inclinaría hacia el n. ° 2 o el n. ° 3.

Con la información proporcionada, modelaría la base de datos para tener lo siguiente:

POLITICAS

  • POLICY_ID (principal key)

PASIVO

  • LIABILITY_ID (principal key)
  • POLICY_ID (extranjero key)

PROPIEDADES

  • PROPERTY_ID (principal key)
  • POLICY_ID (extranjero key)

… y así sucesivamente, porque espero que haya diferentes attributes asociado con cada sección de la política. De lo contrario, podría haber un solo SECTIONS mesa y además de la policy_id, habría un section_type_code

De cualquier manera, esto le permitiría admitir secciones opcionales por política …

No entiendo qué le parece insatisfactorio acerca de este enfoque: así es como almacena los datos mientras mantiene la integridad referencial y no los duplica. El término está “normalizado” …

Debido a que SQL está basado en SET, es bastante ajeno a los conceptos de programación procedimental / OO y requiere código para la transición de un ámbito a otro. Los ORM a menudo se consideran, pero no funcionan bien en sistemas complejos de gran volumen.

Aquí tienes las comentarios y valoraciones

Si eres capaz, eres capaz de dejar un artículo acerca de qué te ha gustado de esta sección.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *