Você está na página 1de 88

Editorial

Nesta edio damos destaque ao SGBD Oracle. Como o leitor perceber,


abordamos diferentes assuntos. Entretanto, damos destaque especial para as
matrias relacionadas otimizao: Influenciando o otimizador de consultas Oracle
baseado em custos Parte 1 e, Entendendo plan table e planos de consulta.
Otimizao sempre um assunto muito interessante e d margem a diversas
discusses. A primeira matria, capa desta edio, o primeiro de uma srie e
apresenta algumas dicas interessantes sobre como manipular o otimizador do
Oracle. J o segundo artigo um complemento e auxiliar o leitor no entendimento
da matria de capa.
Apresentamos dois artigos de autoria do Paulo Ribeiro sobre o SQL Server
discutindo questes de performance relacionadas ao uso de campos calculados e
heap tables. No artigo Utilizando colunas calculadas na implementao de regras e
otimizao de performance, o autor apresenta, considerando questes de
desempenho, trs possibilidades para a criao de campos calculados: armazenar a
frmula em uma stored procedure; armazenar a frmula em uma funo, e;
armazenar a frmula em uma coluna calculada. No artigo Heap tables: livre-se
delas para ganhar performance, aprendemos que os processos de desfragmentao
existentes no SQL Server 2000 foram criados para desfragmentar ndices.
Aprendemos tambm que, como as pginas de dados de uma heap no so regidas
por um ndice, no possvel desfragmentar uma heap utilizando os comandos
convencionais. Por isso, heaps fragmentadas so indicadoras de m performance.
Temos tambm nesta edio mais uma matria da Isabela e Luiz Esteves. Depois
de terem fechado uma srie excelente de trs matrias sobre Data Warehouse,
chegou a hora de acompanhar sua implementao na prtica. Na matria,
Implementando um data mart em um banco de dados multidimensional, os autores
apresentam, passo a passo, como implementar um modelo multidimensional
conceitual em um banco de dados.
Dando continuidade matria sobre 10 passos para a criao de um modelo
conceitual de banco de dados, o professor Jos Prata nos mostra que a modelagem
tradicional nem sempre adequada para representar determinados esquemas de
banco de dados. Como exemplo, tem-se a modelagem orientada a objetos. Neste
caso, o autor utiliza os exemplos j apresentados no primeiro artigo da srie para
demonstrar a aplicao do roteiro dos 10 passos na modelagem orientada a
objetos.
Gostaria de destacar tambm a nova srie de artigos que estamos iniciando.
Ronaldo, Vincius e Thiago nos trazem um assunto bastante interessante, bancos de
dados espaciais. O espao ento aqui referido o espao fsico que nos cerca, a
superfcie da Terra, dos continentes, dos pases, dos estados, das cidades, dos
bairros ou das regies poltico-administrativas de um pas, por exemplo. No artigo
Dados de natureza espacial e o Oracle Spatial so apresentados os conceitos
bsicos do geoprocessamento e mostrado que os dados de natureza espacial j so
suportados pelo Oracle.
Por fim, voltamos a contar nesta edio com um artigo do Ricardo Rezende. Na
matria PL/SQL Developer, ele apresenta a ferramenta para desenvolvimento de
programas (functions, procedures, triggers, packages) armazenados em um BD
Oracle.
Desejo a voc uma tima leitura. Um abrao.

Rodrigo Oliveira Spnola

editor@sqlmagazine.com.br
Utilizando colunas
calculadas na
implementao de
regras e otimizao
de performance
Segundo as regras de normalizao, no devemos armazenar em uma coluna
valores que podem ser obtidos por operaes executadas sobre outras colunas.
Esse tipo de procedimento pode "custar caro" por vrios motivos:
Consome espao em disco;
Exige que todas as aplicaes que manipulam as colunas que fazem parte da
frmula estejam sincronizadas para atualizar tambm a coluna calculada;
Recuperar o resultado de uma frmula do disco um processo lento.

Pensando assim, no seria conveniente criar uma coluna col_C em uma tabela
teste para armazenar o produto de duas outras colunas (col_A * col_B). Cabe aqui
um questionamento: Como fazer para manter a mesma regra de clculo em todas
as aplicaes, evitando-se que sejam utilizados diferentes critrios para obter
col_C?
Existem trs possibilidades:
1. Armazenar a frmula em uma stored procedure. A aplicao que necessitar
de col_C ser obrigada a executar a procedure;
2. Armazenar a frmula em uma funo. A aplicao que necessitar de col_C
ser obrigada a executar a funo;
3. Armazenar a frmula em uma coluna calculada. A coluna col_C ser criada
na tabela teste; para obter o resultado de col_C, basta efetuar um select na
tabela;

Das trs opes, a criao da coluna calculada a que apresenta melhor custo-
benefcio e menor complexidade para implantao. Vamos proceder criao da
tabela teste, de modo que consigamos avaliar a implementao das trs solues
propostas (ver Listagem 1).

Listagem 1. Script para criao da tabela teste.


use NorthWind
go
if exists (select name from sysobjects where name='teste' and xtype='u') drop
table teste
create table teste
(
col_PK int identity (1000,1) primary key,
col_A int,
col_B int
)
go

insert into teste (col_A, col_B) values (4,2)


insert into teste (col_A, col_B) values (3,5)
insert into teste (col_A, col_B) values (6,8)
go

Utilizando uma stored procedure para obter o produto entre col_A e col_B
Imagine um select que precise listar as trs colunas: col_A, col_B e col_C. Se a
frmula de clculo estivesse embutida em uma stored procedure (SP), a nica
opo seria criar um cursor e efetuar chamadas pontuais para a SP, conforme a
Listagem 2.

Listagem 2. Criao da procedure para obter Col_C


/* criao da sp */
if exists
( select name
from sysobjects
where name='stp_calcular_col_C'
and xtype='p'
) drop proc stp_calcular_col_C
go
create proc stp_calcular_col_C (@col_A int, @col_B int, @col_C int OUTPUT)
as
set @col_C = @col_A * @col_B
RETURN
go
/* liberar permisses para public */
grant exec on stp_calcular_col_C to public
go
/* teste de execuo */
declare @col_A int
declare @col_B int
declare @col_C int
set @col_A = 10
set @col_B = 5
exec stp_calcular_col_C @col_A, @col_B, @col_C OUTPUT
select col_C = @col_C
go
------------------------------------------------------
col_C
-----------
50

A Listagem 3 mostra os passos para criao de um cursor que processar todas


as linhas da tabela teste.
Listagem 3. Criao do cursor
/* declarao de variaveis */
declare @col_A int,
@col_B int,
@col_C int
/*declarao do cursor */
declare cr_Cursor cursor FAST_FORWARD
FOR
select col_A, col_B
from teste
/* abertura do cursor */
OPEN cr_Cursor
/* inprimindo a header das colunas */
print 'col_A' +char(9)+'col_B' +char(9)+'col_C'
print '-----' +char(9)+'-----' +char(9)+'-----'
/* processando o cursor */
FETCH NEXT FROM cr_Cursor INTO @col_A, @col_B
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
exec stp_calcular_col_C @col_A, @col_B, @col_C OUTPUT
print convert(char(5), @col_A) + char(9) +
convert(char(5), @col_B) + char(9) + convert(char(5), @col_C)
END
FETCH NEXT FROM cr_Cursor INTO @col_A, @col_B
END
/* fechando o cursor e liberando a memria */
CLOSE cr_Cursor
DEALLOCATE cr_Cursor
go

col_A col_B col_C


-------- -------- --------
4 2 8
3 5 15
6 8 48

A soluo com a SP envolve a manipulao das linhas por um cursor. Cursores


so sinnimos de baixa performance, pois induzem ao processamento pontual,
tirando a eficincia dos comandos T-SQL insert, update e delete, cuja caracterstica
de processar um grande volume de linhas de uma s vez.

Utilizando uma funo para obter o produto entre col_A e col_B


A utilizao de uma funo mais interessante do que a SP, mas ainda perde
para a coluna calculada por dois motivos:
1. Uma funo um objeto no banco e, como todo objeto, necessitar do
controle adequado de permisses;
2. mais simples listar o contedo de uma coluna calculada, que se porta
como uma coluna convencional, do que chamar a funo na linha do select;

A Listagem 4 mostra a recuperao de Col_C com o auxlio de uma funo.

Listagem 4. Utilizao de funo para se obter o valor de ColC


/* criando a funo */
if object_id('fn_calcular_col_C') is not null drop function fn_calcular_col_C
go
create function dbo.fn_calcular_col_C (@col_A int, @col_B int)
returns int
as
begin
return (@col_A * @col_B)
end
/* executando a funo num comando select */
select col_A, col_B, col_C = dbo.fn_calcular_col_C (col_A, col_B)
from teste

col_A col_B col_C


----------- ----------- -----------
4 2 8
3 5 15
6 8 48
(3 row(s) affected)

Utilizando uma coluna calculada para obter o produto entre col_A e col_B
Em relao s opes anteriores, a coluna calculada mais fcil de implementar e
sua utilizao transparente para os usurios. Como a coluna calculada no
armazenada na tabela, no estaremos violando regras de normalizao mais
precisamente a terceira forma normal. A coluna calculada utilizar somente alguns
ciclos do processador para, no momento em que um comando SQL referenciar a
coluna - e somente nesse momento - efetuar o clculo desejado em memria, e
apresentar o resultado. A listagem 5 mostra a criao da coluna calculada e sua
utilizao em um select.

Listagem 5. Criao e utilizao de uma coluna calculada.


/* criando a coluna calculada na tabela teste*/
alter table teste add col_C as (col_A * col_B)
/* selecionando as linhas da tabela teste */
select * from teste

col_A col_B col_C


----------- ----------- -----------
4 2 8
3 5 15
6 8 48
(3 row(s) affected)

O leitor poderia questionar que a coluna calculada pode ser substituda pela
incluso da frmula de clculo na linha do select, como no exemplo abaixo:

select col_A, col_B, col_C = col_A * col_B


from teste

Sim, de fato quase a mesma coisa. O grande diferencial da coluna calculada


que, pelo fato da regra estar gravada no banco, torna-se independente das
aplicaes. Deixando a frmula por conta da aplicao, corre-se o risco de
aplicaes diferentes utilizarem critrios tambm diferentes para a mesma frmula.

Algumas observaes sobre a utilizao de colunas calculadas


1. Uma coluna calculada no pode figurar na linha do comando insert. Lembre-
se que a coluna calculada uma implementao lgica e no fsica.
2. Voc pode materializar a coluna calculada com a criao de um ndice. O
ndice forar a gravao do resultado da frmula expressa na coluna
calculada, auxiliando em processos de ordenao ou filtragem de resultados,
por exemplo: select * from teste where col_C > 10 ou select * from teste
order by col_C; Para criar um ndice sobre a coluna calculada col_C,
usamos: create index ix_Teste on teste (col_C).
3. Na frmula de uma coluna calculada, podemos utilizar somente colunas que
pertenam mesma tabela. Caso haja necessidade de utilizar colunas de
outras tabelas, um join ou funo seriam os mais adequados.

Concluso
Vimos nesse artigo que o uso de colunas calculadas bastante interessante,
principalmente por quatro motivos:
1. Padroniza as regras do negcio na camada de banco, tornando-as
independentes da aplicao;
2. Simplifica a utilizao de frmulas complexas;
3. fcil de implementar;
4. Podemos turbinar uma query que possui ordenao e/ou comparaes
baseadas na frmula atravs da criao de um ndice sobre a coluna
calculada.

Um forte abrao a todos e at a prxima!


PL/SQL Developer
O PL/SQL Developer uma IDE (Integrated Development Environment) para
desenvolvimento de programas (functions, procedures, triggers, packages)
armazenados em um BD Oracle. Atravs dele podemos construir todo o mdulo
executado no servidor de uma aplicao cliente-servidor. Enfim, uma ferramenta
grfica que auxilia muito nas tarefas de desenvolvimento e tambm de
administrao de um BD Oracle.
O objetivo deste artigo no o de se tornar um tutorial sobre a ferramenta e sim
oferecer uma viso geral do que ela proporciona.
O PL/SQL Developer oferece uma interface amigvel e extremamente produtiva
para as tarefas de edio, compilao, correo, testes, limpeza (debugging),
otimizao e consulta de programas para sua aplicao cliente-servidor em Oracle,
alm de outras funcionalidades como execuo de scripts SQL, criao e
modificao de definies de tabelas (atravs de linguagem DDL) e relatrios.
A primeira coisa que ser solicitada quando iniciado o PL/SQL Developer a
conexo ao BD (Figura 1).

Figura 1. Logon na inicializao do PL/SQL Developer.

Deveremos informar o usurio, senha, qual a instncia a se conectar e o modo de


conexo, que poder ser Normal, SYSDBA ou SYSOPER.

Nota 1
O PL/SQL Developer um aplicativo 32 bit para SO Windows (no mnimo
Windows 95 ou NT4) e necessita da verso 32 do SQL*Net, Net 8 ou Net 9. A
verso de avaliao (sem nenhuma restrio de funcionalidade mas funcional
durante 30 dias) do PL/SQL Developer pode ser baixada gratuitamente no site
do fabricante: http://www.allroundautomations.nl.

Administrando o BD Oracle

Criando usurios
Uma das primeiras tarefas de um DBA a criao de usurios e esquemas.
Atravs da interface do PL/SQL Developer, a tarefa bastante simplificada; no
sendo necessrio memorizar todas as definies do comando SQL para efetuar a
atividade (Figura 2).
Figura 2. A janela Create User. Facilidade na criao de usurios.

Uma das grandes vantagens do uso da ferramenta que podemos, por exemplo,
criar o usurio atribuindo-lhe os devidos privilgios e tambm definir cotas nas
tablespaces que ele poder acessar e criar objetos.
Na guia General, deve-se definir o nome e senha do usurio. possvel tambm
definir quais so as tablespaces padro e temporria (caso no seja informado,
ser utilizada a tablespace SYSTEM).
A guia Object Privileges permite a visualizao, concesso ou modificao de
privilgios a objetos (select, insert, update, delete, execute, alter, etc) ao usurio.
As opes so: deixar em branco, para que o usurio no tenha tal privilgio,
Yes, para que haja o privilgio ou Grantable, para que o usurio, alm de
possuir tal privilgio, possa conced-lo a outros usurios.
Pode-se ainda conceder privilgios a determinados papis (Roles) como connect,
dba, resource, exp_full_database, etc. definindo tambm como Grantable, se
necessrio.
Em System Privileges possvel conceder privilgios de sistema como create
any table, create session, etc. A opo Grantable tambm est presente.
Finalmente, podemos atribuir cotas (Quotas) (em bytes, Kb ou Mb) para o usurio
em cada tablespace (isso significa dizer qual o mximo que o usurio poder alocar
em uma tablespace) ou definir esta cota como ilimitada.
H ainda a opo de visualizar os comandos SQL gerados, clicando no boto View
SQL (Figura 3), e grav-los em um arquivo para posterior utilizao.

Figura 3. Visualizao das instrues em SQL.


Otimizao
Para otimizar expresses SQL, podemos fazer uso do utilitrio Explain Plan para
visualizar o trajeto de execuo da expresso. Podemos ainda visualizar as
estatsticas sobre a execuo de uma expresso SQL, configurando inclusive quais
os dados estatsticos queremos visualizar, incluindo tempo de CPU, leituras fsicas e
lgicas, escritas fsicas entre outros.
Para usar este utilitrio, basta pressionar o boto New na barra de ferramentas e
selecionar a opo Explain Plan Window. Ser aberta uma janela vazia onde apenas
necessrio digitar a expresso SQL a ser analisada na metade superior da janela
e ento pressionar o boto Execute (tecla de atalho F8) para visualizar a estratgia
de acesso na metade inferior da janela (Figura 4).

Figura 4. A janela Explain Plan.

H tambm a opo de alterar o objetivo do otimizador, selecionando em


Optimizer goal entre as opes:
Choose: o otimizador far a escolha entre o acesso baseado em custo ou
baseado em regra, dependendo da existncia ou no de estatsticas
disponveis. a opo default;
Rule: o otimizador utilizar o acesso baseado em regra, independentemente da
existncia ou no de estatsticas disponveis;
First rows: utilizada uma mistura de acesso baseado em custo e heurstica
(conjunto de mtodos que auxiliam na resoluo de problemas) para encontrar
o melhor plano de execuo para trazer um nmero pequeno de linhas;
All rows: ser utilizado o acesso baseado em custo, independentemente da
existncia ou no de estatsticas disponveis e otimiza com o objetivo de
melhorar a taxa de transferncia (throughput), ou seja, a menor utilizao de
recursos para executar uma instruo SQL completa.

A janela Explain Plan oferece ainda a possibilidade de navegao atravs da


consulta pela ordem de operao, ou seja, possvel analisar cada um dos
comandos utilizados pelo otimizador do Oracle para alcanar a informao
desejada. Na Figura 4, est em destaque o comando INDEX UNIQUE SCAN e na
barra de status um comentrio da operao que est sendo executada. No caso
est sendo selecionado o valor nico atravs de um ndice nico (PK_CLIENTE, a
chave primria), demonstrando uma boa estratgia de acesso adotada pelo
otimizador.
Para questes de otimizao, temos tambm o utilitrio tkprof que utilizado
para obter informaes de uso de recursos sobre todas as execues de expresses
SQL atravs da habilitao do SQL Trace. Em uma SQL Window ou Test Window em
uso, possvel habilitar o SQL Trace atravs do menu Session -> SQL Trace. Aps
isso, todo processo executado no servidor vindo do SQL Window ou Test Window
sero armazenados em um arquivo de trace no servidor de BD.
A visualizao do trace feita atravs da utilizao do utilitrio tkprof no servidor
de BD. O utilitrio ir gerar um relatrio (Listagem 1) contendo informaes teis
para anlise de performance de expresses SQL ou blocos PL/SQL.

TKPROF: Release 7.2.2.3.1 - Production on Fri Sep 26 14:59:08 1997


Copyright (c) Oracle Corporation 1979, 1994. All rights reserved.
Trace file: ora07087.trc
Sort options: default
******************************************************************
**************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
******************************************************************
**************
begin
:deptname := employee.deptname(:empno);
end;
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.01 0 0 0 1
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.01 0.01 0 0 0 1
Misses in library cache during parse: 0
Optimizer hint: CHOOSE
Parsing user id: 16
******************************************************************
**************
SELECT DEPT.DNAME
FROM
DEPT,EMP WHERE EMP.EMPNO = :b1 AND DEPT.DEPTNO = EMP.DEPTNO

call count cpu elapsed disk query current rows


------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 5
Fetch 1 0.06 0.06 4 4 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.06 0.06 4 4 0 6
Misses in library cache during parse: 0
Optimizer hint: CHOOSE
Parsing user id: 16 (recursive depth: 1)
******************************************************************
**************
Listagem 1. Relatrio gerado pelo utilitrio tkprof.

O relatrio gerado pelo tkprof informa os valores encontrados na anlise de uma


instruo que foi passada para o banco de dados executar. A coleta de informaes
feita para trs momentos diferentes da execuo da instruo:
Parse: a compilao da instruo caso a mesma no esteja ainda em
memria devido a uma execuo anterior. Caso a instruo j tenha sido utilizada e
permanea em memria, o Oracle reutiliza o comando no necessitando fazer o
parse da instruo;
Execute: a execuo da instruo propriamente dita;
Fetch: o momento em que a informao retornada.

Os dados coletados em cada passo da execuo (parse, execute e fetch) so


referentes a:
Count: nmero de vezes que o procedimento foi executado;
Cpu: tempo de utilizao de processamento (cpu) em segundos;
Elapsed: tempo total de execuo em segundos;
Disk: nmero de leituras fsicas executadas em disco;
Query: nmero de informaes em memria para leitura consistente;
Corrent: nmero de informaes em memria em modo corrente (normalmente
em operaes de update);
Rows: nmero de linhas processadas em fetch ou execute.

Manipulao de objetos no PL/SQL


O PL/SQL Developer permite manipular objetos no PL/SQL com extrema
facilidade. Dentre estes objetos, podemos destacar a criao/manipulao de:
Usurios (visto anteriormente Figura 2);
Tabelas (Figura 5).

Composto por seis pginas, o editor de tabelas permite definir/alterar as


informaes sobre armazenamento dos dados, cluster, durao e organizao
(atravs da guia General). Na guia Columns possvel visualizar, adicionar, excluir,
mover ou modificar colunas da tabela. Para manipular as chaves primria, nica ou
estrangeira da tabela, acesse a guia Keys.

Figura 5. O editor de definies de tabelas.

A pgina Checks permite manipular as restries de verificao (check


constraints), que so as restries criadas para garantir regras de negcios.
Podemos ainda manipular os ndices existentes na tabela. Para isso, acesse a
pgina Indexes. Finalmente, atravs da pgina Privileges, possvel manipular a
concesso ou negao de privilgios sobre o objeto a outros usurios:
Sequncias (sequences): atravs do editor de sequncias, pode-se efetuar a
definio de informaes como valor mnimo e mximo que a sequncia ir adotar,
qual o valor inicial de trabalho, incremento, etc.;
Podemos ainda manipular sinnimos (synonyms), bibliotecas, diretrios, roles,
profiles, database links;
Tarefas (Jobs) (Figura 6). Podemos agendar atividades que sero executadas
automaticamente. Para isso devemos criar jobs. A criao dos jobs atravs do
PL/SQL Developer feita na janela Jobs, que internamente est invocando o pacote
(package) DBMS_JOB, que acompanha o Oracle 9i.

Figura 6. O editor de tarefas.

Desenvolvendo programas com o PL/SQL Developer


