domingo, 5 de febrero de 2012

Sistemas objeto–relacionales

El modo en que los objetos han entrado en el mundo de las bases de datos relacionales es
en forma de dominios, actuando como el tipo de datos de una columna. Hay dos implicaciones
muy importantes por el hecho de utilizar una clase como un dominio:
Es posible almacenar m´ultiples valores en una columna de una misma fila ya que
un objeto suele contener m´ultiples valores. Sin embargo, si se utiliza una clase como
dominio de una columna, en cada fila esa columna s´olo puede contener un objeto de
la clase (se sigue manteniendo la restricci´on del modelo relacional de contener valores
at´omicos en la intersecci´on de cada fila con cada columna).
Es posible almacenar procedimientos en las relaciones porque un objeto est´a enlazado
con el c´odigo de los procesos que sabe realizar (los m´etodos de su clase).
Otro modo de incoporar objetos en las bases de datos relacionales es construyendo tablas
de objetos, donde cada fila es un objeto.
Ya que un sistema objeto–relacional es un sistema relacional que permite almacenar
objetos en sus tablas, la base de datos sigue sujeta a las restricciones que se aplican a todas las
bases de datos relacionales y conserva la capacidad de utilizar operaciones de concatenaci´on
(join) para implementar las relaciones “al vuelo”.
5.1 Objetos en Oracle 23
5.1. Objetos en Oracle
Los tipos de objetos en Oracle son tipos de datos definidos por el usuario. La tecnolog´ıa de
objetos que proporciona es una capa de abstracci´on construida sobre su tecnolog´ıa relacional,
por lo que los datos se siguen almacenando en columnas y tablas. En los siguientes apartados
se resume la orientaci´on a objetos que soporta la versi´on 9i de Oracle.
5.1.1. Tipos de objetos y referencias
Para crear tipos de objetos se utiliza la sentencia CREATE TYPE. A continuaci´on se muestran
algunos ejemplos:
CREATE TYPE persona AS OBJECT
(
nombre VARCHAR2(30),
telefono VARCHAR2(20)
);
CREATE TYPE lineaped AS OBJECT
(
nom articulo VARCHAR2(30),
cantidad NUMBER,
precio unidad NUMBER(12,2)
);
CREATE TYPE lineaped tabla AS TABLE OF lineaped;
CREATE TYPE pedido AS OBJECT
(
id NUMBER,
contacto persona,
lineasped lineaped tabla,
MEMBER FUNCTION obtener valor RETURN NUMBER
);
lineasped es lo que se denomina una tabla anidada (nested table) que es un objeto de
tipo colecci´on. Una vez creados los objetos, ´estos se pueden utilizar como un tipo de datos
al igual que NUMBER o VARCHAR2. Por ejemplo, podemos definir una tabla relacional para
guardar informaci´on de personas de contacto:
24 5 Sistemas objeto–relacionales
CREATE TABLE contactos
(
contacto persona,
fecha DATE
);
Esta es una tabla relacional que tiene una columna cuyo tipo es un objeto. Cuando los
objetos se utilizan de este modo se les denomina objetos columna.
Cuando se declara una columna como un tipo de objeto o como una tabla anidada, se
puede incluir una cl´ausula DEFAULT para asignar valores por defecto. Veamos un ejemplo:
CREATE TYPE persona AS OBJECT
(
id NUMBER,
nombre VARCHAR2(30),
direccion VARCHAR2(30)
);
CREATE TYPE gente AS TABLE OF persona;
CREATE TABLE departamento
(
num dept VARCHAR2(5) PRIMARY KEY,
nombre dept VARCHAR2(20),
director persona DEFAULT persona(1,'Pepe P¶erez',NULL),
empleados gente DEFAULT gente( persona(2,'Ana L¶opez','C/del Pez, 5'),
persona(3,'Eva Garc¶³a',NULL) )
)
NESTED TABLE empleados STORE AS empleados tab;
Las columnas que son tablas anidadas y los atributos que son tablas de objetos requieren
una tabla a parte donde almacenar las filas de dichas tablas. Esta tabla de almacenamiento
se especifica mediante la cl´ausula NESTED TABLE...STORE AS.... Para recorrer las filas de
una tabla anidada se utilizan cursores anidados.
Sobre las tablas de objetos se pueden definir restricciones. En el siguiente ejemplo se
muestra c´omo definir una clave primaria sobre una tabla de objetos:
5.1 Objetos en Oracle 25
CREATE TYPE ubicacion AS OBJECT
(
num edificio NUMBER,
ciudad VARCHAR2(30)
);
CREATE TYPE persona AS OBJECT
(
id NUMBER,
nombre VARCHAR2(30),
direccion VARCHAR2(30),
oficina ubicacion
);
CREATE TABLE empleados OF persona
(
id PRIMARY KEY
);
El siguiente ejemplo define restricciones sobre atributos escalares de un objeto columna:
CREATE TABLE departamento
(
num dept VARCHAR2(5) PRIMARY KEY,
nombre dept VARCHAR2(20),
director persona,
despacho ubicacion,
CONSTRAINT despacho cons1
UNIQUE (despacho.num edificio,despacho.ciudad),
CONSTRAINT despacho cons2
CHECK (despacho.ciudad IS NOT NULL)
);
Sobre las tablas de objetos tambi´en se pueden definir disparadores. Sobre las tablas de
almacenamiento especificadas mediante NESTED TABLE no se pueden definir disparadores.
CREATE TABLE traslado
(
id NUMBER,
despacho antiguo ubicacion,
despacho nuevo ubicacion
);
26 5 Sistemas objeto–relacionales
CREATE TRIGGER disparador
AFTER UPDATE OF despacho ON empleados
FOR EACH ROW
WHEN new.despacho.ciudad='Castellon'
BEGIN
IF (:new.despacho.num edificio=600) THEN
INSERT INTO traslado (id, despacho antiguo, despacho nuevo)
VALUES (:old.id, :old.despacho, :new.despacho);
END IF;
END;
Las relaciones se establecen mediante columnas o atributos REF. Estas relaciones pueden
estar restringidas mediante la cl´ausula SCOPE o mediante una restricci´on de integridad referencial
(REFERENTIAL). Cuando se restringe mediante SCOPE, todos lo valores almacenados
en la columna REF apuntan a objetos de la tabla especificada en la cl´ausula. Sin embargo,
puede ocurrir que haya valores que apunten a objetos que no existen. La restricci´on mediante
REFERENTIAL es similar a la especificaci´on de claves ajenas. La regla de integridad referencial
se aplica a estas columnas, por lo que las referencias a objetos que se almacenen en estas
columnas deben ser siempre de objetos que existen en la tabla referenciada.
Para evitar ambig¨uedades con los nombres de atributos y de m´etodos al utilizar la
notaci´on punto, Oracle obliga a utilizar alias para las tablas en la mayor´ıa de las ocasiones
(aunque recomienda hacerlo siempre, para evitar problemas). Por ejemplo, dadas las tablas:
CREATE TYPE persona AS OBJECT (dni VARCHAR2(9));
CREATE TABLE ptab1 OF persona;
CREATE TABLE ptab2 (c1 persona);
las siguientes consultas muestran modos correctos e incorrectos de referenciar el atributo
dni:
SELECT dni FROM ptab1; -- Correcto
SELECT c1.dni FROM ptab2; -- Ilegal: notaci¶on punto sin alias de tabla
SELECT ptab2.c1.dni FROM ptab2; -- Ilegal: notaci¶on punto sin alias
SELECT p.c1.dni FROM ptab2 p; -- Correcto
5.1.2. M´etodos
Los m´etodos son funciones o procedimientos que se pueden declarar en la definici´on de
un tipo de objeto para implementar el comportamiento que se desea para dicho tipo de
5.1 Objetos en Oracle 27
objeto. Las aplicaciones llaman a los m´etodos para invocar su comportamiento. Para ello
se utiliza tambi´en la notaci´on punto: objeto.metodo(lista param). Aunque un m´etodo no
tenga par´ametros, Oracle obliga a utilizar los par´entesis en las llamadas objeto.metodo().
Los m´etodos escritos en PL/SQL o en Java, se almacenan en la base de datos. Los m´etodos
escritos en otros lenguajes se almacenan externamente.
Hay dos clases de m´etodos: miembros y est´aticos. Hay otro tercer tipo, los m´etodos
constructores, que el propio sistema define para cada tipo de objeto.
Los m´etodos miembro son los que se utilizan para ganar acceso a los datos de una
instancia de un objeto. Se debe definir un m´etodo para cada operaci´on que se desea que
haga el tipo de objeto. Estos m´etodos tienen un par´ametro denominado SELF que denota
a la instancia del objeto sobre la que se est´a invocando el m´etodo. Los m´etodos miembro
puden hacer referencia a los atributos y a los m´etodos de SELF sin necesidad de utilizar el
cualificador.
CREATE TYPE racional AS OBJECT
(
num INTEGER,
den INTEGER,
MEMBER PROCEDURE normaliza,
...
);
CREATE TYPE BODY racional AS
MEMBER PROCEDURE normaliza IS
g INTEGER;
BEGIN
g := gcd(SELF.num, SELF.den);
g := gcd(num, den); -- equivale a la l¶³nea anterior
num := num / g;
den := den / g;
END normaliza;
...
END;
SELF no necesita declararse, aunque se puede declarar. Si no se declara, en las funciones
se pasa como IN y en los procedimientos se pasa como IN OUT.
Los valores de los tipos de datos escalares siguen un orden y, por lo tanto, se pueden
comparar. Sin embargo, con los tipos de objetos, que pueden tener m´ultiples atributos de
distintos tipos, no hay un criterio predefinido de comparaci´on. Para poder comparar objetos
se debe establecer este criterio mediante m´etodos de mapeo o m´etodos de orden.
28 5 Sistemas objeto–relacionales
Un m´etodo de mapeo (MAP) permite comparar objetos mapeando instancias de objetos
con tipos escalares DATE, NUMBER, VARCHAR2 o cualquier tipo ANSI SQL como CHARACTER
o REAL. Un m´etodo de mapeo es una funci´on sin par´ametros que devuelve uno de los tipos
anteriores. Si un tipo de objeto define uno de estos m´etodos, el m´etodo se llama autom´aticamente
para evaluar comparaciones del tipo obj1 > obj2 y para evaluar las comparaciones
que implican DISTINCT, GROUP BY y ORDER BY.
CREATE TYPE rectangulo AS OBJECT (
alto NUMBER,
ancho NUMBER,
MAP MEMBER FUNCTION area RETURN NUMBER,
...
);
CREATE TYPE BODY rectangulo AS
MAP MEMBER FUNCTION area RETURN NUMBER IS
BEGIN
RETURN alto*ancho;
END area;
...
END;
Los m´etodos de orden ORDER hacen comparaciones directas objeto–objeto. Son funciones
con un par´ametro declarado para otro objeto del mismo tipo. El m´etodo se debe escribir
para que devuelva un n´umero negativo, cero o un n´umero positivo, lo que significa que el
objeto SELF es menor que, igual o mayor que el otro objeto que se pasa como par´ametro.
Los m´etodos de orden se utilizan cuando el criterio de comparaci´on es muy complejo como
para implementarlo con un m´etodo de mapeo.
Un tipo de objeto puede declarar s´olo un m´etodo de mapeo o s´olo un m´etodo de orden,
de manera que cuando se comparan dos objetos, se llama autom´aticamente al m´etodo que
se haya definido, sea de uno u otro tipo.
Los m´etodos est´aticos son los que pueden ser invocados por el tipo de objeto y no por
sus instancias. Estos m´etodos se utilizan para operaciones que son globales al tipo y que
no necesitan referenciar datos de una instancia concreta. Los m´etodos est´aticos no tienen el
par´ametro SELF. Para invocar estos m´etodos se utiliza la notaci´on punto sobre el tipo del
objeto: tipo objeto.m¶etodo()
Cada tipo de objeto tiene un m´etodo constructor impl´ıcito definido por el sistema. Este
m´etodo crea un nuevo objeto (una instancia del tipo) y pone valores en sus atributos. El
m´etodo constructor es una funci´on y devuelve el nuevo objeto como su valor. El nombre del
m´etodo constructor es precisamente el nombre del tipo de objeto. Sus par´ametros tienen los
nombres y los tipos de los atributos del tipo.
5.1 Objetos en Oracle 29
CREATE TABLE departamento (
num dept VARCHAR2(5) PRIMARY KEY,
nombre dept VARCHAR2(20),
despacho ubicacion
);
INSERT INTO departamento
VALUES ( '233', 'Ventas', ubicacion(200,'Borriol') );
5.1.3. Colecciones
Oracle soporta dos tipos de datos colecci´on: las tablas anidadas y los varray. Un varray
es una colecci´on ordenada de elementos. La posici´on de cada elemento viene dada por un
´ındice que permite acceder a los mismos. Cuando se define un varray se debe especificar el
n´umero m´aximo de elementos que puede contener (aunque este n´umero se puede cambiar
despu´es). Los varray se almacenan como objetos opacos (RAW o BLOB). Una tabla anidada
puede tener cualquier n´umero de elementos: no se especifica ning´un m´aximo cuando se define.
Adem´as, no se mantiene el orden de los elementos. En las tablas anidades se consultan y
actualizan datos del mismo modo que se hace con las tablas relacionales. Los elementos de
una tabla anidada se almacenan en una tabla a parte en la que hay una columna llamada
NESTED TABLE ID que referencia a la tabla padre o al objeto al que pertenece.
CREATE TYPE precios AS VARRAY(10) OF NUMBER(12,2);
CREATE TYPE lineaped tabla AS TABLE OF lineaped;
Cuando se utiliza una tabla anidada como una columna de una tabla o como un atributo
de un objeto, es preciso especificar cu´al ser´a su tabla de almacenamiento mediante NESTED
TABLE...STORE AS....
Se pueden crear tipos colecci´on multinivel, que son tipos colecci´on cuyos elementos son
colecciones.
CREATE TYPE satelite AS OBJECT (
nombre VARCHAR2(20),
diametro NUMBER );
CREATE TYPE tab satelite AS TABLE OF satelite;
30 5 Sistemas objeto–relacionales
CREATE TYPE planeta AS OBJECT (
nombre VARCHAR2(20),
masa NUMBER,
satelites tab satelite );
CREATE TYPE tab planeta AS TABLE OF planeta;
En este caso, la especificaci´on de las tablas de almacenamiento se debe hacer para todas y
cada una de las tablas anidadas.
CREATE TABLE estrellas (
nombre VARCHAR2(20),
edad NUMBER,
planetas tab planeta )
NESTED TABLE planetas STORE AS tab alm planetas
(NESTED TABLE satelites STORE AS tab alm satelites);
Para crear una instancia de cualquier tipo de colecci´on tambi´en se utiliza el m´etodo
constructor, tal y como se hace con los objetos.
INSERT INTO estrellas
VALUES('Sol',23,
tab planeta(
planeta(
'Neptuno',
10,
tab satelite(
satelite('Proteus',67),
satelite('Triton',82)
)
),
planeta(
'Jupiter',
189,
tab satelite(
satelite('Calisto',97),
satelite('Ganimedes',22)
)
)
)
);
5.1 Objetos en Oracle 31
Las colecciones se pueden consultar con los resultados anidados:
SELECT e.nombre,e.proyectos
FROM empleados e;
NOMBRE PROYECTOS
------ ---------
'Pedro' tab proyecto(67,82)
'Juan' tab proyecto(22,67,97)
o con los resultados sin anidar:
SELECT e.nombre, p.*
FROM empleados e, TABLE(e.proyectos) p;
NOMBRE PROYECTOS
------ ---------
'Pedro' 67
'Pedro' 82
'Juan' 22
'Juan' 67
'Juan' 97
La notaci´on TABLE sustituye a la notaci´on THE subconsulta de versiones anteriores.
La expresi´on que aparece en TABLE puede ser tanto el nombre de una colecci´on como una
subconsulta de una colecci´on. Las dos consultas que se muestran a continuaci´on obtienen el
mismo resultado.
SELECT p.*
FROM empleados e, TABLE(e.proyectos) p
WHERE e.numemp = '18';
SELECT *
FROM TABLE(SELECT e.proyectos
FROM empleados e
WHERE e.numemp = '18');
32 5 Sistemas objeto–relacionales
Tambi´en es posible hacer consultas con resultados no anidados sobre colecciones multinivel.
SELECT s.nombre
FROM estrellas e, TABLE(e.planetas) p, TABLE(p.satelites) s;
5.1.4. Herencia de tipos
La versi´on 9i es la primera versi´on de Oracle que soporta herencia de tipos. Cuando
se crea un subtipo a partir de un tipo, el subtipo hereda todos los atributos y los m´etodos
del tipo padre. Cualquier cambio en los atributos o m´etodos del tipo padre se reflejan autom
´aticamente en el subtipo. Un subtipo se convierte en una versi´on especializada del tipo
padre cuando al subtipo se le a˜naden atributos o m´etodos, o cuando se redefinen m´etodos
que ha heredado, de modo que el subtipo ejecuta el m´etodo “a su manera”. A esto es a lo
que se denomina polimorfismo ya que dependiendo del tipo del objeto sobre el que se invoca
el m´etodo, se ejecuta uno u otro c´odigo. Cada tipo puede heredar de un solo tipo, no de
varios a la vez (no soporta herencia m´ultiple), pero se pueden construir jerarqu´ıas de tipos
y subtipos.
Cuando se define un tipo de objeto, se determina si de ´el se pueden derivar subtipos
mediante la cl´ausula NOT FINAL. Si no se incluye esta cl´ausula, se considera que es FINAL (no
puede tener subtipos). Del mismo modo, los m´etodos pueden ser FINAL o NOT FINAL. Si un
m´etodo es final, los subtipos no pueden redefinirlo (override) con una nueva implementaci´on.
Por defecto, los m´etodos son no finales (es decir, redefinibles).
CREATE TYPE t AS OBJECT ( ...,
MEMBER PROCEDURE imprime(),
FINAL MEMBER FUNCTION fun(x NUMBER) ...
) NOT FINAL;
Para crear un subtipo se utiliza la cl´ausula UNDER.
CREATE TYPE estudiante UNDER persona ( ...,
titulacion VARCHAR2(30),
fecha ingreso DATE
) NOT FINAL;
El nuevo tipo, adem´as de heredar los atributos y m´etodos del tipo padre, define dos nuevos
atributos. A partir del subtipo se pueden derivar otros subtipos y del tipo padre tam5.1
Objetos en Oracle 33
bi´en se pueden derivar m´as subtipos. Para redefinir un m´etodo, se debe utilizar la cl´ausula
OVERRIDING.
Los tipos y los m´etodos se pueden declarar como no instanciables. Si un tipo es no
instanciable, no tiene m´etodo constructor, por lo que no se pueden crear instancias a partir
de ´el. Un m´etodo no instanciable se utiliza cuando no se le va a dar una implementaci´on
en el tipo en el que se declara sino que cada subtipo va a proporcionar una implementaci´on
distinta.
CREATE TYPE t AS OBJECT (
x NUMBER,
NOT INSTANTIABLE MEMBER FUNCTION fun() RETURN NUMBER
) NOT INSTANTIABLE NOT FINAL;
Un tipo puede definir varios m´etodos con el mismo nombre pero con distinta signatura.
La signatura es la combinaci´on del nombre de un m´etodo, el n´umero de par´ametros, los tipos
de ´estos y el orden formal. A esto se le denomina sobrecarga de m´etodos (overloading).
En una jerarqu´ıa de tipos, los subtipos son variantes de la ra´ız. Por ejemplo, en tipo
estudiante y el tipo empleado son clases de persona. Normalmente, cuando se trabaja
con jerarqu´ıas, a veces se quiere trabajar a un nivel m´as general (por ejemplo, seleccionar
o actualizar todas las personas) y a veces se quiere trabajar s´olo son los estudiantes o s´olo
con los que no son estudiantes. La habilidad de poder seleccionar todas las personas juntas,
pertenezcan o no a alg´un subtipo, es lo que se denomina sustituibilidad. Un s´upertipo es
sustituible si uno de sus subtipos puede sustituirlo en una variable, columna, etc. declarada
del tipo del s´upertipo. En general, los tipos son sustituibles.
Un atributo definido como REF miTipo puede contener una REF a una instancia de
miTipo o a una instancia de cualquier subtipo de miTipo.
Un atributo definido de tipo miTipo puede contener una instancia de miTipo o una
instancia de cualquier subtipo de miTipo.
Una colecci´on de elementos de tipo miTipo puede contener instancias de miTipo o
instancias de cualquier subtipo de miTipo.
Dado el tipo libro:
CREATE TYPE libro AS OBJECT (
titulo VARCHAR2(30),
autor persona );
34 5 Sistemas objeto–relacionales
se puede crear una instancia de libro especificando un t´ıtulo y un autor de tipo persona o
de cualquiera de sus subtipos, estudiante o empleado:
libro('BD objeto-relacionales',
estudiante(123,'Mar¶³a Gil','C/Mayor,3','II','10-OCT-99')
A continuaci´on se muestra un ejemplo de la sustituibilidad en las tablas de objetos.
CREATE TYPE persona AS OBJECT
(id NUMBER,
nombre VARCHAR2(30),
direccion VARCHAR2(30)) NOT FINAL;
CREATE TYPE estudiante UNDER persona
(titulacion VARCHAR2(10),
especialidad VARCHAR2(30)) NOT FINAL;
CREATE TYPE estudiante doctorado UNDER estudiante
(programa VARCHAR2(10));
CREATE TABLE personas tab OF persona;
INSERT INTO personas tab
VALUES (persona(1234,'Ana','C/Mayor,23'));
INSERT INTO personas tab
VALUES (estudiante(2345,'Jose','C/Paz,3','ITDI','Mec¶anica'));
INSERT INTO personas tab
VALUES (estudiante doctorado(3456,'Luisa','C/Mar,45','IInf',NULL,'CAA'));
5.1.5. Funciones y predicados ´utiles con objetos
VALUE : esta funci´on toma como par´ametro un alias de tabla (de una tabla de objetos) y
devuelve instancias de objetos correspondientes a las filas de la tabla.
SELECT VALUE(p)
FROM personas tab p
WHERE p.direccion LIKE 'C/Mayor %';
5.1 Objetos en Oracle 35
La consulta devuelve todas las personas que viven en la calle Mayor, sean o no de alg´un
subtipo.
REF : es una funci´on que toma como par´ametro un alias de tabla y devuelve una referencia
a una instancia de un objeto de dicha tabla.
DEREF : es una funci´on que devuelve la instancia del objeto correspondiente a una referencia
que se le pasa como par´ametro.
IS OF : permite formar predicados para comprobar el nivel de especializaci´on de instancias
de objetos.
SELECT VALUE(p)
FROM personas tab p
WHERE VALUE(p) IS OF (estudiante);
De este modo se obtienen las personas que son del subtipo estudiante o que son
de alguno de sus subtipos. Para obtener solamente aquellas personas cuyo tipo m´as
espec´ıfico es estudiante se utiliza la cl´ausula ONLY:
SELECT VALUE(p)
FROM personas tab p
WHERE VALUE(p) IS OF (ONLY estudiante);
TREAT : es una funci´on que trata a una instancia de un s´upertipo como una instancia de uno
de sus subtipos:
SELECT TREAT(VALUE(p) AS estudiante)
FROM personas tab p
WHERE VALUE(p) IS OF (ONLY estudiante);
Bibliograf´

No hay comentarios:

Publicar un comentario