miércoles, abril 12, 2006

Hablemos de Constraints.


Las constraints son reglas que ofrecen una garantía de integridad en la información vinculada. Existen 5 tipos de constraints.

-   Primary key
-   Foreign key
-   Unique key
-   Not Null
-   Check

Las constraints tienen, básicamente, tres propósitos:

         1.- Forzar integridad. Una constraint con estado ENABLED evita que, sobre las tablas, puedan modificarse valores de forma que no se satisfaga la regla de la constraint.

         2.- Validar la información. Una constraint con estado DISABLED VALIDATE realiza una validación sobre los datos, certificando que la información contenida en las tablas satisface la regla de la constraint.

         3.- Asumir la validez de la información. Una constraint con estado RELY no verifica la información, ni fuerza la integridad para las modificaciones y asume que los datos introducidos satisfacen la regla de la constraint.



Las constraints, por tanto, pueden estar ENABLED o DISABLED.
Las constraints habilitadas cumplen el propósito 1. Ningún dato introducido o modificado viola la integridad de la regla de la constraint. De este modo, sobre una primary key ENABLED no se permite un insert sobre una fila ya existente. No obstante, si la constraint está en el estado ENABLED NOVALIDATE, no se permitirán cambios que violen la regla, pero no se verificarán que los datos existentes la cumplan.

Las constraints, por tanto, pueden estar en estado VALIDATE o NOVALIDATE independientemente de si están ENABLED o DISABLED.
Las constraints con VALIDATE cumplen el propósito 2: La información existente está validada. No obstante, si la constraint está deshabilitada con DISABLED VALIDATE, no se permitirán cambios sobre las columnas afectadas, ya que aunque la constraint no está habilitada, certifica que los datos existentes son válidos y cumplen con la regla de la constraint.

Las constraints, por tanto, pueden estar en estado RELY o NORELY (también conocido como BELIEF) cuando las constraints están en estado DISABLED NOVALIDATE.
Las constraints en ese estado cumplen con el propósito 3: Asumen que la información es correcta y aportan al optimizador información válida para el uso de vistas materializadas, optimización de queries, etc. De este modo, por ejemplo, al optimizador le puede resultar mucho más fácil encontrar tablas FACT o DIMENSION por las constraints de foreign key entre las tablas.


Las constraints DISABLED NOVALIDATE RELY ni validan la información de la tabla, ni comprueban que las modificaciones cumplen las reglas de las restricciones.


Ejemplo 1: Una restricción de clave primaria habilitada con la opción de NOVALIDATE. No verifica la integridad referencial de las filas, pero no permite que las nuevas filas puedan violar la restricción.


SQL> create table valores(
  2   id number,
  3   valor varchar2(50),
  4   descrip varchar2(300),
  5   CONSTRAINT PK_VALORES PRIMARY KEY (id) deferrable initially immediate);

Tabla creada.

SQL> alter table valores disable primary key;

Tabla modificada.

SQL> insert into valores values (1,'ELEMENTO UNO','Primer elemento, tabla vacía');

1 fila creada.

SQL> insert into valores values (1,'ELEMENTO UNO''','Primer elemento, repetido');

1 fila creada.