Em um BD Oracle, podemos criar cinco diferentes tipos de unidades de programa
armazenadas no prprio BD (stored programs): functions (funes), procedures
(procedimentos), packages (pacotes), types (tipos) e triggers (gatilhos).

Criando unidades de programa (program units)


Para criar um novo programa, basta selecionar o tipo de unidade que se deseja
criar atravs do menu File -> New -> Program Window (Figura 7) e selecionar o
tipo de unidade de programa que se deseja criar.
Figura 7. Acesso ao Program Window.

Nos ser apresentado um assistente onde definiremos as opes solicitadas para


criao da unidade de programa, tais como: nome da unidade, parmetros (in, out
ou in/out), valores de retorno (no caso das functions), etc. Aps definidas as
opes iniciais, ser exibida a janela Program Window (Figura 8), em que vrias
partes do cdigo, como o famoso CREATE OR REPLACE PROCEDURE j estaro
inseridos pelo assistente do PL/SQL Developer.

Figura 8. Exemplo de janela Program Window na manipulao de uma procedure.

Na coluna da direita voc encontrar o contedo do cdigo. J na coluna da


esquerda da janela so mostradas as variveis, constantes, tipos, excees
(exceptions), funes locais e procedures utilizadas na unidade de programa que
est sendo desenvolvida. Esta funcionalidade se torna muito til quando se
programa um cdigo longo, como um package body, por exemplo.
Existe ainda a opo de salvar o arquivo do cdigo do programa, utilizando
extenses padronizadas de acordo com o tipo de unidade de programa. A Tabela 1
mostra as extenses padronizadas para as unidades.

Tipo de unidade de programa extenso


Function .fnc
Procedure .prc
Especificao e corpo de .pck
Package
Especificao de Package .spr
Corpo de Package .bdy
Especificao e corpo de tipos .typ
(type)
Especificao de tipos (type) .tps
Corpo de tipos (type) .tpb
Trigger .trg
Cdigo Java .jsp
Tabela 1. Extenses padronizadas.

As extenses padronizadas para os arquivos das unidades de programa so


apenas uma sugesto fornecida pelo PL/SQL Developer e podem ser alteradas pelo
desenvolvedor sem nenhum impacto na programao. Todos os arquivos de
unidades de programa salvos atravs do PL/SQL Developer possuem um formato
totalmente compatvel com o Oracle SQL*Plus.

Testando e depurando o programa


Aps o programa ter sido compilado com sucesso, precisaremos test-lo. Para
isto, basta clicar com boto direito do mouse sobre a unidade de programa, na
janela de navegao esquerda, e selecionar a opo Test. Ser apresentada a
janela Test Window com os parmetros contidos no cdigo para efetuar o teste.
(Figura 9). Basta informar valores de teste para os parmetros e iniciar o teste
(atravs da barra de ferramentas do prprio Test Window ou pressionando a tecla
F8).

Figura 9. O Test Window em ambiente de depurao.

O PL/SQL Developer possui ainda um depurador integrado ao Test Window que


permite rastrear erros nas unidades de programa. H uma barra de ferramentas no
alto da janela com funes relativas depurao.
Se for encontrado algum erro durante a execuo da unidade de programa, ser
apresentada uma mensagem contendo qual o erro ocorrido e lhe ser dado a opo
de visualizar o cdigo identificando a linha exata em que o erro ocorreu (Figura
10).
Figura 10. Identificao da linha de cdigo que produziu um erro.

Executando expresses SQL


Frequentemente, durante o desenvolvimento de programas, necessrio
executar algumas expresses SQL para visualizar ou mesmo atualizar dados em
tabelas. O PL/SQL Developer oferece uma interface para este tipo de tarefa atravs
do SQL Window. Para acessar o SQL Window, v em File -> New -> SQL Window.
Para executar a expresso SQL informada pressione o boto Execute (tecla de
atalho F8) (Figura 11).

Figura 11. SQL Window com o retorno das dez primeiras linhas de um SELECT.

Utilizando variveis de substituio


Pode-se utilizar variveis de substituio na expresso SQL para permitir uma
entrada de dados do usurio quando a expresso executada. Para utilizar este
recurso, basta acrescentar o nome da varivel precedida do caractere &. No
momento da execuo da expresso, ser apresentada uma janela de entrada de
dados para que seja inserido o valor que ser utilizado como substituio na
expresso SQL (Figura 12).
Figura 12. Expresso SQL com recurso de varivel de substituio.

A janela de comandos
O PL/SQL Developer oferece ainda uma interface de linha de comando
extremamente parecida com o SQL*Plus, que possibilita a execuo de scripts SQL
alm das expresses SQL em geral. Para acessar a Command Window, selecione
File -> New -> Command Window (Figura 13).

Figura 13. O Command Window, interface similar ao SQL*Plus.

Relatrios
Existe a opo de gerao de relatrios sobre os dados da aplicao que estiver
sendo desenvolvida ou at mesmo sobre as informaes do dicionrio de dados.
Esta segunda, bastante til para os DBAs. Esto disponveis vrios relatrios
padronizados de acordo com a caracterstica das informaes que se pretende
obter.
Para ter acesso aos relatrios, v em Reports e escolha a seo de relatrio
necessria. So quatro as opes de informaes para os relatrios: DBA, Objects,
PL SQL e User.
DBA: refere-se a relatrios que buscam informaes do dicionrio de dados.
Temos as seguintes opes:
o Initialization Parameters: indica as informaes dos parmetros de
inicializao do BD;
o NLS Database Parameters: informaes sobre os parmetros de suporte a
lngua nativa configurados no BD;
o Role Privileges: relatrio sobre os privilgios concedidos a um papel (role);
o Roles: relatrio de todos os papeis (roles) criadas no BD;
o Rollback Segments: traz as informaes de todos os segmentos de rollback
configurados no sistema;
o Server Components: mostra os componentes do SGBD tais como: verso do
BD, do PL/SQL, etc.;
o System Privileges: informa os privilgios de sistema concedidos a todos os
usurios ou a um usurio especfico;
o Tablespaces: relatrio de informaes da configurao das tablespaces;
o Users: mostra as informaes dos usurios do BD;
Objects: refere-se aos objetos criados no BD e esto subdivididos em:
o All Objects: prove informaes sobre todos os objetos do BD ou todos os
objetos de um determinado usurio;
o Indexes: informaes sobre os ndices de uma tabela ou de um esquema
completo;
o Sequences: exibe as configuraes das seqncias ou de uma determinada
seqncia no esquema;
o Synonyms: mostra as informaes dos sinnimos presentes no sistema;
o Tables: informaes sobre as tabelas do esquema;
o Triggers: exibe as informaes dos gatilhos, incluindo a descrio e o corpo
do gatilho;
o Types: informa todos os tipos criados no esquema;
o Views: exibe as vises criadas no esquema;
PL SQL: oferece somente a opo de Compilation errors para visualizar os
erros de compilao dos blocos de programa PL/SQL;
User: apresenta os relatrios referentes s informaes do usurio atravs das
seguintes opes:
o Granted Roles: exibe os papeis concedidas ao usurio;
o Granted System Privileges: mostra os privilgios de sistema concedidos ao
usurio;
o NLS Session Parameters: indica o valor dos parmetros de suporte lngua
nativa configurados para a sesso;
o Object Privileges Made: indica os privilgios de objeto que o usurio
concedeu a outros;
o Object Privileges Received: exibe os privilgios de objeto recebidos por
outros usurios.

Os relatrios ainda oferecem a opo de visualizao da expresso SQL que d


origem aos resultados obtidos pelo relatrio, e se o acesso expresso foi liberada
(em alguns casos, o acesso est travado), possvel ainda edit-la, alterando
conforme necessidade. Por fim, temos que a exibio feita em formato HTML e
existe a possibilidade de gravao do arquivo HTML e at mesmo exportao do
relatrio para formatos CVS, TSV ou XML e Excel.

Projetos
Para uma melhor organizao dos trabalhos, o PL/SQL Developer permite a
organizao dos arquivos manipulados atravs de projetos. Um projeto nada mais
do que uma coleo de cdigos fonte, objetos de BD, notas e opes. Desta forma,
pode-se trabalhar apenas com um escopo de itens especficos ao invs de trabalhar
com um BD ou esquema completos.
O nico cuidado que devemos ter o de garantir que a opo Use Projects esteja
selecionada nas preferncias do PL/SQL Developer. V em Tools -> Preferences ->
Options e selecione a opo Use Projects caso ainda no esteja selecionada.
Atravs do menu Project -> New, preencha as opes de criao do novo projeto
(Figura 14).

Figura 14. Criao de um novo projeto.

Salve o projeto (por padro, a extenso ser .prj) e a partir deste instante, todas
as vezes em que este projeto for aberto, as definies, objetos, cdigos, etc. a ele
associados, estaro disponveis organizadamente.
Agora o momento de adicionar as unidades de programa, objetos, etc. ao seu
projeto. Para adicionar uma unidade de programa previamente salva, basta abri-la
e selecionar Project -> Add to Project para que esta unidade de programa seja
includa na lista de itens do projeto. Uma outra maneira de adicionar unidades de
programa ou objetos atravs do navegador esquerda da rea de trabalho do
PL/SQL Developer. Neste navegador estaro disponveis apenas as unidades de
programa ou objetos que j tenham sido criadas no BD. Abra a janela Project Items
(Project -> Project Items...) e depois selecione a unidade de programa ou objeto
no navegador e, pressionando o boto direito do mouse, selecione a opo Add to
project (Figura 15).

Figura 15. Itens adicionados ao projeto.

Finalmente, basta compilar o projeto. Para isso, selecione a opo Build ou Make
no menu Project. A funo Build ir simplesmente compilar todos os componentes
do projeto que estiverem habilitados para compilao. Os itens sero compilados na
ordem em que aparecem na lista de itens do projeto (Figura 15). A funo Make
somente compilar os objetos que sofreram alguma alterao desde a ltima
compilao.
Concluses
Desenvolver aplicaes ou executar administrao em um BD Oracle no uma
tarefa simples, requer um alto grau de conhecimento do BD e tambm da
linguagem procedural PL/SQL alm, claro, da estrutura de expresses SQL.
Considerando estas tarefas, ferramentas grficas que podem nos trazer facilidades
e agilidade no processo de desenvolvimento e administrao do BD so muito bem-
vindas.
O PL/SQL Developer uma destas ferramentas que nos permite um alto grau de
produtividade e confiabilidade nas informaes e resultados.
Por fim, um conselho que me permito dar o de no se viciar nas ferramentas
grficas e sim us-las apenas como um apoio s tarefas. No se esquea nunca das
expresses SQL para chegar nesta ou naquela informao, pois no nem um
pouco improvvel que em uma consultoria voc possa ter acesso apenas a um
terminal de fsforo verde piscando em sua frente ou mesmo, sem chegar a
extremos, um BD instalado sobre um sistema operacional Linux, por exemplo, sem
interface grfica instalada para poupar recursos de memria. Lembre-se, sempre
teremos o velho e bom SQL*Plus em qualquer ambiente.
Espero que tenha sido uma leitura agradvel. At a prxima.

Ricardo Rezende (ricarezende@sqlmagazine.com.br - ricarezende@yahoo.com.br)


professor das disciplinas de Banco de Dados, Linguagem de Programao e
Tcnicas de programao pelo Centro Estadual de Educao Tecnolgica Paula
Souza nas unidades de Taubat-SP e Caapava-SP, DBA Oracle com cursos oficiais
pela Oracle University, consultor de Bancos de Dados e subeditor da revista SQL
Magazine.

Implementando um
data mart em um
banco de dados
multidimensional
Leitura obrigatria: SQL Magazine 13 e 14, Modelagem de data warehouses e
data marts (partes 1 e 2).
Leitura obrigatria: SQL Magazine 9, Arquiteturas de Ferramentas Olap.

Aps discutir a modelagem de um data warehouse/data mart utilizando o modelo


multidimensional (SQL Magazine 13 e 14) chegou a hora de acompanhar sua
implementao na prtica. Neste artigo vamos mostrar, passo a passo, como
implementar um modelo multidimensional conceitual em um banco de dados com
uma arquitetura especialmente preparada para este tipo de modelo.
Existem no mercado vrios bancos de dados multidimensionais, normalmente de
arquitetura proprietria, que possibilitam a implementao e carga de data marts
de forma bastante fcil. Devido s suas caractersticas especiais, as agregaes e
os clculos baseados nas regras de negcio que o usurio define so realizados
rapidamente. Estes bancos de dados especiais geralmente possuem uma
ferramenta OLAP (On-Line Analytical Processing) para acesso e anlise dos dados
armazenados. Vale ressaltar que alguns deles podem tambm ser acessados
atravs de outras ferramentas OLAP disponveis no mercado.
As ferramentas OLAP possuem recursos para permitir ao usurio final analisar um
grande conjunto de dados de forma simplificada, flexvel e sem que o usurio tenha
que conhecer o banco de dados ou como definir comandos SQL. O aspecto mais
importante que algumas delas permitem ao usurio criar as vises que mais lhe
interessam, com uma interface amigvel, que possibilita a escolha das mtricas (ou
fatos) a serem analisados e os aspectos (dimenses) da anlise em diversos nveis
de agregao, atravs de mecanismos do tipo drag-and-drop. Claro que nem todos
os usurios do data warehouse ou do data mart querem ou precisam utilizar uma
ferramenta com estes recursos. Vrios usurios preferem receber vises
previamente definidas, atravs da web, por exemplo, e navegar por estas vises
prontas, variando os nveis de detalhamento da informao apresentada.
Os dados de um data warehouse ou data mart no precisam necessariamente
estar armazenados em um banco multidimensional. Podem ser armazenados em
um banco relacional e serem tambm acessados atravs de uma ferramenta OLAP.
Estas podem:
acessar apenas bases de dados relacionais, sendo neste caso chamadas de
ferramentas ROLAP (Relational OLAP) ou DOLAP (Desktop OLAP);
acessar apenas bases de dados multidimensionais, sendo neste caso
chamadas de ferramentas MOLAP (Multidimensional OLAP);
acessar os dois tipos de base, sendo neste caso chamadas de ferramentas
HOLAP (Hybrid OLAP). No caso das ferramentas HOLAP, normalmente o
acesso aos dados agregados feito na base multidimensional e aos dados
detalhados, no banco relacional.

Existe atualmente no mercado uma grande discusso sobre qual arquitetura de


tecnologia OLAP mais eficiente e tambm sobre qual o melhor tipo de banco de
dados para se armazenar um data warehouse ou data mart. Este artigo no tem a
pretenso de entrar nesta discusso. Nossa experincia em projetos de implantao
de data warehouses e data marts nos mostra que existem vantagens e
desvantagens nas diversas opes de implementao e arquiteturas. Entretanto,
bases de dados multidimensionais so mais adequadas para a implementao de
data marts e nem sempre so utilizadas em data warehouses corporativos.
Assim, vamos iniciar a implementao do nosso data mart em um banco de dados
multidimensional, chamado TM1. O TM1 desenvolvido pela Applix Inc. (EUA) que,
no Brasil, fornecido e suportado pela CONSIST.

O modelo lgico do data mart


Antes de iniciarmos a implementao prtica no TM1, vamos apresentar o modelo
de dados do data mart. um modelo bastante parecido com os exemplos do artigo
de modelagem, apresentado na edio 14 desta revista. Este modelo uma das
formas possveis de se desenhar um data mart, cuja escolha depende do projetista.
um modelo simples, que representa as vendas de uma rede de papelarias. O
modelo formado por uma tabela fato e trs dimenses de negcio: tempo, loja e
produto. Este modelo est representado na Figura 1.
Figura 1. Modelo lgico do data mart de vendas.

Neste modelo exemplo, as vendas, representadas na Fato Vendas sero avaliadas


atravs das seguintes mtricas:
Quantidade: indica a quantidade vendida de um determinado item de produto;
Preo Mdio Item: indica o preo mdio do item, nas vendas realizadas, em
Reais;
Custo Mdio Item: indica o custo mdio do item, quando a venda ocorreu, em
Reais;
Valor Venda: indica o valor total dos itens envolvidos nas vendas, em Reais
(preo mdio item quantidade);
Custo Total: indica o custo total dos itens envolvidos nas vendas, em Reais
(custo mdio item quantidade);
Margem: indica a margem resultante da venda, em Reais (valor venda custo
total);
Margem %: indica a margem resultante da venda, em percentual (margem
valor venda).

As dimenses do modelo, representadas na Figura 1, possuem hierarquias que


permitiro o agrupamento das informaes armazenadas. De acordo com a
dimenso Tempo, as vendas sero armazenadas diariamente (data o nvel de
granularidade mais baixo) e sero sumariadas por ms, semestre e ano. Na
dimenso Loja, podemos ver que o nvel de armazenamento das informaes ser
por loja, agrupadas por cidades, estados (UF) e regies. A dimenso Produto indica
que as vendas sero informadas por item de produto e agrupadas em linhas de
produtos, que por sua vez, sero agrupadas por categorias. Assim, o data mart a
ser implementado armazenar as vendas por dia, por item de produto e por loja,
em seu nvel mais baixo de detalhe (ou de granularidade).
bom lembrar alguns pontos importantes sobre este modelo. As chaves utilizadas
so do tipo surrogate key, ou seja, seu contedo no est associado a um cdigo
especfico (como o de produto, por exemplo), armazenando um valor genrico (1,
2, 3, ...). Nas tabelas dimenso, os atributos no-chave, como loja, cidade,
semestre, linha e outros, armazenam descries. Assim, na dimenso Loja, por
exemplo, a coluna loja armazenar valores como Ptio Brasil, Faria Lima,
Universidades, que representam os nomes das lojas que a rede de papelarias
possui. A coluna data, na dimenso Tempo, teria valores como 12/07/04,
14/09/03, por exemplo. O mesmo vale para os outros atributos no-chave.
O modelo fsico do data mart no banco de dados multidimensional
Os bancos de dados multidimensionais possuem, normalmente, arquitetura
proprietria e por esta razo, existem diferenas entre as formas de implementao
e estruturas internas dos diversos bancos. No caso do banco multidimensional TM1,
o modelo lgico representado na Figura 1 no ser implementado exatamente
como as tabelas do diagrama, mesmo assim, o modelo lgico vlido e ser nosso
ponto de partida. Para a implementao fsica de um data mart no TM1, as chaves
no so necessrias. Isto porque a estrutura interna para armazenamento de dados
do TM1 diferente de um banco de dados relacional. Os dados das dimenses
esto diretamente ligados aos dados do fato atravs dos valores de Data, Loja e
Produto no havendo necessidade de joins. Assim, o modelo que melhor
corresponde implementao fsica est representado na Figura 2.

Figura 2. Modelo lgico mais prximo ao que ser implementado fisicamente no


banco de dados multidimensional TM1.

Os atributos Loja, Data e Produto continuam sendo textuais (descries, nomes


etc.), como j descrito, e so tambm as chaves que associam os valores da tabela
fato s tabelas dimenso. Por esta razo, cada descrio de Loja tem que ser nica,
assim como cada descrio de Produto e tambm os valores de Data. Este um
ponto importante, pois indica que o processo de carga tem que ser preciso ao
carregar os valores das colunas das tabelas dimenso. Por exemplo, se um produto
foi carregado com Lpis de cor Bear 24 cores na coluna Produto, dever ser
sempre referenciado por esta descrio nas prximas cargas. Caso um processo de
carga carregue, por exemplo, Lpis de cor Bear caixa 24 cores, este ser
considerado um novo produto. Talvez voc esteja pensando em todos os critrios
de normalizao que sempre aplicou na modelagem de bancos de dados
transacionais. Lembre-se que um data mart ou data warehouse no tem o mesmo
objetivo de um banco de dados transacional. Os bancos transacionais atendem aos
sistemas operacionais da empresa (folha de pagamento, contas a pagar etc.) e sua
modelagem visa garantir a consistncia e integridade dos dados durante as
transaes (que envolvem alteraes dos dados); por esta razo necessitam da
aplicao das regras de normalizao para garantir que no ocorrero anomalias.
J os data marts e data warehouses so bancos de dados voltados para consultas
de suporte deciso, com grandes volumes de dados. Assim, armazenam dados
com redundncia para agilizar as consultas, e no precisam atender a todas as
formas normais, pois as alteraes na base ocorrem sempre atravs de processos
de carga controlados e peridicos.
Com estas observaes em mente, vamos partir para a implementao do modelo
lgico representado na Figura 2 no banco de dados multidimensional TM1.
A Figura 3 mostra como nosso modelo (ou cubo) VENDAS est implementado no
TM1. O cubo VENDAS possui quatro dimenses (na verdade, trs dimenses e uma
fato).

Figura 3. O Cubo VENDAS e suas dimenses, no banco de dados multidimensional


TM1.

Cada uma das dimenses definida diretamente com seus valores e a hierarquia
entre estes valores. As Figuras 4, 5 e 6 mostram como ficam armazenadas as
dimenses Loja, Tempo e Produto no TM1, respectivamente. Perceba que as
hierarquias so definidas no prprio banco de dados, indicando como sero
realizados os agrupamentos das informaes.
Na Figura 4 podemos observar os detalhes da dimenso Loja onde os nomes das
lojas (coluna Loja) aparecem no nvel de granularidade mais baixo, com o smbolo
ao lado. Os outros atributos, como Cidade, Estado e Regio aparecem
agrupando os nveis abaixo de cada um deles. Por serem agrupamentos, aparecem
com o smbolo ao lado. Para facilitar as consultas e anlises que os usurios iro
realizar, inclumos o nvel Total Loja, que agrupa as lojas de todas as regies.
Daqui a pouco iremos analisar o contedo da tabela fato e vamos ver que os
valores so armazenados apenas para o nvel mais baixo de granularidade (Loja,
Data e Produto). atravs da estrutura das dimenses que o banco de dados pode,
automaticamente, agrupar os valores de vendas para os nveis superiores. Baseado
nesta descrio o leitor tambm entender as dimenses apresentadas nas Figuras
5 e 6.
Figura 4. Contedo da dimenso Loja, mostrando todos os nveis.
Figura 5. Contedo da dimenso Tempo, mostrando todos os nveis (alguns meses
esto fechados para favorecer a visualizao).
Figura 6. Contedo da dimenso Produto, mostrando todos os nveis (algumas
linhas de produtos esto fechadas para favorecer a visualizao).

