Directriz: Ingeniería inversa de bases de datos relacionales
En esta directriz se describen los pasos implicados en la ingeniería inversa de una base de datos y la correlación de las tablas de modelo de datos resultantes con clases de diseño del modelo de datos.
Relaciones
Elementos relacionados
Descripción principal

Introducción

En esta directriz se describen los pasos implicados en la ingeniería inversa de una base de datos y en la correlación de las tablas de modelo de datos resultantes con clases de diseño en el modelo de diseño. El diseñador de base de datos puede utilizar este proceso para generar el desarrollo de modificaciones para la base de datos como parte de un ciclo de desarrollo de evolución. El diseñador de base de datos debe gestionar el proceso de ingeniería inversa a lo largo del ciclo de vida de desarrollo del proyecto.  En muchos casos, el proceso de ingeniería inversa se lleva a cabo en una fase temprana del ciclo de vida del proyecto y, a continuación, los cambios en el diseño de datos se gestionan de forma incremental, sin necesidad de realizar ingeniería inversa posterior de la base de datos.

Los pasos más importantes del proceso para ingeniería inversa de una base datos y la transformación de los elementos del modelo de datos resultantes en elementos del modelo de diseño son los siguientes:

  • Crear un modelo de datos físico que contenga tablas para representar el diseño físico de datos persistentes en la base de datos.  Este paso se puede llevar a cabo automáticamente utilizando las herramientas que se proporcionan con RDBMS (sistema de gestión de bases de datos relacionales), o bien, a través de las herramientas de modelado visual más modernas.
  • Transformar las tablas del modelo de datos físico en clases de diseño del modelo de datos.  Este paso se puede llevar a cabo por medio de la combinación del soporte de herramientas automatizadas para la transformación inicial y, a continuación, realizando ajustes manuales.
  • Definir asociaciones entre las clases en el modelo de diseño.
  • Definir operaciones adecuadas en las clases del modelo de diseño basadas en las acciones llevadas a cabo en los elementos del modelo de datos correspondiente.
  • Agrupar las clases del modelo de diseño en subsistemas y paquetes, según proceda.

Ingeniería inversa de base de datos RDBMS o script DDL para generar un modelo de datos

Normalmente, el proceso de ingeniería inversa de script DDL (lenguaje de definición de datos) o de bases de datos produce un conjunto de elementos de modelo (por ejemplo, tablas, vistas o procedimientos almacenados). Dependiendo de la complejidad de la base de datos, es posible que el diseñador de bases de datos deba particionar los elementos de modelo de ingeniería inversa en paquetes de área temática que contengan conjuntos de tablas relacionados de forma lógica.

Transformación del modelo de datos en modelo de diseño

Se puede seguir el procedimiento siguiente para producir clases de diseño a partir de elementos de modelo en el modelo de datos. La creación de réplicas de la estructura de la base de datos en un modelo de clase es relativamente sencilla. En el proceso que se indica más abajo se describe el algoritmo para transformar elementos del modelo de datos en elementos del modelo de diseño.

En la tabla siguiente se muestra un resumen de la correlación general entre elementos del modelo de diseño y elementos del modelo de datos.

Elemento del modelo de datos 

Elemento del modelo de diseño correspondiente 

Tabla  Clase 
Columna  Atributo 

Relación de no identificación 

Asociación 

Tabla de intersección

 

Clase de asociación

Asociación varios a varios

Asociación calificada 

Relación de identificación 

Agregación 

Cardinalidad 

 

Multiplicidad 

 
Comprobar restricción con una cláusula enumerada  Clase <<ENUM>> 
Esquema  Paquete 

Algunos elementos de modelo del modelo de datos no tienen correlación directa en el modelo de diseño. Estos elementos incluyen los espacios de tablas y la base de datos en sí misma, que modelan las características de almacenamiento físico de la base de datos y se representan como componentes. Otro elemento son las vistas de la base de datos, que son tablas "virtuales" sin significado en el modelo de diseño.  Por último, los índices de las claves principales de las tablas y las funciones de desencadenamiento de la base de datos, que se utilizan para optimizar el funcionamiento de las bases de datos, y sólo tienen significado en el contexto de la base de datos y el modelo de datos.

