Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR
-
Upload
fabio-telles-rodriguez -
Category
Technology
-
view
1.495 -
download
1
description
Transcript of Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR
![Page 1: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/1.jpg)
por Fábio Telles8 de Dezembro de 2007
![Page 2: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/2.jpg)
por Fábio Telles8 de Dezembro de 2007
Melhores Práticas Melhores práticas são diretrizes e não dogmas:● Uma pessoa sem bom senso não se preocupa com melhores práticas;● Uma pessoa com bom senso e pouca experiência procura aprender e utilizar as melhores práticas;● Uma pessoa com bom senso e muita experiência sabe quando não utilizar as melhores práticas;
![Page 3: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/3.jpg)
por Fábio Telles8 de Dezembro de 2007
ModelagemEstrutura de dados inteligentes e código burro trabalham
muito melhor que ao contrário. (Eric Raimond)
Problemas de performance quando causados por falhas na modelagem podem demorar anos para aparecer.
Quando surgem são quase insolúveis.
A parte mais importante no sucesso de uma aplicação com comunicação tipo Matriz/Filial está na modelagem e não na
replicação
![Page 4: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/4.jpg)
por Fábio Telles8 de Dezembro de 2007
Modelagem● Abuse de PK, FK, NOT NULL, CHECK;● Use domínios para melhorar a semântica dos dados;● Use seqüências para gerar números únicos;● Use visões para tornar o modelo lógico mais simples que o
modelo físico;● Evite desnormalizar o modelo de dados;● Nunca deixe de documentar DDL, DER e Dicionário de Dados;● Nunca crie campos e tabelas do tipo “FLEX”;● Cuidado com FRAMEWORKs e GERADORES DE
CÓDIGO;
![Page 5: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/5.jpg)
por Fábio Telles8 de Dezembro de 2007
Desempenho● Use funções para processar tarefas em lote;● Agregue várias consultas pequenas em uma única consulta maior;● Use o PREPARE ... EXECUTE quando não for possível agregar
consultas menores;● Use poucas transações grandes no lugar de muitas transações
pequenas;● Use índices em campos muito utilizados em cláusulas WHERE;● Evite utilizar muitos índices em ambiente transacional pesado;● Evite operações pesadas de DELETE e UPDATE;● Evite o uso indiscriminado de gatilhos;● Evite usar funções quando SQL puro resolve;
![Page 6: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/6.jpg)
por Fábio Telles8 de Dezembro de 2007
PadrõesAplicações independentes de SGDB não existem...● Use funções específicas do PostgreSQL quando:
● houver grande ganho de performance ou ● esta função for chave para a sua aplicação;
... mas a necessidade de fornecer soluções para mais de um SGDB existe!
● Use ao máximo o padrão ANSI/SQL;● Evite o uso de funções que não sejam em PL/pgSQL;● Evite ao máximo o uso de funções exóticas que não tenha
implementação similar em outro SGDB de mercado;
![Page 7: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/7.jpg)
por Fábio Telles8 de Dezembro de 2007
Desenvolvedores● Abuse da documentação oficial;● Abuse de transações com BEGIN, COMMIT e ROLLBACK;● Use proteção efetiva contra SQL Injection;● Use desconexão automática por ociosidade;● Use de tratamento de erros com tratamento especial para erros
de violação de constraints;● Use logs de erro armazenados em servidores de aplicação;● Nunca exiba mensagens de erro do banco na tela do usuário;● Nunca confie em conversões implícitas de tipo de dados;
![Page 8: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/8.jpg)
por Fábio Telles8 de Dezembro de 2007
DBAs● Abuse da documentação oficial;● Use backup periódico do seu ambiente de produção e teste;● Nunca deixe de testar, rotinas de backup e restauração;● Nunca utilize TRUST ou PASSWORD como método de
autenticação no pg_hba.conf;● Nunca deixe de acompanhar os logs de erro;● Nunca utilize codificação de caracteres SQL_ASCII;● Nunca deixe de dormir!!!
![Page 9: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/9.jpg)
por Fábio Telles8 de Dezembro de 2007
Escrevendo SQL● Abuse de editores de texto puro;● Use o psql com a opção \i● Use palavras reservadas em letra maiúscula e nome de
objetos em letra minúscula;● Use o nome do esquema em operações DML e nomes
explícitos para índices, restrições e seqüências em DDL ;● Evite realizar operações pesadas em ambiente gráfico;● Evite criar objetos em interfaces gráficas;● Antes de dizer que um SQL não funciona, teste sempre no
psql;
![Page 10: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/10.jpg)
por Fábio Telles8 de Dezembro de 2007
O PostgreSQL é case sensitive!● Ruim:CREATE TABLE FUNCIONARIO (IDFUNCIONARIO SERIAL PRIMARY KEY,NOME VARCHAR(50) NOT NULL,DEPTO INTEGER REFERENCES DEPTO(IDDEPTO));● Péssimo:Create Table Funcionario (IdFuncionario Serial Primary Key,Nome Varchar(50) Not Null,Depto Integer References Depto(IdDepto));
![Page 11: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/11.jpg)
por Fábio Telles8 de Dezembro de 2007
USE MINÚSCULAS para nome de objetos
● Bom: CREATE TABLE funcionario ( id_funcionario SERIAL PRIMARY KEY, nome VARCHAR(50) NOT NULL, id_depto INTEGER REFERENCES depto(id_depto));
![Page 12: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/12.jpg)
por Fábio Telles8 de Dezembro de 2007
Explícito > Implícito● Ótimo:CREATE SEQUENCE hr.funcionario_seq;CREATE TABLE hr.funcionario ( id_funcionario INTEGER DEFAULT NEXTVAL('hr.funcionario_seq'), nome VARCHAR(50) NOT NULL, depto INTEGER CONSTRAINTS funcionario_pk PRIMARY KEY (id_funcionario) USING INDEX TABLESPACE tbs_rh_index, funcionario_depto_fk FOREIGN KEY (id_depto) REFERENCES rh.depto(id_depto)) TABLESPACE tbs_rh_table;
![Page 13: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/13.jpg)
por Fábio Telles8 de Dezembro de 2007
Explícito > Implícito● Excelente:SET DEFAULT_TABLESPACE = tbs_rh_table;CREATE SEQUENCE rh.funcionario_seq;CREATE TABLE rh.funcionario ( id_funcionario INTEGER DEFAULT NEXTVAL('rh.funcionario_seq'), nome VARCHAR(50) NOT NULL, depto INTEGER );SET DEFAULT_TABLESPACE = tbs_rh_index;ALTER TABLE rh.funcionario ADD CONSTRAINT funcionario_pk PRIMARY KEY (id_funcionario) USING INDEX funcionario_pk_ix;ALTER TABLE rh.funcionario ADD CONSTRAINT funcionario_depto_fk FOREIGN KEY (id_depto) REFERENCES rh.depto(id_depto);
![Page 14: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/14.jpg)
por Fábio Telles8 de Dezembro de 2007
Inteligência da Aplicação no Banco de Dados
Vantagens:● Maior controle por parte do DBA;● Maior velocidade em operações que envolvem um
grande volume de dados e um número limitado de cálculos;
● Acesso padronizado para diversas aplicações;● Facilidade de manutenção;● Baixa curva de aprendizado;
![Page 15: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/15.jpg)
por Fábio Telles8 de Dezembro de 2007
Inteligência da Aplicação no Banco de Dados
Desvantagens:● Menor controle por parte do desenvolvedor;● PL = Procedural Language, ou seja não é orientado a objeto;● Dificuldade em migrar aplicação para outros SGDBs;● Não existe COMMIT ou ROLLBACK dentro de uma função;● Código não pode ser ofuscado;● Alguns servidores de aplicação escalam processamento
melhor que o PostgreSQL;● Concentração de carga de processamento no SGDB;
![Page 16: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/16.jpg)
por Fábio Telles8 de Dezembro de 2007
Inteligência da Aplicação no Banco de Dados
Boas Práticas:● Confie no PostgreSQL para reforçar restrições!● Utilize funções para cálculos em lote;● Utilize gatilhos para auditar tabelas chave;● Utilize funções e visões para aumentar a segurança no
acesso a informações sensíveis;● Utilize gatilhos, funções e visões para integrar dados de
diferentes aplicações;
![Page 17: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/17.jpg)
por Fábio Telles8 de Dezembro de 2007
Ambientes● Produção: utilizado por todos usuários da
aplicação;● Homologação: aceite de novas versões pelo
usuário, testes de performance;● Teste: desenvolvimento de aplicações;● Laboratório: teste de novas versões, patches e
funcionalidades do SGDB.
![Page 18: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/18.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQL
● Autenticação Interna: um usuário do PostgreSQL por usuário da Aplicação;
● Autenticação Externa: um usuário do PostgreSQL por usuário da Aplicação com autenticação externa;
● Autenticação via Aplicação: um usuário do PostgreSQL para todos usuários da aplicação;
![Page 19: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/19.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQLAutenticação Interna:● PostgreSQL é capaz de distinguir quais usuários estão conectados;● Auditoria consistente;● Uso de ROLEs para agrupar privilégios em objetos;● DBA precisa criar usuários no banco de dados manualmente;● Aplicação deve trocar senha do usuário na primeira vez em que ele se
conectar;● Se a aplicação for Cliente/Servidor, PostgreSQL não consegue
impedir o usuário de se conectar por fora da aplicação;● Não é possível fazer pool de conexões.
![Page 20: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/20.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQL
Autenticação Externa:● Tem as mesmas características da Autenticação
Interna com as seguintes diferenças:● Administração de senhas fica a cargo do
Administrador de Sistemas;● Se integra com os demais usuários da rede;● É mais complexo para ser configurado;
por Fábio Telles8 de Dezembro de 2007
![Page 21: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/21.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQL
Autenticação pela Aplicação:● O PostgreSQL não é capaz de distinguir qual usuário está conectado;● Auditoria deve ser implementada pela aplicação;● Cadastro de usuários, senhas e permissões é de inteira responsabilidade
da aplicação;● Senha de acesso ao PostgreSQL deve ficar em posse da aplicação;● A senha da aplicação deve ser trocada com freqüência;● O ROLE da aplicação deve ter os menores privilégios possíveis;● O ROLE da aplicação nunca pode ser mesmo que o ROLE do
desenvolvedor ou o dono dos objetos da aplicação;
por Fábio Telles8 de Dezembro de 2007
![Page 22: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/22.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQLBoas Práticas:● Aplicações web não corporativas com muitos usuários
devem ser utilizar autenticação pela aplicação;● Aplicações que precisam de pool de conexões devem
utilizar autenticação pela aplicação;● Aplicações corporativas com 3 ou mais camadas devem
preferir devem preferir autenticação externa;● Mude o pg_hba.conf conforme o ambiente (produção,
homologação, teste e laboratório)
![Page 23: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/23.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQLpg_hba.conf:● Sempre identifique o nome do banco de dados;● Utilize SSL se você se preocupar com o tráfego de informações
pela rede sem encriptação;● Limite a faixa de Ips ao máximo:
● No caso aplicações em 3 ou mais camadas, limite aos IPs dos servidores de aplicação;
● No caso de aplicações Cliente/Servidor, limite a rede local que eles utilizam;
![Page 24: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/24.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQLpg_hba.conf:● Separe as regras por grupos de usuários:
● DBAs;● Desenvolvedores;● Aplicações (autenticação pela aplicação)● Aplicações (autenticação interna)● Aplicações (autenticação externa)● Usuários especiais;
● Utilize 'ident' apenas para os usuários DBAs, localmente e MD5 para conexões remotas, limitadas aos Ips/Redes locais dos DBAs;
![Page 25: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/25.jpg)
por Fábio Telles8 de Dezembro de 2007
Autenticando Aplicações no PostgreSQLpg_hba.conf● Utilize 'md5' para e o nome dos ROLEs da aplicação para
autenticação pelo PostgreSQL ou pela aplicação;● Utilize 'ldap', 'gss' ou 'sspi' para autenticação externa;● Desenvolvedores devem utilizar 'reject' no ambiente de
produção;● Usuários de aplicação autenticados pelo PostgreSQL ou
externamente devem ter 'reject' no ambiente de teste e homologação;
● Somente usuários especiais devem ter acesso ao ambiente de teste e homologação;
![Page 26: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/26.jpg)
por Fábio Telles8 de Dezembro de 2007
Esquema, Tablespace, Banco de Dados e Cluster
● Esquema: estrutura lógica onde os objetos são criados. Todo objeto é criado em um esquema;
● Tablespace: local físico de armazenamento de tabelas e índices;● Banco de Dados: conjunto de esquemas e seus objetos. Pode
compartilhar (padrão) ou não os ROLES de outros bancos de dados do cluster;
● Cluster (initdb): conjunto de arquivos que compõe uma única instância do PostgreSQL. Esta utiliza um único conjunto de processos, shared buffers e porta de rede, mas pode conter vários bancos de dados;
![Page 27: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/27.jpg)
por Fábio Telles8 de Dezembro de 2007
Um Esquema Por Aplicação● PostgreSQL não acessa nativamente outros bancos de dados;● Compartilhe dados entre as aplicações;● Crie um esquema para cada aplicação;● Cada esquema de aplicação deve possuir seu próprio dono;● Utilize um esquema separado para auditoria de vários sistemas;● Utiliza um esquema separado para monitoramento do DBA;● Utilize o esquema public apenas para compartilhar dados entre diversas aplicações;●Não utilize os esquemas information_schema, pg_catalog, pg_toast para criar, alterar ou excluir nenhum objeto;
![Page 28: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/28.jpg)
por Fábio Telles8 de Dezembro de 2007
Dois tablespaces por aplicação● Utilizar no mínimo um tablespace para índices e um para tabelas;● Mais fácil identificar o espaço físico ocupado pela aplicação;● Mais fácil identificar arquivos de backup físico;● Mais fácil identificar uso e volume de índices ou tabelas;● Mais fácil fazer ajuste de I/O e desempenho;● Uma camada a mais de segurança na criação de objetos;
![Page 29: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/29.jpg)
por Fábio Telles8 de Dezembro de 2007
Na Prática:
● No bash do Linux:#mkdir /postgresql#chown postgres /postgresql#su postgres$cd /postgresql$mkdir /postgresql/tbs_hr_index$mkdir /postgresql/tbs_hr_table$psql pgcon
![Page 30: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/30.jpg)
por Fábio Telles8 de Dezembro de 2007
Na Prática:● No psql do PostgreSQL:pgcon=#REVOKE ALL ON TABLESPACE pg_default,pg_global FROM public;pgcon=#REVOKE ALL ON SCHEMA public FROM public;pgcon=#CREATE ROLE hr NOLOGIN;pgcon=#CREATE TABLESPACE hr_index OWNER hr LOCATION '/postgresql/tbs_hr_index';pgcon=#CREATE TABLESPACE hr_table OWNER hr LOCATION '/postgresql/tbs_hr_table';CREATE SCHEMA AUTHORIZATION hr;
![Page 31: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/31.jpg)
por Fábio Telles8 de Dezembro de 2007
Quando utilizar novos TABLESPACES?
Só faz sentido utilizar muitos tablespaces se você tem ou pretende ter vários discos!
● Tablespace temporário em ambiente com muitas consultas pesadas (novo no 8.3!);
● Separar dados históricos e partições de tabelas pouco utilizadas em discos mais baratos;
● Tabelas e índices onde o desempenho é crítico;● Tabelas onde a disponibilidade é crítica;
![Page 32: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/32.jpg)
por Fábio Telles8 de Dezembro de 2007
Quando utilizar mais de um banco de dados no mesmo cluster?
● Você quer aproveitar os processos do cluster existente mas precisa comparar uma nova versão dos mesmos objetos;
● Você tem aplicações que precisam utilizar diferentes codificações de caracteres;
● NUNCA coloque um ambiente de teste e produção no mesmo cluster!
![Page 33: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/33.jpg)
por Fábio Telles8 de Dezembro de 2007
Quando utilizar mais de um cluster no mesmo Sistema Operacional?
● Você precisa utilizar um LC_COLLATE diferente;● Você precisa utilizar diferentes versões do PostgreSQL
ao mesmo tempo;● NUNCA coloque um ambiente de teste e produção no
mesmo SO!
![Page 34: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/34.jpg)
por Fábio Telles8 de Dezembro de 2007
Quando virtualizar o SO?
Sempre procure utilizar discos distintos para cada VM!● Você precisa testar uma nova versão ou funcionalidade do
PostgreSQL e não tem um ambiente de laboratório separado;● Você precisa manter o ambiente de produção junto com o
ambiente de homologação ou teste no mesmo servidor físico.● Você deseja ter múltiplos ambientes de laboratório,
homologação ou teste no mesmo servidor físico.
![Page 35: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/35.jpg)
por Fábio Telles8 de Dezembro de 2007
Equilíbrio
![Page 36: Fazendo Um Elefante Passar Debaixo da Porta - PGCon-BR](https://reader034.fdocuments.net/reader034/viewer/2022052601/55980b571a28ab3a2c8b4681/html5/thumbnails/36.jpg)
por Fábio Telles8 de Dezembro de 2007
OBRIGADO
Dúvidas, sugestões, correções, indignações e cervejas são bem vindas!
Fábio Telles Rodriguez, Consultoria em PostgreSQL, Oracle e MySQL
SAVEPOINT: http://www.midstorm.org/~telles e-mail: [email protected]