2-Apontadores

Propaganda
III - Oracle9i
Apontadores – Tipo de Dado (REF)
Identificador de Objeto
• A todo objeto de uma “object table” é
associado um OID (“Object IDentifier”)
lógico e globalmente único, que identifica
internamente o objeto
• Por default, o OID é gerado pelo sistema
(”system-generated”), e ocupa 16 bytes
• Não há interface para o acesso à estrutura
interna de um OID
• OID é uma coluna invisível de uma “object
table”, com cada valor ocupando 16 bytes
Identificador de Objeto
(2)
• Um OID pode também ser definido como sendo o
valor do atributo chave primária do objeto 
chave do objeto
• Isto é possível em um ambiente em que um
identificador local pode ser também assumido
como sendo globalmente único (“object table” não
distribuída, ou não duplicada)
• Uma vantagem indiscutível de chave primária
sobre OID é a seguinte: a criação dos objetos é
mais rápida, pois não há perda de tempo com a
geração de OIDs
Identificador de Objeto
(3)
• Tanto OID como chave primária
oneram o acesso aos objetos: em um
caso e outro os endereços são
lógicos, necessitando portanto de ser
mapeados para endereços físicos dos
objetos
– Os mapeamentos são feitos com a ajuda
de índices, quer para OID quer para
chave primária, os quais são
automaticamente mantidos pelo sistema
Identificador de Objeto
(4)
• Em termos de economia de espaço,
qual seria a melhor escolha, “systemgenerated” ou chave primária?
– Note que, se o OID for a chave de um
objeto, a coluna OID da tabela é
economizada, ou deixa de existir
– Entretanto, não é sempre certo que
haverá economia de espaço com chave
primária (ver adiante)
Tipo de Dado REF
• REFs e coleções de REFs modelam associações entre
objetos, usando OIDs como apontadores
– Fácil mecanismo para navegação entre objetos
– Colunas de tabelas híbridas podem ser do tipo REF
• Valor de um tipo REF
– OID do objeto referenciado (16 bytes), ou chave (tamanho
definido pelo usuário)
– OID da “object table” (16 bytes)
– ROWID (10 bytes)
• REF IS ROWID
Tipo de Dado REF
• Espaço
– Caso cada chave (OID) requeira mais de
16 bytes, e havendo um grande número
de valores tipo REF, então chave
primária será pior que OID com relação
a espaço em disco, pois neste caso as
chaves vão ser duplicadas nos valores
REF
REF com Escopo
• Pode ser necessário declarar que um valor REF deva conter
somente referências a objetos de uma “object table”
específica
– REF com escopo (“scoped REF”)
CREATE TABLE pessoas (
id NUMBER(4),
nome VARCHAR2(60),
ref_endereco REF endereço_objtyp SCOPE
IS endereço_objtab,
fones_ntab fone_ntabtyp)
NESTED TABLE fones_ntab STORE AS fones_ntab2
REF com Escopo (2)
• Se a “object table” do escopo for de um subtipo
(herança), o escopo é estendido para compreender
também as “object table”s dos subtipos do subtipo
• REFS com escopo são armazenados de maneira mais
eficiente do que REFs sem escopo
– OID (gerado pelo sistema ou chave primária)
– Opção WITH ROWID não é válida
• Somente colunas REF com escopo podem ser
indexadas
• REFs com escopo facilitam a tarefa do Otimizador de
Consultas
Indexação de Colunas
REF com Escopo
CREATE TABLE endereco_objtab OF
endereco_objtyp
CREATE TABLE pessoas (
id NUMBER(4) PRIMARY KEY,
nome VARCHAR2(60),
ref_endereco REF endereço_objtyp SCOPE
IS
endereço_objtab,
fones_ntab fone_ntabtyp)
NESTED TABLE fones_ntab STORE AS
fones_ntab2
Indexação de Colunas
REF com Escopo (3)
CREATE INDEX endereco_ref_ind
ON pessoas (ref_endereco)
SELECT id FROM pessoas p
WHERE p.ref_endereco.estado =
‘PB’
REF IS ROWID
• Restrições de uso
– Não pode ser usada com REF com escopo
– Nem com REF com regra de integridade
referencial
– Nem com REF baseado em chave
primária
REF ‘Sujo’
• É possível que um objeto identificado
por um REF se torne indisponível 
remoção do objeto, mudança nos
privilégios de acesso ao objeto
– Tal REF torna-se então ‘sujo’ (“dangling”)
– Para testar se um REF é sujo, usa-se o
predicado IS DANGLING
Funções com REF
• -- Tratamento de OIDs
SQL> CREATE TYPE t_emp AS OBJECT
2 (mat NUMBER, nome VARCHAR(20),
salario NUMBER)
3 /
Tipo criado.
SQL> CREATE TABLE tab_emp OF t_emp
2 (PRIMARY KEY (mat))
3 /
Tabela criada.
Funções com REF (2)
SQL> INSERT INTO tab_emp VALUES (10, 'Joao', 5000)
2 /
1 linha criada.
SQL> -- Funcao REF (retorna um valor do tipo REF)
SQL> SELECT REF(e) FROM tab_emp e
2 /
REF(E)
000028020922C58AF8D1054214AA0129C4B2F76373609AE5
0203BB46158870504B45770248004084A00000
Funções com REF (3)
SQL> CREATE TABLE tab_depto
2 (cod NUMBER,
3 gerente REF t_emp SCOPE IS tab_emp)
4 /
Tabela criada.
SQL> INSERT INTO tab_depto
2 SELECT 10, REF(e) FROM tab_emp e
3 /
1 linha criada.
SQL> -- Funcao DEREF
SQL> SELECT DEREF(d.gerente) FROM tab_depto d
2 /
DEREF(D.GERENTE)(MAT, NOME, SALARIO)
T_EMP(10, 'Joao', 5000)
Funções com REF (4)
SQL> SELECT DEREF(d.gerente).nome FROM tab_depto d
2 /
DEREF(D.GERENTE).NOM
-------------------Joao
SQL> SELECT d.gerente.nome FROM tab_depto d
2 /
GERENTE.NOME
-------------------Joao
Funções com REF (5)
SQL> -- Funcao VALUE
SQL> SELECT value(e) FROM tab_emp e
2 /
VALUE(E)(MAT, NOME, SALARIO)
T_EMP(10, 'Joao', 5000)
SQL> SELECT value(e).nome FROM tab_emp e
2 /
VALUE(E).NOME
Joao
REF WITH ROWID
create type teste as object (x number)
/
tipo criado.
create type teste2 as object(y REF teste)
/
tipo criado.
create table teste_tab of teste
/
tabela criada.
create table teste2_tab of teste2 (
y WITH ROWID)
/
tabela criada.
Download