iii – oracle10g apontadores – tipo de dado (ref)

22
II II I I Oracle10g Oracle10g Apontadores – Tipo de Dado Apontadores – Tipo de Dado (REF) (REF)

Upload: internet

Post on 21-Apr-2015

111 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: III – Oracle10g Apontadores – Tipo de Dado (REF)

IIIIII –– Oracle10g Oracle10gIIIIII –– Oracle10g Oracle10g

Apontadores – Tipo de Dado Apontadores – Tipo de Dado (REF)(REF)

Page 2: III – Oracle10g 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

Page 3: III – Oracle10g Apontadores – Tipo de Dado (REF)

• 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

Page 4: III – Oracle10g Apontadores – Tipo de Dado (REF)

• 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

Page 5: III – Oracle10g Apontadores – Tipo de Dado (REF)

• 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)

Page 6: III – Oracle10g Apontadores – Tipo de Dado (REF)

• 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

Page 7: III – Oracle10g Apontadores – Tipo de Dado (REF)

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”

Page 8: III – Oracle10g Apontadores – Tipo de Dado (REF)

• Espaço

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

será pior que OID “system-generated”

Page 9: III – Oracle10g Apontadores – Tipo de Dado (REF)

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”

Page 10: III – Oracle10g Apontadores – Tipo de Dado (REF)

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

Page 11: III – Oracle10g Apontadores – Tipo de Dado (REF)

• 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

Page 12: III – Oracle10g Apontadores – Tipo de Dado (REF)

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

Page 13: III – Oracle10g Apontadores – Tipo de Dado (REF)

CREATE INDEX endereco_ref_ind ON pessoas (ref_endereco)

SELECT id FROM pessoas p

WHERE p.ref_endereco.estado = ‘PB’

Page 14: III – Oracle10g Apontadores – Tipo de Dado (REF)

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

Page 15: III – Oracle10g Apontadores – Tipo de Dado (REF)

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”

Page 16: III – Oracle10g Apontadores – Tipo de Dado (REF)

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.

Page 17: III – Oracle10g Apontadores – Tipo de Dado (REF)

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

Page 18: III – Oracle10g Apontadores – Tipo de Dado (REF)

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)

Page 19: III – Oracle10g Apontadores – Tipo de Dado (REF)

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

Page 20: III – Oracle10g Apontadores – Tipo de Dado (REF)

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

Page 21: III – Oracle10g Apontadores – Tipo de Dado (REF)

• SELECT e.nome FROM tab_emp e

NOME João

Page 22: III – Oracle10g Apontadores – Tipo de Dado (REF)

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.