Vamos ver agora, passo a passo, como criar uma dimenso no TM1. Para criar
uma nova dimenso, preciso clicar com o boto direito sobre Dimensions, como
mostra a Figura 7, e comear a inserir o contedo da nova dimenso. Vamos
simular a criao da dimenso Produto, conforme o exemplo que estamos utilizando
neste artigo. Pode-se inserir os elementos em qualquer ordem, ou seja, pode-se
partir do nvel mais alto da hierarquia e, aps isto, incluindo os elementos filho
ou, pode-se iniciar pelo nvel mais baixo de granularidade e depois incluir os pais.
A qualquer momento possvel tambm incluir elementos de qualquer nvel
hierrquico, bastando apenas indicar o local da hierarquia onde voc quer que o
elemento seja includo. Se a dimenso for muito grande, normalmente criado um
processo de carga que carrega os elementos da dimenso partindo de um arquivo
(texto, planilha MS-Excel ou outros). Neste caso, apesar da dimenso conter muitos
elementos, vamos criar manualmente o contedo da dimenso. Assim, vamos
iniciar com a incluso dos valores do nvel mais alto da hierarquia de produtos
(categoria) e depois iremos incluindo os filhos (linha e produto) at completar a
dimenso. A Figura 8 mostra a insero do primeiro valor na dimenso Escolar /
Escritrio que est no nvel mais alto da hierarquia (categoria). Uma vez que os
valores para categoria dos produtos forem inseridos na dimenso, podemos iniciar
a insero dos filhos das categorias, que so as linhas dos produtos. Na Figura 9
podemos ver como esta insero feita (clicar com o boto da direita sobre o valor
da categoria e solicitar a insero de filhos). A partir deste ponto vamos inserindo
valor por valor at completar o contedo da dimenso produto, salvar, escolhendo
um nome para a dimenso, que ficar exatamente como representado na Figura 6.
Mesmo depois de estar em produo, possvel incluir novos valores sem afetar as
aplicaes analticas j existentes, pois novos produtos podem ser comercializados
pela rede de papelarias. Caso um produto deixe de ser comercializado, no
comum exclu-lo da base de dados. A razo mais importante que existem vendas
anteriores para este produto e se ele for excludo da base, o histrico das vendas
ser perdido.

Figura 7. Criao de uma dimenso no TM1.

Figura 8. Insero dos valores da dimenso no TM1.


Figura 9. Insero dos elementos que esto no nvel abaixo da categoria de
produtos.

J podemos perceber outras caractersticas que diferenciam a estrutura interna de


um banco de dados multidimensional. No necessrio executar comandos group
by para realizar os agrupamentos, o banco de dados efetua as consolidaes
automaticamente, pois a hierarquia armazenada como recurso nativo do banco de
dados.
Veremos agora como criar a tabela fato no TM1. A tabela fato tambm
considerada uma dimenso no TM1, porm uma dimenso com caractersticas
especiais. Assim, o processo de criao do fato comea idntico ao da criao de
uma dimenso, conforme representado na Figura 7. A diferena que no iremos
incluir os valores (contedo) da tabela. Iremos criar os atributos, ou seja, as
mtricas do nosso modelo (veja a Figura 2), que so: quantidade, preo mdio do
item, custo mdio do item, valor da venda, custo total, margem e margem %. Os
valores sero inseridos depois atravs de um processo de carga. Assim, a Figura
10 mostra a criao dos atributos da tabela fato, de forma idntica aos valores
inseridos nas dimenses.

Figura 10. Criao das mtricas na tabela fato.


Na Figura 11 temos a estrutura final da tabela fato definida no TM1. Nela esto
presentes as mtricas disponveis para as consultas e anlises dos usurios.

Figura 11. Estrutura da tabela fato.

Uma vez que as dimenses foram carregadas e a tabela fato foi definida, temos
que criar o cubo que conter as informaes das vendas. Para criar a estrutura do
cubo no TM1, basta solicitar a criao de um novo cubo (clicar com boto direito
sobre Cubes, como mostra a Figura 12). Com isto, o TM1 apresentar a
possibilidade de se escolher as dimenses que iro compor o cubo (como mostra a
Figura 13) e, ao clicar no boto Properties, informar, entre as dimenses do cubo,
qual a tabela fato (no TM1: Measures dimension, como mostra a Figura 14).

Figura 12. Criao de um cubo no TM1.


Figura 13. Escolha das dimenses que iro compor o cubo.

Figura 14. Escolha da dimenso que representa a Fato.

Aps a execuo destas etapas j temos o cubo de Vendas pronto, porm vazio,
isto , as dimenses foram escolhidas e esto carregadas, mas os valores das
mtricas ainda no <<alterei esta frase, acho que ficou melhor>>. Assim, iremos
efetuar o processo de carga dos dados do fato. Para isto, usaremos um arquivo tipo
texto com os dados a serem carregados (o TM1 permite carga a partir de diversos
tipos de arquivos diferentes como planilhas MS Excel, tabelas em bancos de dados
relacionais, dados armazenados no BW (data warehouse do SAP), entre outros).

O processo de carga dos dados


No iremos carregar todas as mtricas a partir do arquivo texto. Algumas sero
calculadas no prprio TM1. A escolha entre efetuar o clculo no processo de carga
(e j mandar os valores calculados para o banco multidimensional) ou deixar para o
banco multidimensional calcul-los uma escolha do projetista do data mart.
Quando tiver que decidir, lembre-se que ao deixar os clculos para o banco de
dados e o volume de dados for muito grande, pode-se prejudicar um pouco a
performance das consultas. No caso especfico do TM1, os clculos so efetuados
no primeiro acesso mtrica. Neste momento, o TM1 efetua o clculo e armazena
em memria os valores j calculados que ficam disponveis para todos os usurios.
Em nosso exemplo, vamos carregar as mtricas: Quantidade, Preo Mdio Item,
Custo Mdio Item, Valor Venda e Custo Total. Deixaremos para o TM1 calcular a
Margem (em Reais) e a Margem %. Um fragmento do arquivo texto que ser usado
para a carga dos dados est representado na Figura 15.
Note que as mtricas so carregadas para cada item vendido em cada loja e em
cada dia. Assim, fica claro que a carga das mtricas feita nos nveis mais baixos
de granularidade de cada dimenso. O banco multidimensional ser responsvel
por somar as mtricas ao longo de cada dimenso. Por exemplo, a quantidade
vendida de um determinado produto em um dia ser somada ao longo da dimenso
tempo, determinando a quantidade vendida daquele item por ms, semestre, ano.
O mesmo vale para as outras dimenses: a quantidade do item vendido em uma
loja ser somada por cidade, estado e regio. Isto vale para as mtricas aditivas.
Mtricas semi-aditivas e no-aditivas devem ser tratadas de forma especial. o
caso do preo mdio e do custo mdio. No faz sentido somar o preo mdio de
cada dia para consolidar no ms. O preo mdio praticado no ms no igual a
soma dos preos mdios. Neste caso, o preo mdio no ms deve ser calculado
como a mdia dos preos praticados nas vendas. No semestre e no ano o clculo
deve ser similar. O custo mdio do produto tambm deve ser calculado assim.
Veremos como implementar isso no cubo mais adiante neste artigo. Por enquanto
vamos voltar ao processo de carga dos dados.

Figura 15. Detalhe de fragmento do arquivo texto usado na carga da tabela fato.

Os dados so carregados atravs de processos automticos que podem ser


programados para execuo diria, semanal, mensal etc. No TM1, definimos um
processo de carga onde so especificados: o nome e tipo do arquivo fonte,
variveis, nome do cubo a ser carregado, associao das variveis do arquivo fonte
com as dimenses do cubo, ao do processo de carga (sobreposio ou
acumulao dos valores), data e hora para execuo programada etc. No vamos
detalhar muito este processo j que, como em todos os bancos de dados, existem
vrias formas de se carregar dados a partir de arquivos fonte.

As mtricas calculadas
Considerando que as informaes foram carregadas, com exceo dos valores de
Margem e Margem %, vamos continuar com o processo de preparao dos dados
para as anlises e consultas. O prximo passo informar ao banco de dados qual a
frmula de clculo para as mtricas que faltam. Esta etapa no requer que os
dados j estejam carregados, poderamos ter criado as frmulas de clculo com o
cubo vazio. No TM1, assim como em outros bancos de dados multidimensionais,
existe um editor que permite a criao de campos calculados.
A Figura 16 apresenta o clculo das mtricas Margem e Margem %. Veja que o
clculo simples e vlido para todos os nveis de agregao das informaes.
Assim, para um determinado item de produto, a margem ser calculada sobre o
valor da venda do produto menos o custo total. O mesmo vale para uma linha de
produto, isto , a margem ser calculada sobre o valor de venda de todos os
produtos que compem uma determinada linha subtraindo-se o custo total dos
produtos daquela linha. Esta uma grande vantagem de se usar um banco
multidimensional, os clculos so automaticamente executados nos diferentes
nveis de agrupamento. A mtrica Margem % est definida no banco de dados
como sendo do tipo percentual, assim o clculo tambm fica simplificado, bastando
apenas dividir o valor da Margem pelo Valor Venda.

Figura 16. Regras de clculo definidas para as mtricas Margem e Margem %.

Existe ainda um problema a ser resolvido. Como mencionamos anteriormente,


existem mtricas no-aditivas neste cubo: Preo Mdio Item e Custo Mdio Item.
Temos que dar um tratamento especial a estas mtricas, pois elas no podem ser
somadas ao longo das dimenses. Para resolver este problema, iremos incluir uma
regra de clculo apenas para os valores sumariados das dimenses, ou seja, para
os nveis de agrupamento. Este clculo est representado nas novas regras
includas, representadas na Figura 17.
No caso do TM1, o clculo de valores para nveis consolidados (agrupados)
representado por C:, indicando que este clculo vale apenas para os nveis de
agrupamento. No nvel de granularidade mais baixo, os valores so aqueles que
foram carregados. Assim, ao visualizar os valores vendidos de um determinado
item no semestre, o preo mdio do item ser calculado de acordo com a frmula
definida, que apresentar o preo mdio deste item praticado durante o semestre
em questo.
Figura 17. Incluso das regras de clculo para as mtricas no-aditivas.

Feito isto, os dados armazenados esto prontos para as anlises dos usurios.

Explorando as informaes
Uma forma bem simples de se visualizar informaes no TM1 atravs do MS
Excel. Isto feito atravs de um plug-in do TM1 instalada no MS Excel tornando
possvel que os dados armazenados no banco de dados multidimensional TM1
sejam visualizados diretamente atravs das planilhas. Note que os dados no esto
sendo transferidos para as planilhas, mas esto armazenados na base de dados
multidimensional. Esta interface permite ao usurio explorar a base de dados da
forma que lhe interesse, possibilitando operaes da anlise multidimensional como
drill down (descer nveis de detalhe), drill up/roll up (subir nveis de detalhe),
pivoteamento (fixar dimenses) entre outras. A anlise multidimensional ser
descrita em outro artigo. O importante aqui percebermos que o usurio tem total
liberdade de explorao das informaes armazenadas no banco de dados. Um
exemplo de explorao mostrado na Figura 18, onde esto representadas as
categorias de produtos vendidas por ms em todas as lojas, visualizando-se apenas
as mtricas Quantidade, Margem e Valor Venda. Mais dois exemplos so: (1) a
visualizao apresentada na Figura 19 mostra os produtos que apresentaram
maiores margens (em percentual) no ano de 2003, e; (2) a variao das
quantidades vendidas de um determinado produto nas diferentes lojas mostrado na
Figura 20. As vises no so estticas, ou seja, o usurio pode explorar diferentes
itens, datas, lojas e mtricas. Como exemplo, na anlise da Figura 20, caso o
usurio quisesse analisar outro produto, bastaria clicar na dimenso produto e
escolher um novo item para ser analisado.
O MS Excel no a nica interface disponvel no TM1. possvel tambm
executar anlises atravs da web, utilizando apenas um browser na estao cliente.
Na verdade, os recursos de explorao das informaes atravs das ferramentas
OLAP so inmeros.
Figura 18. Viso de explorao de dados: categorias de produtos vendidas ao
longo do tempo.
Figura 19. Viso de explorao de dados: itens de produtos com maior margem
percentual no ano de 2003.

Figura 20. Viso de explorao de dados: venda do produto CD regravvel nas


lojas ao longo do perodo indicado.

Concluso
Este artigo mostrou como definir, carregar e explorar as informaes
armazenadas no banco de dados multidimensional TM1. interessante notar as
diferenas da estrutura deste banco multidimensional se comparado aos bancos de
dados relacionais. Estas diferenas visam facilitar o processo de anlise
multidimensional, atravs das ferramentas OLAP, onde operaes especiais como
drill down, drill up e outras esto disponveis. Em suma, bancos multidimensionais
so geis e bastante flexveis.
Existem outros bancos multidimensionais no mercado e sua estrutura interna
pode variar, mantendo, porm, os mesmos conceitos bsicos de armazenamento e
funcionamento.
Por fim, vale ressaltar que os aspectos mais importantes no projeto de um data
warehouse (ou de um data mart) esto na definio e criao de bases de dados
com informaes precisas e na escolha de ferramentas de fcil uso que possibilitem
ao usurio explorar os dados de acordo com as suas necessidades de negcio,
otimizando seu trabalho.

Isabel Cristina Italiano. Gerente de Business Intelligence da Consist, com 20


anos de experincia em tecnologia da informao. Mestre em Cincia da
Computao pelo Instituto de Matemtica e Estatstica da USP e doutoranda em
Computao pela Escola Politcnica da USP, ambos com rea de concentrao em
Bancos de Dados e Data Warehouse. Professora em cursos de graduao e ps, nas
reas de bancos de dados, data warehouse e business intelligence.

Luiz Antonio Esteves. Diretor da LT Consultoria e Tecnologia, atuando h mais de


25 anos na rea de tecnologia da informao, em atividades relacionadas a
desenvolvimento de software, consultoria e planejamento em bancos de dados e
sistemas de suporte deciso. Graduado em Engenharia de Produo, Mestre em
Management Engineering pelo Rensselaer Polytechnic Institute-USA. Professor e
palestrante em Data Warehousing / Business Intelligence.

Entendendo plan
table e planos de
consulta
O ajuste fino de comandos SQL no nem um bicho de sete cabeas e nem
mgica. Todos os SGBDs relacionais geram um plano de execuo para um
comando submetido. Este plano informa ao SGBD qual a estratgia de acesso aos
dados ou como realizar as tarefas atreladas aos dados. Quanto melhor a
compreenso de como interpretar estes planos, mais fcil ser a resoluo de
possveis problemas de desempenho com comandos SQL.

A plan table
O Oracle popula uma plan table sempre que solicitado. Esta plan table contm o
plano de execuo para um comando SQL particular. Se um determinado esquema
no possui uma plan table, pode-se rodar o script utlxplan.sql utilizando o Oracle
userid, ou solicitar ao administrador do BD para execut-lo. Eu sempre uso a plan
table que foi instalada com a instncia do Oracle. Existem vrios modos de popular
uma plan table, entretanto, nos concentraremos em dois deles.
Utilizando o SQL*Plus, insira o comando set autotrace on explain statistics (ver
Figura 1). Isto popular a plan table e fornecer um plano de consulta gerado
automaticamente com suas estatsticas de runtime.
Figura 1. SQL*Plus utilizando o autotrace.

O mtodo para criao da plan table que apresentarei agora no roda


efetivamente o SQL, ele simplesmente produz um plano de consulta. Alm disso,
ser necessrio um script para formatar a sada (show_plan.sql um desses tipos
de script que pode ser encontrado em www.danhotka.com). A sintaxe utilizada
explain plan set statement id = <some identifier> for <some SQL statement>.
Esta sintaxe ir popular a plan table e colocar o statement ID nomeado dentro do
campo STATEMENT_ID. Este ser utilizado pelo script show_plan.sql para organizar
a sada (ver Figura 2).
Figura 2. Plano de consulta gerado utilizando Show_Plan.sql.

Entendendo o plano de consulta


Examinando a Figura 2, fcil de acompanhar as endentaes do plano de
consulta. O Oracle ir trabalhar com o item mais endentado primeiro. Est difcil de
acompanhar as endentaes? Todos os exemplos anteriores possuem duas colunas
de nmeros esquerda. A primeira coluna a statement ID (identificao
comando) e o segundo nmero a parent ID (identificao pai). Por exemplo, h
NESTED LOOPS em ambos os statement ID 3 e 4. A partir do NESTED LOOP na
coluna 4, pode se ver que seu parent ID um 3, ou seja, a sada desta linha ser
passada para o statement ID 3. Portanto, statement ID 4 tem dois acessos tabela
(ver statement IDs 5 e 7) e ambos os comandos tem um INDEX access - acesso a
ndice (statement IDs 6 e 8). Perceba que o INDEX acessa pontos parent ID para
a TABLE ACCESS imediatamente acima. O Oracle est usando um Index para
acessar as linhas na tabela. Se no existir nenhuma linha TABLE ACCESS
associada, o Oracle utilizar o ndice para resolver o que estiver sendo solicitado.
A Tabela 1 apresenta um pouco da sintaxe encontrada em planos de consulta e o
que significa cada um dos itens (no de maneira nenhuma uma lista completa).

Ao Descrio da notao

Os FILTERs aplicam outro critrio na consulta


FILTER
para qualificar as linhas.

A tabela ser acessada por completo, sem usar


FULL Table Scan
um Index. Clusula HAVING.

Comandos SQL utilizam um ndice nico para


INDEX (UNIQUE)
pesquisar por um valor especfico.
Comandos SQL contm uma condio de
INDEX (RANGE
desigualdade (non-equality condition) ou uma
SCAN)
condio BETWEEN.

Os comandos SQL iniciaram uma operao de


juno hash (hash-join), as tabelas so lidas e
HASH JOIN colocadas em uma estrutura em memria
acessada via clculo matemtico (conhecido
como chave Hash Hash key).

Um mtodo de juno (join method) est sendo


usado quando mais de uma tabela aparece na
clusula FROM. O Oracle ir ordenar os dois
MERGE JOIN conjuntos de resultados que esto sendo
reunidos sobre as colunas de juno (join
columns) e ento intercalar (merging) os
resultados baseados nas colunas de juno.

Esta operao representa uma outra forma de


juno de tabelas. Uma linha recuperada a
partir da linha fonte (source row) do primeiro
NESTED LOOPS
statement ID dentro do NESTED LOOP e ento
reunida a todas as colunas correspondentes na
outra tabela referenciada no NESTED LOOP.

Tabela 1. Descries presentes em planos de consulta.

Cada uma das condies de juno NESTED LOOPS, MERGE JOIN e HASH JOINS
produzem um conjunto de resultados intermedirios que repassado ao parent
ID. Assim, o comando NESTED LOOP no statement ID 3 na Figura 2, obtm a
sada do NESTED LOOP no statement ID 4 e a seguir itera na tabela restante da
clusula FROM no statement ID 9. Perceba que o parent ID do statement ID 9 o
3, ou seja, o primeiro comando NESTED LOOP neste explain plan.
Outro aspecto interessante : como dizer quais partes do comando SQL
correspondem a que parte do plano de consulta? aqui que fica difcil para o
ajustador principiante. Pode-se ler nas entrelinhas e verificar quais ndices so
acessados e qual a coluna ndice. Voltando clusula WHERE, veem-se quais so
as colunas correspondentes e ento possvel fazer chutes educados.

Concluso
Entender planos de consulta o elemento-chave para o ajuste de comandos SQL.
Quanto mais informao disponvel, melhores decises podem ser feitas sobre
quais alteraes so necessrias para um determinado comando SQL.
Informao adicional sobre o contedo de planos de consulta e detalhes de ajuste
do SQL em geral podem ser encontrados consultando-se o Oracle SQL Tuning
Pocket Reference de autoria de Mark Gurry, editora OReilly.

Dan Hotka consultor Oracle tendo mais de 20 anos em experincia com produtos
Oracle.
Influenciando o
otimizador de
consultas Oracle
baseado em custos
Parte 1
Muitos desenvolvedores Oracle e DBAs esto familiarizados com a teoria bsica
por trs da otimizao de consultas baseadas-em-custo: o otimizador usa
estatsticas descrevendo o contedo de tabelas, colunas e ndices para estimar o
custo de vrios planos de consulta possveis para uma dada query e escolhe aquela
com o menor custo. Na prtica, o plano de consulta selecionado nem sempre o
mais rpido e pode, at mesmo, nem ser prximo do mais rpido. Tipicamente,
quando isto acontece, podemos considerar o uso de dicas para forar o otimizador
a utilizar um plano de consulta melhor. Porm, isto requer a modificao do
programa que solicitou a consulta, o que nem sempre possvel. Por esta e outras
razes, muitos especialistas no recomendam o uso de dicas para passar por
cima do otimizador, exceto como um meio de experimentar vrios planos de
consulta com o intuito de comparar os tempos de execuo.
Perfis armazenados (stored outlines) tambm podem ser problemticos, pois eles
devem casar com as consultas s quais se aplicam. Mesmo pequenas mudanas
no texto de uma consulta podem conduzir a um perfil no utilizvel, e muitos stios
operacionais no tm disciplina suficiente nos seus processos de gerncia de
configurao para assegurar que o perfil ir migrar para a produo junto com a
consulta. Finalmente, para criarmos um perfil, preciso fazer com que o otimizador
escolha o plano de consulta correto sem modificar a consulta - se isso fosse
possvel, voc no estaria lendo este artigo!
Aps o ajuste fino dos parmetros optimizer_index_caching e
optimizer_index_cost_adj, e a coleta de estatsticas nas tabelas do banco de dados,
o que faremos se ainda existirem alguns casos em que o otimizador escolha um
plano de acesso sub-otimizado? Este artigo o primeiro de uma srie que descreve
algumas dessas situaes, e algumas aes que podemos tomar para contorn-las
antes de recorrer a dicas.

