iii – oracle10g apontadores – tipo de dado (ref)
TRANSCRIPT
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.