Modelo objeto-relacional en Oracle ÍNDICE
Modelo objeto-relacional en Oracle ÍNDICE
Modelo objeto-relacional en Oracle ÍNDICE
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Modelo</strong> <strong>objeto</strong>-<strong>relacional</strong> <strong>en</strong><br />
<strong>Oracle</strong><br />
<strong>Modelo</strong>s Avanzados de Bases de<br />
Datos<br />
Práctica 2<br />
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS DISTINTOS<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
1
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS DISTINTOS<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
LOBS<br />
• El tipo de datos predefinido LOB (Large<br />
OBjects) permite manejar las necesidades de<br />
almac<strong>en</strong>ami<strong>en</strong>to de imág<strong>en</strong>es, videos,<br />
docum<strong>en</strong>tos y <strong>en</strong> g<strong>en</strong>eral, cualquier tipo de dato<br />
no estructurado y de tamaño grande.<br />
• Los datos no estructurados no se pued<strong>en</strong><br />
descomponer <strong>en</strong> unidades de información más<br />
pequeñas y manejables.<br />
• Los datos multimedia probablem<strong>en</strong>te ocupe<br />
miles de veces ese espacio. Por ello, con el fin<br />
de minimizar el espacio de almac<strong>en</strong>ami<strong>en</strong>to <strong>en</strong><br />
la BD<br />
2
LOBS<br />
• G<strong>en</strong>eralm<strong>en</strong>te la información recogida por un LOB se<br />
guardará <strong>en</strong> ficheros que serán manejados por el<br />
sistema de ficheros del sistema operativo<br />
• En el campo correspondi<strong>en</strong>te al valor de tipo LOB habrá<br />
un puntero que permitirá acceder al cont<strong>en</strong>ido de dicho<br />
fichero.<br />
• <strong>Oracle</strong> puede almac<strong>en</strong>ar <strong>en</strong> la misma tabla LOBs<br />
pequeños, de hasta 4K de tamaño. Cuando el LOB<br />
supera ese tamaño, el SGBD lo almac<strong>en</strong>a fuera de la<br />
tablay pone <strong>en</strong> su lugar el localizador que permita<br />
acceder a la nueva ubicación de los datos.<br />
• Así, los LOBs son capaces de almac<strong>en</strong>ar hasta 4G de<br />
datos; además, se pued<strong>en</strong> definir varias columnas de<br />
tipo LOB <strong>en</strong> una misma tabla, así como varios atributos<br />
de un tipo de <strong>objeto</strong> pued<strong>en</strong> ser de tipo LOB.<br />
LOBS<br />
• Los LOBs se divid<strong>en</strong> básicam<strong>en</strong>te <strong>en</strong> dos<br />
subtipos:<br />
– INTERNOS: aquellos que se almac<strong>en</strong>an <strong>en</strong> los<br />
espacios de tabla (tablespaces) de la propia BD:<br />
BLOB (Binary Large OBjects), compuestos de datos<br />
binarios no estructurados, y los CLOB (Character<br />
Large OBjects) y NCLOB (National Character Large<br />
OBjects), que almac<strong>en</strong>an datos de tipo carácter;<br />
– EXTERNOS: los que almac<strong>en</strong>a el sistema de ficheros<br />
del sistema operativo. Los únicos LOBs externos son<br />
los BFILEs, que son grandes cantidades de datos<br />
binarios. Una columna o un atributo de tipo BFILE<br />
almac<strong>en</strong>a un puntero al comi<strong>en</strong>zo del fichero que<br />
conti<strong>en</strong>e los datos.<br />
3
• Ejemplo:<br />
LOBS<br />
CREATE TABLE Plano<br />
( planoID INTEGER PRIMARY KEY,<br />
fecha_fin DATE,<br />
gráfico BFILE);<br />
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS DISTINTOS<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
4
TIPOS ANY<br />
• <strong>Oracle</strong> permite crear variables y columnas que<br />
pued<strong>en</strong> almac<strong>en</strong>ar datos de cualquier tipo,<br />
permiti<strong>en</strong>do comprobar el valor de ese dato <strong>en</strong><br />
cualquier mom<strong>en</strong>to;<br />
• De este modo se puede ver su repres<strong>en</strong>tación<br />
subyac<strong>en</strong>te, es decir, el tipo concreto del dato.<br />
• Empleando este tipo de datos, una misma<br />
columna puede almac<strong>en</strong>ar <strong>en</strong> una fila un valor<br />
numérico, <strong>en</strong> otra fila una cad<strong>en</strong>a de caracteres<br />
y <strong>en</strong> otra un <strong>objeto</strong>.<br />
TIPOS ANY<br />
• Exist<strong>en</strong> tres tipos de datos que permit<strong>en</strong> el<br />
tipado dinámico:<br />
– SYS.ANYDATA, que almac<strong>en</strong>a un valor de<br />
cualquier tipo escalar o tipo de <strong>objeto</strong>,<br />
– SYS.ANYDATASET, que almac<strong>en</strong>a valores<br />
de cualquier tipo colección y finalm<strong>en</strong>te, el<br />
– SYS.ANYTYPE que permite manipular y<br />
comprobar información de tipos.<br />
5
• Ejemplo<br />
CREATE TABLE tabla<br />
(un_valor SYS.AnyData);<br />
TIPOS ANY<br />
INSERT INTO tabla<br />
VALUES (SYS.AnyData.ConvertNumber(5));<br />
CREATE TYPE tipoEmpleado AS OBJECT(<br />
numE INTEGER,<br />
nombre VARCHAR (20))<br />
/<br />
INSERT INTO tabla<br />
VALUES (SYS.AnyData.ConvertObject(tipoEmpleado(5555,<br />
‘Pepe’)));<br />
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS DISTINTOS<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
6
TIPOS DEFINIDOS POR EL<br />
USUARIO<br />
• Al igual que el estándar SQL:2003, <strong>Oracle</strong><br />
soporta dos clases de tipos definidos por<br />
el usuario:<br />
– los tipos distintos y<br />
– los tipos estructurados<br />
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS DISTINTOS<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
7
TIPOS DISTINTOS<br />
• En SQL-92 las columnas de una tabla se definían<br />
mediante tipos de datos primitivos.<br />
• Dos columnas, con distinta semántica y por tanto,<br />
distinto comportami<strong>en</strong>to, podían estar definidas bajo el<br />
mismo tipo de datos comparti<strong>en</strong>do, por tanto, la misma<br />
repres<strong>en</strong>tación.<br />
• Esto daba lugar a incompatibilidades y errores, ya que,<br />
por ejemplo, se podía igualar el atributo LongSala a<br />
AreaSala, si ambos eran de tipo INTEGER. Sin<br />
embargo, esta asignación es semánticam<strong>en</strong>te<br />
incorrecta, ya que estos atributos ti<strong>en</strong><strong>en</strong> un significado y<br />
un comportami<strong>en</strong>to distinto.<br />
TIPOS DISTINTOS<br />
• Con los tipos distintos se resuelve este<br />
problema. Se usan cuando dos tipos de<br />
datos compart<strong>en</strong> una misma<br />
repres<strong>en</strong>tación pero ti<strong>en</strong><strong>en</strong> distinto<br />
comportami<strong>en</strong>to.<br />
• La definición de tipos distintos se basa <strong>en</strong><br />
el r<strong>en</strong>ombrado de tipos, de tal modo que<br />
el tipo distinto no es comparable con el<br />
tipo fu<strong>en</strong>te.<br />
8
SQL:2003<br />
TIPOS DISTINTOS<br />
CREATE TYPE tipoSala<br />
AS CHAR(10) FINAL;<br />
CREATE TYPE tipoMetros<br />
AS INTEGER FINAL;<br />
CREATE TYPE tipoMetrosCuad<br />
AS INTEGER FINAL;<br />
CREATE TABLE Sala (<br />
IdSala tipoSala,<br />
LongSala tipoMetros,<br />
AnchoSala tipoMetros,<br />
AreaSala tipoMetrosCuad,<br />
PerimSala tipoMetros));<br />
<strong>ÍNDICE</strong><br />
Incorrecto<br />
UPDATE Sala<br />
SET AreaSala=LongSala;<br />
Correcto<br />
UPDATE Sala<br />
SET AnchoSala=LongSala;<br />
• LOBS<br />
• TIPOS ANY<br />
• URI TYPES<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS DISTINTOS<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
9
TIPOS ESTRUCTURADOS<br />
• Se utilizan:<br />
– como tipos de una columna,<br />
– como tipos de un atributo de otro tipo definido por el<br />
usuario o<br />
– como el tipo de una tabla.<br />
• Cuando se utilizan como el tipo de una columna<br />
o de un atributo, son tipos de datos valor;<br />
• Cuando se utilizan como el tipo de una tabla se<br />
conviert<strong>en</strong> <strong>en</strong> tipos de <strong>objeto</strong>s.<br />
TIPOS ESTRUCTURADOS<br />
• Se defin<strong>en</strong> mediante la cláusula<br />
CREATE TYPE AS OBJECT,<br />
• tanto para definir un tipo de dato valor,<br />
como para definir un tipo de <strong>objeto</strong>.<br />
• Lo que determinará si se trata de un tipo<br />
de dato valor o un tipo de <strong>objeto</strong> es el que<br />
dicho tipo se utilice como el tipo de una<br />
columna (o un atributo) o como el tipo de<br />
una fila.<br />
10
TIPOS ESTRUCTURADOS<br />
• Un ejemplo de tipo estructurado, utilizado como<br />
tipo de dato valor <strong>en</strong> <strong>Oracle</strong> (ya que se utiliza <strong>en</strong><br />
la definición de una columna de una tabla<br />
<strong>relacional</strong> ):<br />
CREATE OR REPLACE TYPE tipoDireccion AS OBJECT(<br />
calle VARCHAR2 (30),<br />
ciudad VARCHAR2 (20),<br />
provincia VARCHAR2 (2),<br />
CP VARCHAR2 (5))<br />
/<br />
CREATE TABLE Persona (<br />
nombre VARCHAR2(30),<br />
vive_<strong>en</strong> tipoDireccion,<br />
foto BLOB);<br />
TIPOS ESTRUCTURADOS<br />
• Un tipo de <strong>objeto</strong> se define igual que un tipo<br />
estructurado. La difer<strong>en</strong>cia radica <strong>en</strong> que no se<br />
usa como el tipo de una columna, sino como el<br />
tipo de una tabla tipada.<br />
CREATE OR REPLACE TYPE tipoEmpleado AS OBJECT<br />
( DNI NUMBER,<br />
nombre VARCHAR2(30),<br />
fecha_nac DATE)<br />
/<br />
CREATE TABLE Empleado OF tipoEmpleado;<br />
11
TIPOS ESTRUCTURADOS<br />
• En este caso, el tipo estructurado<br />
tipoEmpleado, es un tipo de <strong>objeto</strong>, ya que<br />
se utiliza como el tipo de la tabla<br />
Empleado.<br />
• Así, la definición del tipo especifica la<br />
int<strong>en</strong>sión (o estructura del mismo)<br />
mi<strong>en</strong>tras que la ext<strong>en</strong>sión se definirá<br />
mediante la creación de una tabla tipada.<br />
TIPOS ESTRUCTURADOS<br />
• Igualm<strong>en</strong>te, pued<strong>en</strong> crearse varias tablas<br />
sobre un mismo tipo estructurado.<br />
– La tabla t<strong>en</strong>drá una columna por cada atributo<br />
del tipo,<br />
– además de la columna REF;<br />
– sus filas van a ser las instancias de los<br />
<strong>objeto</strong>s del tipo de <strong>objeto</strong>.<br />
– Las restricciones (de clave primaria, unicidad,<br />
etc.) se defin<strong>en</strong> sobre la tabla, no sobre el<br />
tipo.<br />
12
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
TIPOS REF<br />
• Un tipo refer<strong>en</strong>cia (REF) es un tipo de<br />
datos que conti<strong>en</strong>e el valor del atributo<br />
REF (que se correspondería con el OID)<br />
de una fila de una tabla tipada.<br />
• REF, <strong>en</strong> realidad, es un constructor de<br />
tipo, ya que existe un tipo REF por cada<br />
tabla tipada.<br />
13
TIPOS REF<br />
• Así, <strong>en</strong> el ejemplo de la figura, la columna REF<br />
cont<strong>en</strong>drá valores del tipo REF (tipoPropiedad).<br />
• El tipo refer<strong>en</strong>cia permite implem<strong>en</strong>tar relaciones<br />
prescindi<strong>en</strong>do de la utilización de claves aj<strong>en</strong>as. Un<br />
atributo definido como de tipo refer<strong>en</strong>cia cont<strong>en</strong>drá el<br />
valor del atributo REF del <strong>objeto</strong> refer<strong>en</strong>ciado.<br />
PROPIEDADES<br />
REF precio num_habitaciones tamaño ubicación<br />
TIPOS REF<br />
calle ciudad provincia CP<br />
• En la sigui<strong>en</strong>te s<strong>en</strong>t<strong>en</strong>cia SQL se puede ver la<br />
creación de un tipo tipoPropiedad que conti<strong>en</strong>e<br />
un atributo, propietario, de tipo refer<strong>en</strong>cia al tipo<br />
estructurado tipoPersona.<br />
CREATE TYPE tipoPropiedad AS (<br />
propietario REF (tipoPersona),<br />
precio INTEGER,<br />
num_habitaciones INTEGER,<br />
tamaño DECIMAL (8,2),<br />
ubicacion tipoDireccion);<br />
CREATE TABLE Propiedades OF tipoPropiedad;<br />
14
TIPOS REF<br />
• Un tipo estructurado ti<strong>en</strong>e un tipo refer<strong>en</strong>cia<br />
correspondi<strong>en</strong>te.<br />
• Un tipo refer<strong>en</strong>cia puede ser usado <strong>en</strong> cualquier sitio<br />
donde pueda ser usado otro tipo de datos.<br />
• Aunque el tipo REF nos va a permitir implem<strong>en</strong>tar<br />
relaciones <strong>en</strong>tre tipos de <strong>objeto</strong>s, hay que t<strong>en</strong>er <strong>en</strong><br />
cu<strong>en</strong>ta que el tipo refer<strong>en</strong>cia no ti<strong>en</strong>e la misma semántica<br />
que la clave aj<strong>en</strong>a.<br />
• Mi<strong>en</strong>tras que la clave aj<strong>en</strong>a implica una dep<strong>en</strong>d<strong>en</strong>cia de<br />
inclusión, debido a la restricción de integridad refer<strong>en</strong>cial,<br />
el tipo REF no, permitiéndose la posibilidad de<br />
refer<strong>en</strong>cias que no apunt<strong>en</strong> a ninguna parte (son las<br />
d<strong>en</strong>ominadas “dangling refer<strong>en</strong>ces”).<br />
• Además, el tipo REF soporta la noción de tipado fuerte<br />
que no va ligada a una clave aj<strong>en</strong>a; de este modo, un<br />
atributo de tipo REF puede, por ejemplo, usarse como<br />
parámetro <strong>en</strong> la llamada de un método.<br />
TIPOS REF<br />
• Los tipos refer<strong>en</strong>cia permit<strong>en</strong> navegar de una tabla a<br />
otra, eliminando la necesidad de joins del modelo<br />
<strong>relacional</strong>.<br />
CREATE OR REPLACE TYPE tipoDepartam<strong>en</strong>to AS OBJECT<br />
( nombre_Dep VARCHAR2(30))<br />
/<br />
CREATE OR REPLACE TYPE tipoEmpleado AS OBJECT<br />
( DNI NUMBER,<br />
nombre VARCHAR2(30),<br />
fecha_nac DATE,<br />
pert<strong>en</strong>ece_a REF tipoDepartam<strong>en</strong>to)<br />
/<br />
CREATE TABLE Departam<strong>en</strong>to OF tipoDepartam<strong>en</strong>to;<br />
CREATE TABLE Empleado OF tipoEmpleado;<br />
15
TIPOS REF<br />
• De este modo, las relaciones podrán seguir<br />
implem<strong>en</strong>tándose mediante claves aj<strong>en</strong>as, o bi<strong>en</strong><br />
utilizar refer<strong>en</strong>cias.<br />
• Para las consultas que involucr<strong>en</strong> a dos tablas, <strong>en</strong><br />
el primer caso se seguirán realizando mediante<br />
joins, mi<strong>en</strong>tras que <strong>en</strong> el caso de haberlas<br />
relacionado mediante refer<strong>en</strong>cias se realizarán<br />
utilizando la notación “punto”:<br />
SELECT nombre, e.pert<strong>en</strong>ece_a.nombre_Dep<br />
FROM Empleado e<br />
WHERE DNI=9687452;<br />
que devolvería el nombre del empleado con DNI<br />
9687452, así como el nombre del departam<strong>en</strong>to al<br />
que pert<strong>en</strong>ece.<br />
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
16
MÉTODOS<br />
• Es posible asociar comportami<strong>en</strong>to a los tipos<br />
de <strong>objeto</strong>s, defini<strong>en</strong>do la cabecera de los<br />
métodos como parte de la definición del tipo:<br />
CREATE OR REPLACE TYPE tipoEmpleado AS OBJECT<br />
( DNI NUMBER,<br />
nombre VARCHAR2(30),<br />
fecha_nac DATE,<br />
pert<strong>en</strong>ece_a REF tipoDepartam<strong>en</strong>to,<br />
MEMBER FUNCTION edad RETURN NUMBER)<br />
/<br />
CREATE TABLE Empleado OF tipoEmpleado;<br />
MÉTODOS<br />
• Los métodos de un tipo se declaran como<br />
funciones miembro y no como métodos. El<br />
cuerpo del método se define por separado.<br />
CREATE TYPE BODY tipoEmpleado AS<br />
MEMBER FUNCION edad RETURN NUMBER IS<br />
BEGIN<br />
...<br />
RETURN edad;<br />
END;<br />
END;<br />
/<br />
17
MÉTODOS<br />
• Los métodos recib<strong>en</strong> siempre como parámetro<br />
implícito la lista de atributos del tipo de <strong>objeto</strong> al<br />
que pert<strong>en</strong>ec<strong>en</strong>.<br />
• La palabra reservada a través de la cual un<br />
método se refiere a dichos atributos es SELF.<br />
Así, por ejemplo, SELF.nombre, hace refer<strong>en</strong>cia<br />
al nombre de un empleado concreto.<br />
• Puede existir sobrecarga <strong>en</strong> la definición de<br />
métodos. Es decir, puede haber dos métodos<br />
que se llam<strong>en</strong> igual siempre que sus parámetros<br />
formales varí<strong>en</strong> <strong>en</strong> número, ord<strong>en</strong> o tipo de<br />
dato.<br />
MÉTODOS<br />
• Cada tipo de <strong>objeto</strong> ti<strong>en</strong>e un método<br />
constructor; se trata de una función definida por<br />
el sistema con el mismo nombre que el tipo de<br />
<strong>objeto</strong>.<br />
• El constructor inicializa y devuelve una instancia<br />
del tipo de <strong>objeto</strong>.<br />
• Los parámetros formales que recibe el<br />
constructor son los atributos, <strong>en</strong> el mismo ord<strong>en</strong><br />
que se han definido, del tipo de <strong>objeto</strong>.<br />
18
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
HERENCIA<br />
• <strong>Oracle</strong> 8 no soportaba una de las características<br />
más importantes de la ori<strong>en</strong>tación al <strong>objeto</strong>, la<br />
her<strong>en</strong>cia. Desde la versión 9i de <strong>Oracle</strong> se<br />
incorpora ya la her<strong>en</strong>cia simple de tipos, pero<br />
no soporta la her<strong>en</strong>cia de tablas.<br />
• El tipo raíz de una jerarquía se crea empleando<br />
la s<strong>en</strong>t<strong>en</strong>cia CREATE TYPE y debe ser<br />
declarado como NOT FINAL. La opción por<br />
defecto es FINAL (indicando así, que pued<strong>en</strong><br />
derivarse subtipos de él).<br />
19
HERENCIA<br />
CREATE TYPE tipoPersona AS<br />
OBJECT<br />
(DNI VARCHAR(9),<br />
nombre VARCHAR(25),<br />
fecha_nac DATE,<br />
direccion VARCHAR(1000),<br />
MEMBER FUNCTION edad<br />
RETURN NUMBER)<br />
NOT INSTANTIABLE NOT FINAL<br />
/<br />
CREATE TYPE tipoEstudiante UNDER<br />
tipoPersona<br />
(estudios VARCHAR(50))<br />
/<br />
CREATE TYPE tipoEmpleado UNDER<br />
tipoPersona<br />
(empresa VARCHAR(50))<br />
/<br />
Estudiante<br />
estudios: String<br />
HERENCIA<br />
Persona<br />
DNI: String<br />
nombre: String<br />
fecha_nac: Date<br />
direccion: String<br />
edad(): Integer<br />
Empleado<br />
empresa: String<br />
• La her<strong>en</strong>cia simple de tipos que contempla<br />
<strong>Oracle</strong> implica que cualquier subtipo hereda de<br />
su padre los métodos y atributos que posea.<br />
• Así, para el ejemplo pres<strong>en</strong>tado, los subtipos<br />
tipoEstudiante y tipoEmpleado pose<strong>en</strong> los dos la<br />
función edad().<br />
• Por tanto, esta función podrá ser invocada sobre<br />
cualquier instancia de estos tipos, es decir,<br />
cuando se defina una tabla de cualquiera de los<br />
dos subtipos, podremos llamar a la función<br />
edad() sobre cualquiera de las filas de la tabla<br />
(que no son sino <strong>objeto</strong>s).<br />
20
HERENCIA<br />
• La característica [NOT] FINAL permite<br />
indicar si la clase puede t<strong>en</strong>er subclases o<br />
no<br />
• La característica [NOT] INSTANTIABLE<br />
permite indicar si la clase va a poder<br />
instanciarse o no.<br />
HERENCIA<br />
• Es muy importante t<strong>en</strong>er <strong>en</strong> cu<strong>en</strong>ta que <strong>Oracle</strong><br />
no soporta la her<strong>en</strong>cia de tablas; es decir, la<br />
definición de jerarquías de tablas sobre tipos<br />
que están integrados <strong>en</strong> una jerarquía de tipos.<br />
• <strong>Oracle</strong> sólo permite asegurar que los atributos y<br />
métodos del supertipo de la tabla padre, se<br />
heredarán <strong>en</strong> las tablas definidas sobre los<br />
subtipos.<br />
• Sin embargo, las restricciones, disparadores,<br />
etc. definidos para una tabla no podrán ser<br />
heredados por otras tablas, aunque sus tipos<br />
subyac<strong>en</strong>tes pert<strong>en</strong>ezcan a la misma jerarquía.<br />
21
HERENCIA<br />
• A continuación se muestran las s<strong>en</strong>t<strong>en</strong>cias para<br />
crear las tablas del tipo padre y de los dos<br />
subtipos.<br />
• Es necesario definir <strong>en</strong> cada tabla sus propias<br />
restricciones, ya que éstas no se propagan:<br />
CREATE TABLE Persona OF tipoPersona<br />
(PRIMARY KEY (DNI),<br />
CHECK(direccion like (‘%Madrid%’)));<br />
CREATE TABLE Estudiante OF tipoEstudiante<br />
(PRIMARY KEY (nombre));<br />
CREATE TABLE Empleado OF tipoEmpleado<br />
(PRIMARY KEY (DNI));<br />
HERENCIA<br />
• Las tablas Estudiante y Empleado definidas sobre<br />
subtipos del tipo tipoPersona no deb<strong>en</strong> cumplir <strong>en</strong><br />
absoluto las restricciones impuestas para la tabla<br />
Persona definida sobre el tipo padre TipoPersona.<br />
• Así, por ejemplo, podemos insertar <strong>en</strong> la tabla Empleado<br />
una fila <strong>en</strong> la que el valor del atributo direccion no<br />
cont<strong>en</strong>ga la cad<strong>en</strong>a ‘Madrid’, mi<strong>en</strong>tras que <strong>en</strong> la tabla<br />
Persona nos sería imposible.<br />
• Así mismo, podemos definir el campo nombre como<br />
clave primaria <strong>en</strong> la tabla Estudiante, aunque <strong>en</strong> la tabla<br />
padre Persona la clave primaria se definió sobre el<br />
campo DNI.<br />
22
HERENCIA<br />
• Pero, además de que las tablas no hered<strong>en</strong> las<br />
restricciones de la tabla definida para el supertipo, existe<br />
un problema aun mayor, y es que con el ejemplo<br />
anterior, no podemos recoger el hecho, implícito <strong>en</strong> toda<br />
jerarquía, de que todo estudiante es persona y de que<br />
todo empleado es persona.<br />
• Esto es debido a que no existe relación alguna <strong>en</strong>tre las<br />
tablas, no hay nada que le indique al SGBD que un<br />
empleado o un alumno es también una persona. Por<br />
ello, al realizar una consulta a persona, obt<strong>en</strong>dríamos<br />
sólo aquellas personas que no fueran ni estudiantes ni<br />
empleados.<br />
HERENCIA<br />
• De este modo, para la implem<strong>en</strong>tación de<br />
una jerarquía <strong>en</strong> <strong>Oracle</strong>, aunque podamos<br />
apoyarnos <strong>en</strong> ocasiones <strong>en</strong> la utilización<br />
de la her<strong>en</strong>cia de tipos, necesitamos<br />
además recurrir a los clásicos<br />
mecanismos empleados <strong>en</strong> <strong>relacional</strong><br />
(claves aj<strong>en</strong>as, o refer<strong>en</strong>cias, <strong>en</strong>tre las<br />
tablas, restricciones, vistas, etc.).<br />
23
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
TIPOS COLECCIÓN<br />
• <strong>Oracle</strong> soporta dos tipos de colecciones: VARRAY y<br />
NESTED TABLE.<br />
• El tipo VARRAY es un tipo de longitud variable; es decir,<br />
se almac<strong>en</strong>a sólo la longitud ocupada del array.<br />
CREATE OR REPLACE TYPE tipoTelefono<br />
AS VARRAY (3) of VARCHAR(10)<br />
/<br />
CREATE TABLE Empleado<br />
( DNI NUMBER,<br />
nombre VARCHAR2(30),<br />
telefonos_contacto tipoTelefono);<br />
INSERT INTO Empleado<br />
VALUES (‘9876543’, ‘Pepe’, tipoTelefono (‘914445566’, ‘606445566’,<br />
‘934445566’));<br />
24
TIPOS COLECCIÓN<br />
• Desde una s<strong>en</strong>t<strong>en</strong>cia SELECT no es<br />
posible acceder a los elem<strong>en</strong>tos<br />
individuales del VARRAY indexándolos;<br />
• Para el tratami<strong>en</strong>to individual de cada<br />
elem<strong>en</strong>to del VARRAY, es necesario<br />
hacerlo mediante PL/SQL, que<br />
proporciona cláusulas para posicionarse<br />
<strong>en</strong> los distintos elem<strong>en</strong>tos del array.<br />
TIPOS COLECCIÓN<br />
• <strong>Oracle</strong> soporta otro tipo de datos colección que<br />
son las tablas anidadas o NESTED TABLES.<br />
• Es posible definir un tipo de datos como una<br />
tabla, y utilizar dicho tipo como el tipo de datos<br />
de la columna de otra tabla.<br />
• De este modo, la columna cont<strong>en</strong>drá una<br />
colección de valores, <strong>objeto</strong>s o refer<strong>en</strong>cias, que<br />
se almac<strong>en</strong>arán <strong>en</strong> formato de tabla.<br />
• Aunque <strong>Oracle</strong> almac<strong>en</strong>a las filas de una<br />
NESTED TABLE sin ord<strong>en</strong>, al recuperarlas es<br />
posible referirse a ellas según un ord<strong>en</strong> de<br />
indexación que empieza <strong>en</strong> el 1.<br />
25
TIPOS COLECCIÓN<br />
CREATE TYPE tipoNombres AS VARRAY(5) OF vARCHAR(20)<br />
CREATE TYPE tipoPlano AS OBJECT<br />
( plano_ID NUMBER,<br />
num_figuras NUMBER,<br />
arquitectos tipoNombres)<br />
CREATE TABLE Plano OF tipoPlano<br />
(PRIMARY KEY (plano_Id));<br />
CREATE OR REPLACE TYPE refTipoPlano AS OBJECT<br />
(refPlano REF tipoPlano)<br />
CREATE OR REPLACE TYPE NT_Planos AS TABLE OF<br />
refTipoPlano<br />
CREATE OR REPLACE TYPE tipoProyecto AS OBJECT<br />
( proyecto_ID NUMBER,<br />
nombre VARCHAR(30),<br />
ti<strong>en</strong>e_plano NT_Planos)<br />
/<br />
CREATE TABLE Proyecto OF tipoProyecto<br />
(PRIMARY KEY (proyecto_ID),<br />
UNIQUE (nombre))<br />
NESTED TABLE ti<strong>en</strong>e_plano STORE AS ListaPlanos;<br />
INSERT INTO Plano VALUES (1, 5,NULL);<br />
INSERT INTO Plano VALUES (2, 4,NULL);<br />
DECLARE<br />
p1_ref refTipoPlano;<br />
p2_ref refTipoPlano;<br />
--Se utilizan refer<strong>en</strong>cias a los dos nuevos<br />
--planos para introducir valores <strong>en</strong> la tabla<br />
--anidada creada<br />
BEGIN<br />
SELECT refTipoPlano(REF(p1)) INTO p1_ref<br />
FROM Plano p1 WHERE p1.plano_id=1;<br />
SELECT refTipoPlano(REF(p2)) INTO p2_ref<br />
FROM Plano p2 WHERE p2.plano_id=2;<br />
INSERT INTO Proyecto<br />
VALUES (1, 'MIDAS', NT_Planos (p1_ref, p2_ref));<br />
END;<br />
/<br />
TIPOS COLECCIÓN<br />
• Al definir una tabla tipada que conti<strong>en</strong>e un atributo que<br />
es de tipo tabla, es necesario darle un nombre de<br />
almac<strong>en</strong>ami<strong>en</strong>to a la NESTED TABLE mediante la<br />
cláusula STORE AS que es un nombre interno y no se<br />
puede utilizar para acceder directam<strong>en</strong>te a la tabla<br />
anidada.<br />
• La tabla anidada es un tipo colección y funciona como<br />
tal. Por tanto, el acceso a sus miembros (bi<strong>en</strong> para<br />
inserción, borrado o consulta) es necesario hacerlo a<br />
través de la tabla principal.<br />
SELECT P.proyecto_ID, Pl.refplano.Plano_ID,<br />
Pl.refplano.num_figuras<br />
FROM Proyecto P, TABLE(P.ti<strong>en</strong>e_plano) Pl<br />
WHERE P.Nombre='MIDAS';<br />
26
TIPOS COLECCIÓN<br />
• Las principales difer<strong>en</strong>cias <strong>en</strong>tre los tipos<br />
colección VARRAY y NESTED TABLE son:<br />
– Los VARRAYS ti<strong>en</strong><strong>en</strong> un tamaño máximo fijo que se<br />
especifica <strong>en</strong> la definición del tipo, mi<strong>en</strong>tras que las<br />
NESTED TABLES son de tamaño variable (no se<br />
dim<strong>en</strong>sionan).<br />
– A la hora del almac<strong>en</strong>ami<strong>en</strong>to <strong>en</strong> la base de datos,<br />
los VARRAYS se guardan <strong>en</strong> el mismo espacio que<br />
la tabla. Sin embargo, las NESTED TABLES se<br />
almac<strong>en</strong>an como otra tabla indep<strong>en</strong>di<strong>en</strong>te asociada a<br />
la tabla sobre la que está definida, pero sobre la que<br />
solo se pued<strong>en</strong> realizar consultas a través de la tabla<br />
<strong>en</strong> la que esta definida.<br />
TIPOS COLECCIÓN<br />
• Cuando se necesite emplear un tipo colección, a la hora<br />
de elegir <strong>en</strong>tre una NESTED TABLE o un VARRAY hay<br />
varios criterios a seguir<br />
– Si el ord<strong>en</strong> <strong>en</strong> que se almac<strong>en</strong>an los elem<strong>en</strong>tos de la colección<br />
es relevante, se emplea un VARRAY, puesto que la NESTED<br />
TABLE no conservan el ord<strong>en</strong>.<br />
– En caso de saber de antemano el número de elem<strong>en</strong>tos que<br />
t<strong>en</strong>drá la colección, se emplea un VARRAY porque permite<br />
limitar su tamaño <strong>en</strong> el mom<strong>en</strong>to de su definición.<br />
– En g<strong>en</strong>eral, si el tamaño y el ord<strong>en</strong> no son especialm<strong>en</strong>te<br />
relevantes: si se necesitan consultas sobre la colección, que nos<br />
permitan tratar los elem<strong>en</strong>tos de la colección por separado, se<br />
emplea una NESTED TABLE, mi<strong>en</strong>tras que si se desea<br />
recuperar la colección como un todo, se empleará un VARRAY,<br />
aunque también se permitiría el acceso a los elem<strong>en</strong>tos<br />
individuales.<br />
27
<strong>ÍNDICE</strong><br />
• LOBS<br />
• TIPOS ANY<br />
• TIPOS DEFINIDOS POR EL USUARIO<br />
– TIPOS ESTRUCTURADOS<br />
– TIPOS REF<br />
– MÉTODOS<br />
– HERENCIA<br />
– TIPOS COLECCIÓN: NESTED TABLES Y VARRAYS<br />
– EVOLUCIÓN DE TIPOS<br />
EVOLUCIÓN DE TIPOS<br />
• La evolución de tipos es un mecanismo que permite al usuario<br />
cambiar la definición de un tipo y propagar esos cambios a otros<br />
<strong>objeto</strong>s del esquema que us<strong>en</strong> el tipo modificado.<br />
• Estos <strong>objeto</strong>s se d<strong>en</strong>ominan dep<strong>en</strong>di<strong>en</strong>tes del tipo y pued<strong>en</strong> ser,<br />
por ejemplo, una tabla, otro tipo o subtipo, una unidad de<br />
programación o bloque PL/SQL (procedimi<strong>en</strong>to, función, paquete o<br />
disparador), etc.<br />
• La evolución de tipos permite realizar las sigui<strong>en</strong>tes modificaciones<br />
sobre un tipo definido por el usuario:<br />
– Añadir y eliminar atributos.<br />
– Añadir y eliminar métodos.<br />
– Modificar un atributo de tipo numérico, cambiando su longitud, precisión<br />
o escala.<br />
– Modificar un atributo de tipo carácter de tamaño variable, para<br />
increm<strong>en</strong>tar el tamaño que admite.<br />
– Cambiar las propiedades final e instantiable de un tipo.<br />
28
EVOLUCIÓN DE TIPOS<br />
• Pero, ¿qué sucede con un <strong>objeto</strong> dep<strong>en</strong>di<strong>en</strong>te cuando<br />
se modifica el tipo del que dep<strong>en</strong>de? Esto estará <strong>en</strong><br />
función de la naturaleza del <strong>objeto</strong> y de la modificación<br />
efectuada.<br />
• Por ejemplo, si el <strong>objeto</strong> es una tabla, por cada atributo<br />
añadido al tipo se añad<strong>en</strong> a la tabla una o varias<br />
columnas, según el tipo del nuevo atributo añadido al<br />
tipo (esos nuevos atributos se añad<strong>en</strong> con valor nulo).<br />
• En el caso de eliminar atributos <strong>en</strong> el tipo, las columnas<br />
del <strong>objeto</strong> dep<strong>en</strong>di<strong>en</strong>te asociadas con esos atributos son<br />
eliminadas, y si lo que se hace es modificar la definición<br />
del atributo (escala, tamaño...), se realizan las mismas<br />
modificaciones <strong>en</strong> las columnas del <strong>objeto</strong> dep<strong>en</strong>di<strong>en</strong>te<br />
asociadas con dicho atributo.<br />
EVOLUCIÓN DE TIPOS<br />
• Introducir estas modificaciones <strong>en</strong> los <strong>objeto</strong>s<br />
dep<strong>en</strong>di<strong>en</strong>tes requiere:<br />
– por un lado, modificar los metadatos (información<br />
sobre la estructura de una tabla, que describe sus<br />
columnas y los tipos de éstas), lo cual no consume<br />
demasiado tiempo, y,<br />
– por otro, modificar los datos de la tabla para reflejar la<br />
redefinición del tipo; si hay una gran cantidad de<br />
datos, esta modificación puede consumir una<br />
importante cantidad de tiempo, por ello, <strong>Oracle</strong><br />
proporciona opciones para la s<strong>en</strong>t<strong>en</strong>cia ALTER TYPE<br />
(empleada para redefinir un tipo), que pospon<strong>en</strong><br />
estas modificaciones <strong>en</strong> los datos hasta que sean<br />
actualizados.<br />
29
EVOLUCIÓN DE TIPOS<br />
• En cualquier caso, <strong>Oracle</strong> siempre devuelve los datos de<br />
una tabla <strong>en</strong> el formato especificado por la última<br />
versión del tipo.<br />
• Así, si la tabla está aún almac<strong>en</strong>ada <strong>en</strong> el formato de<br />
una versión anterior del tipo, <strong>Oracle</strong> convierte los datos<br />
antes de devolverlos, aunque el formato <strong>en</strong> que están<br />
almac<strong>en</strong>ados no cambia hasta que los datos sean<br />
reescritos.<br />
• En el ejemplo sigui<strong>en</strong>te se cambia el tipo tipoPersona,<br />
añadiéndole un atributo y eliminando otro.<br />
• La palabra clave CASCADE propaga el cambio a los<br />
tipos y tablas dep<strong>en</strong>di<strong>en</strong>tes, mi<strong>en</strong>tras que la cláusula<br />
NOT INCLUDING TABLE DATA pospone la conversión<br />
de los datos de esas tablas dep<strong>en</strong>di<strong>en</strong>tes hasta que se<br />
reescriban.<br />
EVOLUCIÓN DE TIPOS<br />
CREATE TYPE tipoPersona AS OBJECT<br />
( nombre VARCHAR(30),<br />
apellidos VARCHAR(30),<br />
edad NUMBER(3))<br />
/<br />
CREATE TABLE Persona OF tipoPersona;<br />
INSERT INTO Persona<br />
VALUES (tipoPersona (‘Pepe’, ‘Sánchez’, 50));<br />
En la consulta se recupera el valor de los <strong>objeto</strong>s de la tabla Persona:<br />
SELECT VALUE(p) FROM Persona p;<br />
El resultado sería el sigui<strong>en</strong>te:<br />
VALUE(P)(NOMBRE, APELLIDOS, EDAD)<br />
----------------------------------------------<br />
TIPOPERSONA (’Pepe', ’Sánchez', 50)<br />
30
EVOLUCIÓN DE TIPOS<br />
A continuación, modificamos el tipo tipoPersona sustituy<strong>en</strong>do el<br />
atributo edad por f_nacimi<strong>en</strong>to. En este punto, la redefinición del tipo<br />
tipoPersona, ha cambiado también la definición de la tabla Persona,<br />
pero los datos de la tabla no han sido modificados aún, para ajustarse<br />
a la nueva definición.<br />
ALTER TYPE tipoPersona<br />
ADD ATTRIBUTE (f_nacimi<strong>en</strong>to DATE),<br />
DROP ATTRIBUTE edad CASCADE NOT INCLUDING TABLE DATA;<br />
Cuando consultamos ahora el valor de los <strong>objeto</strong>s de la tabla Persona<br />
obt<strong>en</strong>emos lo sigui<strong>en</strong>te:<br />
SELECT value(p) FROM TablaPersona p;<br />
VALUE(P)(NOMBRE, APELLIDOS, F_NACIMIENTO)<br />
----------------------------------------------<br />
TIPOPERSONA(’Pepe', ’Sánchez', NULL)<br />
EVOLUCIÓN DE TIPOS<br />
• Cuando la consulta anterior recupera los datos<br />
de la tabla Persona, <strong>Oracle</strong> los modifica para<br />
que concuerd<strong>en</strong> con la nueva definición del tipo.<br />
• En este caso, como se ha añadido un nuevo<br />
atributo, se limita a inicializarlo con valor nulo,<br />
NULL.<br />
• Para borrar tipos con tablas u otros tipos<br />
dep<strong>en</strong>di<strong>en</strong>tes, es necesario borrar antes todos<br />
los <strong>objeto</strong>s dep<strong>en</strong>di<strong>en</strong>tes o bi<strong>en</strong> incluir la<br />
cláusula FORCE.<br />
• Así, por ejemplo, para borrar el tipo tipoPersona,<br />
t<strong>en</strong>dríamos que especificar:<br />
DROP TYPE tipoPersona FORCE;<br />
31