Como se ha explicado anteriormente, en este trabajo se representan las restricciones de integridad mediante reglas activas (evento, condición, y acción). El evento es una operación de actualización, la condición es una proposición lógica definida sobre uno o varios elementos del esquema, y la acción es el código que se ejecuta dependiendo del resultado de evaluar la condición.
La derivación de reglas activas a partir de la especificación de las restricciones de integridad de la BD es un tema muy estudiado en la literatura. La mayoría de los lenguajes utilizados para especificar las restricciones se derivan de las notaciones formales del cálculo relacional de tuplas (Tuple Relational Calculus-TRC) [Ceri et al., 1994] [Ishakbeyoglu y Ozsoyoglu, 1998] [Elmasri y Navathe, 2004] [Decker,
2002]. El cálculo relacional de tuplas se basa en la especificación de un cierto número de variables de tupla, lo que significa que una variable puede adoptar como valor cualquier tupla de una relación.
Típicamente, se puede especificar una restricción de integridad de tal manera que todas las tuplas cualificadas de una tabla o de una combinación de tablas tengan que satisfacer un predicado que contenga operadores de comparación (≤ ≥ ≠ < = >) u operadores lógicos (∧ AND, ∨ OR, ¬ NOT). Por ejemplo, “el sueldo de un director tiene que ser igual o mayor que 1500 €” (Empleado.sueldo ≥ 1500 € ⇒ Empleado.tipo = ‘Director”). Como se muestra a continuación:
Una restricción de integridad en TRC es:
∀ e1 ∈ R1, e2 ∈ R2,..., en ∈ Rn: <COND>
Donde:
e1, e2, ….: Son las variables de tuplas de las relaciones R1, R2, ….., Rn. Una
restricción de integridad puede asociar con una o más tablas del esquema ℜ ={ R1,
R2, ….., Rn }.
<COND>: La condición es una expresión lógica sobre las columnas de las relaciones R1, R2,..., Rn.
Donde:
COND ⇒ COND ∧ COND
| COND ∨ COND
| ¬ COND
| (∀ t: COND)
| (∃ t: COND)
| ATOM
ATOM es una o más formulas, como; e ∈ R, o e.a Θ c donde Θ:{≤ ≥ ≠ < = >} Una cláusula del cálculo relacional que representa una restricción de integridad puede definirse de manera manual, utilizando este lenguaje para especificar las restricciones, como por ejemplo, la propuesta presentada en [Olivé, 2003] que utiliza
el cálculo relacional para describir restricciones de integridad en los métodos del diagrama de clases de UML. También pueden definirse de manera automática, utilizando un motor que derive cláusulas del cálculo relacional de las restricciones de integridad contempladas en el diagrama conceptual.
En la metodología propuesta se ha utilizado la segunda opción porque el objetivo es escoger e implementar todas las restricciones de integridad del modelo conceptual que no tienen una transformación directa. Las restricciones de integridad vistas en el apartado anterior 3.1.2 (las interrelaciones binarias de todos los tipos N:M, 1:N, 1:1 y las jerarquías de tipo totalidad y exclusividad) tienen representación gráfica en el modelo conceptual pero no se transforman a ningún mecanismo para conservarlas en el modelo relacional.
Por ello, y para facilitar el trabajo a los desarrolladores de BD, en esta metodología propone un mecanismo para derivar las cláusulas del cálculo relacional automáticamente a partir de un diagrama conceptual.
Así pues, para una restricción de cardinalidad de tipo N:M se puede representar cada rol en la interrelación utilizando una cláusula del calculo relacional, como se muestra a continuación:
Caso (1), véase la tabla 3.2.
Rol (A_en_R: Obligatorio): TIPO N:M
∀ a ∈ A:
∃ r ∈ R: r.ID_A = a.ID_A
Rol (B_en_R: Obligatorio): TIPO N:M
∀ b ∈ B:
∃ r ∈ R: r.ID_B = b.ID_B
En el caso de que cualquiera de estos roles sea una participación opcional entonces la cláusula que lo representa será nula, es decir, se elimina del proceso de transformación porque es rarísimo utilizar disparadores para controlar la participación opcional. Los nombres de las tablas, las claves primarias, y las claves
ajenas son parámetros que pueden definirse al principio del proceso para personalizar estas cláusulas para cada rol en la interrelación.
Para una restricción de cardinalidad de tipo 1:N se puede representar cada rol que se juega en la interrelación utilizando una cláusula del calculo relacional, como se muestra a continuación:
Caso (1), véase la tabla 3.3
Rol (A_en_B: Obligatorio): TIPO 1:N
∀ a ∈ A:
∃ b ∈ B: b.ID_A = a.ID_A
Rol (B_en_A: Obligatorio): TIPO 1:N
∀ b ∈ B:
∃ a ∈ A: a.ID_A = b.ID_A
El rol B_en_A indica que cualquier ocurrencia en B tiene que relacionarse con una en A. En este caso, utilizar un disparador para recoger esta restricción se considera redundante porque se puede controlar utilizando la cláusula NOT NULL a la hora de definir el campo de la clave ajena. Quedar por controlar la primera restricción utilizando disparadores.
En el caso de las restricciones de cardinalidad máxima conocida o mínima mayor que uno, cada rol en estas interrelaciones se representa utilizando las cláusulas que se muestran a continuación (véase la tabla 3.4):
Rol (A_en_R: Obligatorio): TIPO N:M
∀ a ∈ A:
∃ r ∈ R: (COUNT(r.ID_A)>=x2 ∧ COUNT(r.ID_A)<=y2)
Rol (B_en_R: Obligatorio): TIPO N:M
∀ b ∈ B:
∃ r ∈ R: (COUNT(r.ID_B)>=x1 ∧ COUNT(r.ID_B)<=y1)
Donde las variables x1 y x2 son las cardinalidades mínimas; y1 e y2 son las cardinalidades máximas de las participaciones de cada entidad en la interrelación.
Para las jerarquías se ha contemplado solo el tipo de totalidad y exclusividad por ser el más común y el más crítico. Según la tabla 3.5, la totalidad que indica que toda ocurrencia del supertipo debe pertenecer a uno de los subtipos, se representa:
Rol (A_en_RJ: Obligatorio): TIPO Supertipo/Jerarquía
∀ a ∈ A:
(∃ b ∈ B: a.ID_A = b.ID_A) ∨ (∃ c ∈ C: a.ID_A =
c.ID_A)
Para controlar la exclusividad de una jerarquía que indica que una ocurrencia del supertipo sólo puede pertenecer a uno de los subtipos se definen las siguientes cláusulas:
Rol (B_en_RJ: Opcional): TIPO Subtipo/Jerarquía
∀ b ∈ B:
¬∃ c ∈ C: b.ID_A = c.ID_A
Rol (C_en_RJ: Opcional): TIPO Subtipo/Jerarquía
∀ C ∈ C:
¬∃ b ∈ B: c.ID_A = b.ID_A
A partir de estas cláusulas, ya se puede abordar la siguiente fase en la metodología propuesta que se ocupa de transformar estas cláusulas del cálculo relacional a disparadores del estándar SQL3.