Cardinalidade estimada
A estimativa do otimizador em relao ao custo de um plano de consulta
derivada principalmente pelo nmero estimado de linhas que sero processadas a
cada passo, o que chamado de cardinalidade. Se for utilizado o comando EXPLAIN
PLAN com o otimizador baseado em custo (CBO cost based optimizer), ele ir
fornecer na coluna PLAN_TABLE.CARDINALITY, a cardinalidade estimada a cada
passo do plano de consulta. Este valor baseado no fato de que melhorando a
preciso da cardinalidade estimada, ser incrementada a preciso do custo
estimado e, portanto, ser aumentada a probabilidade de que o otimizador
baseado-em-custo escolher realmente o mais rpido plano de consulta. E agora,
como fazer para que as cardinalidades sejam as mais precisas possveis?
Para estimar as cardinalidades de uma fonte de linhas especfica, o otimizador
deve estimar a seletividade dos predicados que usam essa fonte de linhas.
Seletividade a probabilidade que o predicado seja verdadeiro para qualquer linha
dada (um nmero entre 0 e 1). Assim, se a fonte de linhas prov N linhas, e a
seletividade dos predicados dessa fonte S, ento a cardinalidade estimada aps a
aplicao dos predicados ser N*S. Para predicados que combinam duas fontes A e
B, a cardinalidade estimada NA*NB*S.
Estimativas de seletividade de predicados so baseadas em muitos fatores:
As colunas que a consulta utiliza em seus predicados;
A estatstica de colunas, incluindo informaes como o nmero de valores
diferentes (NDV number of distinct values) e densidade (a densidade
1/NDV quando no h histograma e derivada de uma frmula complexa
quando h histograma);
O tipo de predicados na sua consulta, tais como comparaes de igualdade,
desigualdades, operaes LIKE, subconsultas, etc;
Pressupostos embutidos no projeto do otimizador sobre os quais no h
controle.

O ltimo item, os pressupostos de projeto do otimizador, tambm importante.


Enquanto os pressupostos estejam de acordo com a realidade do banco, o
otimizador funcionar bem. No entanto, quando os pressupostos forem incorretos,
as seletividades estimadas sero imprecisas, talvez altamente imprecisas, e as
cardinalidades estimadas e custos derivados delas sero imprecisas tambm. No
de surpreender que os planos de consulta para estes casos sejam normalmente
ruins.
Wolfgang Breitling do Centrex Consulting Corporation, tem redigido vrios artigos
acerca da operao interna do CBO, os quais podem ser encontrados em
www.centrexcc.com. Estes artigos descrevem em detalhes como o CBO deduz as
estimativas de cardinalidade e custos, quais pressupostos so usados para estimar
a seletividade dos predicados e como usar o rastreador 10053 (10053 tracer) para
dissecar o comportamento do otimizador em uma consulta especfica. Um artigo
especialmente til intitulado Using DBMS_STATS in Access Path Optimization,
no qual descrita uma tcnica de ajuste fino de consulta chamada cardinality
feedback.
Quando enfrentamos uma consulta com desempenho fraco, um primeiro passo
lgico rastrear sua execuo com o TKPROF. Comparando a contagem de linhas
atual no rastreamento com a cardinalidade estimada no plano de consulta, pode-se
rapidamente constatar se existe algum problema. Mas no leve esta comparao
muito a srio; bastante raro obter-se uma cardinalidade estimada no n raiz do
plano de consulta que chegue perto da contagem de linhas correta. Porm se as
contagens nas duas ou trs primeiras tabelas da juno diferem substancialmente
da contagem do TKPROF, por um fator de 100 ou mais, algum tipo de ao deve
ser tomada para reparar esta situao.
Quando comparamos cardinalidades estimadas com contagens de linhas reais
provenientes do TKPROF, devemos ser cautelosos quanto tabela interior de uma
juno aninhada (o segundo filho abaixo do n NESTED LOOPS). A sada do
EXPLAIN PLAN mostra a cardinalidade estimada da tabela interior por iterao do
loop. Em contrapartida, a contagem de linhas real na sada do TXPROF ser o total
de todas as iteraes. Portanto, deve-se multiplicar a estimativa de contagem
interior pela estimativa de contagem exterior antes de comparar com a contagem
real do TKPROF.
Na prxima seo e nos artigos subsequentes, observaremos modos pelos quais
uma consulta pode desviar-se dos pressupostos de projeto do otimizador, e sero
discutidas algumas tcnicas para lidar com essas situaes.
Exemplo
Este exemplo baseado num esquema de teste que, embora idealizado, supe-se
que seja de alguma forma um subconjunto real de um DB de pedidos de clientes.
Nesta consulta, relacionaremos pedidos de clientes que contenham itens de um tipo
especfico, onde o nmero de itens do tipo que nos interessa constitui uma pequena
frao do total de itens. Tambm desejamos somente o endereo mais recente do
cliente, portanto h uma subconsulta para assegurar que a data efetiva realmente
a ltima para cada cliente (no caso de algum imaginar que esta estrutura
realstica demais, esta tcnica foi usada em centenas de tabelas em esquemas da
PeopleSoft HR e, de fato, o otimizador em muitos casos se comporta como ilustrado
aqui).
O teste foi executado em um PC dedicado de mdia potncia rodando Oracle
9.2.0.1 e Windows XP. O tempo exato para rodar cada teste no relevante. Na
verdade, os testes pretendem ilustrar a reduo em tempo de execuo e E/S
lgica, que ocorre quando o otimizador escolhe um plano de consulta melhorado.
Para todos os testes, foram computadas estatsticas utilizando 100% das linhas,
para assegurar que os efeitos no so provocados por erros de amostragem. Foram
adicionados histogramas para cada coluna cujo contedo foi deliberadamente criado
com uma distribuio distorcida. Adicionalmente, foram utilizados os valores
apresentados na Tabela 1.

_unnest_subquery false

optimizer_dynamic_sampling 1

optimizer_features_enable 9.2.0

optimizer_index_caching 90

optimizer_index_cost_adj 30

optimizer_max_permutations 79999

optimizer_mode CHOOSE

Tabela 1.

Na Listagem 1 apresentamos a consulta de teste.

select *
from address a
join customer c on (a.cust_id = c.cust_id)
join ord o on (o.cust_id = c.cust_id)
join line_item li on (li.order_num = o.order_num)
join item i on (i.item_id = li.item_id)
where i.type = 4
and a.eff_dt =
(select max(eff_dt)
from address a2
where a2.cust_id = a.cust_id
)
;
Listagem 1. Consulta utilizada no exemplo.
O plano de consulta escolhido para a consulta est apresentado na Figura 1. O
n destacado de interesse posterior.

Figura 1. Plano de consulta original.

Porm, quando este plano de consulta foi executado, a consulta levou mais de 20
minutos, executou mais de 2,4 milhes de leituras lgicas (consistent gets) e, por
fim, retornou somente 2.706 linhas (ver Figura 2).

Figura 2. Resultado obtido ao rodar o plano de consulta original.

Observando-se a sada do TKPROF (ver Listagem 2), podemos comparar as


cardinalidades reais com as estimadas pelo otimizador. Isto nos d uma pista sobre
o problema.

Rows Row Source Operation


------- ---------------------------------------------------
2706 FILTER (cr=2424113 r=171850 w=0 time=1391957253 us)
2706 HASH JOIN (cr=2421262 r=171500 w=0 time=1388041105 us)
50 TABLE ACCESS FULL OBJ#(24171) (cr=92 r=89 w=0 time=89960 us)
2751461 TABLE ACCESS BY INDEX ROWID OBJ#(24176) (cr=2421170 r=171411
w=
3251462 NESTED LOOPS (cr=1908513 r=20307 w=0 time=240521896 us)
500000 NESTED LOOPS (cr=901960 r=5033 w=0 time=54126638 us)
100000 NESTED LOOPS (cr=200989 r=1316 w=0 time=11103474 us)
100000 TABLE ACCESS FULL OBJ#(24169) (cr=806 r=690 w=0
time=1329674 us)
100000 TABLE ACCESS BY INDEX ROWID OBJ#(24167) (cr=200183 r=626
w=
100000 INDEX UNIQUE SCAN OBJ#(24168) (cr=100183 r=245 w=0 time=
500000 TABLE ACCESS BY INDEX ROWID OBJ#(24173) (cr=700971 r=3717
w=
500000 INDEX RANGE SCAN OBJ#(24175) (cr=201473 r=1150 w=0 time=
2751461 INDEX RANGE SCAN OBJ#(24177) (cr=1006553 r=15274 w=0 time=
2669 SORT AGGREGATE (cr=2851 r=350 w=0 time=3812246 us)
2669 FIRST ROW (cr=2851 r=350 w=0 time=3754618 us)
2669 INDEX RANGE SCAN (MIN/MAX) OBJ#(24170) (cr=2851 r=350 w=
Listagem 2. Sada do TKPROF.

A linha acima destacada da sada do TKPROF, corresponde ao ADDRESS table


step, destacado na Figura 1. O otimizador previu 100 linhas, mas a contagem real
foi de 100.000. No momento em que o nmero de linhas da primeira tabela da
juno produziu trs ordens de magnitude a mais do que o previsto, todos os
passos subseqentes foram muito mais custosos que o previsto. Ento, porque a
cardinalidade foi to maior do que a prevista?
No Oracle 9i, o PLAN_TABLE inclui colunas que mostram predicados de consulta
especficos que se aplicam a cada passo do plano de consulta. Se observarmos os
predicados na address table, veremos que h none at all (nenhum) no n 8, porm
o predicado no n 1 :

"SYS_ALIAS_1"."EFF_DT"= (SELECT /*+ */ MAX("A2"."EFF_DT")


FROM "ADDRESS" "A2" WHERE "A2"."CUST_ID"=:B1)

Isto significa que o processador de consultas avalia a subconsulta quando atinge o


n 1 do plano, depois que todas as junes foram processadas. Alm disto, as
estatsticas do ADDRESS table indicam que existem mais de 100.00 linhas e que h
1.000 valores diferentes de data efetiva (ver Figura 3).

Figura 3.

A cardinalidade estimada pelo otimizador o produto do nmero de linhas na


tabela (100.000) vezes a densidade de EFF_DT (0,001), levando a uma estimativa
de 100 linhas. Portanto, temos na realidade dois problemas aqui:
Em primeiro lugar, o otimizador assume que a seletividade de
EFF_DT=(subconsulta) a mesma de EFF_DT=(constante). Mas na realidade,
esta subconsulta ir passar um endereo para cada ID de cliente, portanto a
verdadeira seletividade depende no nmero mdio de endereos por cliente.
No BD de teste, isto foi exatamente 1,0. Num BD real, poder haver mais de 1
endereo por cliente, porm no muito mais de 1.000 por cliente, assim, a
seletividade real ser muito mais alta que 0,001;
O segundo problema reside no fato de que o otimizador aplicou a filtragem do
predicado de data efetiva no n 8 destacado na Figura 1, mesmo quando no
podia realmente processar o predicado at o n 1. Este o bug 3558780
(confirmado pelo Suporte tcnico Oracle (Oracle Tech Support)).

A soluo de contorno para ambos os problemas consiste em fixar (ver Listagem


3) o nmero de valores diferentes de ADDRESS.EFF_DT para o nmero mdio por
cliente e estabelecer a densidade para o recproco desse nmero. No meu teste,
ambos os valores so 1,0. No mundo real, 1,0 pode ser suficientemente preciso
para conduzir a resultados aceitveis.

begin
dbms_stats.set_column_stats (
ownname => user,
tabname => 'ADDRESS',
colname => 'EFF_DT',
distcnt => 1.0,
density => 1.0
);
end;
/
Listagem 3.

Agora o plano de consulta tem o aspecto apresentado na Figura 4.

Figura 4. Plano de consultas aps ter modificado as estatsticas em


ADDRESS.EFF_DT.

Perceba que a ordem de juno foi totalmente revertida. Desta maneira, o tempo
de execuo e de E/S lgica foram reduzidos drasticamente (ver Figura 5).

Figura 5. Resultado aps rodar o plano de consulta modificado.

Agora temos na Listagem 4 a sada TKPROF confirmando que a contagem de


linhas real bastante prxima da cardinalidade estimada.

Rows Row Source Operation


------- ---------------------------------------------------
2706 FILTER
2706 SORT GROUP BY
2706 HASH JOIN
2706 TABLE ACCESS BY INDEX ROWID ADDRESS
5413 NESTED LOOPS
2706 NESTED LOOPS
2706 NESTED LOOPS
2706 NESTED LOOPS
50 TABLE ACCESS FULL ITEM
2706 TABLE ACCESS BY INDEX ROWID LINE_ITEM
2706 INDEX RANGE SCAN LINE_ITEM_FK2 (object id 24178)
2706 TABLE ACCESS BY INDEX ROWID ORD
2706 INDEX UNIQUE SCAN ORD_PK (object id 24174)
2706 TABLE ACCESS BY INDEX ROWID CUSTOMER
2706 INDEX UNIQUE SCAN CUSTOMER_PK (object id 24168)
2706 INDEX RANGE SCAN ADDRESS_PK (object id 24170)
100000 INDEX FAST FULL SCAN ADDRESS_PK (object id 24170)
Listagem 4.

Vale aqui um alerta: qualquer consulta que tenha um predicado em


ADDRESS.EFF_DT ser afetada ao modificar as estatsticas do jeito que fizemos
aqui. Tenha certeza de testar sua aplicao exaustivamente para se assegurar que
o efeito da mudana ou positiva ou neutra em todas as consultas.

Concluso
Pelo fato do otimizador basear suas escolhas na cardinalidade estimada, os planos
resultantes podem ser ineficientes quando essas estimativas no so precisas.
Neste artigo, vimos um exemplo onde a seletividade de um predicado foi muito
menor que a assumida pelo otimizador. Mesmo estatsticas precisas e histogramas
no levam em conta o efeito das presunes do otimizador sobre predicados na
forma COLUMN=(subconsulta). Contornamos as presunes incorretas modificando
a estatstica de coluna de forma que a seletividade do predicado passou a ser
precisa, e o otimizador nos forneceu um plano de consulta melhorado.
Tenha em mente que a tcnica descrita aqui no uma panacia universal. O
nico meio de saber ao certo se uma dada modificao ser eficiente ou no
testando num BD de teste contendo tabelas que reflitam as que sero utilizadas em
produo.

Glenn Goodrum consultor Oracle. Possui 15 anos de experincia em tuning de


bancos de dados e seu projeto visando alta escalabilidade.

Heap Tables
Livre-se delas para ganhar
performance
Leitura obrigatria: SQL Magazine 10, artigo Entendendo e utilizando
ndices na otimizao de queries no SQL Server.
Dedicarei esse artigo a um assunto especial e pouco explorado: Heap tables, ou
se preferir, tabelas que no possuem ndice cluster.
Os processos de desfragmentao existentes no SQL Server 2000 foram criados
para desfragmentar ndices. Como as pginas de dados de uma heap no so
regidas por um ndice, no possvel desfragmentar uma heap utilizando os
comandos convencionais DBCC dbReindex e IndexDefrag. Heaps fragmentadas so
indicadoras de m performance, e a simples criao de um ndice cluster poderia
resolver o problema, como veremos a seguir.

Heap tables x performance


Um ndice cluster atua diretamente sobre as pginas de dados da tabela,
dispensando a utilizao de ponteiros, como acontece nos ndices convencionais.
Em tabelas que possuem ndice cluster, a gravao das linhas nas pginas de dados
obedece classificao da chave do ndice.
Em oposio s tabelas com ndice cluster, esto as heap tables. Heap sinnimo
de aleatrio, desordenado. Heap tables so tabelas cujas linhas so gravadas nas
pginas de dados sem que exista uma ordenao pr-estabelecida, levando-se em
conta a regra de inserir onde existe espao, atravs de consulta nas pginas PFS
(ver Nota 1).
Nota 1. FPS
PFS, anacrnimo de Page Free Space, uma pgina especial destinada a controlar o espao livre nas pginas do database.

Uma PFS controla 8.000 pginas; cada byte da pgina PFS pode assumir quatro estados: totalmente vazia, at 50% de

utilizao, de 51 a 80% de 81 a 95% e de 96 a 100%. O controle de pginas PFS utilizado por heaps ou por tabelas que

possuem colunas ntext, text ou image.

Se compararmos as pginas de dados de uma tabela de nomes com e sem


ndice cluster definido aps uma srie de inseres, atualizaes e excluses,
visualizaramos os cenrios apresentados nas Figuras 1 e 2.

Antonio Arisvaldo Danilo Lucimara 4


. . .
1 2 3
Paulo
Ademir Beatriz espao
espao . . .
livre espa
Aldo Carlos livre espa
o livre
espao o livre
espao espao es
livre espa espao es . . .
livre pao livre
o livre pao livre
espao espao es espao
espao
livre pao livre livre
livre
espao espao espao
espao
espao livre
livre
livre espao
espao
espao livre espa
livre espa
o livre
espao li

Figura 1. Pginas de dados da tabela de nomes com ndice cluster.

Antonio Danilo Ademir Beatriz . . .


1 2 3 4

Lucimara espao Aldo espao


. . .
livre espa livre espa
espao espao
o livre o livre
livre espa livre espa
espao es espao es
o livre o livre . . .
espao es Arisvaldo espao es Paulo
pao livre
Carlos espao espao
espao
livre espa livre espa
o livre livre
o livre o livre
espao es espao
espao es espao es
livre
pao livre espao pao livre
espao livre espa espao

Figura 2. Pginas de dados de tabela de nomes sem ndice cluster (heap).

Aps a reindexao das tabelas, o resultado seria o seguinte:


Na tabela com ndice cluster, a desfragmentao deixou-a mais enxuta,
liberando as pginas 3 e 4, e condensando os dados nas pginas 1 e 2 (ver
Figura 3);
Na heap, no houve nenhuma alterao, continuando a ocupar 4 pginas, sem
qualquer tipo de desfragmentao (ver Figura 4)

Antonio Carlos . . . . . . . . .
1 2

Danilo
Ademir Lucimara
. . . . . . . . .
Aldo Paulo
Arisvaldo
. . . . . . . . .
Beatriz

Figura 3. Pginas de dados da tabela de nomes com ndice cluster aps


reindexao.

Antonio Danilo Ademir Beatriz . . .


1 2 3 4

Lucimara espao Aldo espao


. . .
livre espa livre espa
espao espao
o livre o livre
livre espa livre espa
espao es espao es
o livre o livre . . .
espao es Arisvaldo espao es Paulo
pao livre
Carlos espao espao
espao
livre espa livre espa
o livre livre
o livre o livre
espao es espao
espao es espao es
livre
pao livre espao pao livre
espao livre espa espao

Figura 4. Pginas de dados de tabela de nomes sem ndice cluster (=heap) aps
reindexao.

Podemos concluir que um processo de reindexao ir reorganizar os ndices,


eliminando a fragmentao. Pginas de dados de tabelas que possuem ndice
cluster sero automaticamente desfragmentadas, em funo da caracterstica
peculiar desse tipo de ndice. Pginas de dados em heaps permanecero
exatamente como esto, totalmente fragmentadas. Para reduzir a fragmentao
em uma heap, precisaramos mover os dados para uma rea temporria, excluir a
tabela, recri-la e re-inserir os dados.
As heap tables so devoradoras de espao em disco, principalmente se os dados
sofrerem muitas remoes. Espaos subutilizados em pginas de dados so
sinnimos de m performance, pois fora o sistema de discos a efetuar um maior
nmero de leituras. A soluo identificar heaps no database e proceder criao
de ndices cluster adequados.

Como identificar uma heap


Heap tables possuem uma entrada na tabela SysIndexes, onde o campo IndId
0. Clustered Tables possuem uma entrada onde IndId 1. Todos os outros ndices
sero armazenados tendo o valor de IndId entre 2 e 250. Portanto, para rastrear
as heap tables em um database, basta executar a query da Listagem 1.
Listagem 1. Query para descobrir as tabelas heap do database.
select object_name(i.id)
from SysIndexes i
inner join SysObjects o on i.id = o.id
where (IndId = 0) and (xType='U')

Heap table: um exemplo prtico


Para que possamos visualizar o efeito da reindexao nas pginas de dados de
uma heap, criaremos uma tabela temporria chamada temp_Orders no database
NorthWind. O script para gerao e inicializao da tabela encontra-se na
Listagem 2.

Listagem 2. Script para criao da tabela heap.