SQL> insert into valores values (1,'ELEMENTO UNO''''','Primer elemento, otra vez repetido');

1 fila creada.

SQL> alter table valores enable novalidate primary key;

Tabla modificada.

SQL> insert into valores values (1,'ELEMENTO UNO''''''','Primer elemento, violando PK, repetido');
insert into valores values (1,'ELEMENTO UNO''''''','Primer elemento, violando PK, repetido')
*
ERROR en lÝnea 1:
ORA-00001: restricci¾n ·nica (DW_VIAJES.PK_VALORES) violada

SQL> select * from valores;

        ID VALOR                                    DESCRIP
---------- ---------------------------------------- ----------------------------------------
         1 ELEMENTO UNO                             Primer elemento, tabla vacía
         1 ELEMENTO UNO'                            Primer elemento, repetido
         1 ELEMENTO UNO''                           Primer elemento, otra vez repetido
 


Ejemplo 2: Una restricción de clave primaria deshabilitada con la opción de VALIDATE. Verifica la integridad referencial de las filas, pero como está deshabilitada, no permite DML sobre la columna.


SQL> truncate table valores;

Tabla truncada.

SQL> alter table valores disable primary key;

Tabla modificada.

SQL> insert into valores values (1,'ELEMENTO UNO','Primer elemento, tabla vacía');

1 fila creada.

SQL> insert into valores values (2,'ELEMENTO DOS','Segundo elemento, ID distinto.');

1 fila creada.

SQL> insert into valores values (3,'ELEMENTO TRES','Tercer elemento, ID distinto.');

1 fila creada.

SQL> alter table valores disable validate primary key;

Tabla modificada.

SQL> insert into valores values (3,'ELEMENTO TRES','Tercer elemento, ID distinto.');
insert into valores values (3,'ELEMENTO TRES','Tercer elemento, ID distinto.')
*
ERROR en lÝnea 1:
ORA-25128: No se puede insertar/actualizar/suprimir en la tabla con la restricci¾n (DW_VIAJES.PK_VALORES) desactivada y validada


SQL> insert into valores values (4,'ELEMENTO CUATRO','Cuarto elemento, ID distinto.');
insert into valores values (4,'ELEMENTO CUATRO','Cuarto elemento, ID distinto.')
*
ERROR en lÝnea 1:
ORA-25128: No se puede insertar/actualizar/suprimir en la tabla con la restricci¾n (DW_VIAJES.PK_VALORES) desactivada y validada


Ejemplo 3: Una restricción de clave ajena deshabilitada. Permite la entrada de valores no existentes en la PK. La opción de enable constraint con la cláusula EXCEPTIONS INTO registra en la tabla exceptions los identificadores de las filas que no cumplen la condición de la constraint.


SQL> create table master (id number primary key);

Tabla creada.

SQL> create table detail (id number primary key,  valor varchar2(50),
  2  master_id number constraint fk_master_id references master(id));

Tabla creada.

SQL> insert into master select rownum from user_tables;

40 filas creadas.

SQL> alter table detail disable constraint fk_master_id;

Tabla modificada.

SQL> insert into detail select rownum, object_name, mod(rownum,45)+1 from user_objects;

68 filas creadas.

SQL> alter table detail enable constraint fk_master_id exceptions into exceptions;
alter table detail enable constraint fk_master_id exceptions into exceptions
                                     *
ERROR en línea 1:
ORA-02298: no se puede validar (ORADBA.FK_MASTER_ID) - claves principales no encontradas

SQL> select count(*) from exceptions;

  COUNT(*)
----------
         5
SQL> select * from exceptions;

ROW_ID             OWNER                          TABLE_NAME                     CONSTRAINT
------------------ ------------------------------ ------------------------------ ------------------
AAAY/nAAJAAAd7KAAn ORADBA                         DETAIL                         FK_MASTER_ID
AAAY/nAAJAAAd7KAAo ORADBA                         DETAIL                         FK_MASTER_ID
AAAY/nAAJAAAd7KAAp ORADBA                         DETAIL                         FK_MASTER_ID
AAAY/nAAJAAAd7KAAq ORADBA                         DETAIL                         FK_MASTER_ID
AAAY/nAAJAAAd7KAAr ORADBA                         DETAIL                         FK_MASTER_ID

5 comentarios:

Anónimo dijo...

voy a estudiarme esto.
gracias

migue dijo...

genial!

Javier Morales dijo...

Gracias, Migue! :)

Unknown dijo...

gracias :)

JBlen dijo...

A estas alturas llego por acá y sigue siendo un post super bueno!!! Muchísimas gracias