Transformar una tabla en una clase

Para cada tabla que desee transformar, cree una clase que la represente. Para cada columna, cree un atributo en la clase con el tipo de datos adecuado. Intente que el tipo de datos del atributo y el tipo datos de la columna asociada coincidan lo máximo posible.

Ejemplo

Considere la tabla de base de datos Cliente, con la estructura siguiente de la figura que se muestra más abajo:

Nombre de columna Tipo de datos
ID_Cliente Número
Nombre Varchar
Calle Varchar
Ciudad Varchar
Estado/Provincia Char(2)
Código postal Varchar
País Varchar

Definición de tabla para la tabla Cliente

Empezando a partir de este punto, se crea una clase, Cliente, con la estructura que se muestra en la figura siguiente:

Definición de la clase Cliente

Clase Cliente inicial

En esta clase Cliente inicial, en la tabla Cliente existe un atributo para cada columna. Cada atributo tiene visibilidad public, puesto que se puede consultar cualquiera de las columnas de la tabla de origen.

Observe que el icono "+" listado a la izquierda del atributo indica que el atributo es 'public'; por omisión, todos los atributos derivados de las tablas RDBMS deben ser públicos puesto que, por lo general, RDBMS permite consultar cualquier columna sin restricciones.

Identificación de clases implícitas o incorporadas

Con frecuencia, la clase que es resultado de la correlación de tabla-clase directa contiene atributos que se pueden separar en una clase separada, especialmente, en aquellos casos en los que los atributos aparecen en varias clases transformadas. Estos "atributos repetidos" pueden ser resultado de la desnormalización de tablas por motivos de rendimiento, o bien, de un modelo de datos simplificado en exceso. En estos casos, divida la clase correspondiente en dos o más clases que representen una vista normalizadas de las tablas.

Ejemplo

Después de definir la clase Cliente, más arriba, se puede definir una clase Dirección que contenga toda la información relacionada con la dirección (dando por supuesto que hay otros elementos con direcciones en el sistema), lo que dejaría las clases siguientes:

Diagrama descrito en el texto adjunto.

clase Cliente revisada, con la clase Dirección extraída

La asociación que se dibuja entre ambas es una agregación, puesto que la dirección del cliente se puede considerar como parte del cliente.

Manejo de relaciones de claves externas

Para cada relación de clave externa de la tabla, cree una asociación entre las clases asociadas, eliminando el atributo de la clase que se ha correlacionado con la columna de claves externas. Si la columna de claves externas se ha representado, inicialmente, como un atributo, elimínelo de la clase.

Ejemplo

Suponga la estructura de la tabla Pedido listada más abajo:

Nombre de columna  Tipo de datos 
Número  Número 
ID_Cliente  Varchar 

Estructura de la tabla Pedido

En la tabla Pedido listada más abajo, la columna ID_Cliente es una referencia de clave externa; esta columna contiene el valor de clave principal del cliente asociado al pedido, tal como se representa en el modelo de diseño que se muestra más abajo:

El diagrama UML se describe a continuación.

Representación de las relaciones de claves externas en el modelo de diseño

La clave externa se representa como una asociación entre las clases Pedido y Elemento.

Manejo de relaciones de varios a varios

Los modelos de datos RDBMS representan relaciones de varios a varios con lo que ha dado en llamar una tabla de unión, o bien, una tabla de asociación. Estas tablas permiten representar relaciones de varios a varios por medio de una tabla intermedia que contiene las claves principales de dos tablas diferentes que se pueden unir entre sí. El motivo por el que se necesitan tablas de unión es que una referencia de clave externa sólo puede contener una referencia a un solo valor de clave externa; una sola fila se puede relacionar con otras filas de otra tabla, pero se necesita una tabla de unión para asociarlas.