/* Criao da tabela temporria temp_Orders */
if object_id ('temp_Orders') is not null drop table temp_Orders
CREATE TABLE [dbo].[temp_Orders]
(
[OrderID] [int] IDENTITY NOT NULL ,
[CustomerID] [nchar] (5) NULL ,
[EmployeeID] [int] NULL ,
[OrderDate] [datetime] NULL ,
[RequiredDate] [datetime] NULL ,
[ShippedDate] [datetime] NULL ,
[ShipVia] [int] NULL ,
[Freight] [money] NULL ,
[ShipName] [nvarchar] (40) NULL ,
[ShipAddress] [nvarchar] (60) NULL ,
[ShipCity] [nvarchar] (15) NULL ,
[ShipRegion] [nvarchar] (15) NULL ,
[ShipPostalCode] [nvarchar] (10) NULL ,
[ShipCountry] [nvarchar] (15) NULL
) ON [PRIMARY]
GO
/* Criao de ndice no cluster na tabela temp_Orders */
create NONCLUSTERED index ix_noncluster_Orders on temp_Orders (OrderId)
go
/* Populando temp_orders 'a partir da tabela Orders */
declare @i tinyint
set @i=1
while @i <= 100
begin
insert into temp_Orders
(
CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Frei
ght,ShipName,Ship Address,
ShipCity,ShipRegion,ShipPostalCode,ShipCountry
)
SELECT
CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Frei
ght,ShipName,Ship Address,
ShipCity,ShipRegion,ShipPostalCode,ShipCountry
from Orders
set @i=@i+1
end

Vamos checar a fragmentao da tabela temp_orders e do ndice


ix_noncluster_orders com o auxlio do comando DBCC ShowContig. O resultado
est na Figura 5.

/* executando o ShowContig nas pginas de /* executando o ShowContig no indice


dados da heap */ ix_noncluster_Orders) */

dbcc showcontig('temp_orders')
dbcc
showcontig('temp_orders','ix_noncluster_O
rders')

DBCC SHOWCONTIG scanning 'temp_Orders' DBCC SHOWCONTIG scanning


table... 'temp_Orders' table...

Table: 'temp_Orders' (1318295756); index Table: 'temp_Orders' (1318295756); index


ID: 0, database ID: 6 ID: 2, database ID: 6

TABLE level scan performed. LEAF level scan performed.

- Pages Scanned................................: - Pages Scanned................................:


2042 155

- Extents Scanned..............................: 259 - Extents Scanned..............................: 23

- Extent Switches..............................: 258 - Extent Switches..............................: 22

- Avg. Pages per Extent........................: 7.9 - Avg. Pages per Extent........................:


6.7
- Scan Density [Best Count:Actual
Count].......: 98.84% [256:259] - Scan Density [Best Count:Actual
Count].......: 86.96% [20:23]

- Logical Scan Fragmentation ..................:


- Extent Scan Fragmentation ...................:
4.52%
8.49%
- Extent Scan Fragmentation
- Avg. Bytes Free per Page.....................:
...................: 95.65%
310.0
- Avg. Bytes Free per Page.....................:
- Avg. Page Density (full).....................: 63.7
96.17%
- Avg. Page Density (full).....................:
DBCC execution completed. If DBCC printed
99.21%
error messages, contact your system
administrator. DBCC execution completed. If DBCC
printed error messages, contact your
system administrator.

Figura 5. Resultado do DBCC ShowConfig.

Podemos notar que a fragmentao praticamente nula nesse momento, com


ndices de preenchimento de pgina (Avg. Page Density) superiores a 96%. A
tabela ocupa 2042 pginas; o ndice ix_nonlcluster_Orders, 155.
Submeteremos a tabela temp_Orders um grande volume de remoes de
dados, forando a fragmentao:

/* sero deletadas todas as linhas com OrderId par */


delete from temp_orders where OrderId % 2 = 0
-----------------------------------------------------
(41500 row(s) affected)

Aps as excluses, podemos comprovar a fragmentao de quase 50% nas


pginas da tabela e do ndice, conforme Figura 6.
/* executando o ShowContig nas pginas de /* executando o ShowContig no indice
dados da heap */ ix_noncluster_Orders) */
dbcc showcontig('temp_orders')
dbcc
showcontig('temp_orders','ix_noncluster_O
rders')

Table: 'temp_Orders' (1318295756); index Table: 'temp_Orders' (1318295756); index


ID: 0, database ID: 6 ID: 2, database ID: 6

TABLE level scan performed. LEAF level scan performed.

- Pages Scanned................................: - Pages Scanned................................:


2042 155

- Extents Scanned..............................: 259 - Extents Scanned..............................: 23

- Extent Switches..............................: 258 - Extent Switches..............................: 22


- Avg. Pages per Extent........................: 7.9
- Avg. Pages per Extent........................:
- Scan Density [Best Count:Actual 6.7
Count].......: 98.84% [256:259]
- Scan Density [Best Count:Actual
Count].......: 86.96% [20:23]

- Extent Scan Fragmentation ...................: - Logical Scan Fragmentation ..................:


8.49% 4.52%

- Avg. Bytes Free per Page.....................: - Extent Scan Fragmentation


4180.7 ...................: 95.65%

- Avg. Page Density (full).....................: - Avg. Bytes Free per Page.....................:


48.35% 4079.9

DBCC execution completed. If DBCC printed - Avg. Page Density (full).....................:


error messages, contact your system 49.59%
administrator.
DBCC execution completed. If DBCC
printed error messages, contact your
system administrator.

Figura 6. Fragmentao dos dados causada pela remoo de registros.

Atravs do comando abaixo, a tabela temp_Orders ser submetida a um processo


de reindex.

dbcc dbreindex('temp_Orders')
---------------------------------------------------------------------------------------------
-------
DBCC execution completed. If DBCC printed error messages, contact your system
administrator.

Nota-se que o processo de reindex ir corrigir somente a fragmentao do ndice


ix_noncluster_Orders. Como as pginas de dados numa heap table no esto
associadas a um ndice cluster, o reindex no causar qualquer efeito nelas (ver
Figura 7).
/* executando o ShowContig nas pginas de /* executando o ShowContig no indice
dados da heap */ ix_noncluster_Orders) */
dbcc showcontig('temp_orders')
Dbcc
showcontig('temp_orders','ix_noncluster_O
rders')

DBCC SHOWCONTIG scanning 'temp_Orders' DBCC SHOWCONTIG scanning


table... 'temp_Orders' table...

Table: 'temp_Orders' (1318295756); index Table: 'temp_Orders' (1318295756); index


ID: 0, database ID: 6 ID: 2, database ID: 6

TABLE level scan performed. LEAF level scan performed.

- Pages Scanned................................: - Pages Scanned................................:


2042 77

- Extents Scanned..............................: 259 - Extents Scanned..............................: 10

- Extent Switches..............................: 258 - Extent Switches..............................: 9

- Avg. Pages per Extent........................: 7.9 - Avg. Pages per Extent........................:


7.7
- Scan Density [Best Count:Actual
Count].......: 98.84% [256:259] - Scan Density [Best Count:Actual
Count].......: 100.00% [10:10]

- Logical Scan Fragmentation ..................:


- Extent Scan Fragmentation ...................: 11.69%
8.49%
- Extent Scan Fragmentation
- Avg. Bytes Free per Page.....................: ...................: 0.00%
4180.7
- Avg. Bytes Free per Page.....................:
- Avg. Page Density (full).....................:
11.6
48.35%
- Avg. Page Density (full).....................:
DBCC execution completed. If DBCC printed
99.86%
error messages, contact your system
administrator. DBCC execution completed. If DBCC
printed error messages, contact your
system administrator.
Figura 7. Resultado da reindexao da tabela.

Agora, transformaremos a heap table temp_Orders em uma tabela clusterizada.


Para isso, removeremos o ndice no cluster e criaremos um ndice cluster (ver
Listagem 3).

Listagem 3. Script para remoo do ndice no cluster e criao de um ndice


cluster.
/* dropar o ndice no cluster */
drop index temp_Orders.ix_noncluster_orders
/* criar um ndice cluster */
create CLUSTERED index ix_cluster_orders on temp_orders (orderId)
-----------------------------------------------------------------
The command(s) completed successfully.

A criao do ndice cluster ir desfragmentar as pginas de dados da tabela,


causando reduo no nmero de pginas utilizadas (de 2042 para 1000), devido ao
aumento significativo na densidade das pginas, que subiu de 48.35% para
98.78% (ver Figura 8).

/* executando o ShowContig nas pginas de


dados da heap */
dbcc showcontig('temp_orders')

DBCC SHOWCONTIG scanning 'temp_Orders'


table...

Table: 'temp_Orders' (1350295870); index ID:


1, database ID: 6

TABLE level scan performed.

- Pages Scanned................................: 1000

- Extents Scanned..............................: 126


- Extent Switches..............................: 125

- Avg. Pages per Extent........................: 7.9

- Scan Density [Best Count:Actual Count].......:


99.21% [125:126]

- Logical Scan Fragmentation ..................:


11.00%

- Extent Scan Fragmentation ...................:


15.87%

- Avg. Bytes Free per Page.....................: 99.0


- Avg. Page Density (full).....................:
98.78%

DBCC execution completed. If DBCC printed


error messages, contact your system
administrator.

Figura 8. Resultado da criao de um ndice cluster.

Fica demonstrado porque a existncia de um ndice cluster fundamental nos


processos de desfragmentao das pginas de dados das tabelas. A questo agora
outra: qual seria a melhor escolha para a chave de um ndice cluster?

Escolhendo a chave do ndice cluster


O ndice cluster atua diretamente nas pginas de dados de uma tabela,
organizando as linhas inseridas e/ou alteradas segundo a chave definida. Se o
contedo da coluna que compe o ndice cluster no crescer gradualmente durante
as inseres (por exemplo: 1,2,3 ou 1,10,15) estaremos criando um ambiente
propcio para page-splits (ver Nota 2). Uma boa opo para chave de um ndice
cluster utilizar colunas identity, pois elas possuem crescimento linear garantido.

Nota 2. Page-splits
Os ndices armazenam os dados de forma ordenada. Quando temos um ndice
com chave numrica e realizamos inseres com valores aleatrios (ex:
1,44,10,9,8), o ndice se encarregar de reagrupar a seqncia ordenadamente
(ex: 1,8,9,10,44). Mas o que aconteceria ao tentarmos inserir uma nova
seqncia (exemplo: 2, 3), e a pgina do ndice estivesse cheia, sem espao
para acomodar novas inseres? Nesse caso, aproximadamente metade da
pgina no exemplo os valores 10 e 44 seriam movidos para uma nova
pgina, para acomodar as novas inseres. O que antes cabia em uma nica
pgina, agora est distribudo em duas pginas: (no exemplo: 1,2,3,8,9 e
10,44). Page-Split o termo utilizado para explicar uma diviso de pgina de
ndice (cluster ou no cluster) para acomodar uma insero pontual.

Concluso
Vimos que tabelas com grande nmero de linhas esto mais sujeitas a problemas
de performance. Se a tabela for uma heap, o problema pode estar relacionado
fragmentao. A soluo, nesse caso, escolher uma chave adequada e criar um
ndice cluster para a tabela. Caso no exista uma chave adequada, uma identity
poder ser criada para esse fim.
Um grande abrao e at a prxima!

Variveis Bind
Uma viso prtica
O uso de instrues SQL pela maioria das linguagens de programao e sistemas
gerenciadores de banco de dados pode ser parametrizado de forma eficiente e
segura, atravs das bind variables, ou variveis de ligao, podendo ser utilizadas
nos comandos SELECT, UPDATE, DELETE e INSERT. Variveis de ligao funcionam
como parmetros em instrues SQL possibilitando a atribuio de valores
dinmicos. Na execuo de instrues SQL comum usar parmetros para
selecionar ou atualizar dados atravs das clusulas where, values ou set.
H uma semelhana muito grande de uma mesma instruo SQL elaborada com
variveis de ligao ou valores fixos ambos usados como parmetros. Mas a
semelhana s na escrita dos comandos ou instrues SQL. Na verdade, a
diferena existe na execuo destes comandos no servidor de banco de dados.
Quando uma instruo SQL elaborada com varivel de ligao ocorre apenas a
leitura e substituio do valor atribudo varivel de ligao, e caso a instruo
SQL j esteja na memria do servidor de banco de dados ocorre o retorno ou
atualizao dos dados, sem ter que passar pelas etapas de preparao e execuo
da instruo, ou seja, com o uso de variveis de ligao permitido o reuso de
instrues SQL j armazenadas em memria. Se uma instruo SQL for executada
atravs de parmetros com valores fixos ou strings concatenadas atravs de
alguma linguagem de programao, o servidor de banco de dados ir sempre
refazer e executar sempre uma nova instruo SQL.
bom lembrar que parmetros usados em instrues SQL podem ser valores
fixos, variveis concatenadas atravs de alguma linguagem de programao e
tambm variveis de ligao.
possvel definir varivel de ligao de diversas maneiras. Serve de ponte para a
execuo de uma instruo SQL j preparada na memria do servidor, onde so
enviados apenas os valores nela contidos.
O uso dessas variveis no desenvolvimento de sistemas de informao permite
maior segurana e eficincia na manipulao de dados, sendo suportadas pela
maioria das linguagens de programao, entre elas o Visual Basic, C++ Builder e
Java. Alguns sistemas gerenciadores de banco de dados tambm permitem o uso
de variveis de ligao na construo de funes e procedimentos armazenados
(stores procedures), como por exemplo, o Oracle.
O foco deste artigo conceituar e exemplificar o uso de variveis de ligao
utilizando o SGBD Oracle atravs de sua linguagem PL/SQL, e tambm atravs da
linguagem Java.
Para os exemplos apresentados nesse artigo, utilizaremos o modelo de dados
apresentado na figura 1.

Figura 1. Modelo de dados usado nos exemplos e listagens citadas ao longo do


artigo.
Memria compartilhada no Oracle
A estrutura de memria compartilhada, ou shared pool, contm informaes
usadas para executar comandos SQL. Essa estrutura formada por reas
reservadas na memria, denominadas shared SQL e Data Dictionary.
A rea identificada como shared SQL contm:
O texto dos comandos SQL;
A interpretao dos comandos SQL;
O plano de execuo para os comandos SQL.

O compartilhamento dos planos de execuo dos diversos comandos nessas reas


de memria otimiza o uso da memria, uma vez que as definies dos comandos
podem ser compartilhadas entre as diversas aplicaes.

A memria tambm dinamicamente ajustada de acordo com o conjunto de


comandos SQL que so executados e, como a fase de PREPARE reduzida, o tempo
de execuo de um comando pode diminuir consideravelmente.

Na rea de memria identificada como data dictionary, so identificadas as linhas


com as informaes do dicionrio de dados.

Processo de execuo de um comando para manipulao de dados


Para entender os fundamentos do uso de variveis de ligao,
importante compreender como feita a execuo das instrues SQL
de manipulao de dados. O Oracle, assim como a maioria dos
sistemas gerenciadores de banco de dados, executa as instrues
SQL em vrias fases. A Tabela 1 mostra cada instruo e sua fase de
execuo no servidor de banco de dados.

INSTRU FASE DE EXECUO


O
1 FASE 2 FASE 3 FASE
SELECT PREPARE EXECUTE FETCH
UPDATE PREPARE EXECUTE -
INSERT PREPARE EXECUTE -
DELETE PREPARE EXECUTE -
Tabela 1. Fases da execuo das instrues SQL.

Como pode ser visto na Tabela 1, apenas o comando SELECT passa


pela fase FETCH. Cada fase tem uma caracterstica fundamental na
execuo de um comando SQL, sendo que o incio de uma fase
depende do trmino da execuo da fase anterior. A seguir so
citados conceitos bsicos sobre estas fases:

Prepare

Durante a fase PREPARE, a instruo SQL enviada pelo usurio para o servidor de

banco de dados para ser analisada. Em seguida, carregada na rea de


compartilhamento do SQL. Este processo de anlise e preparao do SQL consiste

em:

Validao da sintaxe do comando SQL;


Pesquisa no dicionrio de dados, verificando a definio de tabela e colunas;
Bloqueio sobre as definies dos objetos requeridos, para que no sejam
alterados durante a fase da anlise;
Checagem dos privilgios de acesso aos objetos referenciados;
Determinao do plano timo de execuo da instruo;
Carregamento da instruo na rea compartilhada do SQL;
Para instrues distribudas, roteamento de todas as suas partes aos ns
remotos que contm dados referenciados.

A instruo SQL analisada somente no caso de no existir uma outra idntica


na rea de compartilhamento do SQL, gerando assim a alocao de uma nova
rea de compartilhamento para armazen-la. A fase da anlise executada
apenas uma vez, independentemente da quantidade de vezes que a instruo
executada, desde que esteja na rea de compartilhamento do SQL.

Execute

Nesta fase, o servidor de banco de dados j tem todos os recursos e informaes


necessrias para executar a instruo. Caso a instruo seja um comando SELECT
ou INSERT, nenhuma linha precisa ser bloqueada, j que nenhum dado est sendo
alterado. Caso a instruo seja UPDATE, DELETE, SELECT FOR UPDATE ou com
WITH LOCK, todas as linhas afetadas pela instruo so bloqueadas, impedindo que
outros usurios as alterem at o prximo COMMIT, ROLLBACK ou SAVEPOINT da
transao, garantindo assim, a integridade do dado.

Fetch

Nesta fase, as linhas que satisfizerem ao resultado de uma consulta so

recuperadas e enviadas para a aplicao que as requisitou.

Aps a execuo de um comando SQL, o servidor de banco de dados


armazena em memria o comando executado, deixando-o pronto e
preparado para uma nova execuo.
Variveis bind usadas como parmetros da instruo SQL
Durante a execuo de uma instruo SQL, podemos definir condies de
filtragem dos dados atravs da clusula WHERE. As variveis de ligao so usadas
como parmetro na execuo das instrues SQL, substituindo os valores fixos nas
comparaes.
A grande vantagem de usar as variveis de ligao de aproveitar os comandos
SQL j preparados na memria do servidor, no precisando valid-los.
As Listagens 1 e 2 apresentam um exemplo do uso de varivel de ligao,
comparado ao comando SQL normalmente usados:
Listagem 1. Instruo SQL sem o uso de varivel de ligao
SELECT CODCLIE, NMCLIE, ENDECLIE, CEPCLIE FROM CLIENTES WHERE NMCLIE
= VIVIAM;
SELECT CODCLIE, NMCLIE, ENDECLIE, CEPCLIE FROM CLIENTES WHERE NMCLIE
= EVALDO;

Listagem 2. Instruo SQL com o uso de varivel de ligao


SELECT CODCLIE, NMCLIE, ENDECLIE, CEPCLIE FROM CLIENTES WHERE NMCLIE
= :vNMCLIE;

Se o servidor de banco de dados fosse executar os comandos da


Listagem 1, faria a leitura, preparao e a execuo de duas
instrues SQL. O motivo disso a variao do valor passado na
clusula WHERE. Na execuo do comando da Listagem 2,
estaramos atribuindo ao parmetro vNMCLIE, atravs da linguagem
de programao utilizada, os valores VIVIAM e EVALDO, fazendo com
que o servidor aproveite a mesma instruo em memria, tornando
mais rpida a consulta.
Podemos deduzir que poder haver um ganho considervel de
performance com o SQL j preparado quando usada a varivel de
ligao, ou seja, so usados de forma sensata os recursos oferecidos
pelo servidor.
Instrues SQL seguras com o uso de variveis de ligao
Outro aspecto importante para o uso de variveis de ligao, a
criao de instrues SQL vlidas, evitando possveis erros na
execuo. Nessa seo do artigo, exemplificarei situaes onde a no
utilizao de parmetros pode causar problemas, mostrando tambm
como esses problemas podem ser solucionados atravs da utilizao
de parmetros.
Suponha que seja elaborada uma consulta relacionando as tabelas de
CLIENTES e FITAS atravs dos campos CODCLIE e CODFITA, como
mostrado na Listagem 3.

Listagem 3. Comando SQL com valores texto comparados na clusula WHERE.


SELECT FIT.NMFITA AS FITA, CLIE.NMCLIE_AS CLIENTE,
TO_CHAR(EMP.DT-HR-ALUG-FITA, DD/MM/YYYY) AS DT-ALUG-FITA,
EMP.DT-DEVL-FITA
FROM CLIENTES CLIE, FIT
WHERE EMP.CODCLIE = CLIE.CODCLIE AND
EMP.CODFITA = FIT.CODFITA AND
CLIE.CODCLIE = 1234 AND
FIT.CODFITA = DR0101;

Quando o comando select for enviado atravs de uma aplicao, ele


poder ser montado dinamicamente, indicando os valores
responsveis pela seleo dos registros atravs da clusula where. A
Listagem 4 mostra um exemplo de construo de um comando
select semelhante ao da Listagem 3, em Java, montado atravs da
concatenao de strings.

Listagem 4. Exemplo de concatenao de string usando a linguagem JAVA.


SELECT FIT.NMFITA AS FITA, CLIE.NMCLIE_AS CLIENTE, TO_CHAR(EMP.DT-HR-
ALUG-FITA, DD/MM/YYYY)
+ AS DT-ALUG-FITA, EMP.DT-DEVL-FITA FROM CLIENTES CLIE, FIT WHERE
EMP.CODCLIE = CLIE.CODCLIE
+ AND EMP.CODFITA = FIT.CODFITA AND CLIE.CODCLIE = +
stg_CLIE_CONS +
+ AND FIT.CODFITA = + stg_FITA_CONS +

Nos exemplos das consultas apresentadas nas Listagens 4 e 5,


devemos atentar para a validao da sintaxe do comando SQL
montado, para evitar possveis erros na execuo. Isto porque a
concatenao de strings pode gerar problemas de sintaxe caso algum
dos strings possuam caracteres especiais, como por exemplo, as
aspas simples ().
As figuras 2 e 3 mostram um exemplo utilizando a linguagem Java
para simular a digitao de aspas simples e o erro ocasionado.

Listagem 5. Execuo de um comando SQL sem a utilizao de variveis de


ligao.

Statement instSQL = con.createStatement();

ResultSet retornoRes = instSQL.executeQuery(


"SELECT CLIE.NMCLIE AS CLIENTE, FT.DCFITA AS FITA, FT.PRALUG
AS VALOR_ALUGUEL, "
+"EMP.DTHRALUGFITA AS DATA_ALUGUEL, EMP.DTDEVLFITA AS
DATA_DEVOLUCAO FROM Emprestimos AS EMP, "
+"Clientes AS CLIE, Fitas AS FT "
+"WHERE FT.CODFITA = EMP.CODFITA AND EMP.CODCLIE =
CLIE.CODCLIE "
+"AND CLIE.CODCLIE = " + getCodClie() + " AND FT.CODFITA =
" + getCodFita() + "");

retornoRes.next();
Figura 2. Formulrio de exemplo usado para simular digitao de aspas simples
usando o cdigo da listagem 5.

Figura 3. Erro retornado pelo Oracle na digitao de aspas simples.

Os exemplos indicados mostram a vulnerabilidade do uso de strings


de contedo dinmico na montagem de instrues SQL.
O uso de variveis de ligao soluciona os problemas relacionados
acima, porque no existe a necessidade de concatenar strings. A
varivel de ligao fica fixa na instruo SQL, preparada pela
linguagem de programao. O valor que atribudo varivel de
ligao configurado pela linguagem de programao responsvel
por enviar a instruo SQL para o servidor de banco de dados. As
variveis de ligao no precisam de tratamento de caracteres
especiais em strings e eliminam a possibilidade de adulterao do
comando SQL, mantendo a integridade das consultas existentes.
Nas prximas sees so exemplificados os usos de variveis de
ligao juntamente com a linguagem Java, reforando a afirmao
anterior.
Usando variveis de ligao com Java
Para usar variveis de ligao na linguagem Java, preciso usar comandos
preparados ou Prepared Statement. O comando preparado no Java indicado
quando uma instruo SQL executada vrias vezes. Neste caso, melhor
compilar o texto de instruo SQL uma nica vez, e sempre que for necessrio
execut-lo, basta utilizar a instruo j compilada.
Um comando preparado criado atravs de um objeto PreparedStatement, por
meio do mtodo prepareStatement() de um objeto Connection, passando como
argumento a instruo SQL. A Listagem 6 mostra um exemplo do uso do comando
preparado no Java.

Listagem 6. Execuo de um comando preparado no Java.


//strSQL uma varivel do tipo String.
//con um objeto Connection.

stgSQL = "SELECT CLIE.NMCLIE AS CLIENTE, FT.DCFITA AS FITA, FT.PRALUG AS


VALOR_ALUGUEL, "

+"EMP.DTHRALUGFITA AS DATA_ALUGUEL,
EMP.DTDEVLFITA AS +"DATA_DEVOLUCAO
FROM EMPRESTIMOS AS EMP, "

+"CLIENTES AS CLIE, FITAS AS FT "

+"WHERE FT.CODFITA = EMP.CODFITA NA


DEMP.CODCLIE = +"CLIE.CODCLIE "
+"AND CLIE.CODCLIE =? AND FT.CODFITA =
?";

PreparedStatement stmt = con.prepareStatement(stgSQL);

stmt.clearParameters();

stmt.setString(1, getCodClie());

stmt.setString(2, getCodFita());

ResultSet consRetorno = stmt.executeQuery();

consRetorno.next();

Na Listagem 6, alm da execuo do comando preparado, bom


observar que foi usado o caractere ? representando o parmetro da
consulta. Antes de selecionar os parmetros necessrio limp-los
atravs da funo clearParameters. Para selecionar estes parmetros,
so utilizados mtodos correspondentes ao tipo de dado que ser
passado. No exemplo mostrado, foi usado o mtodo setString para os
dois parmetros. Estes mtodos recebem como parmetros o ndice
da ocorrncia do caractere ?, que ser substitudo pelo valor. O
segundo parmetro o valor que ser passado instruo SQL
atravs do mtodo getCodClie().
Na prxima seo o artigo mostra como possvel usar variveis de
ligao no desenvolvimento de rotinas atravs da linguagem PL/SQL
do SGBD Oracle.
Executando instrues SQL com variveis de ligao usando a
linguagem PL/SQL
A linguagem procedural PL/SQL tambm permite a utilizao de
variveis de ligao na execuo de instrues SQL. comum usar
variveis de ligao em procedimentos armazenados (store
procedures) visando melhorar a performance de execuo das
instrues SQL. Este item do artigo visa mostrar alguns comandos e
exemplos em PL/SQL com o uso de variveis de ligao.
A linguagem PL/SQL oferece o comando EXECUTE IMMEDIATE como
recurso para a execuo de instrues SQL usando variveis de
ligao. Para utilizar este comando necessrio declarar uma
varivel do tipo texto que ter como contedo uma string da
instruo SQL a ser executada. Esta string contm marcadores de
lugar que so identificados por dois pontos. Os marcadores de lugar
so correspondidos por posio com as variveis PL/SQL que se
encontram na clusula USING do comando EXECUTE IMMEDIATE. A
seguir as listagens 7, 8 e 9 mostram a utilizao do comando.

Listagem 7. Sintaxe comando EXECUTE IMMEDIATE.

EXECUTE IMMEDIATE variavel_string [INTO {varivel[, varivel]...| record}]


[USING [IN | OUT | IN OUT] bind_argument [, [IN | OUT | IN OUT]
bind_argument]...];

Listagem 8. Execuo de uma instruo SQL usando o comando


EXECUTE IMMEDIATE.

v_STRING_SQL:= 'INSERT INTO FITAS (CODFITA, DCFITA, PRALUG) VALUES


(:codfita, :desc, :precoalug)';
EXECUTE IMMEDIATE v_STRING_SQL USING '1', 'VAL HELSING', 3.50;

v_STRING_SQL:= 'INSERT INTO FITAS (CODFITA, DCFITA, PRALUG) VALUES (:1,


:2, :3)';
EXECUTE IMMEDIATE v_STRING_SQL USING '2', 'CAZUZA', 3.00;

Listagem 9. Execuo de uma instruo SQL usando o comando


EXECUTE IMMEDIATE retornando valor.

v_STRING_SQL:='SELECT COUNT(1) FROM FITAS WHERE DCFITA = :desc';


EXECUTE IMMEDIATE v_STRING_SQL INTO v_QTDE_FITA USING 'VAL HELSING';

Nota: Os marcadores de lugar no precisam ser declarados. O nome dado ao


marcador pode ser um nmero representando a posio do valor a ser atribudo na
clusula USING.

Tambm possvel usar variveis de ligao na abertura de cursores. As


consultas so executadas utilizando a instruo OPEN FOR. O comando OPEN FOR
tambm usa a clusula USING para a atribuio de valores assim como o comando
EXEUCTE IMMEDIATE. A listagem 10 mostra o exemplo de utilizao do comando
OPEN com varivel de ligao.

Listagem 10. Utilizao do comando OPEN FOR na abertura de


cursor usando varivel de ligao.

CREATE OR REPLACE PACKAGE PA_LOCADORA AS

TYPE tp_CURSOR IS REF CURSOR;


FUNCTION RETORNACLIENTE(v_CLIENTE IN VARCHAR2)
RETURN tp_CURSOR;
END PA_LOCADORA;

CREATE OR REPLACE PACKAGE BODY PAB_LOCADORA AS

FUNCTION RETORNACLIENTE(v_CLIENTE IN VARCHAR2)


RETURN tp_CURSOR
IS

v_Retorno_Cursor tp_CURSOR;
v_STRING_SQL VARCHAR2(500);

BEGIN

v_STRING_SQL := 'SELECT * FROM CLIENTES WHERE


NMCLIENTE = :clie';
OPEN v_Retorno_Cursor FOR v_STRING_SQL USING
v_CLIENTE;
RETURN v_Retorno_Cursor;

END RETORNACLIENTE;

END PAB_LOCADORA;

Concluso
O uso de variveis de ligao fornece ganho e eficincia junto s aplicaes de
banco de dados, dispensando a fase de preparao de instrues SQL que so
executadas vrias vezes. Alm disso, o uso de variveis de ligao permite maior
segurana na execuo de SQL pelos sistemas de informao. possvel concluir
que sempre que possvel, vantagem utilizar variveis de ligao.

Bibliografia

OLIVEIRA, Alcione de Paiva, MACIEL, Vincius Valente. Java na


prtica, tpicos avanados: RMI CORBA JDBC threads redes
servlets JSP. Viosa : Fbrica de Livros Ed. 2003.
THOMPSON, Marco Aurlio. JAVA 2 & Banco de Dados: Aprenda
na prtica a usar JAVA e SQL para acessar bancos de dados
relacionais. So Paulo: rica, 2002.

DVILA, Mrcio. Eficincia e Segurana com SQL


parametrizado.
Disponvel on-line em http://www.mhavila.com.br/topicos/bd/sqlbind.html

FILHO, Gesualdo Saudino. A arquitetura do ORACLE.

Disponvel on-line em
http://www.linhadecodigo.com.br/artigos.asp?id_ac=99&sub=0

Evaldo de Oliveira da Silva (engine@powermail.com.br; eos@mrs.com.br) Analista


de Sistemas, Especialista em Cincia da Computao pela Universidade Federal de Viosa.
Atualmente prestador de servios na rea de desenvolvimento de sistemas da MRS
Logstica S.A .Desenvolve aplicaes em Visual Basic utilizando Oracle. Tem como rea de
interesse banco de dados geogrficos, Sistemas de Informaes Geogrficas, Anlise
Orientada a Objetos e o desenvolvimento de aplicaes usando a linguagem JAVA.

10 passos para a
criao de um
modelo de banco de
dados - Parte II
Na primeira parte deste artigo apresentamos a execuo dos dez passos para
elaborar um modelo conceitual bsico de banco de dados. No entanto, a
modelagem tradicional nem sempre adequada para representar determinados
esquemas de banco de dados. Como exemplo, podemos citar a modelagem
orientada a objetos, onde necessrio explicitar: herana; hierarquia de
relacionamento; agregao e outros conceitos tpicos. Utilizaremos um dos
exemplos j apresentados no primeiro artigo para demonstrar a aplicao do
roteiro dos 10 passos na modelagem orientada a objetos. Acreditamos que desta
forma ser mais fcil ao leitor comparar os diferentes tipos de modelagem.
Utilizaremos o diagrama de classes da UML, normalmente utilizado no projeto de
softwares, e que tem sido largamente utilizado para representar esquemas
orientados a objetos. Essa escolha tambm tem motivao no fato desta linguagem
de modelagem j ter sido bastante tratada em outras edies da SQL Magazine.
Podemos citar a edio 14 da SQL Magazine que contm um excelente artigo
Aprenda UML na prtica. O artigo Desenvolvimento de aplicaes orientadas a
objeto apoiado por tecnologias Java, publicado na edio de nmero 14, tambm
trata os conceitos relacionados orientao a objetos.
Inicialmente vamos relembrar o estudo de caso apresentado no primeiro artigo
desta srie.

Estudo de caso
Uma escola deseja disponibilizar em uma intranet as notas de seus alunos por
matria e por bimestre, sendo que um semestre sempre ter duas notas bimestrais
e a mdia final do semestre ser calculada pelo sistema. Na pgina, o aluno poder
visualizar o cdigo da matria, a descrio da matria, bimestre, nota e no final do
semestre a respectiva mdia final. Tambm poder consultar quais matrias cursa
no semestre, e respectivos professores. J o professor pode visualizar quais
matrias leciona em cada curso e lanar as notas de cada aluno. A escola tambm
deseja extrair relatrios ou pesquisas sobre as matrias que o aluno cursa e vice-
versa e ainda, quais professores lecionam que matria e vice-versa. Para que no
haja confuso entre matrias com mesmo nome, mas em cursos e contedos
diferentes, e ainda considerando que podem existir vrias turmas do mesmo curso
no mesmo semestre, todas as matrias possuiro um cdigo prprio que a
distinguir por curso e por turma. Assim matemtica I da turma A do curso de
administrao ter um cdigo de matria diferente de matemtica I do mesmo
curso de administrao da turma B. Ser diferente tambm da matemtica I de
qualquer outro curso. Desta forma cada cdigo de matria ter somente um
professor responsvel.

Roteiro dos 10 passos


1) Identificando todos os substantivos que designem objetos
Resultado: escola, intranet, nota, aluno, matria, bimestre, semestre,
sistema, pgina, cdigo da matria, descrio da matria, mdia final do semestre,
curso, professor, relatrio, pesquisa, matemtica I, administrao, computao.

