Escolar Documentos
Profissional Documentos
Cultura Documentos
Apresentacao CURSO01 v2
Apresentacao CURSO01 v2
CONSULTORIA
Introdução ao Oracle
modelagem de dados
SQL e PL/SQL
(Módulo Básico)
Objetivo
- introduzir os conceitos de modelagem de dados
- mostrar os comandos SQL e PL/SQL
- técnicas para melhorar desempenho
- introduzir o catálogo do Oracle
Banco de Dados
definição 1
CLIENTE FORNECEDOR
N 1
FORNECIMENTO
M
PRODUTO
N M
CLIENTE CONTA
POSSUI
TEM
CARTAO
Esquema ER - Auto-Relacionamento
EMPREGADO 1
SUPERVISAO
SUPERVISOR
SUBORDINADO
Esquema ER
Generalização e Especialização
EMPREGADO
F1 N1 E1 50 C1
F2 N2 E2 55 C2
F3 N3 E3 45 C3
F4 N4 E4 21 C4
F5 N5 E5 18 C5
F6 N6 E6 15 C6
F7 N7 E7 11 C7
Projeto Lógico – continuação 1
Integridade de Domínio
Integridade de Chave
Integridade de entidade
Integridade Não Nulo
Integridade Referencial
Mapeamento:
Esquema ER Relacional
- entidades se torna relação
- atributos da entidade atributo da relação
- vetores se transformam em novas entidades
- relacionamentos:
evitar nulos
evitar vetores
representar cardinalidade
manter simplicidade
Normalização
5 Paula Gerente RH 6
Procedimentos:
a) Identificar os atributos que não são
funcionalmente dependentes de toda a chave primária;
b) Remover todos esses atributos identificados e criar
uma nova entidade com eles.
3FN
Uma relação R está na 3FN se somente estiver na
2FN e todos os atributos não chave forem
dependentes não transitivos da chave primária.
- Boyce – Codd
- 4FN
- 5FN
Workshop
Estrutura da tabela
DICTIONARY
Lista o significado de todas as tabelas do
Dicionário de Dados, visões, sinônimos.
DICT_COLUMNS
Mostra a informação de todos os atributos que
podem ser acessados pelo usuário.
Algumas visões do DD
USER_TABLES;
USER_TAB_COLUMNS;
USER_INDEXES;
USER_IND_COLUMNS;
USER_OBJECTS;
USER_CATALOG;
USER_CONSTRAINTS;
USER_CONS_COLUMNS.
Restrições
Nível de tabela:
coluna,
[CONSTRAINT nome_restricao] tipo_restricao
(coluna, ...),
Restrição Sintaxe Geral
CHAR(tamanho)
Dados do tipo caracter (letras maiúsculas ou
minúsculas, números e caracteres especiais (*,&,%,
$,etc.)) com comprimento fixo de bytes.
O tamanho é o comprimento máximo e não pode
ser maior que 2000. O tamanho padrão e mínimo é
1.
Tipos de dados do Oracle
VARCHAR2(tamanho)
Dados caracter de comprimento variável (um
tamanho máximo deve ser especificado). O
tamanho mínimo e padrão é 1; o tamanho máximo
possível no Oracle 8i ou superior é 4000 (No Oracle
7.x o valor máximo de tamanho era 2000).
Tipos de dados do Oracle
NUMBER(p,e)
p = precisão
e = escala
Dados numéricos de comprimento variável. Este
número contém precisão p e escala e (A precisão é
o número de dígitos decimais e a escala é o
número de dígitos a direita do ponto decimal). A
precisão pode variar de 1 a 38 e a escala de -84 a
127. Se a precisão não for especificada, será
assumida como 38.
Tipos de dados do Oracle
DATE
Valor de data e hora entre 1° de janeiro de 4712
antes de Cristo e 31 de dezembro de 9999 depois
de Cristo.
Tipos de dados do Oracle
CLOB
Dados caracter de um byte até 4 gigabytes.
BLOB
Dados binários (figuras, vídeos, etc) de até 4
gigabytes.
BFILE
Dados binários de até 4 gigabytes armazenados em
um arquivo externo do S.O.
Tipos de dados do Oracle
Não usar!!!
*RAW(tamanho)
Dados binários brutos com “tamanho” de
comprimento máximo (um tamanho máximo deve
ser especificado. O valor máximo permitido para
tamanho é 2000).
Tipos de dados do Oracle
Não usar!!!
*LONG RAW
Dados binários brutos de comprimento variável de
até 2 gigabytes
*LONG
Similar ao CHAR, mas o valor deve ser maior que
65535 caracteres. Não mais que uma coluna LONG
deve ser especificada em uma tabela.
ALTER TABLE
ALTER TABLE tabela
ADD (coluna tipo_de_dado [DEFAULT expr]
[, coluna tipo_de_dado [DEFAULT
expr]] ...);
ALTER TABLE tabela
MODIFY (coluna tipo_de_dado [DEFAULT expr]
[, coluna tipo_de_dado [DEFAULT
expr]] ...);
Drop Table
USER_SEQUENCES e USER_OBJECTS
informações das seqüências.
Visões
Restringe o acesso, pois a visão pode mostrar apenas uma parte dos
dados armazenados;
Permite aos usuários fazer consultas simples para recuperar dados
de consultas complexas;
Dá independência a usuários ad hoc.
Visões - Sintaxe
CREATE [OR REPLACE] [FORCE | NOFORCE]
VIEW nome_visao
[(alias, alias,...)]
AS subconsulta
[WITH CHECK OPTION [CONSTRAINT restricao]]
[WITH READ ONLY]
Índices
Quando criar um índice
O atributo aparece com freqüência na cláusula WHERE das
consultas ou em condições de junção (join);
O atributo possui um intervalo grande de valores (muitos
valores distintos);
Muitas linhas da tabela possuem valor nulo para o atributo;
Dois ou mais atributos aparecem juntos na cláusula WHERE
das consultas ou em condições de junção com muita
freqüência;
A tabela é muito grande e a maior parte das consultas
retorna até 4% de suas linhas.
Índices
- Defina índices únicos como chave candidata;
- Nem sempre acrescentar um índice significará ganho
de desempenho;
- Tipos: Árvores B e B+; bitmap; IOT; etc.
Índices
Quando não criar um índice:
A tabela é pequena;
O atributo não é usado com freqüência nas
condições de consulta;
A maior parte das consultas sobre a tabela
retornarão mais que 4% de suas linhas;
A tabela sofre muita atualização.
Índices - Sintaxe
Expressões aritméticas
+, -, * , /
Concatenação
|| para concatenar valores do tipo caracter.
Valores literais envolvidos por plics (‘ ’).
Funções
NVL(expr1, expr2)
troca os valores de expr1 por expr2 sempre que
o valor de expr1 for nulo.
LOWER(expr1)
converte os caracteres de expr1 em minúsculas.
Funções
UPPER(expr1)
converte os caracteres de expr1 em maiúsculas.
SUBSTR(expr1, m[, n])
retorna os n primeiros caracteres de expr1
iniciando a contagem da m-ésima posição. Se m for
negativo, a contagem parte do final de expr1.
Funções
LENGTH(expr1)
retorna o valor do número de caracteres de
expr1.
ROUND(expr1, n)
arredonda o valor de expr1 com n casas
decimais. Se n é omitido, arredonda sem casas
decimais. Se n for negativo, arredonda à esquerda do
ponto decimal.
Funções
TRUNC(expr1, n)
trunca o valor de expr1 com n casas decimais.
Se n é omitido, trunca sem casas decimais. Se n for
negativo, trunca os algarismos à esquerda do ponto
decimal para zero.
MOD(m, n)
retorna o resto da divisão de m por n.
Funções
TO_CHAR(numero|data, [formato])
converte o numero ou a data para caracter com
o formato especificado.
TO_NUMBER(caracter)
converte a string de caracteres contendo
apenas dígitos em valor numérico.
Funções
TO_DATE(caracter, [formato])
converte a string de caracteres que representa
uma data em um valor data de acordo com o formado
especificado. Se a formatação é omitida, o formato
padrão será ‘DD-MON-YY’.
Funções de Grupo
AVG(DISTINCT | ALL | n)
valor médio de n, ignorando os valores nulos.
COUNT(DISTINCT | ALL | expr1 | *)
retorna o número de linhas. O * conta todas as
linhas, inclusive as duplicadas e as que possuem
valores nulos.
Funções de Grupo
MAX(DISTINCT | ALL | expr)
retorna o valor máximo de expr.
MIN(DISTINCT | ALL | expr)
retorna o menor valor de expr.
STDDEV(DISTINCT | ALL | n)
retorna o desvio padrão de n, sem considerar
os valores nulos.
Funções de Grupo
SUM(DISTINCT | ALL | n)
soma os valores de n, ignorando os valores
nulos.
VARIANCE(DISTINCT | ALL | n)
retorna a variancia de n, ignorando os valores
nulos.
Comparadores Lógicos
SELECT expr
FROM tab
[ORDER BY {atributo|expressao} [ASC|
DESC] ];
Limitando as linhas
selecionadas
SELECT expr
FROM tab
WHERE condição
[ORDER BY expr];
LIKE
Sintaxe:
Sintaxe:
Resultado:
ALEX trabalha para JOAO
MARIA trabalha para JOAO
JOSE trabalha para JOAO
Junção
Omissão da
cláusula WHERE produto cartesiano
Deve-se evitar esta operação.
Sintaxe:
UPDATE tabela
SET coluna = valor [, coluna = valor]
WHERE condição;
Excluindo linhas das tabelas
DELETE para excluir todas as linhas da tabela
Sintaxe:
DELETE FROM tabela;
irá excluir linhas da condição
Sintaxe:
DELETE FROM tabela
WHERE condição;
Excluindo linhas das tabelas
TRUNCATE
Termina com:
- COMMIT ou ROLLBACK;
- DDL ou DCL (commit implícito);
- Erro, EXIT ou Crash do sistema.
Bloco PL/SQL
DECLARE (opcional)
variáveis e constantes,
- cursores,
- expressões definidas pelo usuário.
BEGIN (obrigatório)
comandos SQL,
- estruturas de controle PL/SQL.
EXCEPTION (opcional)
ações a tomar quando ocorrer uma exceção.
END; (obrigatório)
Estruturas de Controle
- IF
- LOOP
- FOR
- WHILE
Cursores
- Cursores explícitos
DECLARE
CURSOR nome_cursor IS
comando_select;
- Cursores explícitos com parâmetros
DECLARE
CURSOR nome_cursor
[(parâmetro tipo_dado, ...)] IS
comando_select;
Cursores
- Cursores “for update”
DECLARE
CURSOR nome_cursor IS
SELECT ... FROM ... FOR UPDATE
[OF referencia_coluna] [NOWAIT];
Cursores
- Percorrendo cursores
Sintaxe:
FOR nome_registro IN nome_cursor LOOP
comando1;
comando2;
...
END LOOP;
Funções
Sintaxe:
FUNCTION nome_função
[(parâmetro, ...)] RETURN tipo_dado
IS
BLOCO pl/sql;
Procedimentos
Sintaxe:
PROCEDURE nome_procedimento [(parâmetro, ...)]
IS
BLOCO pl/sql;
Sintaxe do parâmetro:
nome_parâmetro [IN | OUT | IN OUT ] tipo_dado
[{:= | DEFAULT} expr]
Controlando exceções
EXCEPTION
WHEN exceção1 [OR exceção2 ...] THEN
comando1;
comando2;
...
[WHEN exceção1 [OR exceção2 ...] THEN
comando1;
comando2;
...]
[WHEN exceção1 [OR exceção2 ...] THEN
comando1;
comando2;
...]
Principais exceções
NO_DATA_FOUND – consulta não retornou nenhuma
linha.
TOO_MANY_ROWS – consulta retornou mais de uma
linha.
INVALID_CURSOR – ocorreu uma operação inválida
sobre um cursor.
Principais exceções
ZERO_DIVIDE – houve tentativa de divisão por 0.
DUP_VAL_ON_INDEX – tentativa de inserção de valor
numa coluna ou conjunto de colunas cujo valor deve
ser único.
OTHERS – qualquer exceção que não tenha sido
explicitamente citada anteriormente será tratada
nesse bloco.
Otimizando o acesso ao
Oracle
Dois caminhos de acesso:
Leitura seqüencial da tabela;
Leitura indireta através de um índice.
Uso do ROWID
Exemplos:
a) alterando o nome do empregado
b) Excluindo registros duplicados
O otimizador
- caminho segundo estratégia de menor custo
- melhor caminho de acesso leva em consideração:
Colunas mencionadas da cláusula where;
Que colunas são índices,
Que colunas estão definidas como NOT NULL,
Que índices podem ser usados.
Regras de Utilização de
Índices
- exemplo citado
Cláusula “WHERE” Pode ser usado? Obeservação
A, B, C SIM Usamos o índice completo
A, B SIM Usamos os dois primeiros atributos
A, C SIM Usamos apenas “A”
B, C NÃO Primeiro atributo não informado
A SIM Usamos apenas “A”
B NÃO Primeiro atributo não informado
C NÃO Primeiro atributo não informado
Um índice pode ser percorrido se:
o índice existe;
a coluna índice for referenciada na cláusula 'where'.
a cláusula 'where' realiza uma operação de:
- Igualdade:
- Intervalo ilimitado:
- Intervalo limitado:
A escolha do índice
- Índices únicos e não únicos: os índices únicos serão
favorecidos sobre os índices não únicos.
Exemplo:
select d.nome_dept, d.id_dept
from dept d
where d.local = 'RJ'
order by d.nome_dept;
Order by
Podemos evitar tabelas temporárias se existir um
índice sobre a coluna alvo do “ORDER BY”:
- Coluna do “ORDER BY” definida com “NOT NULL”;
- Coluna “ORDER BY” deve ser a coluna de um índice
simples ou as primeira coluna de um índice
concatenado;
- “ORDER BY” não contém expressões;
- Não deve haver qualquer cláusula “GROUP BY”,
“DISTINCT” ou “FOR UPDATE”;
- Devemos garantir que o índice utilizado é o que
incide sobre o atributo da cláusula “ORDER BY”.
Order by via índice
- índice em NOME_DEPT:
select d.nome_dept
from dept d
order by d.nome_dept ;
select d.nome_dept,
d.local
from dept d
where d.nome_dept != 'RH'
order by d. nome_dept;
Order by – índice não
prioritário
- índice sobre LOCAL existe
- o índice sobre nome_dept não será usado:
select d.nome_dept,
d.id_dept
from dept d
where d.local = 'RJ'
order by d.nome_dept;
Funções de MAX ou MIN
Condições para uso de índice:
- MAX / MIN incide sobre atributo da lista de seleção;
- Lista de seleção não deve ter operador de adição ou
concatenação;
- Lista de seleção contém somente a ocorrência de
atributo como agrupamento de MAX ou MIN;
- Não há junção;
- Não há cláusula “WHERE” ou “GROUP BY”;
- Coluna alvo do MAX ou MIN é indexada.
Funções de MAX ou MIN
select e.nome_emp
from emp e
where e.cargo = 'GERENTE'
and e.id_dept = 20;
Análise – Índice não único
1) O otimizador procura a primeira ou próxima
referência do índice sobre cargo (driving index)
contendo 'GERENTE';
3) Compara os ROWID's;
Análise – Índice não único
4) Se forem iguais, registro encontrado e vai para a
próxima referência de (1) e compara com a próxima
referência de (2);
select e.nome_emp
from emp e
where e.SALARIO = 3000
and e.id_emp = 7902;
select e.id_dept
from emp e
where e.salario = 3000
and e.nome_emp = 'JOAO'
and e.id_emp = 7602;
select e.nome_emp
from emp e
where e.id_dept = 10
and (e.SALARIO = 3000
or
e.CARGO = 'INF')
OR - Situação I
- índice único em SALARIO / não único em CARGO:
Análise:
a) para o predicado id_dept = 10, haverá uma
pesquisa seqüencial completa da tabela;
b) para SALARIO = 3000, podemos percorrer - Índice
não único sobre SALARIO;
c) para CARGO = 'INF', podemos percorrer o índice
não único sobre CARGO.
OR - Situação I
- índice único em SALARIO / não único em CARGO:
Conclusão:
O caminho de acesso identificado pelo predicado
“and (e.SALARIO = 3000 or e.CARGO = 'INF')” é
melhor do que o identificado por “e.id_dept = 10”.
O otimizador escolherá percorrer o caminho sobre os
índices da cláusula OR.
OR - Situação II
- apenas índice não único sobre o atributo SALARIO:
Análise:
a) para o predicado id_dept = 10, haverá uma
pesquisa seqüencial completa da tabela;
b) para SALARIO = 3000, podemos percorrer o índice
não único sobre SALARIO;
c) para CARGO = 'INF', haverá uma pesquisa
seqüencial completa da tabela.
OR - Situação II
- apenas índice não único sobre o atributo SALARIO:
Conclusão:
O caminho de acesso identificado pelo predicado
“and (e.SALARIO = 3000 or e.CARGO = 'INF')” não
poderá percorrer índice algum, pois o otimizador
exige que haja um índice para cada atributo
informado na cláusula “OR”.
Não há índice criado para “e.id_dept = 10”.
Haverá uma leitura sequencial completa da tabela.
Otimização de consultas
variavel_bind := 10;
--
select e.nome_emp
from emp e
where id_emp = :variavel_bind;
variavel_bind := 55;
--
select e.nome_emp
from emp e
where id_emp = :variavel_bind;
select e.nome_emp
from emp e
where dt_admissao = '19-dec-99';
Quando pensar em
otimização?
- modelo lógico;
- modelo físico;
- desenvolvimento;
- testes;
- implantação;
- produção;
- manutenção.
Otimização
select e.nome_emp
from emp e
where e.id_dept not in
(select d.id_dept
from dept d);
Reescrita de SQL
- SQL que usa o índice com o mesmo resultado:
select e.nome_emp
from emp e, dept d
where e.id_dept = d.id_dept(+)
and d.id_dept is null;
Reescrita de SQL
- 2° SQL que usa o índice c/ o mesmo resultado:
select e.nome_emp
from emp e
where e.id_dept in
(select e2.id_dept
from emp e2
minus
select d.id_dept
from dept d);
UNION no lugar de muitos
AND ou OR
select e.id_emp
from emp e
where (e.id_dept = 10)
or (e.id_dept = 20 and e.SALARIO > 2500)
or (e.id_dept = 30 and e.SALARIO > 5000)
order by e.id_emp;
UNION no lugar de muitos
AND ou OR
select e.id_emp
from emp e
where e.id_dept = 10
union
select e.id_emp
from emp e
where e.id_dept = 20
and e.salario > 2500
union
select e.id_emp
from emp e
where e.id_dept = 30
and e.salario > 5000
order by 1;
UNION no lugar de muitos
AND ou OR
insert into
tab_exemplo (col1,col2,col3,...)
values (:vl1,:vl2,:vl3,...);
no lugar de: