III – Oracle10g Apontadores – Tipo de Dado (REF)

Preview:

Citation preview

IIIIII –– Oracle10g Oracle10gIIIIII –– Oracle10g Oracle10g

Apontadores – Tipo de Dado Apontadores – Tipo de Dado (REF)(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

• 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

• 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

• Em termos de economia de espaço,

qual seria a melhor escolha, “system-generated” 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)

• Mas, é muito importante saber que

um OID pode ser físico– Neste caso, o valor de um OID é o

endereço físico (de disco) de um objeto• ROWID

• OIDs físicos contribuem decisivamente para navegações eficientes em BD OR

Tipo de Dado REF • REFs e coleções de REFs modelam

associações entre objetos, usando OIDs, lógicos ou físicos, como apontadores– Fácil mecanismo para navegação entre objetos

• Formato de um valor REF– OID do objeto referenciado (16 bytes), ou

chave (tamanho definido pelo usuário) + OID da “object table” (16 bytes) + ROWID (10 bytes)

• Para ativar o campo ROWID• REF IS ROWID

– Regra de Integridade (RI) de “object table”

• Espaço

– OID = Chave Primária e Chave > 16 bytes• Para “object tables” volumosas, Chave

será pior que OID “system-generated”

Tabelas Híbridas• São tabelas em que colunas podem ser

dos novos tipos nativos– REF– VARRAY– NESTED TABLE

• Note que Tabela Híbrida – Tabelas tradicionais– “Object tables”

Regra de Integridade de 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”)

• Exemplo: tabela híbrida pessoas 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

• 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

• Restrições ao uso de REF com 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

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

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

– A RI 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• Um bom projeto lógico (integridade

referencial restrita) é o melhor meio para se evitar “dangling pointers”

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.

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) 000028020922C58AF8D1054214AA0129C4B2F76373609AE50203BB46158870504B45770248004084A00000

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 DEREFSQL> SELECT DEREF(d.gerente) FROM tab_depto d 2 /DEREF(D.GERENTE)(MAT, NOME, SALARIO) T_EMP(10, 'Joao', 5000)

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

SQL> -- Funcao VALUESQL> 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

• SELECT e.nome FROM tab_emp e

NOME João

REF WITH ROWIDcreate 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.

Recommended