2) Descartando substantivos que como classe teriam apenas uma


instncia.
Resultado: Escola.

3) Descartando substantivos que servem apenas para entendimento do


problema
Resultado: intranet, semestre, sistema, matemtica I, administrao.

4) Descartando objetos que so referncia a uma futura aplicao


Resultado: mdia final do semestre, relatrio, pgina, pesquisa.

5) Descartando substantivos que se transformados em classes teriam


apenas um atributo
Resultado: bimestre, cdigo da matria, descrio da matria.

6) Listando os substantivos que se tornaro classes e identificando


superclasses
Resultado: curso, aluno, matria, nota, professor, turma. A superclasse pessoa
ser criada para demonstrar a generalizao do que comum entre aluno e
professor, que mantero apenas seus atributos e operaes especficas.
7) Identificando os relacionamentos fsicos e definindo seus tipos,
atravs de verbos ou preposies que demonstrem as relaes entre
as classes.
Resultado: aluno possui nota, matria tem nota, aluno cursa matria,
professor leciona matria, matria pertence a curso, aluno e professor herdam
de pessoa.

8) Estabelecendo o grau de relacionamento entre as classes

Aluno, Matria e Professor tm relaes associativas entre si.

Turma e Matria fazem parte de Curso e por isso esto agregadas a ela.

Pessoa uma superclasse criada para representar os atributos comuns e que


sero herdados por Aluno e Professor. Observamos ento que ocorreu uma
generalizao em Pessoa e uma especializao em Aluno e Professor.
A nota no pode pertencer individualmente a Aluno nem a Matria. Por isso, a
Nota existir para associar as outras duas entidades e representar seus atributos. A
Figura 1 apresenta o diagrama de classes que construmos com as informaes
extradas at agora.
As denominaes entity no topo e persistent no rodap das classes, significam
que estas classes modelam dados de forma persistente. Equivale a entidade do
modelo de banco de dados relacional. Para obter maiores explicaes sobre os
diversos tipos de classes, sugerimos consultar os artigos j mencionados que
tratam de UML e tambm a extensa bibliografia existente sobre o assunto.
Figura 1. Desenho do modelo conceitual demonstrando os tipos e graus de
relacionamentos entre as entidades.

9) Estabelecendo a cardinalidade e multiplicidade do relacionamento


entre as classes

Resultado:

Aluno e Professor so subclasses de Pessoa

Ento: Aluno e Professor herdam de Pessoa

1 Aluno pode cursar nenhuma ou muitas matrias

1 matria pode ser cursada por nenhum ou muitos alunos

Ento: 0..* Aluno 0..* Matria

1 Aluno pode cursar nenhuma ou muitas matrias

1 matria pode ser cursada por nenhum ou muitos alunos

Ento: 0..* Aluno 0..* Matria

1 Turma faz parte de apenas 1 Curso

1 Curso pode ter zero ou muitas turmas

Ento: 1..1 Curso 0..* Turma

1 Matria faz parte de apenas 1 Curso

1 Curso deve ter 1 ou muitas Matrias

Ento: 1..1 Curso 1..* Matria

1 Nota resultado da relao entre 1 Aluno e 1 Matria

1 Aluno em cada Matria tem zero ou muitas notas

Ento: 1 Aluno 1 Matria - 1..* Notas

A Figura 2 apresenta o diagrama de classes ajustado com as informaes de


multiplicidade.
Figura 2. Desenho do diagrama de classes representando o modelo com a
cardinalidade dos relacionamentos.

10) Identificando os atributos de cada entidade

Resultado:

Pessoa = nome, endereo, telefone

Aluno = registro_aluno

Matria = cdigo_matria, nome_matria

Nota = avaliao nota

Professor = registro_professor

Curso = cdigo_curso, nome_curso

Turma = cdigo_turma, nome_turma

A Figura 3 apresenta o diagrama de classes ajustado com os atributos


identificados.
Figura 3 Modelo Conceitual contendo os atributos de cada entidade.

Notem que no adicionamos nenhum mtodo/operao s classes acima, pois


estes representam o comportamento dos objetos modelados, no fazendo parte,
portanto, dos objetivos deste artigo.
O smbolo + ao lado de cada atributo estabelece que esse atributo pblico e
desta forma ser totalmente acessvel para mtodos/operaes de outras classes
que estejam associadas. A preocupao que temos em tornar os atributos pblicos
ou privados remete-nos aos conceitos de encapsulamento, que no tratamos neste
artigo porque no afetam a demonstrao da aplicao do roteiro dos dez passos.
Para maiores informaes sobre esses conceitos sugerimos consultar os artigos j
publicados na SQL Magazine, dentre os quais aqueles j citados no incio deste
artigo.

Concluso
A aplicao do roteiro dos dez passos no primeiro artigo desta srie, onde
utilizamos o diagrama Modelo Entidade-Relacionamento (MER), e nesta segunda
parte, na qual utilizamos o diagrama de classes, apresenta basicamente duas
importantes diferenas:
A criao da classe PESSOA que generaliza os atributos comuns entre
PROFESSOR E ALUNO. Desta forma PROFESSOR E ALUNO especializam seus
atributos exclusivos e herdam os atributos que lhe so comuns de PESSOA;
A utilizao do conceito de agregao para demonstrar que neste exemplo,
MATRIA e TURMA so partes de CURSO.

Generalizao, especializao, agregao e herana so conceitos tpicos de


modelagem orientada objetos e no poderiam ser representados pelo tradicional
Modelo Entidade-Relacionamento. De resto, observamos que a utilizao do roteiro
dos dez passos basicamente a mesma, qualquer que seja o projeto de banco de
dados que se deseja modelar.
Por fim, frisamos novamente que o roteiro dos dez passos deve ser considerado
uma trilha e no um trilho. Muitos outros conceitos devem ser considerados e
utilizados. Nosso objetivo resume-se a procurar demonstrar de forma simples e
rpida, como sistematizar uma primeira modelagem de um banco de dados e a
partir da executar os refinamentos necessrios.

Bibliografia
Elmasri, Ramez, e Navathe S.B., Sistema Gerenciador de Banco de Dados,
Editora LTC, 3 edio, 2000, Rio de Janeiro.
Korth, H.F. e Silberschatz, A.; Sistemas de Bancos de Dados, Makron Books, So
Paulo, 1994.
Date, C.J.; Int. a Sistemas de Bancos de Dados, Editora Campus, 1999, Rio de
Janeiro.
Furlan, Jos Davi, Modelagem de Objetos atravs da UML, Makron Books, So
Paulo, 1998.
Jos Ferreira Prata (jose@infortex.com.br) formado em Administrao de
Empresas, mestre em Engenharia Eltrica com nfase em Computao pela
Universidade Mackenzie, professor das disciplinas de banco de dados, linguagem de
programao, engenharia de software e anlise orientada a objetos no Centro
Universitrio Uninove, Universidade Bandeirantes, Universidade Santo Amaro e
Faculdade So Luis.

Dados de natureza
espacial e o Oracle
Spatial
Com esta matria iniciamos uma srie de artigos sobre dados de natureza
espacial e sua manipulao em sistemas de informaes geogrficas (SIG ou GIS).
Neste primeiro artigo apresentaremos os conceitos bsicos do geoprocessamento e
mostraremos que os dados de natureza espacial j so suportados pelo Oracle. Nos
artigos que seguiro esta srie, mostraremos as tcnicas de modelagem desses
dados e terminaremos com um artigo que mostrar ao leitor algumas utilidades e
aplicaes para os SIGs.
Ao citarmos o termo dados espaciais muitas pessoas imaginam que so dados
oriundos do espao sideral, e no que so dados de natureza espacial. O espao
ento aqui referido o espao fsico que nos cerca, a superfcie da Terra, dos
continentes, dos pases, dos estados, das cidades, dos bairros ou das regies
poltico-administrativas de um pas, por exemplo.
O mundo do geoprocessamento
Segundo Rodrigues, geoprocessamento pode ser definido como o conjunto de
tecnologias de coleta e tratamento de informaes espaciais, e o desenvolvimento,
e uso, de sistemas que as utilizam. Para tratamento de dados geogrficos e de
localizao, necessitamos geocodificar tais dados. Rodrigues definiu geocodificar
como prover referncias espaciais passveis de tratamento automatizado. Para tal
tratamento automatizado, podemos classificar os dados que sero armazenados
nos sistemas computacionais como alfanumricos e espaciais, sendo que uma
entidade do mundo real pode possuir ambos tipos de dados associados a seus
atributos.
Dados alfanumricos so os associados a caractersticas descritivas dos seres ou
das coisas do mundo real, como nome, endereo, cdigo, salrio e etc; a grosso
modo so dados cujos valores esto no domnio dos caracteres e nmeros.
J os dados espaciais so aqueles que possuem uma referncia espacial. A
referncia espacial aqui referida a localizao do dado e sua representao. A
localizao est relacionada a um sistema de referncia, ou seja, de coordenadas.
O leitor pode fazer por exemplo uma simples aluso ao plano XY to famoso
durante o perodo escolar. A Figura 1 exemplifica a localizao de um ponto sobre
um plano XY.

Figura 1. Exemplo de localizao de um ponto num plano cartesiano.

A representao geomtrica mais usada para a superfcie da Terra um elipside.


