¿Herencia en BBDD?

El otro dí­a en un curso de Business Intelligence surgió un caso como este.
Imaginaos que tenemos una base de datos donde almacenamos información al respecto de proveedores, clientes, trabajadores, representantes y convocatorias.
En un momento dado se quieren enviar invitaciones a los diferentes proveedores, clientes… y se quiere tener constancia a nivel de base de datos de quiénes han sido invitados a cada convocatoria.
No sé por qué me vino a la cabeza inmediatamente una solución orientada a objetos, así­ que intenté plasmar la idea a nivel de modelo relacional, surgiendo algo similar a esto:
Herencia en BBDD
Como véis, la herencia se ve a simple vista. La clase invitado es una clase abstracta de la cual heredan tanto el representante, como el proveedor, cliente y trabajador. Para resolver la herencia a nivel de modelo relacional las cuatro tablas inferiores guardan foreign key contra invitado. Además podréis ver que en la tabla LINEA_CONVOCATORIA se tiene referencia a la tabla INVITADO, con esto hacemos algo similar a pasar a un método por parámetro la clase abstracta, para que luego en tiempo de compilación, y segíºn el objeto que se pase (y que obligatoriamente tendrá que heredar de invitado), se actue en consecuencia.
¿Problemas de esto? Mantener a base de datos puede ser como mí­nimo extraño. El campo CO_INVITADO de todas las tablas deberí­a admitir NULL (por cierto hay una errata en el diagrama al respecto ya que como podéis ver es NOT NULL, y por eso la cardinalidad hacia INVITADO aparece siempre como 1, cuando deberí­a ser 0..1). Además, fijaros en el detalle de que la tabla INVITADO tiene un campo llamado TABLA. Allí­ almacenarí­amos el nombre de la tabla donde realmente está el invitado… jejeje, aquí­ es donde se pierde la historia y me deja de gustar el tema, pero es la íºnica manera que se me ocurrió resolver de dónde sacar de dónde viene el invitado cuando empezamos a buscar a partir de la tabla LINEA_CONVOCATORIA, es decir, lo que serí­a en tiempo de compilación que se te pasara un objeto INVITADO y resolver dependiendo de si el objeto es un proveedor, cliente…
Esto solución resulta como mí­nimo curiosa. ¿Se os ocurre cómo mejorarla? ¿Proponéis alternativas?
En el curso se dijo de resolver esto a nivel de Triggers, y dejarse de historias. A mi sinceramente, no me gustan los Triggers, pero eso no quiere decir que no sean la mejor forma de resolver este tipo de problemas.
Saludos!
Miguel.

6 thoughts on “¿Herencia en BBDD?”

  1. Hola he leido tu articulo y he pensado otra posible solución a lo del campo tabla. Una solución alternativa que se me ocurre es parametrizar, por ejemplo podriamos asignar el grupo 001 -> 100 para los representantes, 101-> 200 para proveedores etc..
    Saludos

  2. Sirve, claro, pero tiene el problema de que si tenemos más ocurrencias que el rango definido para cada una de las entidades con las que contamos (representantes, proveedores…) entonces el sistema falla… y lo peor es cómo lo redefinimos sobre la marcha para aumentar el rango… eso serí­a más complicado aíºn resolverlo porque los rangos superiores estarí­an copados por las otras entidades. Podrí­amos jugar con rangos más grandes y con mayor separación entre ellos, pero al final ante un níºmero infinito de inserciones siempre existirí­a un caso que tendrí­amos que ampliar.
    Gracias por la aportación!

  3. La herencia es un tema complicado en BBDD y tal vez no haya una solución que nos nos deje del todo conformes… La solución que propones también se me habí­a ocurrido, a pesar de eso seguí­ buscando para ver si alguien tení­a la solución mágica (simple e intuitiva) …
    Sólo por aportar algo diferente (si quisiéramos quitar el atributo TABLA), con sus ventajas y desventajas, se podrí­a quitar el atributo TABLA de la tabla de invitados y colocarle 4 claves foráneas (de las cuales solo una serí­a NO NULA, y las demás nulas) y quitar las claves foráneas de las tablas hijas.

  4. Buenas, creo que el manejo de la herencia se especifica mas en el modelo de diseño, no asi en la entidad relación, de todas maneras puede trasladarse de alguna manera y siempre va a depender del objetivo que tenga la aplicación.
    Yo lo solucionaría casi idénticamente, en la tabla invitado tendría un FK idInvitado que se relacione la tabla TipoInvitado que contendrá toda la la lista de posibles invitados. Ahora, la relación existentes entre estos tipos de invitados y sus respectivas tablas que heredan de la tabla padre invitado, la realizaría a nivel lógico.

  5. Estimados,
    Cuando se realiza una búsqueda es inevitable hacer un join en dos tablas por ejemplo si quieres obtener los clientes que fueron invitados tendrías que hacer un join con clientes e invitados.
    Otra alternativa es tener una sola tabla en nuestra base de datos que va a tener todos las columnas de las tablas hijas y en esta agregar una columna la que nos va a indicar si es un cliente, proveedor, etc. Por lo general esta solución es la mas eficiente al momento de consultas, dado que no es necesario realizar ningun join y no tendrias ninguna FK. La desventaja es que si es un cliente va a tener los campos de proveedor vació. Dependiendo de el motor te permite configurar para que los campos que estén en nulo no te consuma espacio.
    Saludos,

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.