Ejemplo

Considere el caso de Productos, que puede proporcionar uno de varios Proveedores, y cualquier Proveedor puede ofrecer cualquier número de Productos. Las tablas Productos y Proveedores tienen la estructura que se ha definido más abajo:

Tabla Productos
Nombre de columna Tipo de datos
ID_Producto Número
Nombre Varchar
Descripción Varchar
Precio Número
Tabla Proveedores
Nombre de columna Tipo de datos
ID_Proveedor Número
Nombre Varchar
Calle Varchar
Ciudad Varchar
Estado/Provincia Char(2)
Código postal Varchar
País Varchar

Definiciones de las tablas Productos y Proveedores

Con el objeto de enlazar ambas tablas entre sí para buscar los productos que ofrece un proveedor determinado, se necesita una tabla Productos-Proveedor, que se definen en la tabla siguiente:

Tabla Producto-Proveedor
Nombre de columna  Tipo de datos 
ID_Producto  Número 
ID_Proveedor  Número 

Definición de la tabla Producto-Proveedor

Esta tabla de unión contiene las claves principales de los productos y los proveedores, enlazándolos entre sí. Una fila de la tabla indica que un proveedor determinado ofrece un producto concreto. Todas las filas cuyo ID_Proveedor coincide con un ID de proveedor específico proporcionan un listado de todos los productos que ofrece dicho proveedor.

En el modelo de diseño, esta tabla intermedia es redundante, puesto que un modelo de objeto puede representar asociaciones de varios a varios de forma directa. En la figura siguiente se muestran las clases Proveedor y Producto y sus relaciones, junto con la clase Dirección, que se extrae del Proveedor, tal como se ha explicado más arriba.

Diagrama UML descrito en el título.

Representación de las clases Producto y Proveedor

Introducción de la generalización

A menudo, se encuentran tablas cuya estructura es similar. En el modelo de datos no hay ningún concepto de generalización, por lo que no existe ningún procedimiento para representar que dos o más tablas tienen una estructura en común. A veces, la estructura común es resultado de la desnormalización para el rendimiento, como sucedía en el caso anterior con la tabla Dirección "implícita" que se ha extraído a una clase separada. En otros casos, las tablas comparten características más esenciales que se pueden extraer a una clase padre generalizada con dos o más subclases. Para buscar oportunidades de generalización, observe las columnas repetidas en varias tablas, donde las tablas presentan más similitudes que diferencias.

Ejemplo

Considere las tablas siguientes, SoftwareProduct y HardwareProduct, tal como se muestran más abajo:

Tabla Productos de software
Nombre de columna  Tipo de datos 
ID_Producto  Número 
Nombre  Varchar 
Descripción  Varchar 
Precio  Número 
Versión  Número 
Tabla Productos de hardware
Nombre de columna  Tipo de datos 
ID_Producto  Número 
Nombre  Varchar 
Descripción  Varchar 
Precio  Número 
Versión  Número 


Tablas SoftwareProduct y HardwareProduct

Observe que las columnas resaltadas en azul son idénticas; ambas tablas comparten gran parte de la definición, y presentan ligeras diferencias. Se puede representar extrayendo una clase Producto, con SoftwareProduct y HardwareProduct como subclases del Producto, tal como se muestra en la figura siguiente:

Diagrama descrito en el texto adjunto.

Clases SoftwareProduct y HardwareProduct, mostrando la generalización de la clase Producto.

Al unir todas las definiciones de clases entre sí, la figura siguiente muestra un diagrama de clase consolidado para el sistema de Entrada de pedido (sólo las clases principales).

Diagrama UML complejo descrito en el texto adjunto.

Diagrama de clase consolidado para el sistema de entrada de pedido

Creación de réplicas del comportamiento de RDBMS en el modelo de diseño

La creación de réplicas es más difícil puesto que, normalmente, las bases de datos relacionales no están orientadas a objetos y parecen no tener nada análogo con las operaciones realizadas en una clase del modelo de objeto. Los pasos siguientes le pueden ayudar a volver a construir el comportamiento de las clases identificadas más arriba:

  1. Crear operaciones para obtener un establecer cada atributo. Debe haber un modo de establecer, cambiar y consultar los valores de los atributos de los objetos. Puesto que el único procedimiento para acceder a los atributos de un objeto es por medio de las operaciones que proporciona la clase, se deben definir dichas operaciones en la clase. Al crear las operaciones que establecen el valor de un atributo, asegúrese de que incorpora todas las restricciones de validación que pueden operar en la columna asociada. Si no existen restricciones de validación, elija sólo que se represente el hecho de que los atributos se pueden obtener y establecer al hacer que tengan visibilidad pública, tal como se ha realizado en los diagramas anteriores (con el icono a la izquierda del nombre del atributo).
  2. Crear una operación en la clase para cada procedimiento almacenado que opere en la tabla asociada. Los procedimientos almacenados son rubrutinas ejecutables que se ejecutan en el propio DBMS. Esta lógica se debe convertir al modelo de diseño. Si el procedimiento almacenado sólo opera en una clase, cree una operación en la clase con los mismos parámetros y el mismo tipo de retorno que el procedimiento almacenado. Documente el comportamiento del procedimiento almacenado en la operación, asegurándose de que anota en la descripción del método que el procedimiento almacenado implementa la operación.
  3. Crear operaciones para gestionar asociaciones entre clases. Cuando existe una asociación entre dos clases, debe haber un modo de crear, gestionar y eliminar asociaciones. Las asociaciones entre objetos se gestionan a través de referencias a objetos, así, para crear una asociación entre Order y LineItem (es decir, para añadir LineItem a Order), se invoca una operación en Order, pasando LineItem como un argumento (es decir, Order.add(aLineItem)). También debe haber procedimientos para eliminar y actualizar la asociación (es decir, Order.remove(aLineItem) y Order.change(aLineItem,aNewLineItem)).
  4. Manejar supresión de objetos. Si el lenguaje de destino ofrece soporte para la supresión explícita, añada comportamiento al destructor de la clase que implementa la comprobación de la integridad referencial. En aquellos casos en los que existen restricciones de integridad referencial en la base de datos, por ejemplo cascade delete, se deben crear réplicas del comportamiento en las clases adecuadas. Por ejemplo, la base de datos puede definir una restricción que indique que cada vez que se suprima un Order, también se eliminen todos los LineItems asociados. Si el lenguaje de destino admite la recopilación de basura, cree un mecanismo por el que se eliminen las filas de las tablas cuando se elimine el objeto asociado por medio de la recopilación de basura. Tenga en cuenta que parece más difícil de lo que parece (y parece difícil), puesto que debe implementar un mecanismo que garantice que ningún cliente de la base de datos tenga referencias al objeto que va a recopilar la basura; no es suficiente para depender de las posibilidades de la recopilación de basura de la máquina virtual/entorno de ejecución, puesto que es, simplemente, una vista del cliente.
  5. Manejar el comportamiento que implican las consultas. Examine las sentencias Seleccionar que acceden a la tabla para ver cómo se recupera y manipula la información. Para cada columna que devuelve una sentencia Seleccionar directamente, establezca la propiedad public del atributo asociado en true; todos los demás atributos deben ser private. Para cada columna calculada en una sentencia Seleccionar, cree una operación en la clase asociada para calcular y devolver el valor. Cuando considere las sentencias Seleccionar, incluya también las sentencias Seleccionar incorporadas en definiciones de Ver.

Organizar elementos en el modelo de diseño

Las clases de diseño que se crean a partir de las transformaciones de tabla en clase se deben organizar en paquetes de diseño o subsistemas de diseño adecuados en el modelo de diseño, según proceda, en base a la estructura arquitectónica global de la aplicación.  Consulte los apartados Concepto: Capas y Concepto: Arquitectura de software, donde se proporciona una visión general de la arquitectura de la aplicación.