Sobre o elipside um ponto pode ser localizado, por exemplo, pelas coordenadas
geodsicas, as famosas latitute e longitude, ou por coordenadas cartesianas
(X,Y,Z). Existem diversos elipsides definidos para uso em sistemas de
coordenadas, pode-se citar por exemplo o SAD-69 e o WGS-84.
Alm da localizao, os dados espaciais possuem uma forma de representao
geomtrica. Tal forma pode ser um ponto, um crculo, um retngulo, uma linha e
assim por diante. O leitor deve atentar-se ao fato de que para cada necessidade, ou
seja, para cada finalidade de processamento, uma mesma entidade do mundo real
pode ser representada de formas diferentes. Por exemplo, podemos representar as
ocorrncias dos casos de dengue em um municpio como sendo crculos ou pontos,
dependendo do tipo de consulta a qual os dados sero submetidos ou mais
especificamente, aos propsitos que o sistema se destina. Desse modo, podemos
definir dados espaciais como dados com localizao e uma forma geomtrica
associada. Como foi dito, uma entidade do mundo real pode ter ambos os tipos de
dados. Por exemplo, a uma casa podem ser associados os dados alfanumricos:
rua, nmero e bairro, assim como um retngulo para a representao espacial.
So duas as formas de representar dados espaciais, a forma raster e a forma
vetorial. Raster ou matricial a forma de representao dos dados espaciais na
forma de imagens, as quais so divididas em clulas, na maioria das vezes
quadradas, e nas quais um valor associado determina a intensidade de sua cor. J
a representao vetorial aquela na qual as entidades espaciais so representadas
por um conjunto de traos ou vetores referenciados atravs de coordenadas. As
Figuras 2 e 3 mostram exemplos de representao raster e vetorial.

Figura 2 - Representao raster.

Figura 3. Representao vetorial.


Sobre os dados espaciais podemos identificar relacionamento entre eles, os quais
chamamos de topologia. Dentre esses relacionamentos espaciais, podemos citar:
esquerda de, direita de, acima (mais alto que, sobre), abaixo de (sob), atrs de,
prximo a, longe de, ao lado de (adjacente a), tocando em, dentro de, fora de e
entre. Em um mapa podemos perceber esses relacionamentos entre as
representaes. Por exemplo, entre os estados temos o relacionamento de
adjacncia. Numa representao de rodovia temos o relacionamento pertence entre
as placas e o eixo da rodovia.

Sistemas de informaes geogrficas


Um SIG um sistema computacional que permite captar, modelar, manipular,
recuperar, consultar, analisar e apresentar solues com dados geograficamente
referenciados. A consulta aos dados pode ser feita sobre os atributos alfanumricos
ou sobre sua localizao. Uma consulta sobre atributos alfanumricos responde
questes do tipo quais cidades possuem mais de 50.000 habitantes? . J uma
consulta espacial (ou topolgica) responde questes como quais so os postos de
gasolina mais prximos da minha residncia, num raio de 2Km? .
Existem diversos tipos de sistemas que manipulam dados espaciais, como os
sistemas de cartografia automatizada e os sistemas de CAD (Computer Aided
Design). Entretanto, os SIGs se diferenciam desses sistemas por dois motivos
principais. Primeiro por sua capacidade de representar os relacionamentos espaciais
(topolgicos) entre as representaes espaciais do que existe no mundo real.
Segundo, por permitir a realizao de complexas operaes de anlise espacial.
Os primeiros SIGs eram sistemas sem a capacidade de compartilhar ou gerenciar
os dados eficientemente. Tais sistemas eram desenvolvidos com funes genricas
dificultando o aprendizado e o uso. Com o avano tecnolgico, os SIGs evoluram
as capacidades de armazenamento e recuperao dos dados geogrficos. A
primeira arquitetura que marcou esse avano foi a arquitetura dual. Essa
arquitetura baseia-se no uso de duas bases de armazenamento; uma para
armazenamento de dados alfanumricos e outra para armazenamento de dados de
natureza espacial. Como citado anteriormente, os grandes gerenciadores do
mercado de banco de dados voltaram atenes aos dados de natureza espacial e a
partir disso comearam a surgir as extenses espaciais dos sistemas de banco de
dados, e a partir dessas extenses da arquitetura passou a ser chamada de
arquitetura integrada, ou seja, uma nica base de dados para armazenamento dos
dados de natureza alfanumrica e espacial.
O pioneiro dentre os principais bancos comerciais foi o Oracle, que a partir da
verso 8i possibilitava a incluso do cartucho Oracle Spatial para o tratamento
desse tipo de dado. Tambm podemos citar o DB2 Spatial Extender e o PostGis
para PostgreSQL.

O Oracle Spatial

A Oracle foi uma, seno a primeira, das grandes empresas fabricantes de


sistemas gerenciadores de banco de dados a direcionar esforos para o tratamento
de dados de natureza espacial atravs do Oracle Spatial. A primeira verso do
Spatial surgiu com a release 8i do Oracle, que ao tornar-se um banco de dados
objeto relacional permitiu o armazenamento de tipos de dados complexos.

O Spatial um cartucho, como a prpria Oracle o define, que pode ser agregado
ao banco (na verso enterprise) para estend-lo disponibilizando tipos e funes
para o tratamento dos dados espaciais. Em outras palavras, o Spatial disponibiliza
um conjunto de formas geomtricas para definio das colunas das tabelas para
representao espacial assim como funes que realizam consultas espaciais sobre
essas representaes.

Na release 8i do Oracle, o Spatial no acompanhava a instalao padro do


banco de dados, j a partir da release 9i, ao realizarmos uma instalao padro
da verso enterprise o Spatial instalado tambm. Ele nada mais do que um
esquema (cujo nome MDSYS) que criado no banco de dados para prover
tipos para representao e operaes sobre os dados de natureza espacial.
Como j visto, os dados de natureza espacial podem ser representados por
formas geomtricas. A Figura 4 nos mostra os tipos de geometrias aceitas pelo
Spatial.

Figura 4. Adaptada do Oracle Spatial users guide and reference.

Note que cada figura possui pontos em destaque, ou seja, para formar cada
geometria necessita-se apenas de um conjunto mnimo de pontos. Veja que para se
formar um retngulo, somente precisamos dos pares de coordenadas dos pontos do
canto inferior esquerdo e do canto superior direito do mesmo.

Para armazenarmos geometrias em uma tabela, definimos uma coluna como um


tipo geomtrico, este tipo criado sob o objeto bsico SDO_GEOMETRY. Assim,
coluna que vai armazenar uma representao geomtrica deve ser to tipo
SDO_GEOMETRY, o qual um objeto contido no esquema MDSYS. Veja a Listagem
1, onde criada uma tabela onde sero armazenadas as reas de mercados do
produto X.

Listagem 1. Criao da tabela MERCADOS_X com uma coluna do tipo geometria


CREATE TABLE MERCADOS_X(
Id number,
Nome Varchar2(50),
Area MDSYS.SDO_GEOMETRY);

Veja que no foi feita ainda nenhuma referncia forma geomtrica que
representar o mercado em questo. Vamos agora analisar brevemente o tipo
SDO_GEOMETRY, que composto pelos seguintes atributos:
SDO_GTYPE: um nmero e indica o tipo de geometria. Esse nmero de
quatro dgitos composto pela estrutura dltt, onde:
o d indica a dimenso;
o l identifica o sistema de referncia linear. Um sistema de referncia
linear basicamente uma medida sobre uma linha, ou segmentos que
formam uma linha. Seria como pegar uma rgua, sobre uma linha reta
e marcar a localizao do ponto atravs de uma medida, por exemplo n
cm, e no a partir de um par de coordenadas (x,y). Para geometrias
que no usam referncia linear atribui-se 0 ao valor de l. Por exemplo,
podemos representar uma rodovia como uma linha, e para localizar um
ponto sobre a rodovia ao invs de informarmos latitude e a longitude
do ponto, podemos informar a posio do ponto em termos de
quilometragem, ou seja, se informamos o valor 22,5 queremos
localizar o ponto sobre o quilmetro 22,5. Lembre-se que a
representao de uma rodovia nem sempre uma reta.
o J o componente tt, que varia de 00 a 07, indica o tipo geomtrico. A
Tabela 1 mostra os tipos geomtricos atribudos aos cdigos tt.

dl00 Geometria desconhecida O Spatial ignora essa geometria.

dl01 Ponto A geometria um ponto.

dl02 Linha ou curva (aqui A geometria composta por linhas


tratadas como sinnimos) retas, arcos ou ambos.

dl03 Polgono Polgono com ou sem buracos. Por


exemplo, um quadrado com um crculo
dentro.

dl04 Coleo A geometria uma coleo heterognea


de elementos. uma coleo de todos os
outros tipos.

dl05 Multipontos A geometria tem um ou mais pontos.

dl06 Multilinhas ou multicurvas A geometria uma ou mais sequncias


de linhas.

dl07 Multipoligono A geometria um conjunto de


polgonos.

Tabela 1. Geometria referentes a tt.

SDO_SRID: um nmero que indica o sistema de coordenadas utilizado.


Como citado anteriormente, podemos utilizar latitude e longitude, ou
coordenadas cartesianas (x,y,z), por exemplo, para localizar um ponto sobre a
superfcie da terra. O SDO_SRID indica qual sistema de coordenadas, assim
como qual elipsoide (SAD-69, WGS-84, etc.) estar sendo usado para a
localizao. Caso o SDO_SRID seja nulo, ento as coordenadas so associadas
com a geometria, ou seja, um par (M,N) a localizao de um ponto num
simples plano cartesiano que contenha a geometria. Vale lembrar que todas
as geometrias de uma coluna precisam estar no mesmo sistema de
coordenadas. Os sistemas de coordenadas utilizados pelo Spatial esto
armazenados na tabela CS_SRS do esquema MDSYS, e o valor para SD_SRID
um dos valores, contidos na coluna SRID da tabela CS_SRS. A Listagem 2
mostra um select que retorna 10 sistemas de coordenadas contidos em
CS_SRS.

Listagem 2. Exemplo de 10 sistemas de coordenadas utilizados pelo Spatial


SQL> SELECT SRID, CS_NAME
2 FROM MDSYS.CS_SRS
3 WHERE ROWNUM <= 10
4 ORDER BY CS_NAME;
SRID CS_NAME
---------- ------------------------------------------
8192 Longitude / Latitude
8195 Longitude / Latitude (Adindan)
8196 Longitude / Latitude (Afgooye)
8193 Longitude / Latitude (AGD 66)
8194 Longitude / Latitude (AGD 84)
8197 Longitude / Latitude (Ain el Abd 1970)
8198 Longitude / Latitude (Anna 1 Astro 1965)
8199 Longitude / Latitude (Arc 1950)
8200 Longitude / Latitude (Arc 1960)
2000001 Martian Longitude/Latitude
10 linhas selecionadas.;

Para mais detalhes sobre os sistemas de coordenadas utilizados pelo Spatial


conveniente consultar o captulo 5 do Oracle Spatial users guide and
reference (http://www.oracle.com/technology/documentation/spatial.html).

SDO_ORDINATES: um array varivel de nmeros que armazena as


coordenadas dos pontos que compem a forma geomtrica. Por exemplo, para
um polgono que definido por 4 pontos, no espao bidimensional, esse array
de coordenadas armazenado como: {X1, Y1, X2,Y2, X3, Y3, X4, Y4}. Se o
espao tridimensional as coordenadas dos pontos so armazenadas como:
{X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4}.
SDO_ELEM_INFO: um vetor de valores que ajuda na interpretao do
atributo SDO_ORDINATES. Esse atributo formado por trios de valores, o
primeiro valor do trio indica a partir de qual posio de SDO_ORDINATES
iniciam-se as coordenadas dos pontos que formam a geometria, um polgono
furado formado por duas geometrias, por exemplo, um retngulo com um
crculo dentro. Neste caso, um valor 1 indica que a partir do primeiro valor em
SDO_ORDINATES comeam as coordenadas dos pontos que formam a
primeira geometria. J um valor 15 indica que a partir da 15 posio em
SDO_ORDINATES comeam as coordenadas dos pontos que definem a
segunda geometria. O segundo valor da tripla indica a forma geomtrica e o
quo externa a forma , ou seja, se est contida em outra forma ou no, seja
num polgono com buraco ou no. Por exemplo, o valor 1003 indica um
retngulo exterior, um valor 2003 indica um retngulo dentro do primeiro
retngulo, o valor 1 em 1003 indica que o polgono mais externo, o 2 em
2003 indica que um polgono dentro do polgono 1003. J o ltimo valor da
tripla o SDO_INTERPRETATION, ele pode significar uma ou duas coisas,
depende se a forma geomtrica um elemento composto ou no, o que
definido pelo segundo valor da tripla, o SDO_ETYPE. Como o intuito desse
artigo no fornecer um treinamento em Oracle Spatial, conveniente que o
leitor que esteja interessado em se aprofundar no assunto. Consulte a tabela
com interpretaes para os valores combinados de SDO_ETYPE e
SDO_INTERPRETATION no Oracle Spatial Users Guide and Reference. A
Tabela 2 mostra alguns exemplos de interpretao para a dupla SDO_TYPE e
SDO_INTERPRETATION

SDO_TYPE SDO_INTERPRETATION SIGNIFICADO

1003 or 1 Polgono simples, cujos vrtices so


conectados por linhas retas.
2003

1003 or 2 Polgono formado por uma sequncia de


arcos conectados. O ltimo ponto do
2003
ltimo arco deve coincidir com o primeiro
ponto do primeiro arco

2 1 Linha formada por segmentos cujos


vrtices so conectados por linhas retas.

2 2 Linha formada por uma sequncia de


arcos conectados.

Tabela 2. Algumas interpretaes para a dupla de valores SDO_TYPE e


SDO_INTERPRETATION.

SDO_POINT: um atributo para uso exclusivo na definio de um ponto.


composto por uma tripla de valores (X,Y,Z) que so as coordenadas do ponto.
O SDO_POINT somente usado caso SDO_ELEM_INFO e SDO_ORDINATES
sejam nulos, caso contrrio SDO_POINT ignorado.

Seguindo o exemplo da rea de abrangncia do mercado do produto X, vamos


inserir uma rea na forma do retngulo da Figura 5 (ver Listagem 3).

Figura 5. Retngulo representando a rea de abrangncia do mercado_1 para o


produto X

Listagem 3. Clausula de insero de dados na tabela MERCADO_X


INSERT INTO MERCADO_X(
Id
,Nome
,Area
)
VALUES(
1
,'Mercado_1'
,MDSYS.SDO_GEOMETRY(
2003
,NULL
,NULL
,MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,3),
,MDSYS.SDO_ORDINATE_ARRAY(1,1, 5,7)
)
);

Analisando a sentena de insero acima vemos que 2003 define um polgono


bidimensional, d=2, l=0 e tt=03. Definindo o segundo valor como nulo no
especificamos um sistema de coordenadas para os pontos que definem a
geometria, ser usado ento um sistema relativo. J o terceiro valor, NULL, define
que a geometria no um ponto. Na definio de SDO_ELEM_INFO_ARRAY temos a
definio de um retngulo exterior (valor 1003) e por ltimo na definio de
SDO_ORDINATE_ARRAY as coordenadas dos dois pontos fundamentais para
definio do retngulo, o canto inferior esquerdo e o superior direito.

Podemos perceber que quanto mais complexa a forma que precisamos


representar, mais complexa, e cheia de valores, se torna a sentena de insero.

Aps uma breve descrio de como Spatial armazena as representaes


espaciais, veremos agora alguns operaes implementadas para consulta sobre os
dados:

SDO_FILTER: usada para identificar se um grupo de objetos interage


espacialmente com um objeto ou uma rea de interesse, ou seja, pode-se
verificar quais objetos esto contidos numa determinada rea.
SDO_NN: usada para identificar os vizinhos mais prximos de uma geometria.
SDO_NN_DISTANCE: recupera a distncia dos objetos retornados por
SDO_NN.
SDO_WITHIN_DISTANCE: retorna os objetos que esto a uma determinada
distncia de um objeto.

O Spatial implementa tambm funes geomtricas, dentre as quais podemos


citar:

SDO_GEOM.SDO_AREA: retorna a rea de um polgono bidimensional.


SDO_GEOM.SDO_CENTROID: retorna a centroide, tambm conhecida como
centro de gravidade, de um polgono, ponto ou conjunto de pontos.
SDO_GEOM.SDO_DISTANCE: retorna a distncia entre dois objetos
geomtricos. A distncia calculada como sendo a distncia entre os dois
pontos, ou segmentos mais prximos entre os objetos.

Aps apresentar algumas das operaes espaciais e geomtricas presentes no


Spatial, a seguir temos o exemplo de uma consulta espacial, extrada do Spatial
Users Guide and Reference. A query da Listagem 4 seleciona a distncia entre
duas geometrias que representam cola_d e cola_b. O valor 0.005 o valor de
tolerncia para a operao.
Listagem 4. Consulta que retorna a distncia entre duas representaes
geomtricas

SELECT SDO_GEOM.SDO_DISTANCE(c_b.shape, c_d.shape, 0.005)

FROM cola_markets c_b, cola_markets c_d

WHERE c_b.name = cola_b AND c_d.name = cola_d;

Em mais um exemplo, Listagem 5, mostramos agora uma query que retorna os


polgonos que ficam a uma distncia de 10 unidades da geometria definida pela
varivel aGeom.

Listagem 5. Consulta que retorna as geometrias que ficam a 10 unidades de


distncia da geometria definida por aGeom

SELECT A.GID

FROM POLYGONS A

WHERE

SDO_WITHIN_DISTANCE(A.Geometry, :aGeom, distance = 10) = TRUE;

Vale ressaltar que aps popularmos uma tabela com dados espaciais

importante a criao de ndices espaciais sobre esses dados, e sempre que novos

dados forem inseridos importante reconstruir os ndices. Devido a natureza dos

dados, as tcnicas B-Tree, Hash e etc. no se aplicam aos dados espaciais, o

Spatial recomenda a utilizao da estrutura de indexao R-Tree; no

discutiremos essa estrutura nesse artigo.

O leitor deve estar imaginando como visualizar esses dados. A Oracle oferece o

Oracle Application Server MapViewer, uma API Java usada para visualizao.

Existem tambm outras solues comerciais para visualizao assim como

insero grfica de dados numa base Oracle com Spatial. A Oracle fornece uma

listagem de produtos para visualizao e insero de dados no Oracle Spatial em

http://www.oracle.com/technology/products/spatial/spatial_partners.htm
Concluso

A localizao est se tornando uma informao valiosa, vide por exemplo os


sistemas de localizao de veculos ou os sistemas de real state e geomarketing.
Pudemos nesse primeiro artigo conhecer alguns fundamentos do mundo do
geoprocessamento assim como tomar conhecimento sobre o Oracle Spatial e
suas formas de tratar e a representar os dados de natureza espacial. No prximo
artigo abordaremos tcnicas de modelagem para dados de natureza espacial.

Bibliografia
RODRIGUES, M. Introduo ao Geoprocessamento. In: SIMPSIO BRASILEIRO DE
GEOPROCESSAMENTO, 1., So Paulo, 1990. Curso Introdutrio. So Paulo: EPUSP,
1990. p1-26.
FREEMAN, J. The modelling of spatial relations. Computer Graphics and Image
Processing, n.4, p.156-171, 1975.

Thiago Simonato (simonato@gisconsult.com.br) mestrando em


Geoprocessamento no Departamento de Transportes na Engenharia Civil da
Escola Politcnica da USP, professor na FAIMI no curso de Sistemas de
Informao e Gerente de Tecnologia da GIS Consult.

Ronaldo Sales (ronaldo.sales@poli.usp.br) mestrando em Geoprocessamento


no Departamento de Transportes na Engenharia Civil da Escola Politcnica da
USP. Atua como Oracle Developer na En-Sof Consultoria e Treinamento.

Vinicius Maeda (vinicius.maeda@poli.usp.br) bacharel em Cincias da


Computao pela UEMS de Dourados-MS. Atualmente mestrando do curso de
Geoprocessamento na rea de Informaes Espaciais do Departamento de
Engenharia de Transportes da Escola Politcnica da USP.
PostgreSQL
O caminho das pedras
Muitos programadores possuem o poder de deciso sobre o SGBD a ser utilizado
em sua empresa. Com o avano do Linux no mundo dos servidores e o aumento da
qualidade e oferta dos BDs gratuitos, muitos optaram por migrar de um SGBD pago
para um gratuito. Dentre os que optaram pela migrao, muitos desistiram de
utilizar o PostgreSQL devido a algumas dificuldades no primeiro contato com o
software.
Senti essa dificuldade na pele quando decidi migrar vrios sistemas do MSSQL
para um SGBD gratuito. No comeo foi um pouco difcil de acostumar com as
diferenas de sintaxe, etc. Atravs de pesquisas, artigos e palestras, percebi que o
PostgreSQL era um dos BDs mais recomendados, pois implementa todas as
caractersticas de um SGBD de alto nvel, alm de ser muito robusto.
Neste artigo pretendo ensinar algumas tcnicas de como trabalhar com o
PostgreSQL, mostrando o caminho das pedras. Abordaremos tpicos desde a
criao de tabelas at uma leve otimizao do desempenho de queries.
Caso o leitor ainda esteja estudando qual SGBD utilizar, este artigo poder lhe
fornecer uma noo bem clara de como trabalhar com o PostgreSQL no Linux, e
talvez seja um fator decisivo na sua escolha.

Configuraes iniciais
muito comum instalar o PostgreSQL atravs de pacotes RPM. Aps a instalao,
geralmente enfrentamos alguns problemas que podem ser resolvidos atravs de
uma boa leitura na documentao. Um dos primeiros problemas enfrentados a
tentativa de conexo de um cliente com o servidor. Uma das perguntas mais
frequentes dos iniciantes : Porque consigo conectar o PostgreSQL atravs do
console no servidor Linux, mas no de um terminal de rede? . O fato aqui que o
servidor de banco de dados vem totalmente protegido, e para liberar conexes
devemos editar alguns arquivos de configurao, so eles: pg_hba.conf e
postgresql.conf, ambos localizados na pasta data, dentro do diretrio onde foi
instalado o PostgreSQL.

Habilitando a conexo de clientes


No arquivo pg_hba.conf, encontramos as configuraes de IP e password do
sistema. por meio deste arquivo que dizemos ao PostgreSQL de quem ele deve
aceitar conexes, e se estas conexes devem pedir senha. Atravs deste arquivo,
determinamos tambm se o PostgreSQL dever aceitar conexes de fora de sua
rede local. O arquivo contm exemplos de configuraes e descries dos modos de
autenticao disponveis. Uma autenticao segura e muito utilizada a md5. H
tambm exemplos de mscaras de IPs para conexes de rede local e internet.
Como estes arquivos esto devidamente comentados, e, portanto, so
autoexplicativos, no entrarei em maiores detalhes. A pessoa mais indicada para
configur-los o administrador de rede, podendo, por exemplo, liberar o acesso de
sua rede interna e bloquear o acesso de usurios que no estejam no domnio
atravs do endereo IP.
No exemplo da Listagem 1, a primeira linha libera o acesso a todos databases no
console do prprio servidor, sem autenticao. A segunda linha libera o acesso ao
database db_empresa somente para o IP especificado, utilizando a autenticao do
tipo trust. A terceira linha libera o acesso a todos os databases de qualquer
estao, utilizando a autenticao do tipo md5.
Listagem 1. pg_hba.conf.
#TYPE DATABASE IP_ADDRESS MASK AUTH_TYPE
AUTH_ARGUMENT
local all 127.0.0.1 255.255.255.0
host db_empresa 168.192.137.12 255.255.255.0 trust
host all 0.0.0.0 0.0.0.0 md5

O arquivo postgresql.conf contm as configuraes de inicializao do banco.


importante habilitarmos as conexes via tcp-ip / porta / max-connections /
buffers. A pessoa mais indicada para configurar este arquivo o prprio
programador ou o DBA. importante ressaltar que devemos remover a # do
incio da linha para que ela no seja interpretada como um comentrio. Segundo a
documentao do PostgreSQL, o valor para buffers deve ser o dobro do valor de
max-connections. Na Listagem 2 vemos um exemplo de configurao. Perceba
que as linhas no esto necessariamente nessa ordem no arquivo original.

Listagem 2. postgresql.conf
tcpip_socket = true
max_connections = 32
port = 5432
shared_buffers = 64

Escolhendo um front-end para administrao


Agora que j estamos habilitados a conectar em nosso SGBD atravs de estaes
cliente, chegou a hora de escolher uma boa ferramenta de administrao para o
PostgreSQL. Minha primeira escolha foi testar as bibliotecas nativas que podem ser
instaladas junto com o prprio servidor, conhecidas como pg_access. Porm, estas
rodam somente em Linux e no possuem um conceito R.A.D., isto , no facilitam
muito nossa vida.
O PGAdmin um excelente front-end de administrao para o PostgreSQL, que
vem se aprimorando a cada nova verso. Existem basicamente duas verses: o
PGAdmin II e o PGAdmin III. A principal diferena entre as duas a verso
suportada do PostgreSQL e do sistema operacional. A verso II roda em Windows
98 e pode conectar servidores anteriores verso 7.3.0 do PostgreSQL. J verso
III pode conectar servidores PostgreSQL 7.3.0 ou superiores, e roda somente em
Windows 2000.

Middleware de acesso a dados


Neste ponto j estamos aptos a comear a desenvolver programas que utilizam o
PostgreSQL. Devemos prestar ateno na hora de escolher uma tecnologia de
acesso a dados. Nesse artigo, usarei como exemplo a linguagem Delphi, mas nada
impede de desenvolvermos em Visual Basic, etc.
Para acessar o PostgreSQL via OLEDB, necessrio baixar e instalar um driver
ODBC para o PostgreSQL nas mquinas que faro acesso ao SGBD. Como existem
vrias verses dos drivers ODBC, atente para baixar a verso estvel mais recente.
Para o Delphi, recomendo usar os componentes de conexo ADO (tecnologia
Microsoft), pois desta maneira conectaremos atravs de uma string de conexo
comum de qualquer driver baseado em OLEDB, sem precisar de pacotes de
componentes adicionais. Os drivers dbExpress para PostgreSQL no acompanham o
Delphi, e devem ser adquiridos de terceiros, mas como um dos fatores da migrao
foi o custo de licena, fica meio invivel pagar pelo driver, certo?
Outra opo muito boa utilizar o pacote de componentes Zeos (gratuito), que
oferece conexo com vrios bancos de dados, entre eles o PostgreSQL. Estes
componentes podem ser baixados no endereo http://www.zeoslib.net.

Tcnicas de desenvolvimento com PostgreSQL


A seguir darei algumas dicas valiosas de como comear a desenvolver seu banco
de dados, otimiz-lo, e como programar corretamente seu sistema para evitar
alguns problemas clssicos.
Padres
Aconselho a criao de todos os nomes de objetos em caixa baixa. J tive
problemas utilizando caixa mista onde, algumas vezes, o PostgreSQL no encontrou
um determinado objeto, sendo necessrio colocar aspas em tudo, o que torna a
sintaxe SQL extremamente propensa a erros. Este bug pode ocorrer em algumas
verses mais antigas do PostgreSQL e em alguns front-ends de acesso. A Tabela 1
mostra o padro de nomenclatura que costumo adotar nos meus objetos.

Tipo Padro de Exemplo


Nomenclatura
DataBase db_{database} db_empresa
Schema sc_{schema} / sc_adm / db_adm
db_{schema}
Table tab{name} Tabcliente
View rsv{name} Rsvcliente
Field {fieldname}_{table nome_clt
prefix}
Index ix{fieldname_fieldname} ixnome_clt /
ixnome_clt_sobrenome_clt
Primary Key {tabble}_pkey tabcliente_pkey
Foreing Key fk{fieldname} fkid_clt
Sequence {fieldname}_seq id_clt_seq
Tabela 1. Padro de nomenclatura para os objetos.

Organizao
Muitos programadores/DBAs costumam dividir seus sistemas em vrios
databases, principalmente quando o ambiente tem muitos departamentos. Como o
PostgreSQL no permite a criao de integridade referencial entre mltiplos
databases, aconselho criar apenas um database universal, ou teramos que
implementar a integridade no lado cliente, o que extremamente trabalhoso. A
partir da verso 7.3, foi introduzido o conceito de Schemas (ver abaixo),
possibilitando organizar nossos departamentos atravs de esquemas dentro de um
banco de dados. Por padro, todo database possui o esquema public, mas
recomendo a organizao dos objetos atravs de novos esquemas, com nomes
mais intuitivos.

Schemas
So organizaes lgicas dentro do database que permitem agruparmos as
tabelas por um namespace comum. Devemos tomar cuidado pois atravs desta
prtica podemos ter tabelas com o mesmo nome em Schemas diferentes, o que
pode gerar uma certa confuso nos selects. Em um caso como esse, o PostgreSQL
utiliza o conceito de search path para decidir qual tabela utilizar. Imagine a
seguinte situao:
Database: db_empresa.
Dividido nos schemas: public / sc_adm / sc_web / sc_cadastro /
sc_documentacao.
Se possuirmos duas tabelas chamadas tabcategoria, uma em sc_adm e outra em
sc_web, qual seria utilizada pela clausula SELECT * FROM tabcategoria ? A
resposta : a tabela utilizada ser a primeira a ser encontrada, seguindo-se a
ordem de pesquisa definida pelo search_path atravs do comando set search_path
= ....
Desde que comecei a trabalhar com Schemas, evito este tipo de conflito atravs
de uma anlise bem elaborada. No costumo utilizar o comando set para adicionar
Schemas no search_path, pois isso faz com que o PostgreSQL tenha que pesquisar
em Schemas aos quais j sabemos que a tabela no se encontra. Ao invs disso, na
construo do comando SQL, especifico explicitamente qual o esquema a ser
utilizado, por exemplo: SELECT * FROM sc_adm.tabcategoria.
Sequences
So os campos tipo auto incremento, tambm conhecidos como identity no
MSSQL. Eles so implementados no PostgreSQL da seguinte forma: primeiro
criamos um objeto do tipo sequence, e no valor default do campo utilizamos a
funo nextval com a seguinte sintaxe: nextval ('schema."sequence name"'::text).
No comeo, critiquei muito essa abordagem, mas depois percebi que um conceito
excelente, principalmente quando estamos migrando de um SGBD para outro. Isto
por que permite re-iniciar a sequncia, mudar a razo de incremento e configurar
os valores mnimos e mximos com extrema facilidade.

String de conexo
Podemos perceber (ver Listagem 3) que a string de conexo algo imenso e
assustador, mas tem seu lado bom. Podemos configurar vrios aspectos
relacionamos interao entre nossos componentes e o SGBD. Chamo a ateno
para o parmetro BoolsAsChar: geralmente ele vem configurado de uma maneira
no muito agradvel para os programadores Delphi, trazendo os campos Boolean
como se fossem Strings. Para corrigir isso, mude o valor do parmetro de 1 para 0.

Listagem 3. String de Conexo.


Provider=MSDASQL.1;Extended
Properties="DRIVER={PostgreSQL};DATABASE=db_empresa;SERVER=192.195.23
7.27;PORT=5432;UID=UserName;PWD=Password;ReadOnly=0;Protocol=6.4;Fake
OidIndex=0;ShowOidColumn=0;RowVersioning=0;ShowSystemTables=0;ConnSetti
ngs=;Fetch=100;Socket=4096;UnknownSizes=0;MaxVarcharSize=254;MaxLongVa
rcharSize=65536;Debug=0;CommLog=0;Optimizer=1;Ksqo=1;UseDeclareFetch=0
;TextAsLongVarchar=1;UnknownsAsLongVarchar=0;BoolsAsChar=0;Parse=0;Canc
elAsFreeStmt=0;ExtraSysTablePrefixes=dd_;LFConversion=1;UpdatableCursors=1;
DisallowPremature=0;TrueIsMinus1=0;BI=0;ByteaAsLongVarBinary=0;UseServerSi
dePrepare=0"

No Delphi/ADO, interessante configurar a propriedade KeepConnection do


componente TADOConnection como True, mantendo a conexo com o banco ativa,
mesmo se todos os datasets ligados ela estiverem fechados.

Strings SQL
Existem algumas diferenas bsicas entre o SQL praticado no PostgreSQL em
relao a outros bancos de dados. A Tabela 2 mostra algumas variaes na
construo dos comandos select.

Descrio PostgreSQL
Limitando o retorno SELECT * FROM tabcliente LIMIT 100;
do resultado.
Lista de SubSelect SELECT * FROM tabcliente
1 WHERE id_clt IN (SELECT id_clt FROM tabpedido);
Lista de SubSelect SELECT * FROM tabcliente, tabpedido
2 WHERE tabcliente.id_clt = tabpedido.id_clt;
Final de Instruo Com ADO, o ; pode causar uma diferena de desempenho
SQL no retorno do conjunto de dados. Sempre utilize ; no final
dos seus comandos SQL.
Case/Accent- Crie seu banco com Latin1 e utilize as funes
insentive upper(to_ascii({name})) tanto no campo a ser pesquisado
quanto no valor do critrio.
Tabela 2: Diferenas em comandos select.

Componente ADOQuery
D preferncia ao componente ADOQuery ao invs do ADOTable em seus
projetos. Descobri, na prtica, que podem ocorrer erros de sintaxe em tabelas com
campos do tipo memo quando estes no esto posicionados no final da ADOQuery.
O problema tambm ocorre com o Visual Basic, e resolvido da mesma maneira,
ou seja, deixando os campos memo por ltimo.

Backup
Atravs do script CRON no servidor Linux, podemos agendar vrios tipos de
tarefas, inclusive programar a execuo de backups dos bancos de dados. No
PostgreSQL, um backup feito atravs das ferramentas pg_dump (realiza o backup
de um nico database) e pg_dumpall (realiza o backup de todos os databases do
SGDB) (ver Listagem 4). Ambos so utilitrios de linha de comando que geram
arquivos de backup que podem ser restaurados atravs dos utilitrios pg_restore
(restaura todas definies contidas no arquivo gerado pelo pg_dump ou
pg_dumpall) e psql (console SQL que serve para executar qualquer tipo de Query
no servidor).

Listagem 4. Sintaxe para execuo de backups.


pg_dump d {database} f {filename} U postgres #Database
pg_dumpall > {filename} c U postgres #Todos os Databases
# O parmetro U especifica o nome do usurio a se conectar no database, no
exemplo postgres
# O parmetro c faz com que os comandos de criao do banco sejam includos
no arquivo.
# Existem muitos outros parmetros que devem ser pesquisados para melhor
atender a sua necessidade

Tunning
recomendado executar diariamente a rotina de limpeza de registros que no
so mais utilizados pelo banco. Essa rotina chamada de VACUUM, e visa evitar
perda de peformance no BD. Para esta tarefa, tambm recorremos ao CRON do
Linux, agendando a execuo da rotina preferencialmente noite, ou em um
horrio onde o SGBD no tenha muitos acessos. A Listagem 5 apresenta um
exemplo do comando a ser agendado.

Listagem 5. Sintaxe do comando vacuumdb.


vacuumdb d {database} z v U postgres #Database com log
vacuumdb a q z U postgres #Todos os Databases sem log
# -a Todos os Databases, q Quiet, v Verbose, d Database, z Analyze, U
Username

Experincia do autor
com muita satisfao e segurana que recomendo a utilizao do PostgreSQL no
Linux, e por experincia, digo que um sistema robusto, confivel e gratuito. Ele
tambm engloba alguns conceitos de orientao a objeto, como a criao de
tabelas por herana, e permite criarmos novas funes alm das pr-definidas,
podendo estender os recursos do SGBD.
Hoje tenho seis sistemas migrados de dBase/MsSQL para PostgreSQL. A migrao
geralmente rpida, e depende basicamente do nvel de utilizao de recursos
como as stored procedures e triggers.
Tambm utilizo DataSnap, criando um servidor de aplicao e evitando assim a
necessidade da instalao do driver ODBC nos clientes. O mesmo servidor
DataSnap gerencia conexes para web atravs do Intraweb.
Outro ponto bastante interessante est no nosso site (www.socioambiental.org)
desenvolvido em Zope (ferramenta open source para gerenciamento de contedo
web) acessando PostgreSQL. Ele gerencia todo nosso sistema de e-commerce, alm
de fornecer notcias, manchetes, filiaes, entre outros recursos. Por isso, quando
digo que o PostgreSQL bom, estou opinando baseado em testes reais com
considervel carga de utilizao e dados. Atualmente estamos trabalhando com a
verso 7.3.4, mas j existem outras verses mais recentes.
Concluso
Apesar de alguns percalos tcnicos no inicio da utilizao do PostgreSQL, ele
oferece um custo beneficio satisfatrio em comparao a outros bancos como
MsSQL e Oracle. Acredito que com o surgimento de literatura esclarecendo as
principais dvidas dos programadores e DBAs, esse SGBD vai conquistar cada vez
mais adeptos.
Vale lembrar que periodicamente o PostgreSQL ganha novas verses que incluem
novas funcionalidades. Isto nos d uma segurana extra em relao ao suporte e
evoluo do projeto. J existem diversos grupos de discusso sobre a ferramenta
no Brasil e no exterior, ficando muito fcil encontrar ajuda para resolver grande
parte das dvidas. Tambm grande o nmero de componentes que oferecem
conexo com PostgreSQL em vrios ambientes de desenvolvimento e plataformas.
Espero que esse artigo lhe poupe de algumas dores de cabea. Se por acaso sua
dvida no estava englobada neste artigo, entre em contato comigo atravs para
que possamos resolv-la.

Referncias
Site oficial do PostgreSQL.
http://www.postgresql.org
Site oficial dos Desenvolvedores do PostgreSQL.
http://developer.postgresql.org
Site oficial do PGAdmin III
http://www.pgadmin.org/pgadmin3
Site oficial do driver ODBC
http://gborg.postgresql.org/project/psqlodbc
Grupo de discusso nacional do site Yahoo
http://br.groups.yahoo.com/group/postgresql-br
Centro de informao para usurios brasileiros
http://www.postgresql.org.br/
Comunidades PostgreSQL no Orkut
http://www.orkut.com/Community.aspx?cmm=1782
http://www.orkut.com/Community.aspx?cmm=29893&sid=13524124770919555
04

Fabio Alves Francelino (francelino@socioambiental.org) Analista de Sistemas


formado pela Universidade Presbiteriana Mackenzie. Trabalha com ADO e DataSnap
em projetos Cliente/Servidor e Multicamadas acessando MSSql e PostgreSQL.
Participou da 3 Borland Conference ministrando palestra sobre desenvolvimento
de jogos com Delphi na sala de RAD. colunista ativo da revista Clube Delphi e Sql
Magazine. Desenvolve Componentes, Engines e Jogos em Delphi.
SQL Curso Prtico
Tanto os amantes de banco de dados quanto aqueles que esto aprendendo a se
apaixonar por ele devem ter como leitura obrigatria este excelente livro do
economista e professor de banco de dados Celso Henrique Poderoso de Oliveira.
Destinado principalmente aos que esto iniciando os estudos na ferramenta de
manipulao de banco de dados, esta obra tambm prov importantes conceitos a
respeito do padro aberto da linguagem SQL que sero muito bem aproveitados
pelos usurios mais experientes.
Atravs da grande experincia em ministrar cursos de graduao na rea, foram
includos vrios exerccios ao final de cada captulo para uma boa fixao dos
conceitos apresentados, sem contar a tima didtica em uma leitura de fcil
compreenso.
O livro no se restringe apenas ao bsico da linguagem SQL, ele explora diversos
recursos avanados, sempre utilizando exemplos e exerccios. Para que o leitor
acompanhe melhor as exemplificaes e possa praticar os conceitos e resolver os
exerccios, foi disponibilizado para download os scripts de criao das tabelas e
incluso dos dados do modelo-exemplo.
Dividido em 3 partes: Conceitos e Modelagem de Dados, SQL Bsico e SQL
Avanado, o livro aborda mais que o essencial para qualquer um que deseje se
aventurar na apaixonante arte de banco de dados.
Na primeira parte, temos uma introduo no captulo 1, definindo o que SQL. O
captulo 2 aborda o projeto de banco de dados desde a definio de um banco de
dados at integridade referencial, passando por entidades, registros e chaves.
No captulo 3 o leitor ter contato com as tcnicas de normalizao, onde
abordado da 1FN 5FN, alm de exerccios. O captulo 4 traz a criao de um
banco de dados utilizando o padro SQL-92. visto desde a definio dos dados,
passando pela criao de tabelas, constraints e finalizando com a criao de
ndices. J o captulo 5 trata dos comandos DML, exemplificando os comandos de
insero, alterao e excluso de linhas.
A segunda parte do livro trata o SQL Bsico onde, no captulo 6, o leitor ver a
pesquisa bsica em tabela, ordenando e filtrando os resultados. O captulo 7 mostra
os clculos e funes mais usuais em um banco de dados, como LENGTH, UPPER e
LOWER, TRIM, entre outros. No captulo 8 o leitor ver pesquisas em mltiplas
tabelas, atravs de unies e produtos cartesianos, alm de exerccios.
As funes de grupo e agrupamentos so detalhadas no captulo 9, sempre com
exemplos prticos e de fcil entendimento. O captulo 10 traz uma viso detalhada
de subqueries, onde o leitor aprender todos os conceitos de consultas aninhadas.
E finalizando a segunda parte do livro, o leitor ver as pesquisas avanadas no
captulo 11, onde so vistas operaes de UNION, CASE entre outras.
A ltima parte do livro mostra conceitos avanados de SQL, iniciado pelo captulo
12 que aborda objetos como esquemas e usurios, domnios, vises, tabelas
temporrias, entre outros. O captulo 13, Segurana de Banco de Dados, insere o
leitor nos conceitos de segurana: privilgios de sistema e objetos, atribuindo-os ou
revogando-os, sesses de banco de dados, nveis de isolamento de transaes,
SAVEPOINTS e ROLLBACK.
O captulo 14 realmente um caso a parte, entendendo o padro SQL o ttulo
deste captulo que traz ao leitor alguns dos motivos que tornaram este padro um
verdadeiro sucesso. Descrevendo sua evoluo at chegarmos ao ambiente cliente-
servidor. Aborda tambm as aplicaes para internet atravs da arquitetura n-
camadas, citando tambm as interfaces ODBC e JDBC. O captulo finalizado
mostrando quais as novidades do padro SQL-99, tambm conhecida como SQL-3.
No ltimo captulo do livro, 15 estendendo o padro SQL, o leitor convidado a
conhecer algumas implementaes importantes como o Transact-SQL e o PL/SQL.
So abordados tambm alguns recursos da extenso SQL, apresentando estruturas
de linguagem procedural. visto tambm o conceito de cursores, exemplificando
sua utilizao e, claro, como no poderia ficar de fora, os conceitos de triggers,
SQL dinmica, SQL embutida e a mais nova onda, ORDBMS (Sistema de
Gerenciamento de Banco de Dados Objeto-Relacional).
E como os famosos Bonus Track das nossas bandas favoritas, o autor oferece o
apndice A com os principais comandos SQL e o apndice B, com a resposta aos
exerccios oferecidos durante toda a extenso do livro.
Definitivamente, uma leitura essencial para os iniciantes em tcnicas de bancos
de dados, mas tambm uma verdadeira aula para os experientes, que muitas vezes
deixam alguns conceitos fundamentais e importantssimos carem no esquecimento.

Autor: Celso Henrique Poderoso de Oliveira


Editora Novatec
272 pginas
ISBN: 85-7522-024-1
Preo: R$ 42,00

Você também pode gostar