You are on page 1of 157

1

PostgreSQL Prtico
(verso 8.1.4)
Ribamar FS ribafs@users.sourceforge.net http://ribafs.tk
17 de setembro de 2006
2
N!"#
"$%&t'(o Pgi)$
1 ntroduo . . . . . . . . . . 4
2 - nstalao . . . . . . . . . 8
2.1 - No Linux
2.2 - No Windows
3 - DDL (Data Definition Language) . . . . . . . 13
3.1 - Criao e excluso de bancos, esquemas, tabelas, views, Constraints, etc
3.2 - Alteraes nos objetos dos bancos
3.3 - ndices, Tipos de Dados e ntegridade Referencial
4 - DML (Data Manipulation Language) . . . . . . . 34
4.1 - Consultas (select,insert, update e delete)
4.2 - Consultas JONS
4.3 - Sub Consultas
5 - Funes nternas . . . . . . . . 45
5.1 - Strings
5.2 - Matemticas
5.3 - Agrupamento (Agregao)
5.4 - Data/Hora
5.5 - Formatao de Tipos de Dados
5.6 - Converso de Tipos (CAST)
6 - Funes Definidas pelo Usurio e Triggers . . . . . . 55
6.1 - SQL
6.2 - PlpgSQL
6.3 Triggers
7 - DCL (Data Control Language) - Administrao . . . . . 68
7.1 - Usurios, grupos e privilgios
8 - Transaes . . . . . . . . . . 72
9 Administrao . . . . . . . . . . 75
9.1 - Backup e Restore
9.2 - mportar e Exportar
9.3 - Converter
9.4 - Otimizao e Desempenho
10 - Replicao . . . . . . . . . . 84
11 - Configuraes . . . . . . . . . . 86
10.1 - Copiar o script de inicializao dos contribs
10.2 - Adicionar ao Path
10.3 - Configurar acessos (pg_hba.conf)
10.4- Configuraes diversas (postgresql.conf)
12 Metadados (Catlogo) . . . . . . . . 92
13 - Conectividade . . . . . . . . . . 105
13.1 - Com Java (JDBC)
13.2 - Com aplicativos Windows (ODBC)
13.3 - Com PHP
13.4 - Exemplos de conexo com PHP, Java e VB
3
14 - Ferramentas . . . . . . . . . . 108
14.1 - psql
14.2 - phpPgAdmin
14.3 - PgAdmin
14.4 - EMS PostgreSQL
14.5 - Azzurry Clay (modelagem com o Eclipse)
14.6 - dbVisualizer
14.7 - OpenOffice Base
15 Apndices . . . . . . . . . . 124
15.1 Planejamento e Projeto de Bancos de Dados
15.2 mplementao de Banco de Dados com o PostgreSQL
15.3 - ntegridade Referencial - PostgreSQL
15.4 Dicas Prticas de uso do SQL
15.5 Dicas sobre Desempenho e Otimizaes do PostgreSQL
16 Exerccios . . . . . . . . . . 149
17 - Referncias . . . . . . . . . . 154
4
1 * !)trod'+o
,ist-ri$ dos S./s
Anos 60 - utilizados sistemas gerenciadores de arquivos (SAM e VSAM), usados at hoje.
Anos 70 - Gerenciadores de Bancos de dados de rede. Extinguiram-se nos anos 90.
Anos 80 - SGBDRs (Oracle, DB2, SQLServer)
Anos 90 - SGBDOR (Oracle, DB2, PostgreSQL e nformix)
Anos 90 - SGBDOO (Cach)
SGBD = Composto por programas de gerenciamento, armazenamento e acesso aos dados,
com a finalidade de tornar gil e eficiente a manipulao dos dados.
Dicionrio de dados - metadados, dados sobre os dados, ou seja, informaes sobre a
estrutura dos bancos de dados (nomes de tabelas, de campos, tipos de dados, etc).
DBA - Database Administrator, com as funes de:
- Definir e modificar esquemas, estruturas de armazenamento e mtodos de acesso
- Liberar privilgios de acesso
- Especificao de restrio de integridade
Sim%(i0ic$)do temos ()o PostgreSQL)1 em termos de estr't'r$2
- Um SGBD formado por bancos de dados, tablespaces, usurios e alguns programas
auxiliares;
- Um banco de dados formado pelos esquemas e linguagens;
- Um esquema formado por funes de agrupamento, funes, triggers, procedures,
sequncias, tabelas e views;
- Tabelas so formadas por campos, constraints, ndices e triggers.
- Em termos de dados uma tabela formada por registros e campos.
Segundo a Wikipedia (http://pt.wikipedia.org):
...
A apresentao dos dados pode ser semelhante de uma planilha eletrnica, porm os
sistemas de gesto de banco de dados possuem caractersticas especiais para o
armazenamento, classificao e recuperao dos dados.
Os bancos de dados so utilizados em muitas aplicaes, abrangendo praticamente todo o
campo dos programas de computador. Os bancos de dados so o mtodo de
armazenamento preferencial para aplicaes multiusurio, nas quais necessrio haver
coordenao entre vrios usurios. Entretanto, so convenientes tambm para indivduos, e
muitos programas de correio eletrnico e organizadores pessoais baseiam-se em tecnologias
padronizadas de bancos de dados.
Em Maro, 2004, AMR Research (como citado em um artigo da CNET News.com listado na
seco de "Referncias") previu que aplicaes de banco de dados de cdigo aberto seriam
amplamente aceitas em 2006.
#s3'em$s 4 so subdivises de bancos de dados, cuja funo permitir um melhor nvel de
organizao.
Projetos de mesma categoria, que precisem acessar uns aos outros devem ficar em um
mesmo banco, podendo ficar em esquemas separados.
5
5$be($s 4 so subdivises de um esquema, nelas realmente ficam armazenados os dados
de um banco. Uma tabela parece realmente com uma tabela em papel, tipo planilha, com
linhas e colunas. Cada linha representa um registro de banco de dados e cada cruzamento
de coluna com linha representa um campo de tabela.
Tipo de Dados de um campo restringe o conjunto de valores (domnio) que pode ser atribudo
ao campo e atribui semntica aos dados armazenados. Um campo do tipo numrico no
aceita dados do tipo texto ou similar.
"it$+o d$ !)trod'+o do doc'me)to sobre otimi6$+o do PostgreSQL
POSTGRESQL um SGBD objeto-relational (SGBDOR) desenvolvido via nternet por um
grupo de desenvolvedores espalhados pelo globo. uma alternativa de cdigo fonte-aberta
para SGBDs comerciais como Oracle e nformix.
O POSTGRESQL foi desenvolvido originalmente na Universidade de Califrnia em Berkeley.
Em 1996, um grupo comeou o desenvolvimento do SGBD na nternet. Eles usam e-mail
para compartilhar idias e servidores de arquivos para compartilhar cdigo. POSTGRESQL
agora comparvel SGBDs comerciais em termos de caractersticas, desempenho e
confiana. Hoje tem transaes, views, procedimentos armazenados, e constranints de
integridade referencial. Apia um nmero grande de interfaces de programao, como
ODBC, Java (JDBC), TCL/TK, PHP, Perl e Python, entre outros. POSTGRESQL continua
avanando a um tremendo passo, graas a um grupo talentoso de desenvolvedores via
nternet. (Bruce Momjian - 16th January 2003)
Projeto POSTGRES (1986-1994): Partiu do projeto do SGBD ngres de Berkeley. Projetista:
Michael Stonebraker.
Em 1995 dois estudantes de Berkeley (Jolly Chen e Andrew Yu) adicionam suporte a SQL.
Seu novo nome: Postgres95. Foi totalmente reescrito em C e tambm adotou a SQL. Foi
originalmente patrocinado pelo DARPA, ARO, NSF e ESL nc.
Em 1996: Disponibilizado na nternet sob o nome de PostgreSQL.
O PostgreSQL aniversariou no dia 08/07/2006, quando completou 10 anos (08/07/1996). Seu
dcimo aniversrio foi comemorado nos dias 08 e 09 de julho prximo, em Toronto, Canad,
com algumas conferncias sobre o mesmo. Atualmente est na verso 8.1.4 (14/09/2006).
P$r$ s$ber m$is sobre $ 7ist-ri$ do PostgreSQL visite o site o0ici$( em2
http://www.postgresql.org/docs/current/interactive/history.html
8' em %ort'g'9s em2
http://pgdocptbr.sourceforge.net/pg80/history.html
"$r$cter&stic$s2
O PostgreSQL suporta grande parte do SQL ANS, inclusive do SQL 2003, alm de oferecer
outros recursos importantes, como:
Comandos complexos
Chaves estrangeiras (Foreign Key)
Gatilhos (Triggers)
Vises (views)
ntegridade de Transaes
Controle de Simultaneidade Multiverso (MVCC)
Suporta mltiplas transaes online concorrentes entre usurios.
Suporte a Rules (sistema de regras que reescreve diretivas SQL)
Criao de tabelas temporrias (CREATE TEMP TABLE nome(listadecampos tipos);)
6
5r$6 t$mb:m o%+;es de e<te)so %e(o 's'rio2
Tipos de dados
Funes
Operadores
Funes de Agregao (Agrupamento)
Mtodos de ndice
Linguagens Procedurais (Stored Procedures)
Lice)+$
Sua licena BSD, portanto pode ser utilizado, modificado e distribudo por qualquer pessoa
ou empresa para qualquer finalidade, sem qualquer encargo, em quaisquer dos sistemas
operacionais suportados.
#m%res$s 3'e =ti(i6$m PostgreSQL
BASF (PDF format)
Fujitsu
Apple
RedHat
Sun
Pervasive
Mohawk Software
Proximity
Radio Paradise
Shannon Medical Center
Spiros Louis Stadium
The Dravis Group OSS Report
Vanten nc.
SRA
Rambler
Netezza
VA Software
Travel Post
National Weather Service
>%(ic$+;es "or%or$tiv$s de >(to ?o('me2 =m$ So('+o com o PostgreSQL
A utilizao da dupla PostgreSQL+Linux nas empresas cresce rapidamente e um exemplo
de como produtos Open Source podem ajudar empresas a racionalizar os custos de T. Uma
das caractersticas do PostgreSQL a sua capacidade de lidar com um grande volume de
dados. E-xistem aplicaes em produo com tabelas possuindo mais de 100 milhes de
linhas. No Brasil, existem casos de sucesso de empresas lidando com bases com dezenas
de milhes de registros gerenciadas pelo PostgreSQL.
Uma das maiores implantaes de PostgreSQL no Brasil na Atrium Telecom, empresa de
tele-fonia corporativa de So Paulo. O PostgreSQL utilizado como banco de dados do
sistema de billing e tem uma base de dados de mais de 100GB e efetua 1 milho de
transaes dirias. As maiores tabelas do sistema contam com mais de 70 milhes de linhas.
A utilizao do banco de dados PostgreSQL cada vez mais ampla nas empresas que
buscam um servidor de banco de dados altamente sofisticado, com alta performance, estvel
e capacitado para lidar com grandes volumes de dados. O fato de ser um produto Open
Source, sem custos de licena para nenhum uso, torna o PostgreSQL uma alternativa
extremamente atraente para empresas que buscam um custo total de propriedade (TCO)
menor para os ativos de T.
7
Citao de: http://www.dib.com.br/dib%20cd/LC2003/P%C3%A1ginas/LC2003_Conf.html
Metr de So Paulo e DATAPREV tambm utilizam o PostgreSQL.
Sobre o >'tor
Ribamar FS
Desenvolvedor de aplicativos web para a ntranet do DNOCS (Departamento Nacional de
Obras Contra as Secas). Desenvolve atualmente em PHP com PostgreSQL.
Trabalhou no DNOCS por algum tempo como administrador de redes Linux e FreeBSD.
graduado em Engenharia Civil pela Universidade de Fortaleza (UNFOR)
Com especializao em rrigao e Drenagem pela UFC/RYDA
Cursando Especializao em Java na UNFOR
Concluiu o Curso de PostgreSQL pela dbExpert (So Paulo) e pelo Evoluo (Fortaleza)
Concluiu o curso de Administrao Linux pelo Evoluo (Fortaleza)
Foi escritor colaborador da Revista Forum Access (na rea de Access)
escritor colaborador da Revista Web Mobile (artigo sobre Joomla 02/2006)
Foi professor de cursos de extenso na UNFOR (PHP+MySQL e PHP + PostgreSQL) em
2005 e 2006
Apresentou palestra sobre PostgreSQL na UNFOR no dia 29/03/2006.
Apresentou palestra sobre PostgreSQL na UFC no dia 21/09/2006 ( Semana de Software
Livre da UFC).
Compartilha seus conhecimentos atravs do site:
http://ribafs.tk (http://www.geocities.com/ribafsindex) e http://www.ribafs.net
8
2 4 !)st$($+o
!)st$($+o )o @i)doAs BP
Lembr$r 3'e2 no instala em sistema de arquivos FAT-32, mesmo que seja o XP em FAT-32,
ele no instala. Precisa instalar em NTFS e no instala no XP Start Edition.
- Fazer download do site oficial (www.postgresql.org) (hoje postgresql-8.1.4-1.zip)
- Executar o arquivo postgresql-8.1.msi
- Selecionar idioma e Start. Depois em Prximo.
- Na tela nformaes de nstalaes existem muitas informaes importantes:
- Sugere a leitura da FAQ
- Fala das licenas dos diversos softwares a serem instalados
- As verses 95, 98 e Me do Windows no so suportadas pelo PostgreSQL
- Usar obrigatoriamente em sistema de arquivos NTFS
- nstalar como servio (mesmo que deixe como manual)
- O PostgreSQL no executa com usurio que tenha privilgios de
administrador
- Os drivers jdbc esto no subdiretrio \jdbc, que deve ser adicionada ao
CLASSPATH
- Na Tela "Opes de nstalao" marque:
- Suporte para idioma nativo (importante para ter as mensagens em pt_BR)
- E outros que considere importantes e clique em Prximo
- Na tela "Configurao do Servio":
- Poder optar entre instalar como servio ou no. Como servio mais prtico.
Clique em Prximo (ele criar uma senha)
- Obs.: Caso j tenha instalado o PostgreSQL antes nesta mquina dever
remover o usurio "postgres" antes de continuar:
- Painel de controle - Ferramentas administrativas - Gerenciamento do
computador - Usurios e grupos locais - Usurios. Remova o "postgres"
- Agora clique em Prximo e Sim
- Na tela "nicializar o agrupamento de bancos de dados:
- Caso precise acessar sua mquina de outra remota marque Endereos
- Em Locale selecione Portugus Brasil
- Em Codificao selecione LATN1
- Entre com uma senha e repita. Altere o usurio se for o caso e Prximo.
- Na tela "Habilitar Linguagens Procedurais" deixe marcada PL/pgsql e Prximo
- Na tela "Habilitar Mdulos Contrib" marque os desejados e Prximo
- Na tela "Habilitar PostGS em templae1" marque se precisar que todos os bancos tragam o
PostGS e Prximo e Prximo.
- Aps instalar, na tela "nstalao concluda" recomenda-se que se cadastrar na
lista pgsql-announce, que envia informaes semanais sobre novas verses e correes de
error. Basta clicar no boto, fazer o cadastro e Concluir.
Editar postgresql.conf e adicionar a linha (datestyle = 'sql european'), aps a existente.
9
Pr:*re3'isitos %$r$ i)st$($+o do PostgreSQL )'m =N!B2
make do GNU (gmake ou make)
compilador C, preferido GCC mais recente
gzip
biblioteca readline (para psql)
gettext (para NLS)
kerberos, openssl e pam (opcional, para autenticao)
!)st$($+o )o Li)'<
Vrias distribuies j contam com binrios para instalao do PostgreSQL (Ubuntu, Debian,
Slackware, RedHat, Fedora, etc).
#m 'm$ i)st$($+o %$dro do =b')t' veC$ o 3'e %recis$ %$r$ i)st$($r os 0o)tes2
Antes de instalar:
sudo apt-get install build-essential
sudo apt-get install libreadline-dev
sudo apt-get install zlib1g-dev
sudo apt-get install gettext
E use make ao invs de gmake.
Mas caso queira ter um controle maior instalando os fontes, apenas faa o download e
descompacte (gosto de descompactar em /usr/local/src e instalar no diretrio default, que
/usr/local/pgsql).
nstalar pelos binrios da distribuio tem as vantagens de j instalar e configurar
praticamente tudo automaticamente, mas instalar dos fontes d um maior controle sobre as
configuraes (voc sabe que tudo ficar no /usr/local/pgsql), possibilidade de instalar
sempre a ltima verso.
Aqui a instalao no modo texto, mas mesmo assim no d trabalho. Aps descompactar
visualize ou edite o arquivo NSTALL e siga as recomendaes resumidas existentes no
incio do arquivo, reproduzidas abaixo:
make distclean (adicionei, para o caso de ter que repetir os procedimentos)
./configure
make (build construir)
su (mudar para superusurio, ou no Ubuntu usar sudo para as linhas abaixo)
make install (instalar)
groupadd postgres (criar o grupo postgres)
useradd -g postgres -d /usr/local/pgsql postgres (criar o usurio postgres)
mkdir /usr/local/pgsql/data
chon postgres /usr/local/pgsql/data (tornar o postgres dono da pasta data)
passd postgres
su - postgres (se logar como postgres)
/usr/local/pgsql/bin/initdb -! /usr/local/pgsql/data
/usr/local/pgsql/bin/postmaster -! /usr/local/pgsql/data "logfile #"$% $ (startar)
/usr/local/pgsql/bin/createdb test
/usr/local/pgsql/bin/psql test
&pcionalmente'
./configure enable-nls(pt)*+ ith-openssl (para mensagens em portugu,s e autentica-.o
//0).
10
"o%i$r o scri%t de i)ici$(i6$+o D(i)'<E %$r$ o FetcFi)it.d (ebi$)s)2
De /usr/local/src/postgresql-8.1.4/contrib/start-script/linux para /etc/init.d/postgresql
Dar permisso de execuo: chmod u+x /etc/init.d/postgresql
Se no Ubuntu ou outro Debian:
su - postgres
gedit .bash_profile (e adicione a linha):
PATH=/usr/local/pgsql/bin:$PATH
P-s !)st$($+o (s71b$s71Gs7 e 6s7)2
LD_LBRARY_PATH=/usr/local/pgsql/lib
export LD_LBRARY_PATH
Ou no ~/.bash_profile do usurio postgres
initdb inicializa o cluster, cria os scripts de configurao default.
postmaster inicia o processo do servidor responsvel por escutar por pedidos de conexo.
Para suporte aos locales do Brasil usar:
/usr/local/pgsql/bin/initdb -locale=pt_BR -D /usr/local/pgsql/data
A instalao via fontes (sources) em algumas distribuies muito enxutas, voltadas para para
desktop, pode no funcionar da primeira vez, pois faltaro algumas bibliotecas, compiladores,
etc.
Aps a instalao est criado o agrupamento principal (cluster main) de bancos de dados do
PostgreSQL.
Caso no se tenha confiana nos usurios locais recomendvel utilizar a opo -W, --
pwprompt ou pwfile do initdb, que atribuir uma senha ao superusurio.
No arquivo pg_hba.conf utilizar autenticao tipo md5, password ou cript, antes de iniciar o
servidor pela primeira vez.
Quando o programa que inicia o servidor (postmaster) est em execuo, criado um PD e
armazenado dentro do arquivo postmaster.pid, dentro do subdiretrio data. Ele impede que
mais de um processo postmaster seja executado usando o mesmo cluster e diretrio de
dados.
/$i<$r PostgreSQL vi$ >)o)Hmo's "?S2
Baixar CVS de - http://www.nongnu.org/cvs/
!)st$($r e Log$r com 3'$(3'er se)7$2
cvs -d :pserver:anoncvs@anoncvs.postgresql.org:/projects/cvsroot login
/$i<$r 0o)tes2
cvs -z3 -d :pserver:anoncvs@anoncvs.postgresql.org:/projects/cvsroot co -P pgsql
sto ir instalar o PostgreSQL num subdiretrio pgsql do diretrio atual.
>t'$(i6$r $ I(tim$ i)st$($+o vi$ "?S2
Acesse o diretrio pgsql e execute - cvs -z3 update -d -P
sto ir baixar somente as alteraes ocorridas aps a ltima instalao.
11
5$mb:m %odemos cri$r 'm $r3'ivo .cvsrc )o 7ome do 's'rio com $s d'$s (i)7$s2
cvs -z3
update -d -P
>t'$(i6$+o do PostgreSQL e)tre ?ers;es
Caso voc tenha uma verso que no seja 8.1.x e esteja querendo instalar a 8.1.4, ento
precisa fazer um backup dos seus dados e restaurar logo aps a instalao como sugerido
em seguida. Ser assumido que sua instalao foi em:
/usr/local/pgsql e seus dados no sub data. Caso contrrio atenha-se ao seu path para
ajustes.
1 Ateno para que seus bancos no estejam recebendo atualizao durante o backup. Se
preciso proba acesso no pg_hba.conf.
2 Efetuando backup:
pg_dumpall > bancos.sql .Para preservar os ODs use a opo -o no pg_dumpall.
3 Pare o servidor
pg_ctl stop ou outro comando
Caso queira instalar a nova verso no mesmo diretrio da anterior
mv /usr/local/pgsql /usr/local/pgsql.old
Ento instale a nova verso, crie o diretrio de dados e start o novo servidor.
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
/usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data
Finalmente, restore seus dados com
/usr/local/pgsql/bin/psql -d postgres -f bancos.sql
P$r$ m$is det$(7es sobre os %rocedime)tos de i)st$($+o1 veC$ ite)s 14.J e 14.6 do
m$)'$(.
P($t$0orm$s S'%ort$d$s
Atualmente o PostgreSQL suporta muitas plataformas, entre elas o Windows, Linux,
FreeBSD, NetBSD, OpenBSD, Mac OS e diversos outros. Plataformas suportadas e as no
suportadas na seo 14.7 do manual oficial.
No PostgreSQL o processo postmaster escuta por conexes dos clientes.
Existem mais dois processos tambm iniciados, ambos com nome postgres. Eles cuidam da
gravao dos logs ou tabelas e da manuteno das estatsticas.
Para cada conexo com uma aplicao cliente criado um novo processo com o mesmo
nome do usurio da conexo. Por isso importante que cada aplicativo tenha seu usurio e
se tenha um maior controle.
Os arquivos de configurao (postgresql.conf, pg_hba.conf e pg_ident.conf) a partir da
verso 8 podem ficar em diretrio diferente do PGDATA.
12
S'gesto de P$dro
Nomes de bancos no plural
Nomes de tabelas no singular
Exemplo:
banco clientes
tabela - cliente
"ri$r Novo "('ster
Caso sinta necessidade pode criar outros clusters, especialmente indicado para grupos de
tabelas com muito acesso.
O comando para criar um novo cluster na verso atual (8.1.3) do PostgreSQL :
banco=# \h create tablespace
Comando: CREATE TABLESPACE
Descrio: define uma nova tablespace
Sintaxe:
CREATE TABLESPACE nome_tablespace [ OWNER usurio ] LOCATON 'diretrio'
#<em%(o2
CREATE TABLESPACE ncluster OWNER usurio LOCATON '/usr/local/pgsql/nc';
CREATE TABLESPACE ncluster [OWNER postgres] LOCATON 'c:\\ncluster';
O diretrio deve estar vazio e pertencer ao usurio.
Criando um banco no novo cluster:
CREATE DATABASE bdcluster TABLESPACE = ncluster;
Obs: Podem existir numa mesma mquina vrios agrupamentos de bancos de dados
(cluster) gerenciados por um mesmo ou por diferentes postmasters.
Se usando tablespace o gerenciamento ser de um mesmo postmaster, se inicializados por
outro initdb ser por outro.
Set$r o 5$b(es%$ce de0$'(t2
SET default_tablespace = tablespace1;
List$r os 5$b(es%$ces e<iste)tes2
\db
SELECT spcname FROM pg_tablespace;
et$(7es e<tr$s )o item 14.J do m$)'$( o0ici$(.
13
K * L ($t$ e0i)itio) L$)g'$ge)
K.1 * "ri$+o e e<c('so de b$)cos1 es3'em$s1 t$be($s1 vieAs1 etc
Obs.: Nomes de objetos e campos no podem usar hfen (-). Alternativamente usar
sublinhado (_).
campo-1 nvlido
campo_1 Vlido
Nomes de !de)ti0ic$dores
Utiliza-se por conveno as palavras chaves do SQL em maisculas e os identificadores dos
objetos que criamos em minsculas.
dentificadores digitados em maisculas sero gravados em minsculas, a no ser que
venham entre aspas ".
Levis;es d$ Li)g'$gem SQL
SQL 1989
SQL 1992
SQL 1999
SQL 2003
ivis;es d$ SQL
DML Linguagem de Manipulao de Dados
DDL Linguagem de Definio de Dados
DCL Linguagem de Controle de Dados (autorizao de dados e licena de usurios para
controlar quem tem acesso aos dados).
DQL Linguagem de Consulta de Dados (Tem apenas um comando: SELECT).
14
#<em%(o .r0ico de "o)s'(t$s (5$be($1 com c$m%os "11 "2)
(Adaptao de exemplo da Wikipedia (http://pt.wikipedia.org)
5$be($ 5 "o)s'(t$ Les'(t$do
C1 C2 SELECT * FROM T C1 C2
1 a 1 a
2 b 2 b
C1 C2 SELECT C1 FROM T C1
1 a 1
2 b 2
C1 C2 SELECT * FROM T WHERE C1=1 C1 C2
1 a 1 a
2 b
C1 C2 SELECT C1 FROM T WHERE C2=b C1
1 A 2
2 B
"ri$r /$)co
banco=# \h create database
Comando: CREATE DATABASE
Descrio: cria um novo banco de dados
Sintaxe:
CREATE DATABASE nome
[ [ WTH ] [ OWNER [=] dono_bd ]
[ TEMPLATE [=] modelo ]
[ ENCODNG [=] codificao ]
[ TABLESPACE [=] tablespace ] ]
[ CONNECTON LMT [=] limite_con ] ]
CREATE DATABASE nomebanco;
#<c('i)do =m /$)co
DROP DATABASE nomebanco;
List$r os b$)cos e<iste)tes2
\l - - No psql
psql -l (no prompt)
SELECT datname FROM pg_database;
Quando se cria um novo banco de dados sem indicar o modelo, o que de fato estamos
fazendo clonar o banco de dados template1.
15
"ri$r 'm b$)co %$r$ o'tro 's'rio2
CREATE DATABASE nomebanco OWNER nomeuser;
createdb -O nomeusuario nomebanco
Obs.: requer ser superusurio para poder criar banco para outro usurio.
"ri$r 5$be($
postgres=# \h create table
Comando: CREATE TABLE
Descrio: define uma nova tabela
Sintaxe:
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE nome_tabela ( [
{ nome_coluna tipo_dado [ DEFAULT expresso_padro ] [ restrio_coluna [ ... ] ]
| restrio_tabela
| LKE tabela_pai [ { NCLUDNG | EXCLUDNG } DEFAULTS ] }
[, ... ]
] )
[ NHERTS ( tabela_pai [, ... ] ) ]
[ WTH ODS | WTHOUT ODS ]
[ ON COMMT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace ]
o)de restri+oMco(')$ :2
[ CONSTRANT nome_restrio ]
{ NOT NULL |
NULL |
UNQUE [ USNG NDEX TABLESPACE tablespace ] |
PRMARY KEY [ USNG NDEX TABLESPACE tablespace ] |
CHECK (expresso) |
REFERENCES tabela_ref [ ( coluna_ref ) ] [ MATCH FULL | MATCH PARTAL | MATCH
SMPLE ]
[ ON DELETE ao ] [ ON UPDATE ao ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ NTALLY DEFERRED | NTALLY MMEDATE ]
e restri+oMt$be($ :2
[ CONSTRANT nome_restrio ]
{ UNQUE ( nome_coluna [, ... ] ) [ USNG NDEX TABLESPACE tablespace ] |
PRMARY KEY ( nome_coluna [, ... ] ) [ USNG NDEX TABLESPACE tablespace ] |
CHECK ( expresso ) |
FOREGN KEY ( nome_coluna [, ... ] ) REFERENCES tabela_ref [ ( coluna_ref [, ... ] ) ]
[ MATCH FULL | MATCH PARTAL | MATCH SMPLE ] [ ON DELETE ao ] [ ON UPDATE
ao ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ NTALLY DEFERRED | NTALLY MMEDATE ]
Obs.: Ateno: nesta verso (8.1.3) WTH OD opcional. As tabelas so criadas sem OD.
\d visualizar tabelas e outros objetos
\d nometabela visualizar estrutura da tabela
16
CREATE TABLE primeira_tabela (
primeiro_campo text,
segundo_campo integer
);
#<c('i)do 5$be($
DROP TABLE primeira_tabela;
?$(or e0$'(t (%$dro) P$r$ "$m%os
Ao definir um valor default para um campo, ao ser cadastrado o registro e este campo no for
informado, o valor default assumido. Caso no seja declarado explicitamente um valor
default, o valor nulo (NULL) ser o valor default.
CREATE TABLE produtos (
produto_no integer,
descricao text,
preco numeric DEFAULT 9.99
);
"o)str$i)ts (Lestri+;es)
",#"N
Ao criar uma tabela podemos prever que o banco exija que o valor de um campo satisfaa
uma expresso
CREATE TABLE produtos (
produto_no integer,
descricao text,
preco numeric CHECK (preco > 0)
);
Dando nome restrio check. !sso $C'd$ $ tor)$r m$is $migve( $s me)s$ge)s de
erro.
CREATE TABLE produtos (
produto_no integer,
descricao text,
preco numeric CONSTRANT preco_positivo CHECK (preco > 0)
);
CREATE TABLE produtos (
produto_no integer,
descricao text,
desconto numeric CHECK (desconto > 0 AND desconto < 0.10),
preco numeric CONSTRANT preco_positivo CHECK (preco > 0),
check (preco > desconto)
);
"o)str$i)t N85 N=LL
Obrigar o preenchimento de um campo. deal para campos importantes que no devem ficar
sem preenchimento. Mas devemos ter em mente que at um espao em branco atende a
esta restrio.
CREATE TABLE produtos (
cod_prod integer NOT NULL CHECK (cod_prod > 0),
17
nome text NOT NULL,
preco numeric
);
Obs importante: nulos no so checados. UNQUE no aceita valores repetidos, mas aceita
vrios nulos (j que estes no so checados). Cuidado com NULLs.
=)i3'e "o)str$i)t
8brig$r v$(ores e<c('sivos %$r$ c$d$ c$m%o em todos os registros
CREATE TABLE produtos (
cod_prod integer UNQUE,
nome text,
preco numeric
);
CREATE TABLE produtos (
cod_prod integer,
nome text,
preco numeric,
UNQUE (cod_prod)
);
CREATE TABLE exemplo (
a integer,
b integer,
c integer,
UNQUE (a, c)
);
CREATE TABLE produtos (
cod_prod integer CONSTRANT unq_cod_prod UNQUE,
nome text,
preco numeric
);
Evitando duplicao com nulos:
create table teste(
id serial not null,
parent integer null,
component integer not null
);
postgres=# create unique index naoduplic on teste using btree (component) where (parent is
null);
18
"7$ves Primri$s (Prim$rH NeH)
A chave primria de uma tabela formada internamente pela combinao das constraints
UNQUE e NOT NULL. Uma tabela pode ter no mximo uma chave primria. A teoria de
bancos de dados relacional dita que toda tabela deve ter uma chave primria. O PostgreSQL
no obriga que uma tabela tenha chave primria, mas recomendvel seguir, a no ser que
esteja criando uma tabela para importar de outra que contenha registros duplicados para
tratamento futuro ou algo parecido.
CREATE TABLE produtos (
cod_prod integer UNQUE NOT NULL,
nome text,
preco numeric
);
CREATE TABLE produtos (
cod_prod integer PRMARY KEY,
nome text,
preco numeric
);
CREATE TABLE exemplo (
a integer,
b integer,
c integer,
PRMARY KEY (a, c)
);
"7$ve #str$)geir$ (Ooreig) NeH)
Criadas com o objetivo de relacionar duas tabelas, mantendo a integridade referencial entre
ambas. Especifica que o valor da coluna (ou grupo de colunas) deve corresponder a algum
valor existente em um registro da outra tabela. Normalmente queremos que na tabela
estrangeira existam somente registros que tenham um registro relacionado na tabela
principal. Como tambm garantir que no se remova um registro na tabela principal que
tenha registros relacionados na estrangeira.
Tabela primria
CREATE TABLE produtos (
cod_prod integer PRMARY KEY,
nome text,
preco numeric
);
CREATE TABLE pedidos (
cod_pedido integer PRMARY KEY,
cod_prod integer,
quantidade integer,
CONSTRANT pedidos_fk FOREGN KEY (cod_prod) REFERENCES produtos (cod_prod)
);
19
CREATE TABLE t0 (
a integer PRMARY KEY,
b integer,
c integer,
FOREGN KEY (b, c) REFERENCES outra_tabela - - a coluna de destino ser a PK
);
CREATE TABLE t1 (
a integer PRMARY KEY,
b integer,
c integer,
FOREGN KEY (b, c) REFERENCES outra_tabela (c1, c2)
);
OBS.: Preferir sempre criar FK, utilizando a palavra reservada FOREGN KEY e no somente
com REFERENCES.
Obviamente, o nmero de colunas e tipo na restrio devem ser semelhantes ao nmero e
tipo das colunas referenciadas.
SMULANDO ENUM
Para simular a constraint enum do MySQL, podemos usar a constraint check.
Dica do site "PostgreSQL & PHP Tutorials".
CREATE TABLE pessoa(
codigo int null primary key,
cor_favorita varchar(255) not null,
check (cor_favorita N ('vermelha', 'verde', 'azul'))
);
NSERT NTO pessoa (codigo, cor_favorita) values (1, 'vermelha'); -- OK
NSERT NTO pessoa (codigo, cor_favorita) values (1, 'amarela'); -- Erro, amarelo no consta
,er$)+$
Podemos criar uma tabela que herda todos os campos de outra tabela existente.
CREATE TABLE cidades (
nome text,
populacao float,
altitude int -- (em ps)
);
CREATE TABLE capitais (
estado char(2)
) NHERTS (cidades);
capitais assim passa a ter tambm todos os campos da tabela cidades.
Seg')do 'm$ e)trevist$ (vide /Oree P$g$6i)e No. 2) com $ e3'i%e de
dese)vo(vime)to do PostgreSQL1 evite 'ti(i6$r 7er$)+$ de t$be($s.
#s3'em$s (Sc7em$)
20
\dn visualizar esquemas
Um banco de dados pode conter vrios esquemas e dentro de cada um desses podemos
criar vrias tabelas. Ao invs de criar vrios bancos de dados, criamos um e criamos
esquemas dentro desse. sso permite uma maior flexibilidade, pois uma nica conexo ao
banco permite acessar todos os esquemas e suas tabelas. Portanto devemos planejar bem
para saber quantos bancos precisaremos, quantos esquemas em cada banco e quantas
tabelas em cada esquema.
Cada banco ao ser criado traz um esquema public, que onde ficam todas as tabelas, caso
no seja criado outro esquema. Este esquema public no padro ANS. Caso se pretenda
ao portvel devemos excluir este esquema public e criar outros. Por default todos os usurios
criados tem privilgio CREATE e USAGE para o esquema public.
"ri$)do =m #s3'em$
CREATE SCHEMA nomeesquema;
#<c('i)do =m #s3'em$
DROP SCHEMA nomeesquema;
Aqui, quando o esquema tem tabelas em seu interior, no possvel apagar dessa forma,
temos que utilizar:
DROP SCHEMA nomeesquema CASCADE;
Que apaga o esquema e todas as suas tabelas, portanto muito cuidado.
Obs.: O padro SQL exige que se especifique RESTRCT (default no PostgreSQL) OU
CASCADE, mas nenhum SGBD segue esta recomendao.
Obs.: recomendado ser explcito quanto aos campos a serem retornados, ao invs de usar
* para todos, entrar com os nomes de todos os campos. Assim fica mais claro. Alm do mais
a consulta ter um melhor desempenho.
>cess$)do 5$be($s #m #s3'em$s
SELECT * FROM nomeesquema.nometabela;
Privi(:gios #m #s3'em$s
\dp visualizar permisses
REVOKE CREATE ON SCHEMA public FROM PUBLC; - - Remove o privilgio CREATE de
todos os usurios.
8bte)do !)0orm$+;es sobre os #s3'em$s2
\dn
\df current_schema*
SELECT current_schema();
SELECT current_schemas(true);
SELECT current_schemas(false);
?is;es (vieAs)
\dp visualizar views e outros objetos
Q'e so ?!#@SQ
21
So uma maneira simples de executar e exibir dados selecionados de consultas complexas
em bancos.
Em que elas so teis? Elas economizam grande quantidade de digitao e esforo e
apresentam somente os dados que desejamos.
"ri$)do =m$ ?ieA
CREATE VEW recent_shipments
AS SELECT count(*) AS num_shipped, max(ship_date), title
FROM shipments
JON editions USNG (isbn)
NATURAL JON books AS b (book_id)
GROUP BY b.title
ORDER BY num_shipped DESC;
=s$)do =m$ ?ieA
SELECT * FROM recent_shipments;
SELECT * FROM recent_shipments
ORDER BY max DESC
LMT 3;
estr'i)do =m$ ?ieA
DROP VEW nomeview;
"ri$r $s 5$be($s 3'e serviro de /$se
CREATE TABLE client (
clientid SERAL NOT NULL PRMARY KEY,
clientname VARCHAR(255)
);
CREATE TABLE clientcontact (
contactid SERAL NOT NULL PRMARY KEY,
clientid int CONSTRANT client_contact_check REFERENCES client(clientid),
name VARCHAR(255),
phone VARCHAR(255),
fax VARCHAR(255),
emailaddress VARCHAR(255)
);
CREATE VEW client_contact_list AS
SELECT client.clientid, clientname, name, emailaddress FROM client, clientcontact
WHERE client.clientid = clientcontact.clientid;
Estando no psql e digitando \d podemos visualizar tambm as views.
O nome da viso deve ser distinto do nome de qualquer outra viso, tabela, seqncia ou
ndice no mesmo esquema.
A viso no materializada fisicamente. Em vez disso, a consulta executada toda vez que
a viso referenciada em uma consulta.
Fazer livre uso de vises um aspecto chave de um bom projeto de banco de dados SQL.
As vises podem ser utilizadas em praticamente todos os lugares onde uma tabela real pode
ser utilizada. Construir vises baseadas em vises no raro.
Atualmente, as vises so somente para leitura: o sistema no permite insero, atualizao
22
ou excluso em uma viso. possvel obter o efeito de uma viso atualizvel criando regras
que reescrevem as inseres, etc. na viso como aes apropriadas em outras tabelas. Para
obter informaes adicionais consulte o comando CREATE RULE.
CREATE VEW vista AS SELECT 'Hello World';
ruim por dois motivos: o nome padro da coluna ?column?, e o tipo de dado padro da
coluna unknown. Se for desejado um literal cadeia de caracteres no resultado da viso
deve ser utilizado algo como CREATE VEW vista AS SELECT text 'Hello World' AS hello;
?eC$ c$%&t'(o 4 do Livro RPr$tic$( PostgreSQLR
Supondo que uma consulta seja de particular interesse para uma aplicao, mas que no se
deseja digitar esta consulta toda vez que for necessria, ento possvel criar uma view
baseada na consulta, atribuindo um nome a esta consulta pelo qual ser possvel referenci-
la como se fosse uma tabela comum.
CREATE VEW minha_view AS
SELECT cidade, temp_min, temp_max, prcp, data, localizacao
FROM clima, cidades
WHERE cidade = nome;
SELECT * FROM minha_visao;
Fazer livre uso de vises um aspecto chave de um bom projeto de banco de dados SQL.
As vises permitem encapsular, atrs de interfaces que no mudam, os detalhes da estrutura
das tabelas, que podem mudar na medida em que as aplicaes evoluem.
As vises podem ser utilizadas em praticamente todos os lugares onde uma tabela real pode
ser utilizada. Construir vises baseadas em vises no raro.
L=L#S
O comando CREATE RULE cria uma regra aplicada tabela ou viso especificada.
Uma regra faz com que comandos adicionais sejam executados quando um determinado
comando executado em uma determinada tabela.
importante perceber que a regra , na realidade, um mecanismo de transformao de
comando, ou uma macro de comando.
possvel criar a iluso de uma viso atualizvel definindo regras ON NSERT, ON UPDATE
e ON DELETE, ou qualquer subconjunto destas que seja suficiente para as finalidades
desejadas, para substituir as aes de atualizao na viso por atualizaes apropriadas em
outras tabelas.
23
Existe algo a ser lembrado quando se tenta utilizar regras condicionais para atualizao de
vises: obrigatrio haver uma regra incondicional NSTEAD para cada ao que se deseja
permitir na viso. Se a regra for condicional, ou no for NSTEAD, ento o sistema continuar
a rejeitar as tentativas de realizar a ao de atualizao, porque acha que poder acabar
tentando realizar a ao sobre a tabela fictcia da viso em alguns casos.
banco=# \h create rule
Comando: CREATE RULE
Descrio: define uma nova regra de reescrita
Sintaxe:
CREATE [ OR REPLACE ] RULE nome AS ON evento
TO tabela [ WHERE condio ]
DO [ ALSO | NSTEAD ] { NOTHNG | comando | ( comando ; comando ... ) }
O comando CREATE RULE cria uma regra aplicada tabela ou viso especificada.
eve)to
Evento um entre SELECT, NSERT, UPDATE e DELETE.
co)di+o
Qualquer expresso condicional SQL (retornando boolean). A expresso condicional no
pode fazer referncia a nenhuma tabela, exceto NEW e OLD, e no pode conter funes de
agregao.
!NS5#>
NSTEAD indica que os comandos devem ser executados em vez dos (instead of) comandos
originais.
>LS8
ALSO indica que os comandos devem ser executados adicionalmente aos comandos
originais.
Se no for especificado nem ALSO nem NSTEAD, ALSO o padro.
com$)do
O comando ou comandos que compem a ao da regra. Os comandos vlidos so
SELECT, NSERT, UPDATE, DELETE e NOTFY.
Dentro da condio e do comando, os nomes especiais de tabela NEW e OLD podem ser
usados para fazer referncia aos valores na tabela referenciada. O NEW vlido nas regras
ON NSERT e ON UPDATE, para fazer referncia nova linha sendo inserida ou atualizada.
O OLD vlido nas regras ON UPDATE e ON DELETE, para fazer referncia linha
existente sendo atualizada ou excluda.
Obs.: necessrio possuir o privilgio RULE na tabela para poder definir uma regra para a
mesma.
#<em%(os2
CREATE RULE me_notifique AS ON UPDATE TO datas DO ALSO NOTFY datas;
CREATE RULE r1 AS ON NSERT TO TBL1 DO
(NSERT NTO TBL2 VALUES (new.i); NOTFY TBL2);
CREATE RULE "_RETURN" AS ON SELECT TO minha_viso DO NSTEAD
SELECT * FROM minha_tabela; -- Ao invs de selecionar da viso seleciona da tabela.
24
/$)co de d$dos mode(o i)toc$do
Existe um modelo de banco de dados que sempre se preserva original, que o template0. O
template template1 pode incorporar objetos e acaba algumas vezes ficando invivel seu uso
como modelo. Quando isso acontece podemos substitui-lo com uma cpia do template0.
"ri$)do b$)co de d$dos b$se$do em o'tro mode(o
CREATE DATABSASE nomebanco TEMPLATE template0;
createdb -T template0 nomebanco
Lecri$)do o tem%($te1
\c testes
postgres=# UPDATE pg_database SET datistemplate=false WHERE datname='template1';
testes=# DROP DATABASE template1;
testes=# CREATE DATABASE template1 TEMPLATE template0 ENCODNG 'latin1';
testes=# \c template1
template1=# VACUUM FULL FREEZE;
template1=# VACUUM FULL;
template1=# UPDATE pg_database SET datistemplate=true WHERE datname='template1';
>gor$ temos 'm tem%($te1 origi)$( e (im%o.
K.2 * >(ter$+;es )os obCetos dos b$)cos
Adicionar campo, remover campo, adicionar constraint, remover constraint, alterar valor
default, alterar nome de campo, alterar nome de tabela, alterar tipo de dado de campo
(>=8.0).
>dicio)$r =m "$m%o
ALTER TABLE tabela ADD COLUMN campo tipo;
ALTER TABLE produtos ADD COLUMN descricao text;
Lemover "$m%o
ALTER TABLE tabela DROP COLUMN campo;
ALTER TABLE produtos DROP COLUMN descricao;
ALTER TABLE produtos DROP COLUMN descricao CASCADE; -- Cuidado com CASCADE
>dicio)$r "o)str$i)t
ALTER TABLE tabela ADD CONSTRANT nome;
ALTER TABLE produtos ADD COLUMN descricao text CHECK (descricao <> '');
ALTER TABLE produtos ADD CHECK (nome <> '');
ALTER TABLE produtos ADD CONSTRANT unique_cod_prod UNQUE (cod_prod);
ALTER TABLE produtos ADD FOREGN KEY (cod_produtos) REFERENCES
grupo_produtos;
ALTER TABLE produtos ADD CONSTRANT vendas_fk FOREGN KEY (cod_produtos)
REFERENCES produtos (codigo);
25
Lemover "o)str$i)t
ALTER TABLE tabela DROP CONSTRANT nome;
ALTER TABLE produtos DROP CONSTRANT produtos_pk;
ALTERAR VALOR DEFAULT DE CAMPO:
P'd$r 5i%o de $dos de "$m%o (S- ST8.0)2
ALTER TABLE tabela ALTER COLUMN campo TYPE tipo;
ALTER TABLE produtos ALTER COLUMN preco TYPE numeric(10,2);
ALTER TABLE produtos ALTER COLUMN data TYPE DATE USNG CAST (data AS DATE);
P'd$r Nome e "$m%o
ALTER TABLE tabela RENAME COLUMN campo_atual TO campo_novo;
ALTER TABLE produtos RENAME COLUMN cod_prod TO cod_produto;
Set$rFLemover ?$(or e0$'(t de "$m%o
ALTER TABLE tabela ALTER COLUMN campo SET DEFAULT valor;
ALTER TABLE produtos ALTER COLUMN cod_prod SET DEFAULT 0;
ALTER TABLE produtos ALTER COLUMN preco SET DEFAULT 7.77;
ALTER TABLE tabela ALTER COLUMN campo DROP DEFAULT;
ALTER TABLE produtos ALTER COLUMN preco DROP DEFAULT;
>dicio)$rFLemover N85 N=LL
ALTER TABLE produtos ALTER COLUMN cod_prod SET NOT NULL;
ALTER TABLE produtos ALTER COLUMN cod_prod DROP NOT NULL;
Le)ome$r 5$be($
ALTER TABLE tabela RENAME TO nomenovo;
ALTER TABLE produtos RENAME TO equipamentos;
>dicio)$r "o)str$i)t (Lestri+o)
ALTER TABLE produtos ADD CONSTRANT produtos_pk PRMARY KEY (codigo);
ALTER TABLE vendas ADD CONSTRANT vendas_fk FOREGN KEY (codigo)
REFERENCES produtos(codigo_produto);
ALTER TABLE vendas ADD CONSTRANT vendas_fk FOREGN KEY (codigo)
REFERENCES produtos; -- Neste caso usa a chave primria da tabela produtos
Lemover "o)str$i)t (Lestri+o)
ALTER TABLE produtos DROP CONSTRANT produtos_pk;
ALTER TABLE vendas DROP CONSTRANT vendas_fk;
K.K * )dices1 5i%os de $dos e !)tegrid$de Le0ere)ci$(
importante conhecer bem o mximo de recursos existentes no banco, especialmente
aqueles relacionados s nossas necessidades. Assim trabalhamos com mais eficincia e
criamos bancos mais leves e com mais potencial. Os tipos de dados so fatores de
desempenho.
Exemplo:
Se um campo tipo inteiro ir precisar de valores at 100 e nunca mudar esta faixa. No
devemos usar este campo com o tipo NT8, quando o NT2 atende e sobra.
De forma semelhante escolher todos os demais campos da tabela com bom senso.
P$is et$(7es )o "$%&t'(o 8 do P$)'$(2
7tt%2FF%gdoc%tbr.so'rce0orge.)etF%g80Fd$t$tH%e.7tm(
26
)dices
Os ndices so recursos do SGBD para melhorar o desempenho de consultas. Mas como o
uso de ndices tambm tem um preo importante planejar bem e conhecer as
particularidades antes de adicionar um ndice.
Cada vez que um registro inserido ou atualizado a tabela de ndices tambm atualizada.
Quando criamos consultas SQL, que pesquisam tabelas com muitos registros e esta consulta
usa a clusula WHERE, ento os campos que fazem parte da clusula WHERE so bastante
indicados para ndice, para que melhore o desempenho da consulta.
Os ndices so uma forma de melhorar o desempenho de bancos de dados. Ao invs de
procurar de forma sequencial, o servidor procura pelo ndice, como se faz uma busca em
ndices de livros e vai-se diretamente pgina procurada.
O ndice passado para cada registro adicionado ou removido.
difcil criar regras genricas para determinar que ndices devem ser definidos. Muita
experincia por parte do administrador e muita verificao experimental necessria na
maioria dos casos.
"ri$r 'm &)dice2
CREATE NDEX nomeindice ON tabela (campo);
Regra geral para nome de ndice: idx_nometabela_nomecampo
8bs.2 &)dices )o im%ort$)tes o' )o 'ti(i6$dos devem ser removidos.
Lemover &)dice2
DROP NDEX nomeindice;
"ri$r 'm &)dice U)ico2
CREATE UNQUE NDEX nomeindice ON tabela (campo);
Obs.: Somente os ndices tipo B-tree podem ser do tipo Unique.
"ri$r 'm &)dice com vri$s co(')$s2
CREATE NDEX idx_clientes_ps ON clientes (codigo, nome);
Boa indicao para consultas com WHERE...AND. Ao usar OR o ndice no ser utilizado
pelo PostgreSQL:
SELECT nome FROM clientes WHERE codigo = 12 AND nome = 'Joo';
Usar ndices com vrias colunas com moderao. ndices com mais de 3 colunas tem
grandes possibilidades de no serem utilizados internamente.
27
5i%os de )dices
O PostgreSQL suporta atualmente quatro tipos de ndices: B-tree (rvore B), R-tree (rvore
R), Hash e GiST.
/*tree *S o tipo padro (assume quando no indicamos). So ndices que podem tratar
consultas de igualdade e de faixa, em dados que podem ser classificados.
ndicado para consultas com os operadores: <, <=, =, >=, >. Tambm pode ser utilizado com
LKE, LKE, ~ e ~*.
L*tree *S tipo mais adequado a dados espaciais. Adequado para consultas com os
operadores: <<, &<, &>, >>, @, ~=, &&.
,$s7 *Sindicados para consultas com comparaes de igualdade simples. desencorajado
seu uso. Em seu lugar recomenda-se o B-tree.
.iS5 *S
"ri$)do &)dices de ti%os di0ere)tes2
CREATE NDEX nome ON tabela USNG tipo (campo);
tipo: BTREE, RTREE, HASH, GST
Obs.: Somente os tipos B-tree e GiST suportam ndices com vrias colunas.
ndices com mais de um campo somente ser utilizado se as clusulas com os campos
indexados forem ligados por AND.
Um ndice com mais de 3 campos dificilmente ser utilizado.
)dice P$rci$(
Criado apenas sobre um subconjunto dos registros de uma tabela, definido numa expresso
durante a criao do ndice parcial. um recurso para melhorar o desempenho dos ndices,
j que atualiza somente parte dos registros.
Obs.: na maioria dos casos a vantagem de um ndice parcial sobre um ndice integral no
muita.
#<em%(os2
#<$mi)$)do $ =ti(i6$+o dos )dices
A verificao de uso de ndices deve ser feita com os comandos EXPLAN e ANALYZE,
sendo que o comando ANALYZE sempre deve ser executado antes. O comando ANALYZE
coleta estatsticas sobre a distribuio dos valores na tabela.
Devem ser utilizados dados reais e o conjunto de dados de teste nunca deve ser pequeno.
>te)t$r %$r$ 's$r &)dices )os c$m%os d$s "('s'($s
- FOREGN KEY
- ORDER BY
- WHERE
- ON
- GROUP BY
- HAVNG
#<em%(os %rtico d$ v$)t$gem do )dice
28
- Uma tabela contendo os CEPs do Brasil, com 633.401 registros.
Esta tabela sem nenhum ndice executa a consulta abaixo:
\timing
SELECT * FROM cep_tabela WHERE cep = '60420440';
Em 7691 ms
- Ps adicionar um ndice:
ALTER TABLE cep_tabela ADD CONSTRANT cep_pk PRMARY KEY (cep);
A mesma consulta anterior agora gasta apenas 10 ms.
sso num AMD Duron 1300, 128MB de RAM).
)dice O')cio)$(
CREATE NDEX nomeindice ON tabela (lower (nomecampo));
Vtimo $rtigo )o iP$sters
7tt%2FFAAA.im$sters.com.brF$rtigo.%7%Qc)T18W7XccT2K
7tt%2FFAAA.im$sters.com.brF$rtigo.%7%Qc)T1W22XccT2K
7tt%2FFAAA.im$sters.com.brF$rtigo.%7%Qc)T1WJWXccT2K
?ide m$)'$( o0ici$(1 c$%&t'(o 11 %$r$ det$(7es.
29
5i%os de $dos P$is "om')s
Numricos
Tipo Taman
ho
Apelido Faixa
smallint (INT2) 2 bytes inteiro pequeno -32768 a +32767
integer (INT ou INT4) 4 bytes inteiro -2147483648 at +2147483647
bigint (INT8) 8 bytes inteiro longo -9223372036854775808 a
+9223372036854775807
numeric (p,e) tamanho varivel, preciso especiica!a
pelo usurio" #$ato e sem limite
!ecimal (p,e)
e % escala (casas !ecimais)
p % preciso (total !e !&gitos, inclusive estala)
real (loat) 4 bytes ponto lutuante preciso varivel, no e$ato e preciso !e
' !&gitos
!ouble precision 8 bytes !upla preciso preciso varivel, no e$ato e preciso !e
() !&gitos
int (INT4) mais in!ica!o para &n!ices !e inteiros
Caraceres
character varying(n) varchar(n) comprimento varivel, com limite
character(n) char(n) comprimento i$o, completa com brancos
te$t comprimento varivel e ilimita!o
*esempenho semelhante para os tipos caractere"
!aa"#ora
timestamp+(p), +-itout time
.one,
8 bytes !ata e hora sem
.ona
4713 AC a 5874897 DC
timestamp [ (p) ][ with time
zone ]
8 bytes !ata e hora com
.ona
4713 AC a 5874897 DC
interval (2
bytes
intervalo !e
tempo
178000000 anos a 178000000 anos
!ate 4 bytes somente !ata 4713 AC at 32767 DC
time [ (p) ] [ without time
zone ]
8 bytes somente a hora 00:00:00.00 at 23:59:59.99
time [ (p) ] [ with time zone ] 8 bytes somente a hora 00:00:00.00 at 23:59:59.99
[ (p) ] - a preciso, que varia de 0 a 6 e o defualt 2.
Tipos de Dados Mais Comuns (Continuao)
$oleanos
Tipo Tamanho Apelido Faixa
T/0# /epresenta12es3 't', 'true', 'y', 'yes' e '1'
4567# /epresenta12es3 'f', 'false', 'n', 'no', '0'
Apenas um dos dois estados. O terceiro estado, desconhecido, representado pelo NULL.
30
#<em%(o de co)s'(t$ com boo(e$)2
CREATE TABLE teste1 (a boolean, b text);
NSERT NTO teste1 VALUES (TRUE, 'sic est');
NSERT NTO teste1 VALUES (FALSE, 'non est');
SELECT * FROM teste1;
Retorno:
a | b
---+---------
t | sic est
f | non est
>(ert$: a entrada pode ser: 1/0, t/f, true/false, TRUE/FALSE, mas o retorno ser semp re t/f.
8bs.2 P$r$ c$m%os ti%o d$t$ 3'e %ermit$m N=LL, devemos prever isso na consulta SQL e
passar NULL sem delimitadores e valores no NULL com delimitadores.
8bs2 Evite o tipo MONEY que est em obsolescncia. Em seu lugar use NUMERC.
Prefira NT (NTEGER) em lugar de NT4, pois os primeiros so padro SQL. Em geral evitar
os nomes NT2, NT4 e NT8, que no so padro. O NT8 ou bigint no padro SQL.
Em ndices utilize somente NT, evitando smallint e bigint, que nunca sero utilizados.
5i%os SQL P$dro
bit, bit varying, boolean, char, character varying, character, varchar, date, double precision,
integer, interval, numeric, decimal, real, smallint, time (com ou sem zona horria), timezone
(com ou sem zona horria).
8 ti%o N=P#L!" pode realizar clculos exatos. Recomendado para quantias monetrias e
outras quantidades onde a exatido seja importante. sso paga o preo de queda de
desempenho comparado aos inteiros e flutuantes.
Pensando em portabilidade evita usar NUMERC(12) e usar NUMERC (12,0).
A comparao de igualdade de dois valores de ponto flutuante pode funcionar conforme o
esperado ou no.
8 PostgreSQL tr$b$(7$ com d$t$s do c$(e)drio Y'(i$)o.
Trabalha com a faixa de meio dia de Janeiro de 4713 AC (ano bisexto, domingo de lua nova)
at uma data bem distante no futuro. Leva em conta que o ano tem 365,2425 dias.
S#L!>L
No PostgreSQL um campo criado do "tipo SERAL internamente uma seqncia.
Os principais SGBDs utilizam alguma variao deste tipo de dados (auto-incremento).
Serial o "tipo auto-incremento do PostgreSQL. Quando criamos um campo do tipo SERAL
ao inserir um novo registro na tabela com o comando NSERT omitimos o campo tipo
SERAL, pois ele ser unserido automaticamente pelo PostgreSQL.
31
CREATE TABLE serial_teste (codigo SERAL, nome VARCHAR(45));
NSERT NTO serial_teste (nome) VALUES ('Ribamar FS');
Obs.: A regra nomear uma seqncia "serial_teste_codigo_seq,ou seja,
tabela_campo_seq.
select * from serial_teste_codigo_seq;
Esta consulta acima retorna muitas informaes importantes sobre a seqncia criada:
nome, valor inicial, incremento, valor final, maior e menor valor alm de outras informaes.
Veja que foi omitido o campo cdigo mas o PostgreSQL ir atribuir para o mesmo o valor do
prximo registro de cdigo. Por default o primeiro valor de um serial 1, mas se precisarmos
comear com um valor diferente veja a soluo abaixo:
Set$)do o ?$(or !)ici$( do Seri$(
ALTER SEQUENCE tabela_campo_seq RESTART WTH 1000;
CHAR corresponde a CHAR(1).
VARCHAR corresponde a uma cadeia de tamanho sem limites.
i0ere)+$ de esem%e)7o
nternamente o PostgreSQL armazena em tabelas separados os valores longos, para no
interferirem no acesso dos valores curtos da coluna. O maior valor permitido para uma cadeia
de caracteres de 1GB. Para valores maiores usar TEXT ou VARCHAR sem especificar
comprimento.
5i%os de $dos .eom:tricos
8eometric Types
Name 7torage 7i.e /epresentation *escription
point (' bytes 9oint on the plane ($,y)
line :2 bytes Ininite line (not ully implemente!) (($(,y(),($2,y2))
lseg :2 bytes 4inite line segment (($(,y(),($2,y2))
box :2 bytes /ectangular bo$ (($(,y(),($2,y2))
path (';('n bytes <lose! path (similar to polygon) (($(,y(),""")
path (';('n bytes =pen path +($(,y(),""",
polygon 4>;('n bytes 9olygon (similar to close! path) (($(,y(),""")
circle 24 bytes <ircle ?($,y),r@ (center an! ra!ius)
32
5i%os de $dos de Ledes
Net-orA 5!!ress Types
Name 7torage 7i.e *escription
cidr (2 or 24 bytes I9v4 an! I9v' net-orAs
inet (2 or 24 bytes I9v4 an! I9v' hosts an! net-orAs
macaddr ' bytes B5< a!!resses
5i%os de $dos >rr$H
Podemos ter campos com tipos de dados que no so simples, mas arrays.
CREATE TABLE salario (
nome text,
apgamento integer[],
agendamento text[][]
);
CREATE TABLE tictactoe (
qadrado integer[!][!]
);
Entrando os valores:
'{{1,2,3},{4,5,6},{7,8,9}}'
"#$ERT "#T% sal&emp
'AL(E$ ()Bill),
)*+,,,,, +,,,,, +,,,,, +,,,,-),
)**.meeting., .lnch.-, *.meeting.--)/0
ERR%R1 mltidimensional arrays mst ha2e array expressions 3ith matching
dimensions
9recisa ter a mesma quanti!a!e !e elementos"
"#$ERT "#T% sal&emp
'AL(E$ ()Bill),
)*+,,,,, +,,,,, +,,,,, +,,,,-),
)**.meeting., .lnch.-, *.training., .presentation.--)/0
"#$ERT "#T% sal&emp
'AL(E$ ()Carol),
)*4,,,,, 45,,,, 45,,,, 45,,,-),
)**.brea67ast., .conslting.-, *.meeting., .lnch.--)/0
$ELECT 8 9R%: sal&emp0
name ; pay&by&qarter ; schedle
<<<<<<<=<<<<<<<<<<<<<<<<<<<<<<<<<<<=<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Bill ; *+,,,,,+,,,,,+,,,,,+,,,,- ; **meeting,lnch-,*training,presentation--
Carol ; *4,,,,,45,,,,45,,,,45,,,- ; **brea67ast,conslting-,*meeting,lnch--
(4 ro3s/
= construtor ARRA> tambCm po!e ser usa!o3
33
"#$ERT "#T% sal&emp
'AL(E$ ()Bill),
ARRA>[+,,,,, +,,,,, +,,,,, +,,,,],
ARRA>[[)meeting), )lnch)], [)training), )presentation)]]/0
"#$ERT "#T% sal&emp
'AL(E$ ()Carol),
ARRA>[4,,,,, 45,,,, 45,,,, 45,,,],
ARRA>[[)brea67ast), )conslting)], [)meeting), )lnch)]]/0
Acessando:
SELECT name FROM sal_emp WHERE pay_by_quarter[1] <> pay_by_quarter[2];
SELECT pay_by_quarter[3] FROM sal_emp;
Faixa de valores- inferior:superior:
SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
SELECT array_dims(ARRAY[1,2] || 3);
SELECT array_prepend(1, ARRAY[2,3]);
SELECT array_cat(ARRAY[1,2], ARRAY[3,4]);
SELECT 1 || ARRAY[2,3] AS array;
SELECT ARRAY[1,2] || ARRAY[[3,4]] AS array;
$ELECT 7+[+][<4][!] A$ e+, 7+[+][<+][5] A$ e4
9R%: ($ELECT )[+1+][<41<+][!15]?***+,4,!-,*@,5,A---)11int[] A$ 7+/ A$ ss0
34
4 * PL ($t$ P$)i%'($tio) L$)g'$ge)
SQL (Structure Query Language) - uma linguagem declarativa, onde voc diz ao
computador o que deseja fazer e deixa a mquina decidir a forma correta de chegar ao
resultado.
Para o primeiro contato com o PostgreSQL e para ter certeza de que o mesmo est
corretamente instalado e configurado, podemos digitar na linha de comando do sistema
operacional (como usurio do postgresql):
psql --version
psql -l
O psql o programa de gerenciamento e uso do PostgreSQL pelo usurio local.
Com ele podemos fazer praticamente tudo que se pode fazer com o PG.
Alguns programas esto disponveis na linha de comando do sistema operacional, permitindo
criar e excluir bancos, criar e excluir usurios, entre outros. Os programas a disponveis
dependem da verso instalada, do sistema operacional e da forma que foi instalado.
Quem instala atravs dos fontes (sources) tem um sub-diretrio chamado contrib, onde esto
os demais programas desenvolvidos pela comunidade de programadores do PG. Neste caso
para instalar um destes programas execute "make; make install" estando no respectivo
diretrio. Um exemplo o pgbench.
Os comandos via linha de comandos do SO, normalmente terminam com "db" e so
formados com apenas uma palavra, createdb, por exemplo. J de dentro do psql, eles
normalmente so formados por duas palavras, como por exemplo,
CREATE DATABASE.
Os comandos a seguir sero executados na linha de comando do SO. Supondo que o super-
usurio seja "postgres".
Oorm$ m$is ger$( de 'so2
nome_comando opo -U nomeuser
"ri$r 'm b$)co de d$dos2
createdb controle_estoque -U postgres
?is'$(i6$r o b$)co cri$do2
psql -l -U postgres
#<c('ir o b$)co cri$do2
dropdb controle_estoque -U postgres
>C'd$ sobre os com$)dos2
nome_comando --help
35
>cess$r o b$)co cri$do $tr$v:s do termi)$( i)ter$tivo de gere)ci$me)to do
PostgreSQL (%s3()2
psql controle_estoque -U postgres
D:\Arquivos de programas\PostgreSQL\8.1\bin>psql controle_estoque -U postgres
Bem vindo ao psql 8.1.3, o terminal iterativo do PostgreSQL.
Digite: \copyright para mostrar termos de distribuio
\h para ajuda com comandos SQL
\? para ajuda com comandos do psql
\g ou terminar com ponto-e-vrgula para executar a consulta
\q para sair
controle_estoque=#
Este o prompt do psql. Veja que j nos recebe com boas vindas e com dicas de como
podemos a qualquer momento receber ajuda. Especialmente atente para os comandos:
\h - para receber ajuda sobre comandos SQL. \h comando - ajuda sobre um comando
\? - ajuda sobre os comandos de operao do terminal psql
; - o comando para indicar ao PG que execute nossa seqncia de comandos
\q - para sair do psql
Obs.: Aceita quebras de linha para uma seqncia de comandos.
Mesmo que possamos utilizar ferramentas grficas ou Web para gerenciar o PG, altamente
recomendado que nos familiarizemos com a sintaxe dos comandos para entender como os
comandos so executados internamente e ter maior domnio sobre o PG. Depois dessa fase,
os que resistem aos encantos do psql :) podem usar uma das citadas ferramentas.
Vamos executar alguns comandos do psql e algumas pequenas consultas para ficarmos mais
vontade.
\l -- lista bancos, donos e codificao
\d -- descreve tabela, ndice, seqncia ou view (viso)
\du -- lista usurios e permisses
\dg -- lista grupos
\dp -- lista privilgios de acesso tabelas, views (vises) e sequncias
psql controle_estoque -U postgres
controle_estoque=# SELECT version();
version
-------------------------------------------------------------------
PostgreSQL 8.1.3 on i686-pc-mingw32, compiled by GCC gcc.exe (GCC) 3.4.2 (mingw-
special)
Para distinguir convencionou-se que as palavras chave do SQL sejam escritas em
maisculas, mas podem ser escritas em minsculas sem problema para o interpretador de
comandos.
SELECT 25*4;
SELECT current_date;
36
4.1 * "o)s'(t$s /sic$s em SQL
S#L#"5 4 se(ecio)$r registros de t$be($s
banco=# \h select -- da ajuda via psql
Comando: SELECT
Descrio: recupera (retorna) registros de uma tabela ou viso (view)
Sintaxe:
SELECT [ ALL | DSTNCT [ ON ( expresso [, ...] ) ] ]
* | expresso [ AS nome_sada ] [, ...]
[ FROM item_de [, ...] ]
[ WHERE condio ]
[ GROUP BY expresso [, ...] ]
[ HAVNG condio [, ...] ]
[ { UNON | NTERSECT | EXCEPT } [ ALL ] select ]
[ ORDER BY expresso [ ASC | DESC | USNG operador ] [, ...] ]
[ LMT { contador | ALL } ]
[ OFFSET incio ]
[ FOR { UPDATE | SHARE } [ OF nome_tabela [, ...] ] [ NOWAT ] ]
ASC o default
!temMde %ode ser 'm dos2
[ ONLY ] nome_tabela [ * ] [ [ AS ] alias [ ( alias_coluna [, ...] ) ] ]
( select ) [ AS ] alias [ ( alias_coluna [, ...] ) ]
nome_funo ( [ argumento [, ...] ] ) [ AS ] alias [ ( alias_coluna [, ...] | definio_coluna [, ...]
) ]
nome_funo ( [ argumento [, ...] ] ) AS ( definio_coluna [, ...] )
item_de [ NATURAL ] tipo_juno item_de [ ON condio_juno | USNG ( coluna_juno
[, ...] ) ]
Si)t$<e res'mid$2
SELECT lista_de_campos FROM expresso_de_tabela
> (ist$MdeMc$m%os : o retor)o d$ co)s'(t$.
#<em%(os2
1) SELECT siape AS "Matricula do Servidor FROM pessoal;
2) SELECT pessoal.siape, pessoal.senha, locacoes.lotacao
FROM pessoal, lotacoes WHERE pessoal.siape = lotacoes.siape
ORDER BY lotacoes.lotacao;
!S5!N"5 4 Escrita logo aps SELECT desconsidera os registros duplicados, retornando
apenas registros exclusivos.
SELECT DSTNCT email FROM clientes;
ALL o contrrio de DSTNCT e o padro, retornando todos os registros, duplicados ou
no.
Ao fazer uma consulta, um registro ser considerado igual a outro se pelo menos um campo
for diferente. E os todos os valores NULL sero considerados iguais.
37
"LZ=S=L> @,#L# * Oi(tr$ o retor)o de co)s'(t$s.
Operadores aceitos:
T1 S1 [1 [S1 \T1 ST1 [T
SELECT nome FROM clientes WHERE email = 'ribafs@ribafs.org';
SELECT nome FROM clientes WHERE idade > 18;
SELECT nome FROM clientes WHERE idade < 21;
SELECT nome FROM clientes WHERE idade >= 18;
SELECT nome FROM clientes WHERE idade <= 21;
SELECT nome FROM clientes WHERE UPPER(estado) != 'CE';
SELECT nome FROM clientes WHERE email = 'ribafs@ribafs.org';
/#5@##N1 L!N#1 8L1 >N1 N851 #B!S5S1 !S N=LL1 !S N85 N=LL1 !N
SELECT nome FROM clientes WHERE idade BETWEEN 18 and 45;
SELECT nome FROM clientes WHERE email LKE '%@gmail.com';
SELECT nome FROM clientes WHERE idade >18 21 OR idade < 21; -- entre 18 e 21
SELECT nome FROM clientes WHERE idade >= 18 AND UPPER(estado) = 'CE';
SELECT nome FROM clientes WHERE idade NOT BETWEEN 18 AND 21;
SELECT * FROM datas WHERE EXSTS(SELECT * FROM datas2 WHERE datas.data =
datas2.data);
SELECT nome FROM clientes WHERE estado S NULL;
SELECT nome FROM clientes WHERE estado S NOT NULL;
SELECT nome FROM clientes WHERE estado N ('CE', 'RN');
.L8=P /] * Geralmente utilizada com funes de agrupamento (de agregao), como
tambm com HAVNG. Agrupa o resultado dos dados por um ou mais campos de uma tabela.
Utilizado para agrupar registros (linhas) da tabela que compartilham os mesmos valores em
todas as colunas (campos) da lista. Normalmente feito para calcular agrupamentos
(agregaes) aplicveis aos grupos.
Exemplos:
SELECT SUM(horas) FROM empregados; -- Traz a soma das horas de todos os empregados
SELECT empregado, SUM(horas) FROM empregados GROUPBY empregado; -- Traz a
soma das horas de cada empregado. Veja que "empregado deve aparecer em GROUP BY,
j que os campos de retorno diferentes do usado na funo de agrupamento devem vir no
GROUP BY.
ic$2 Quando se utiliza uma funo de agrupamento num campo da lista do SELECT, os
demais campos da lista devero ser agrupados. Exemplo:
SELECT codigo, nome, count(valor) FROM vendas GROUP BY codigo, nome.
Exemplo:
SELECT c.nome, COUNT(p.quant) AS quantos
FROM clientes c, pedidos p
WHERE c.codigo = p.cod_cliente
GROUP BY (p.cod_cliente);
,>?!N. * Filtra o retorno de GROUP BY. No altera o resultado,apenas filtra.
38
#<em%(o2
SELECT cliente, SUM(uant) AS total
FROM pedidos GROUP BY cliente
HAVNG total > 50; -- ou HAVNG SUM(quant) > 50;
8L#L /] * Ordena o resultado da consulta por um ou mais campos em ordem ascendente
(default) ou descendente.
#<em%(os2
ORDER BY cliente; -- pelo cliente e ascendente
ORDER BY cliente DESC; -- descendente
ORDER BY cliente, quantidade; -- pelo cliente e sub ordenado pela quantidade
ORDER BY cliente DESC, quant ASC;
No exemplo ordenando por dois campos:
SELECT * FROM pedidos ORDER BY cliente, quantidade; A sada ficaria algo como:
Antnio 1
Antnio 2
Joo - 1
Pedro - 1
Pedro - 2
!NS#L5 4 !)serir registros em t$be($s.
banco=# \h insert
Comando: NSERT
Descrio: insere novos registros em uma tabela
Sintaxe:
NSERT NTO tabela [ ( lista_de_campos ) ]
{ DEFAULT VALUES | VALUES ( { expresso | DEFAULT } [, ...] ) | consulta }
#O>=L5 * Se ao criar a tabela definirmos campos com valor default, ao inserir registros e
omitir o valor para estes campos, o servidor os cadastrar com o valor default.
#<em%(o (0orm$ com%(et$)2
Na tabela o campo idade tem valor default 18.
NSERT NTO clientes (codigo, nome, idade) VALUES (1, "Ribamar FS);
Neste exemplo ser cadastrado para a idade o valor 18.
Forma Abreviada:
NSERT NTO clientes VALUES (1, "Ribamar FS);
No recomendada, por no ser clara nem adequada para trabalho em grupo. Caso
utilizemos esta forma somos obrigados a inserir os campos na exata ordem em que esto na
tabela.
39
!)seri)do com S'b"o)s'(t$2
NSERT NTO clientes (codigo, nome, idade) VALUES
(SELECT fnome, fidade FROM funcionarios WHERE cli = 'S');
SELECT firstname, lastname, city, state NTO newfriend FROM friend;
=P>5# * >t'$(i6$r registros de t$be($s
banco=# \h update
Comando: UPDATE
Descrio: atualiza registros de uma tabela
Sintaxe:
UPDATE [ ONLY ] tabela SET coluna = { expresso | DEFAULT } [, ...]
[ FROM lista_de ]
[ WHERE condio ]
#<em%(os2
UPDATE clientes SET idade = idade + 1; -- Todos os registros de clientes sero atualizados
UPDATE pedidos SET quant = quant + 3
WHERE cliente N (SELECT codigo FROM clientes WHERE idade > 18);
#L#5# * Lemover registros de t$be($s
banco=# \h delete
Comando: DELETE
Descrio: apaga registros de uma tabela
Sintaxe:
DELETE FROM [ ONLY ] tabela
[ USNG lista_util ]
[ WHERE condio ]
#<em%(os2
DELETE FROM pedidos; -- Cuidado, excluir todos os registros da tabela pedidos
DELETE FROM pedidos WHERE (codigo S NULL); - - Remove sem confirmao nem com
opo de desfazer.
4.2 * Y')+;es de 5$be($s o' "o)s'(t$s
As junes SQL so utilizadas quando precisamos selecionar dados de duas ou mais
tabelas.
Existem as junes com estilo non-ANS ou theta (juno com WHERE)
E as junes ANS join (com JON). As junes ANS podem ser de dois tipos, as NNER
JONS e as OUTER JONS. A padro a NNER JON. NNER JON pode ser escrito com
apenas JON.
#<em%(o >NS!2
SELECT p.siape, p.senha, l.lotacao FROM pessoal p CROSS JON lotacoes l;
Tipos de Junes
40
!NN#L Y8!N * Onde todos os registros que satisfazem condio sero retornados.
#<em%(o2
SELECT p.siape, p.nome, l.lotacao
FROM pessoal p NNER JON lotacoes l
ON p.siape = l.siape ORDER BY p.siape;
#<em%(o )o esti(o t7et$2
SELECT p.siape, p.nome, l.lotacao
FROM pessoal p, lotacoes l
WHERE p.siape = l.siape ORDER BY p.siape;
8=5#L Y8!N que se divide em L#O5 8=5#L Y8!N e L!.,5 8=5#L Y8!N
L#O5 8=5#L Y8!N o' sim%(esme)te L#O5 Y8!N * Somente os registros da tabela da
esquerda (left) sero retornados, tendo ou no registros relacionados na tabela da direita.
Primeiro, realizada uma juno interna. Depois, para cada linha de T1 que no satisfaz a
condio de juno com nenhuma linha de T2, adicionada uma linha juntada com valores
nulos nas colunas de T2. Portanto, a tabela juntada possui, incondicionalmente, no mnimo
uma linha para cada linha de T1.
A tabela esquerda do operador de juno exibir cada um dos seus registros, enquanto que
a da direita exibir somente seus registros que tenham correspondentes aos da tabela da
esquerda.
Para os registros da direita que no tenham correspondentes na esquerda sero colocados
valores NULL.
#<em%(o (vo(t$r todos some)te de %esso$()2
SELECT p.siape, p.nome, l.lotacao
FROM pessoal p LEFT JON lotacoes l
ON p.siape = l.siape ORDER BY p.siape;
Veja que pessoal fica esquerda em "FROM pessoal p LEFT JON lotacoes l.
L!.,5 8=5#L Y8!N
nverso do LEFT, este retorna todos os registros somente da tabela da direita (right).
Primeiro, realizada uma juno interna. Depois, para cada linha de T2 que no satisfaz a
condio de juno com nenhuma linha de T1, adicionada uma linha juntada com valores
nulos nas colunas de T1. o oposto da juno esquerda: a tabela resultante possui,
incondicionalmente, uma linha para cada linha de T2.
#<em%(o (retor)$r some)te os registros de (ot$coes)2
SELECT p.siape, p.nome, l.lotacao
FROM pessoal p RGHT JON lotacoes l
ON p.siape = l.siape ORDER BY p.nome;
41
O=LL 8=5#L Y8!N
Primeiro, realizada uma juno interna. Depois, para cada linha de T1 que no satisfaz a
condio de juno com nenhuma linha de T2, adicionada uma linha juntada com valores
nulos nas colunas de T2. Tambm, para cada linha de T2 que no satisfaz a condio de
juno com nenhuma linha de T1, adicionada uma linha juntada com valores nulos nas
colunas de T1.
# t$mb:m $s2
"L8SS Y8!N e S#LO Y8!N (%$r$ si mesmo).
?ide item 7.2.1.1 do m$)'$(o0ici$( %$r$ m$is det$(7es e e<em%(os.
L!P!5
LMT (limite) juntamente com OFFSET (deslocamento) permite dizer quantas linhas
desejamos retornar da consulta. Podemos retornar desde apenas uma at todas.
Si)t$<e2
SELECT lista)de)campos
FROM express.o
[LMT { n1mero | ALL }] [OFFSET inicio]
LMT ALL mesmo que imitir LMT.
OFFSET inicio orienta para que a consulta retorne somente a partir de inicio.
OFFSET 0 mesmo que omitir OFFSET.
LMT 50 OFFSET 11 Dever trazer 50 registros do 11 at o 60, caso existam.
Obs.: Quando se utiliza LMT importante utilizar a clusula ORDER BY para estabelecer
uma ordem nica para as linhas do resultado. Caso contrrio, ser retornado um subconjunto
imprevisvel de linhas da consulta; pode-se desejar obter da dcima a vigsima linha, mas da
dcima a vigsima de qual ordem? A ordem desconhecida a no ser que seja especificado
ORDER BY. sto uma conseqncia inerente ao fato do SQL no prometer retornar os
resultados de uma consulta em qualquer ordem especfica, a no ser que ORDER BY seja
utilizado para impor esta ordem.
#<em%(os2
SELECT id, name FROM products ORDER BY name LMT 20 OFFSET 1;
r retornar os registros do 1 at o 20.
SELECT * FROM news_m LMT $inicio, $n_resultados
O comando "SELECT * FROM news_m LMT $n_resultados OFFSET $inicio"
ir pesquisar as noticias da tabela "news_m" comeando do resultado "$inicio" e ir listar
"$n_resultados".
#<em%(o2 "SELECT * FROM news_m LMT 3 OFFSET 2" ir exibir 3 notcias a partir da 2a.
notcia da tabela, ou seja, ir exibir as notcias 2, 3 e 4 da nossa tabela "news_m".
42
4.K 4 S'b co)s'(t$s
So consultas dentro de consultas.
Subconsulta escalar um comando SELECT comum, entre parnteses, que retorna
exatamente um registro, com um campo.
select nome, (select max(preco) from produtos where codigo=1) as "maior preo" from
produtos;
SELECT * FROM tabela1 WHERE tabela1.col1 =
(SELECT col2 FROM tabela2 WHERE col2 = valor);
SELECT name FROM customer WHERE customer_id NOT N ( SELECT customer_id FROM
salesorder );
SELECT 'test' AS test, id FROM (SELECT * FROM books) AS example_sub_query;
SELECT firstname, state,
CASE
WHEN state = 'PA' THEN 'close'
WHEN state = 'NJ' OR state = 'MD' THEN 'far'
ELSE 'very far'
END AS distance
FROM friend;
#<%ress;es de S'b "o)s'(t$s
#B!S5S
SELECT campo1 FROM tabela1 WHERE EXSTS
(SELECT 1 FROM tabela2 WHERE campo2 = tabela1.campo2);
"ombi)$)do ">S# e #B!S5S
CREATE TEMPORARY TABLE frutas (id SERAL PRMARY KEY, nome TEXT);
NSERT NTO frutas VALUES (DEFAULT, 'banana');
NSERT NTO frutas VALUES (DEFAULT, 'ma');
CREATE TEMPORARY TABLE alimentos (id SERAL PRMARY KEY, nome TEXT);
NSERT NTO alimentos VALUES (DEFAULT, 'ma');
NSERT NTO alimentos VALUES (DEFAULT, 'espinafre');
SELECT nome, CASE WHEN EXSTS (SELECT nome FROM frutas WHERE nome=a.nome)
THEN 'sim'
ELSE 'no'
END AS fruta
FROM alimentos a;
!N
SELECT nome, CASE WHEN nome N (SELECT nome FROM frutas)
THEN 'sim'
ELSE 'no'
END AS fruta
FROM alimentos;
NOT N
ANY/SOME
SELECT nome, CASE WHEN nome = ANY (SELECT nome FROM frutas)
THEN 'sim'
43
ELSE 'no'
END AS fruta
FROM alimentos;
">S# @,#N
CREATE TABLE notas (
nota decimal(4,2) CONSTRANT chknota
CHECK (nota BETWEEN 0.00 AND 10.00)
);
NSERT NTO notas VALUES(10);
NSERT NTO notas VALUES(9.2);
NSERT NTO notas VALUES(9.0);
NSERT NTO notas VALUES(8.3);
NSERT NTO notas VALUES(7.7);
NSERT NTO notas VALUES(7.4);
NSERT NTO notas VALUES(6.4);
NSERT NTO notas VALUES(5.8);
NSERT NTO notas VALUES(5.1);
NSERT NTO notas VALUES(5.0);
NSERT NTO notas VALUES(0);
SELECT CASE
WHEN nota < 3 THEN 'E' -- 0 a 3
WHEN nota < 5 THEN 'D' -- 3 a 5
WHEN nota < 7 THEN 'C' -- 5 a 7
WHEN nota < 9 THEN 'B' -- 7 a 9
ELSE 'A' -- 9 a 10
END AS conceito,
COUNT(*) AS quantidade,
MN(nota) AS menor,
MAX(nota) AS maior,
ROUND(AVG(nota)) AS media
FROM notas
GROUP BY CASE
WHEN nota < 3 THEN 'E' -- Aqui podemos utilizar expresses
WHEN nota < 5 THEN 'D'
WHEN nota < 7 THEN 'C'
WHEN nota < 9 THEN 'B'
ELSE 'A'
END
ORDER BY conceito;
Postr$)do os $dos em 'm$ I)ic$ (i)7$2
SELECT COUNT(CASE WHEN nota BETWEEN 9.00 AND 10.00 THEN 1 ELSE NULL END)
AS A,
COUNT(CASE WHEN nota BETWEEN 7.00 AND 8.99 THEN 1 ELSE NULL END) AS B,
COUNT(CASE WHEN nota BETWEEN 5.00 AND 6.99 THEN 1 ELSE NULL END) AS C,
COUNT(CASE WHEN nota BETWEEN 3.00 AND 4.99 THEN 1 ELSE NULL END) AS D,
COUNT(CASE WHEN nota BETWEEN 0.00 AND 2.99 THEN 1 ELSE NULL END) AS E
FROM notas;
44
Postr$r c$d$ )ot$ C')to com $ me)or )ot$1 $ m$ior )ot$1 e $ m:di$ de tod$s $s )ot$s.
SELECT nota,
(SELECT MN(nota) FROM notas) AS menor,
(SELECT MAX(nota) FROM notas) AS maior,
(ROUND(SELECT AVG(nota) FROM notas)) AS media
FROM notas;
45
J * O')+;es !)ter)$s
J.1 4 O')+;es de Stri)gs
Concatenao de Strings * dois ^^ (%i%es)
SELECT 'ae' || 'io' || 'u' AS vogais; --vogais -------- aeiou
SELECT CHR(67)||CHR(65)||CHR(84) AS "Dog"; -- Dog CAT
Q'$)tid$de de "$r$cteres de Stri)g
char_length - retorna o nmero de caracteres
SELECT CHAR_LENGTH('UNFOR'); - -Retorna 6
Ou SELECT LENGTH('Database'); - - Retorna 8
"o)verter %$r$ mi)Isc'($s
SELECT LOWER('UNFOR');
"o)verter %$r$ m$iIsc'($s
SELECT UPPER('universidade');
Posi+o de c$r$ctere
SELECT POSTON ('@' N 'ribafs@gmail.com'); -- Retorna 7
Ou SELECT STRPOS('Ribamar' ,'mar'); - - Retorna 5
S'bstri)g
SUBSTRNG(string [FROM inteiro] [FOR inteiro])
SELECT SUBSTRNG ('Ribamar FS' FROM 9 FOR 10); - - Retorna FS
SUBSTRNG(string FROM padro);
SELECT SUBSTRNG ('PostgreSQL' FROM '.......'); - - Retorna Postgre
SELECT SUBSTRNG ('PostgreSQL' FROM '...$'); - -Retorna SQL
Primeiros ....... e ltimos ...$
Ou
SUBSTR ( 'string', inicio, quantidade);
SELECT SUBSTR ('Ribamar', 4, 3); - - Retorna mar
S'bstit'ir todos os c$r$cteres seme(7$)tes
SELECT TRANSLATE(string, velho, novo);
SELECT TRANSLATE('Brasil', 'il', 'o'); - - Retorna Braso
SELECT TRANSLATE('Brasileiro...leiro', 'eiro', 'eira');
Lemover #s%$+os de Stri)gs
SELECT TRM(' SQL - PADRO ');
"$(c'($r PJ de Stri)g
SELECT MD5('ribafs'); - - Retorna 53cd5b2af18063bea8ddc804b21341d1
Le%etir 'm$ stri)g ) ve6es
SELECT REPEAT('SQL-', 3); - - Retorna SQL-SQL-SQL-
Sobrescrever s'bstri)g em stri)g
SELECT REPLACE ('Postgresql', 'sql', 'SQL'); - - Retorna PostgreSQL
46
ividir "$dei$ de "$r$cteres com e(imit$dor
SELECT SPLT_PART( 'PostgreSQL', 'gre', 2); - -Retorna SQL
SELECT SPLT_PART( 'PostgreSQL', 'gre', 1); - -Retorna Post
!)ici$is P$iIsc'($s
NTCAP(text) - NTCAP ('ol mundo') - - Ol Mundo
Lemover #s%$+os em /r$)co
TRM ([leading | trailing | both] [characters] from string)- remove caracteres da direita e da
esquerda. trim (both 'b' from 'babacatebbbb'); - - abacate
RTRM (string text, chars text) - Remove os caracteres chars da direita (default espao)
rtrim('removarrrr', 'r') - - remova
LTRM - (string text, chars text) - Remove os caracteres chars da esquerda
ltrim('abssssremova', 'abs') - - remova
et$(7es )o item W.4 do P$)'$(2
7tt%2FF%gdoc%tbr.so'rce0orge.)etF%g80F0')ctio)s*stri)g.7tm(
LiGe e _
SELECT * FROM FRENDS WHERE LASTNAME LKE 'M%';
O LKE case Nsensitive e o LKE case sensitive.
~~ equivale ao LKE
~~* equivale equivale ao LKE
!~~ equivale ao NOT LKE
!~~* equivale equivale ao NOT LKE
... LKE '[4-6]_6%' -- Pegar o primeiro sendo de 4 a 6,
-- o segundo qualquer dgito,
-- o terceiro sendo 6 e os demais quaisquer
% similar a *
_ similar a ? (de arquivos no DOS)
"orres%o)d9)ci$ com 'm P$dro
O PostgreSQL disponibiliza trs abordagens distintas para correspondncia com padro: o
operador LKE tradicional do SQL; o operador mais recente SMLAR TO (adicionado ao
SQL:1999); e as expresses regulares no estilo POSX. Alm disso, tambm est disponvel
a funo de correspondncia com padro substring, que utiliza expresses regulares tanto no
estilo SMLAR TO quanto no estilo POSX.
SELECT substring('XY1234Z', 'Y*([0-9]{1,3})'); - - Resultado: 123
SELECT substring('XY1234Z', 'Y*?([0-9]{1,3})'); - - Resultado: 1
47
S!P!L>L 58
O operador SMLAR TO retorna verdade ou falso conforme o padro corresponda ou no
cadeia de caracteres fornecida. Este operador muito semelhante ao LKE, exceto por
interpretar o padro utilizando a definio de expresso regular do padro SQL.
'abc' SMLAR TO 'abc' verdade
'abc' SMLAR TO 'a' falso
'abc' SMLAR TO '%(b|d)%' verdade
'abc' SMLAR TO '(b|c)%' falso
SELECT 'abc' SMLAR TO '%(b|d)%'; -- Procura b ou d em 'abc' e no caso retorna TRUE
REGEXP
SELECT 'abc' ~ '.*ab.*';
~ distingue a de A
~* no distingue a de A
!~ distingue expresses distingue a de A
!~* distingue expresses no distingue a de A
'abc' ~ 'abc' -- TRUE
'abc' ~ '^a' -- TRUE
'abc' ~ '(b|j)' -- TRUE
'abc' ~ '^(b|c)' -- FALSE
J.2 4 O')+;es P$temtic$s
8%er$dores L-gicos2
AND, OR e NOT. TRUE, FALSE e NULL
8%er$dores de "om%$r$+o2
<, >, <=, >=, =, <> ou !=
a BETWEEN x AND y
a NOT BETWEEN x AND y
expresso S NULL
expresso S NOT NULL
expresso S TRUE
expresso S NOT TRUE
expresso S FALSE
expresso S NOT FALSE
expresso S UNKNOWN
expresso S NOT UNKNOWN
48
8P#L>8L N=LL
Em SQL NULL para valores inexistentes. Regra geral: NULL se propaga, o que
significa que com quem NULL se combina o resultado ser um NULL.
NULL no zero, no string vazia nem string de comprimento zero.
Um exemplo: num cadastro de alunos, para o aluno que ainda no se conhece a nota,
no correto usar zero para sua nota, mas sim NULL.
No se pode efetuar clculos de expresses onde um dos elementos NULL.
"8PP>L>N8 N=LLs
NOT NULL com NULL -- Unknown
NULL com NULL -- Unknown
"8N?#LS`8 #FP>L> N=LL
NULLF() e COALESCE()
NULLF(valor1, valor2)
N=LL!O 4 Retorna NULL se, e somente se, valor1 e valor2 forem iguais, caso contrrio
retorna valor1.
Algo como:
if (valor1 == valor2){
then NULL
else valor1;
Retorna valor1 somente quando valor1 == valor2.
"8>L#S"# 4 retorna o primeiro de seus argumentos que no for NULL. S retorna NULL
quando todos os seus argumentos forem NULL.
Uso: mudar o valor padro cujo valor seja NULL.
create table nulos(nulo int, nulo2 int, nulo3 int);
insert into nulos values (1,null,null);
select coalesce(nulo, nulo2, nulo3) from nulos; - - Retorna 1, valor do campo nulo;
select coalesce(nulo2, nulo3) from nulos; - - Retorna NULL, pois ambos so NULL.
.L#>5#S5 * Retorna o maior valor de uma lista - SELECT GREATEST(1,4,6,8,2); - - 8
L#>S5 - Retorna o menor valor de uma lista.
Todos os valores da lista devem ser do mesmo tipo e nulos so ignorados.
Obs.: Ambas as funes acima no pertencem ao SQL standard, mas so uma extenso do
PostgreSQL.
49
"8N">5#N>N8 N=LLs
A regra : NULL se propaga. Qualquer que concatene com NULL gerar NULL.
STRNG || NULL -- NULL
Usos:
- Como valor default para campos que futuramente recebero valor.
- Valor default para campos que podero ser sempre inexistentes.
8%er$dores P$temticos
+, -, *, /, % (mdulo, resto de diviso de inteiros), ^(potncia), !(fatorial), @(valor absoluto)
| / - rais quadrada ( | / 25.0 = 5)
| | / - raiz cbica ( | | / 27.0 = 3)
>(g'm$s 0')+;es P$temtic$s
ABS(x) - valor absoluto de x
CEL(numeric) - arredonda para o prximo inteiro superior
DEGREES(valor) - converte valor de radianos para graus
FLOOR(numeric) - arredonda para o prximo inteiro inferior
MOD(x,y) - resto da diviso de x por y
P() - constante P (3,1415...)
POWER(x,y) - x elevado a y
RADANS(valor) - converte valor de graus para radianos
RANDOM() - valor aleatrio entre 0 e 1
ROUND(numeric) - arredonda para o inteiro mais prximo
ROUND(v, d) - arredonda v com d casas decimais
SGN(numeric) - retorna o sinal da entrada, como -1 ou +1
SQRT(X) - Raiz quadrada de X
TRUNC (numeric) - trunca para o nenhuma casa decimal
TRUNC (v numeric, s int) - trunca para s casas decimais
J.K 4 O')+;es de >gr'%$me)to (>greg$+o)
As funes de agrupamento so usadas para contar o nmero de registros de uma tabela.
avg(expresso)
count(*)
count(expresso)
max(expresso)
min(expresso)
stddev(expresso)
sum(expresso)
variance(expresso)
Onde expresso, pode ser "ALL expresso" ou "DSTNCT expresso.
As funes de Agrupamento (agregao) no podem ser utilizadas na clusula WHERE.
Devem ser utilizadas entre o SELECT e o FROM. Num SELECT que usa uma funo
agregada, as demais colunas devem fazer parte da clusula GROUP BY. Somente podem
aparecer aps o SELECT ou na clusula HAVNG. De uso proibido nas demais clusulas.
50
Obs.: Ao contar os registros de uma tabela com a funo COUNT(campo) e esse campo for
nulo em alguns registros, estes registros no sero computados, por isso cuidado com os
nulos nas funes de agregao.
A clusula HAVNG normalmente vem precedida de uma clusula GROUP BY e
obrigatoriamente contm funes de agregao.
>L#L5>2 Retornam somente os registros onde o campo pesquisado seja diferente de NULL.
NaN - Not a Number (No um nmero)
UPDATE tabela SET campo1 = 'NaN';
SELECT MN(campo) AS "Valor Mnimo" FROM tabela;
"$so te)7$ %rob(em$ com est$ co)s'(t$ 'se2
SELECT campo FROM tabela ORDER BY campo ASC LMT 1;
SELECT MAN(campo) AS "Valor Mximo" FROM tabela;
"$so te)7$ %rob(em$ com est$ co)s'(t$ 'se2
SELECT campo FROM tabela ORDER BY campo DESC LMT 1;
J.4 4 O')+;es de $t$F,or$
8%er$+;es com d$t$s2
timestamp '2001-09-28 01:00' + interval '23 hours' -> timestamp '2001-09-29 00:00'
date '2001-09-28' + interval '1 hour' -> timestamp '2001-09-28 01:00'
date '01/01/2006' date '31/01/2006'
time '01:00' + interval '3 hours'time -> '04:00'
interval '2 hours' - time '05:00' -> time '03:00:00'
O')+o $ge (retor)$ !)terv$() * i0ere)+$ e)tre d$t$s
age(timestamp)interval (Subtrai de hoje)
age(timestamp '1957-06-13') -> 43 years 8 mons 3 days
age(timestamp, timestamp)interval Subtrai os argumentos
age('2001-04-10', timestamp '1957-06-13') -> 43 years 9 mons 27 days
O')+o e<tr$ct (retor)$ do'b(e)
Extrai parte da data: ano, ms, dia, hora, minuto, segundo.
select extract(year from age('2001-04-10', timestamp '1957-06-13'))
select extract(month from age('2001-04-10', timestamp '1957-06-13'))
select extract(day from age('2001-04-10', timestamp '1957-06-13'))
$t$ e ,or$ $t'$is (retor)$m d$t$ o' 7or$)
SELECT CURRENT_DATE;
SELECT CURRENT_TME;
SELECT CURRENT_TME(0);
SELECT CURRENT_TMESTAMP;
SELECT CURRENT_TMESTAMP(0);
8bte)do o di$ do m9s2
SELECT DATE_PART('DAY', CURRENT_TMESTAMP) AS Dia;
51
Som$r di$s e 7or$s $ 'm$ d$t$2
SELECT CAST('06/04/2006' AS DATE) + NTERVAL '27 DAYS' AS Data;
O')+o )oA (retor)$ timest$m% Ait7 6o)e)
now() - Data e hora corrente (timestamp with zone);
No usar em campos somente timestamp.
O')+o d$teM%$rt (retor)$ do'b(e)
SELECT date_part('day', TMESTAMP '2001-02-16 20:38:40');
Resultado: 16 (day uma string, diferente de extract)
O')+o d$teMtr')c (retor)$ timest$m%)
SELECT date_trunc('year', TMESTAMP '2001-02-16 20:38:40');
Retorna 2001-02-16 00:00:00
"o)verte)do (">S5)
select to_date('1983-07-18', 'YYYY-MM-DD')
select to_date('19830718', 'YYYYMMDD')
O')+o timeo0d$H (retor)$ te<to)
select timeofday() -> Fri Feb 24 10:07:32.000126 2006 BRT
!)terv$(
interval [ (p) ]
to_char(interval '15h 2m 12s', 'HH24:M:SS')
date '2001-09-28' + interval '1 hour'
interval '1 day' + interval '1 hour'
interval '1 day' - interval '1 hour'
900 * interval '1 second'
nterval trabalha com as unidades: second, minute, hour, day, week, month, year, decade,
century, millenium ou abreviaturas ou plurais destas unidades.
Se informado sem unidades '13 10:38:14' ser devidamente interpretado '13 days 10 hours
38 minutes 14 seconds'.
CURRENTE_DATE - NTERVAL '1' day;
TO_TMESTAMP('2006-01-05 17:56:03', 'YYYY-MM-DD HH24:M:SS')
5i%os .eom:tricos2
CREATE TABLE geometricos(ponto PONT, segmento LSEG, retangulo BOX, poligono
POLYGON, circulo CRCLE);
ponto (0,0),
segmento de (0,0) at (0,1),
retngulo (base inferior (0,0) at (1,0) e base superior (0,1) at (1,1)) e
crculo com centro em (1,1) e raio 1.
NSERT NTO geometricos VALUES ('(0,0)','((0,0),(0,1))', '((0,0),(0,1))',
'((0,0),(0,1),(1,1),(1,0))','((1,1),1)');
5i%os de $dos %$r$ Lede2
Para tratar especificamente de redes o PostgreSQL tem os tipos de dados cidr, inet e
macaddr.
52
cidr para redes PV4 e PV6
inet para redes e hosts PV4 e PV6
macaddr endereos MAC de placas de rede
Assim como tipos data, tipos de rede devem ser preferidos ao invs de usar tipos texto para
guardar Ps, Mscaras ou endereos MAC.
?eC$ 'm e<em%(o em )dices P$rci$is e $ doc'me)t$+o o0ici$( %$r$ m$is det$(7es.
J.J * Oorm$t$+o de 5i%os de $dos
TO_CHAR - Esta funo deve ser evitada, pois ser descontinuada.
58M>5#
date TO_DATE(text, text); Recebe dois parmetros text e retorna date.
Um dos parmetros a data e o outro o formato.
SELECT TO_DATE('29032006','DDMMYYYY'); - Retorna 2006-03-29
58M5!P#S5>PP
tmt TO_TMESTAMP(text,text) - Recebe dois text e retorna timestamp with zone
SELECT TO_TMESTAMP('29032006 14:23:05','DDMMYYYY HH:M:SS'); - Retorna 2006-
03-29 14:23:05+00
58MN=P/#L
numeric TO_NUMBER(text,text)
SELECT TO_NUMBER('12,454.8-', '99G999D9S'); Retorna -12454.8
SELECT TO_NUMBER('12,454.8-', '99G999D9'); Retorna 12454.8
SELECT TO_NUMBER('12,454.8-', '99999D9'); Retorna 12454
et$(7es )o item W.8 do m$)'$(.
J.6 * "o)verso #<%(&cit$ de 5i%os (">S5)
CAST ( expresso AS tipo ) AS apelido; -- Sintaxe SQL ANS
Outra forma:
Tipo ( expresso );
#<em%(o2
SELECT DATE '10/05/2002' - DATE '10/05/2001'; -- Retorna a quantidade de dias
- -entre as duas datas
Para este tipo de converso devemos:
Usar float8 ao invs de double precision;
Usar entre aspas alguns tipos como interval, time e timestamp
Obs.: aplicaes portveis devem evitar esta forma de converso e em seu lugar usar o
CAST explicitamente.
A funo CAST() utilizada para converter explicitamente tipos de dados em outros.
SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "exp";
SELECT ~ CAST('20' AS int8) AS "negativo"; - Retorna -21
53
SELECT round(CAST (4 AS numeric), 4); - Retorna 4.0000
SELECT substr(CAST (1234 AS text), 3);
SELECT 1 AS "real" UNON SELECT CAST('2.2' AS REAL);
O')+;es ivers$s
SELECT CURRENT_DATABASE();
SELECT CURRENT_SCHEMA();
SELECT CURRENT_SCHEMA(boolean);
SELECT CURRENT_USER;
SELECT SESSON_USER;
SELECT VERSON();
SELECT CURRENT_SETTNG('DATESTYLE');
SELECT HAS_TABLE_PRVLEGE('usuario','tabela','privilegio');
SELECT HAS_TABLE_PRVLEGE('postgres','nulos','insert'); - - Retorna: t
SELECT HAS_DATABASE_PRVLEGE('postgres','testes','create'); - - Retorna: t
SELECT HAS_SCHEMA_PRVLEGE('postgres','public','create'); - - Retorna: t
SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
>rr$Hs
SELECT ARRAY[1.1,2.2,3.3]::NT[] = ARRAY[1,2,3];
SELECT ARRAY[1,2,3] = ARRAY[1,2,8];
SELECT ARRAY[1,3,5] || ARRAY[2,4,6];
SELECT 0 || ARRAY[2,4,6];
Array de char com 48 posies e cada uma com 2:
campo char(2) [48]
O')+;es .eom:tricos
area(objeto) - - area(box '((0,0), (1,1))');
center(objeto) - - center(box '((0,0), (1,2))');
diameter(circulo double) - - diameter(circle '((0,0), 2.0)');
height(box) - - height(box '((0,0), (1,1))');
length(objeto) - - length(path '((-1,0), (1,0))');
radius(circle) - - radius(circle '((0,0), 2.0)');
width(box) - - width(box '((0,0), (1,1))');
54
O')+;es %$r$ Ledes
Funes cidr e inet
host(inet) - - host('192.168.1.5/24') - - 192.168.1.5
masklen(inet) - - masklen('192.168.1.5/24') - - 24
netmask(inet) - - netmask('192.168.1.5/24') - - 255.255.255.0
network(inet) - - network('192.168.1.5/24') - - 192.168.1.0/24
Funo macaddr
trunt(macaddr) - - trunc(maraddr '12:34:34:56:78:90:ab') - - 12:34:56:00:00:00
O')+;es de !)0orm$+o do Sistem$
current_database()
current_schema()
current_schemas(boolean)
current_user()
inet_client_addr()
inet_client_port()
inet_server_addr()
inet_server_port()
pg_postmaster_start_time()
version()
has_table_privilege(user, table, privilege) - d privilgio ao user na tabela
has_table_privilege(table, privilege) - d privilgio ao usurio atual na tabela
has_database_privilege(user, database, privilege) - d privilgio ao user no banco
has_function_privilege(user, function, privilege) - d privilgio ao user na funo
has_language_privilege(user, language, privilege) - d privilgio ao user na linguagem
has_schema_privilege(user, schema, privilege) - d privilgio ao user no esquema
has_tablespace_privilege(user, tablespace, privilege) - d privilgio ao user no tablespace
current_setting(nome) - valor atual da configurao
set_config(nome, novovalor, is_local) - seta parmetro de retorna novo valor
pg_start_backup(label text)
pg_stop_backup()
pg_column_size(qualquer)
pg_tablespace_size(nome)
pg_database_size(nome)
pg_relation_size(nome)
pg_total_relation_size(nome)
pg_size_pretty(bigint)
pg_ls_dir(diretorio)
pg_read_file(arquivo text, offset bigint, tamanho bigint)
pg_stat_file(arquivo text)
55
6 * O')+;es e0i)id$s %e(o =s'rio e 5riggers
O PostgreSQL oferece quatro tipos de funes:
- Funes escritas em SQL
- Funes em linguagens de procedimento (PL/pgSQL, PL/Tcl, PL/php, PL/Java, etc)
- Funes internas (rount(), now(), max(), count(), etc).
- Funes na linguagem C
CREATE [ OR REPLACE ] FUNCTON
name ( [ [ argmode ] [ argname ] argt2pe [, ...] ] )
[ RETURNS rett2pe ]
{ LANGUAGE langname
| MMUTABLE | STABLE | VOLATLE
| CALLED ON NULL NPUT | RETURNS NULL ON NULL NPUT | STRCT
| [ EXTERNAL ] SECURTY NVOKER | [ EXTERNAL ] SECURTY DEFNER
| AS 'definition'
| AS 'ob3)file', 'link)s2mbol'
} ...
[ WTH ( attribute [, ...] ) ]
Para reforar a segurana interessante usar o parmetro SECURTY DEFNER, que
especifica que a funo ser executada com os privilgios do usurio que a criou.
SECURTY NVOKER indica que a funo deve ser executada com os privilgios do usurio
que a chamou (padro).
SECURTY DEFNER especifica que a funo deve ser executada com os privilgios do
usurio que a criou.
Uma grande fora do PostgreSQL que ele permite a criao de funes pelo usurio em
diversas linguagens: SQL, PlpgSQL, TCL, Perl, Phyton, Ruby.
Para ter exemplos a disposio vamos instalar os do diretrio "tutorial" dos fontes do
PostgreSQL:
Acessar /usr/local/src/postgresql-8.1.3/src/tutorial e executar:
make install
Feito isso teremos 5 arquivos .sql.
O syscat.sql traz consultas sobre o catlogo de sistema, o que se chama de metadados
(metadata).
O basic.sql e o advanced.sql so consultas SQL.
O complex.sql trata da criao de um tipo de dados pelo usurio e seu uso.
O func.sql traz algumas funes em SQL e outras em C.
56
6.1 4 O')+;es em SQL
O que outros SGBDs chamam de stored procedures o PostgreSQL chama de funes, que
podem ser em diversas linguagens.
CREATE OR REPLACE FUNCTON olamundo() RETURNS int4
AS 'SELECT 1' LANGUAGE 'sql';
SELECT olamundo() ;
CREATE OR REPLACE FUNCTON add_numeros(nr1 int4, nr2 int4) RETURNS int4
AS 'SELECT $1 + $2' LANGUAGE 'sql';
SELECT add_numeros(300, 700) AS resposta ;
Podemos passar como parmetro o nome de uma tabela:
CREATE TEMP TABLE empregados (
nome text,
salario numeric,
idade integer,
baia point
);
NSERT NTO empregados VALUES('Joo',2200,21,point('(1,1)'));
NSERT NTO empregados VALUES('Jos',4200,30,point('(2,1)'));
CREATE FUNCTON dobrar_salario(empregados) RETURNS numeric AS $$
SELECT $1.salario * 2 AS salario;
$$ LANGUAGE SQL;
SELECT nome, dobrar_salario(emp.*) AS sonho
FROM empregados
WHERE empregados.baia ~= point '(2,1)';
Algumas vezes prtico gerar o valor do argumento composto em tempo de execuo. sto
pode ser feito atravs da construo ROW.
SELECT nome, dobrar_salario(ROW(nome, salario*1.1, idade, baia)) AS sonho
FROM empregados;
O')+o 3'e retor)$ 'm ti%o com%osto. O')+o 3'e retor)$ 'm$ I)ic$ (i)7$ d$ t$be($
em%reg$dos2
CREATE FUNCTON novo_empregado() RETURNS empregados AS $$
SELECT text 'Nenhum' AS nome,
1000.0 AS salario,
25 AS idade,
point '(2,2)' AS baia;
$$ LANGUAGE SQL;
Ou
57
CREATE OR REPLACE FUNCTON novo_empregado() RETURNS empregados AS $$
SELECT ROW('Nenhum', 1000.0, 25, '(2,2)')::empregados;
$$ LANGUAGE SQL;
Chamar assim:
SELECT novo_empregado();
ou
SELECT * FROM novo_empregado();
O')+;es SQL como 0o)tes de t$be($s
CREATE TEMP TABLE teste (testeid int, testesubid int, testename text);
NSERT NTO teste VALUES (1, 1, 'Joo');
NSERT NTO teste VALUES (1, 2, 'Jos');
NSERT NTO teste VALUES (2, 1, 'Maria');
CREATE FUNCTON getteste(int) RETURNS teste AS $$
SELECT * FROM teste WHERE testeid = $1;
$$ LANGUAGE SQL;
SELECT *, upper(testename) FROM getteste(1) AS t1;
5$be($s 5em%orri$s * criar tabelas temporrias (TEMP), faz com que o servidor se
encarregue de remov-la (o que faz logo que a conexo seja encerrada).
CREATE TEMP TABLE nometabela (campo tipo);
O')+;es SQL retor)$)do co)C')to
CREATE FUNCTON getteste(int) RETURNS SETOF teste AS $$
SELECT * FROM teste WHERE testeid = $1;
$$ LANGUAGE SQL;
SELECT * FROM getteste(1) AS t1;
O')+;es SQL %o(im-r0ic$s
As funes SQL podem ser declaradas como recebendo e retornando os tipos polimrficos
anyelement e anyarray.
CREATE FUNCTON constroi_matriz(anyelement, anyelement) RETURNS anyarray AS $$
SELECT ARRAY[$1, $2];
$$ LANGUAGE SQL;
SELECT constroi_matriz(1, 2) AS intarray, constroi_matriz('a'::text, 'b') AS textarray;
CREATE FUNCTON eh_maior(anyelement, anyelement) RETURNS boolean AS $$
SELECT $1 > $2;
$$ LANGUAGE SQL;
SELECT eh_maior(1, 2);
P$is det$(7es )o c$%&t'(o K1 do m$)'$(.
58
6.2 * O')+;es em P(%gSQL
As funes em linguagens procedurais no PostgreSQL, como a PlpgSQL so
correspondentes ao que se chama comumente de Stored Procedures.
Por default o PostgreSQL s traz suporte s funes na linguagem SQL. Para dar suporte
funes em outras linguagens temos que efetuar procedimentos como a seguir.
Para que o banco postgres tenha suporte linguagem de procedimento PlPgSQL
executamos na linha de comando como super usurio do PostgreSQL:
cre$te($)g %(%gs3( 4= )ome'ser )omeb$)co
A PlpgSQL a linguagem de procedimentos armazenados mais utilizada no PostgreSQL,
devido ser a mais madura e com mais recursos.
CREATE FUNCTON func_escopo() RETURNS integer AS $$
DECLARE
quantidade integer := 30;
BEGN
RASE NOTCE 'Aqui a quantidade %', quantidade; -- A quantidade aqui 30
quantidade := 50;
--
-- Criar um sub-bloco
--
DECLARE
quantidade integer := 80;
BEGN
RASE NOTCE 'Aqui a quantidade %', quantidade; -- A quantidade aqui 80
END;
RASE NOTCE 'Aqui a quantidade %', quantidade; -- A quantidade aqui 50
RETURN quantidade;
END;
$$ LANGUAGE plpgsql;
=> SELECT func_escopo();
CREATE FUNCTON instr(varchar, integer) RETURNS integer AS $$
DECLARE
v_string ALAS FOR $1;
index ALAS FOR $2;
BEGN
-- algum processamento neste ponto
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTON concatenar_campos_selecionados(in_t nome_da_tabela) RETURNS
text AS $$
BEGN
RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
END;
$$ LANGUAGE plpgsql;
59
CREATE FUNCTON somar_tres_valores(v1 anyelement, v2 anyelement, v3 anyelement)
RETURNS anyelement AS $$
DECLARE
resultado ALAS FOR $0;
BEGN
resultado := v1 + v2 + v3;
RETURN resultado;
END;
$$ LANGUAGE plpgsql;
SELECT somar_tres_valores(10,20,30);
=ti(i6$+o de ti%o com%osto2
CREATE FUNCTON mesclar_campos(t_linha nome_da_tabela) RETURNS text AS $$
DECLARE
t2_linha nome_tabela2%ROWTYPE;
BEGN
SELECT * NTO t2_linha FROM nome_tabela2 WHERE ... ;
RETURN t_linha.f1 || t2_linha.f3 || t_linha.f5 || t2_linha.f7;
END;
$$ LANGUAGE plpgsql;
SELECT mesclar_campos(t.*) FROM nome_da_tabela t WHERE ... ;
Temos uma tabela (datas) com dois campos (data e hora) e queremos usar uma funo para
manipular os dados desta tabela:
CREATE or REPLACE FUNCTON data_ctl(opcao char, fdata date, fhora time) RETURNS
char(10) AS '
DECLARE
opcao ALAS FOR $1;
vdata ALAS FOR $2;
vhora ALAS FOR $3;
retorno char(10);
BEGN
F opcao = '''' THEN
insert into datas (data, hora) values (vdata, vhora);
retorno := ''NSERT'';
END F;
F opcao = ''U'' THEN
update datas set data = vdata, hora = vhora where data=''1995-11-01'';
retorno := ''UPDATE'';
END F;
F opcao = ''D'' THEN
delete from datas where data = vdata;
retorno := ''DELETE'';
ELSE
retorno := ''NENHUMA'';
END F;
RETURN retorno;
END;
' LANGUAGE plpgsql;
//select data_ctl('','1996-11-01', '08:15');
60
select data_ctl('U','1997-11-01','06:36');
select data_ctl('U','1997-11-01','06:36');
P$is et$(7es )o c$%&t'(o KJ do m$)'$( o0ici$(.
O')+;es 3'e Letor)$m "o)C')tos de Legistros (S#5S)
CREATE OR REPLACE FUNCTON codigo_empregado (codigo NTEGER)
RETURNS SETOF NTEGER AS '
DECLARE
registro RECORD;
retval NTEGER;
BEGN
FOR registro N SELECT * FROM empregados WHERE salario >= $1 LOOP
RETURN NEXT registro.departamento_cod;
END LOOP;
RETURN;
END;
' language 'plpgsql';
select * from codigo_empregado (0);
select count (*), g from codigo_empregado (5000) g group by g;
O')+;es 3'e retor)$m Legistro
Para criar funes em plpgsql que retornem um registro, antes precisamos criar uma varivel
composta do tipo ROWTYPE, descrevendo o registro (tupla) de sada
da funo.
CREATE TABLE empregados(
nome_emp text,
salario int4,
codigo int4 NOT NULL,
departamento_cod int4,
CONSTRANT empregados_pkey PRMARY KEY (codigo),
CONSTRANT empregados_departamento_cod_fkey FOREGN KEY (departamento_cod)
REFERENCES departamentos (codigo) MATCH SMPLE
ON UPDATE NO ACTON ON DELETE NO ACTON
)
CREATE TABLE departamentos (codigo NT primary key, nome varchar);
CREATE TYPE dept_media AS (minsal NT, maxsal NT, medsal NT);
create or replace function media_dept() returns dept_media as
'
declare
r dept_media%rowtype;
dept record;
bucket int8;
counter int;
begin
bucket := 0;
counter := 0;
r.maxsal :=0;
r.minsal :=0;
61
for dept in select sum(salario) as salario, d.codigo as departamento
from empregados e, departamentos d where e.departamento_cod = d.codigo
group by departamento loop
counter := counter + 1;
bucket := bucket + dept.salario;
if r.maxsal <= dept.salario or r.maxsal = 0 then
r.maxsal := dept.salario;
end if;
if r.minsal <= dept.salario or r.minsal = 0 then
r.minsal := dept.salario;
end if;
end loop;
r.medsal := bucket/counter;
return r;
end
' language 'plpgsql';
O')+;es 3'e Letor)$m "o)C')to de Legistros (S#58O1 Les'(t Set)
Tambm requerem a criao de uma varivel (tipo definidopelo user)
CREATE TYPE media_sal AS
(deptcod int, minsal int, maxsal int, medsal int);
CREATE OR REPLACE FUNCTON medsal() RETURNS SETOF media_sal AS
'
DECLARE
s media_sal%ROWTYPE;
salrec RECORD;
bucket int;
counter int;
BEGN
bucket :=0;
counter :=0;
s.maxsal :=0;
s.minsal :=0;
s.deptcod :=0;
FOR salrec N SELECT salario AS salario, d.codigo AS departamento
FROM empregados e, departamentos d WHERE e.departamento_cod =
d.codigo ORDER BY d.codigo LOOP
F s.deptcod = 0 THEN
s.deptcod := salrec.departamento;
s.minsal := salrec.salario;
s.maxsal := salrec.salario;
counter := counter + 1;
bucket := bucket + salrec.salario;
ELSE
F s.deptcod = salrec.departamento THEN
F s.maxsal <= salrec.salario THEN
s.maxsal := salrec.salario;
END F;
F s.minsal >= salrec.salario THEN
62
s.minsal := salrec.salario;
END F;
counter := counter +1;
ELSE
s.medsal := bucket/counter;
RETURN NEXT s;
s.deptcod := salrec.departamento;
s.minsal := salrec.salario;
s.maxsal := salrec.salario;
counter := 1;
bucket := salrec.salario;
END F;
END F;
END LOOP;
s.medsal := bucket/counter;
RETURN NEXT s;
RETURN;
END '
LANGUAGE 'plpgsql';
select * from medsal()
Le($cio)$)do2
select d.nome, a.minsal, a.maxsal, a.medsal
from medsal() a, departamentos d
where d.codigo = a.deptcod
6.K * 5riggers (.$ti(7os)
"$%&t'(o K2 do m$)'$( o0ici$(. e2
7tt%2FF%gdoc%tbr.so'rce0orge.)etF%g80Fs3(*cre$tetrigger.7tm(
At a verso atual no existe como criar funes de gatilho na linguagem SQL.
Uma funo de gatilho pode ser criada para executar antes (BEFORE) ou aps (AFTER) as
consultas NSERT, UPDATE OU DELETE, uma vez para cada registro (linha) modificado ou
por instruo SQL. Logo que ocorre um desses eventos do gatilho a funo do gatilho
disparada automaticamente para tratar o evento.
A funo de gatilho deve ser declarada como uma funo que no recebe argumentos e que
retorna o tipo TRGGER.
Aps criar a funo de gatilho, estabelecemos o gatilho pelo comando CREATE TRGGER.
Uma funo de gatilho pode ser utilizada por vrios gatilhos.
As funes de gatilho chamadas por gatilhos-por-instruo devem sempre retornar NULL.
As funes de gatilho chamadas por gatilhos-por-linha podem retornar uma linha da tabela
(um valor do tipo HeapTuple) para o executor da chamada, se assim o decidirem.
Si)t$<e2
CREATE TRGGER nome { BEFORE | AFTER } { evento [ OR ... ] }
ON tabela [ FOR [ EACH ] { ROW | STATEMENT } ]
EXECUTE PROCEDURE nome_da_funo ( argumentos )
63
O gatilho fica associado tabela especificada e executa a funo especificada
nome_da_funo quando determinados eventos ocorrerem.
O gatilho pode ser especificado para disparar antes de tentar realizar a operao na linha
(antes das restries serem verificadas e o comando NSERT, UPDATE ou DELETE ser
tentado), ou aps a operao estar completa (aps as restries serem verificadas e o
NSERT, UPDATE ou DELETE ter completado).
eve)to
Um entre NSERT, UPDATE ou DELETE; especifica o evento que dispara o gatilho. Vrios
eventos podem ser especificados utilizando OR.
#<em%(os2
CREATE TABLE empregados(
codigo int4 NOT NULL,
nome varchar,
salario int4,
departamento_cod int4,
ultima_data timestamp,
ultimo_usuario varchar(50),
CONSTRANT empregados_pkey PRMARY KEY (codigo) )
CREATE FUNCTON empregados_gatilho() RETURNS trigger AS $empregados_gatilho$
BEGN
-- Verificar se foi fornecido o nome e o salrio do empregado
F NEW.nome S NULL THEN
RASE EXCEPTON 'O nome do empregado no pode ser nulo';
END F;
F NEW.salario S NULL THEN
RASE EXCEPTON '% no pode ter um salrio nulo', NEW.nome;
END F;
-- Quem paga para trabalhar?
F NEW.salario < 0 THEN
RASE EXCEPTON '% no pode ter um salrio negativo', NEW.nome;
END F;
-- Registrar quem alterou a folha de pagamento e quando
NEW.ultima_data := 'now';
NEW.ultimo_usuario := current_user;
RETURN NEW;
END;
$empregados_gatilho$ LANGUAGE plpgsql;
CREATE TRGGER empregados_gatilho BEFORE NSERT OR UPDATE ON empregados
FOR EACH ROW EXECUTE PROCEDURE empregados_gatilho();
NSERT NTO empregados (codigo,nome, salario) VALUES (5,'Joo',1000);
NSERT NTO empregados (codigo,nome, salario) VALUES (6,'Jos',1500);
NSERT NTO empregados (codigo,nome, salario) VALUES (7,'Maria',2500);
SELECT * FROM empregados;
64
NSERT NTO empregados (codigo,nome, salario) VALUES (5,NULL,1000);
NEW Para NSERT e UPDATE
OLD Para DELETE
CREATE TABLE empregados (
nome varchar NOT NULL,
salario integer
);
CREATE TABLE empregados_audit(
operacao char(1) NOT NULL,
usuario varchar NOT NULL,
data timestamp NOT NULL,
nome varchar NOT NULL,
salario integer
);
CREATE OR REPLACE FUNCTON processa_emp_audit() RETURNS TRGGER AS
$emp_audit$
BEGN
--
-- Cria uma linha na tabela emp_audit para refletir a operao
-- realizada na tabela emp. Utiliza a varivel especial TG_OP
-- para descobrir a operao sendo realizada.
--
F (TG_OP = 'DELETE') THEN
NSERT NTO emp_audit SELECT 'E', user, now(), OLD.*;
RETURN OLD;
ELSF (TG_OP = 'UPDATE') THEN
NSERT NTO emp_audit SELECT 'A', user, now(), NEW.*;
RETURN NEW;
ELSF (TG_OP = 'NSERT') THEN
NSERT NTO emp_audit SELECT '', user, now(), NEW.*;
RETURN NEW;
END F;
RETURN NULL; -- o resultado ignorado uma vez que este um gatilho AFTER
END;
$emp_audit$ language plpgsql;
CREATE TRGGER emp_audit
AFTER NSERT OR UPDATE OR DELETE ON empregados
FOR EACH ROW EXECUTE PROCEDURE processa_emp_audit();
NSERT NTO empregados (nome, salario) VALUES ('Joo',1000);
NSERT NTO empregados (nome, salario) VALUES ('Jos',1500);
NSERT NTO empregados (nome, salario) VALUES ('Maria',250);
UPDATE empregados SET salario = 2500 WHERE nome = 'Maria';
DELETE FROM empregados WHERE nome = 'Joo';
SELECT * FROM empregados;
SELECT * FROM empregados_audit;
65
Outro exemplo:
CREATE TABLE empregados (
codigo serial PRMARY KEY,
nome varchar NOT NULL,
salario integer
);
CREATE TABLE empregados_audit(
usuario varchar NOT NULL,
data timestamp NOT NULL,
id integer NOT NULL,
coluna text NOT NULL,
valor_antigo text NOT NULL,
valor_novo text NOT NULL
);
CREATE OR REPLACE FUNCTON processa_emp_audit() RETURNS TRGGER AS
$emp_audit$
BEGN
--
-- No permitir atualizar a chave primria
--
F (NEW.codigo <> OLD.codigo) THEN
RASE EXCEPTON 'No permitido atualizar o campo codigo';
END F;
--
-- nserir linhas na tabela emp_audit para refletir as alteraes
-- realizada na tabela emp.
--
F (NEW.nome <> OLD.nome) THEN
NSERT NTO emp_audit SELECT current_user, current_timestamp,
NEW.id, 'nome', OLD.nome, NEW.nome;
END F;
F (NEW.salario <> OLD.salario) THEN
NSERT NTO emp_audit SELECT current_user, current_timestamp,
NEW.codigo, 'salario', OLD.salario, NEW.salario;
END F;
RETURN NULL; -- o resultado ignorado uma vez que este um gatilho AFTER
END;
$emp_audit$ language plpgsql;
CREATE TRGGER emp_audit
AFTER UPDATE ON empregados
FOR EACH ROW EXECUTE PROCEDURE processa_emp_audit();
NSERT NTO empregados (nome, salario) VALUES ('Joo',1000);
NSERT NTO empregados (nome, salario) VALUES ('Jos',1500);
NSERT NTO empregados (nome, salario) VALUES ('Maria',2500);
UPDATE empregados SET salario = 2500 WHERE id = 2;
UPDATE empregados SET nome = 'Maria Ceclia' WHERE id = 3;
UPDATE empregados SET codigo=100 WHERE codigo=1;
ERRO: No permitido atualizar o campo codigo
66
SELECT * FROM empregados;
SELECT * FROM empregados_audit;
Crie a mesma funo que insira o nome da empresa e o nome do cliente retornando o id de
ambos
create or replace function empresa_cliente_id(varchar,varchar) returns _int4 as
'
declare
nempresa alias for $1;
ncliente alias for $2;
empresaid integer;
clienteid integer;
begin
insert into empresas(nome) values(nempresa);
insert into clientes(fkempresa,nome) values (currval (''empresas_id_seq''), ncliente);
empresaid := currval(''empresas_id_seq'');
clienteid := currval(''clientes_id_seq'');
return ''{''|| empresaid ||'',''|| clienteid ||''}'';
end;
'
language 'plpgsql';
"rie 'm$ 0')+o o)de %$ss$mos como %$rametro o id do c(ie)te e seC$ retor)$do o
se' )ome
create or replace function id_nome_cliente(integer) returns text as
'
declare
r record;
begin
select into r * from clientes where id = $1;
if not found then
raise exception ''Cliente no existente !'';
end if;
return r.nome;
end;
'
language 'plpgsql';
Crie uma funo que retorne os nome de toda a tabela clientes concatenados em um s
campo
create or replace function clientes_nomes() returns text as
'
declare
x text;
r record;
begin
x:=''nicio'';
for r in select * from clientes order by id loop
x:= x||'' : ''||r.nome;
67
end loop;
return x||'' : fim'';
end;
'
language 'plpgsql';
68
7 * "L ($t$ "o)tro( L$)g'$ge)
7.1 * =s'rios1 gr'%os e %rivi(:gios
De fora do banco utiliza-se comandos sem espao: createdb, dropdb, etc.
De dentro do banco (psql) os comandos so formados por duas palavras:
CREATE DATABASE, DROP DATABASE, etc.
e de)tro do b$)co2
CREATE USER agora um alias para CREATE ROLE, que tem mais recursos.
banco=# \h create role
Comando: CREATE ROLE
Descrio: define um novo papel (role) do banco de dados
Sintaxe:
CREATE ROLE nome [ [ WTH ] opo [ ... ] ]
onde opo pode ser:
SUPERUSER | NOSUPERUSER
| CREATEDB | NOCREATEDB
| CREATEROLE | NOCREATEROLE
| CREATEUSER | NOCREATEUSER
| NHERT | NONHERT
| LOGN | NOLOGN
| CONNECTON LMT limite_con
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'senha'
| VALD UNTL 'tempo_absoluto'
| N ROLE nome_role [, ...]
| N GROUP nome_role [, ...]
| ROLE nome_role [, ...]
| ADMN nome_role [, ...]
| USER nome_role [, ...]
| SYSD uid
Caso no seja fornecido ENCRYPTED ou UNENCRYPTED ento ser usado o valor do
parmetro passord)encr2ption (postgresql.conf).
"ri$r =s'rio
CREATE ROLE nomeusuario;
Nas verses anteriores usava-se o parmetro "CREATEUSER para indicar a criao de um
superusurio, agora usa-se o parmetro mais adequado SUPERUSER.
P$r$ %oder cri$r 'm )ovo 's'rio (oc$(1 com se)7$1 devemos set$r $)tes o
%gM7b$.co)02
local all all 127.0.0.1/32 password
Comentar as outras entradas para conexo local.
sso para usurio local (conexo via socket UNX).
69
"ri$mos $ssim2
CREATE ROLE nomeuser WTH ENCRYPTED PASSWORD '********';
Ao se logar: psql -U nomeuser nomebanco.
CREATE ROLE nomeusuario VALD UNTL 'data'
#<c('i)do =s'rio
DROP USER nomeusuario;
"omo 's'rio1 0or$ do b$)co2
Criar Usurio
CREATEROLE nomeusuario;
#<c('i)do =s'rio
DROPUSER nomeusuario;
Detalhe: sem espaos.
"ri$)do S'%er's'rio
CREATE ROLE nomeuser WTH SUPERUSER ENCRYPTED PASSWORD '******';
>(ter$r "o)t$ de =s'rio
ALTER ROLE nomeuser ENCRYPTED PASSWORD '******' CREATEUSER
ALTER ROLE nomeuser VALD UNTL '12/05/2006';
ALTER ROLE fred VALD UNTL 'infinity';
ALTER ROLE miriam CREATEROLE CREATEDB;
Obs.: Lembrando que ALTER ROLE uma extenso do PostgreSQL.
List$)do todos os 's'rios2
SELECT usename FROM pg_user;
A tabela pg_user uma tabela de sistema (_pg) que guarda todos os usurios do
PostgreSQL.
5$mb:m %odemos 'ti(i6$r2
\du no psql
"ri$)do =m .r'%o
CREATE GROUP nomedogrupo;
>dicio)$rFLemover =s'rios #m .r'%os
ALTER GROUP nomegrupo ADD USER user1, user2,user3 ;
ALTER GROUP nomegrupo DROP USER user1, user2 ;
#<c('i)do .r'%o
DROP GROUP nomegrupo;
Obs.: isso remove o grupo mas no remove os usurios do mesmo.
List$)do todos os gr'%os2
SELECT groname FROM pg_group;
70
Privi(:gios
Dando Privilgios A Um Usurio
GRANT UPDATE ON nometabela TO nomeusuario;
$)do Privi(:gios > =m .r'%o !)teiro
GRANT SELECT ON nometabela TO nomegrupo;
Lemove)do 5odos os Privi(:gios de 5odos os =sers
REVOKE ALL ON nometabela FROM PUBLC
Privi(:gios
O superusurio tem direito a fazer o que bem entender em qualquer banco de dados do
SGBD.
O usurio que cria um objeto (banco, tabela, view, etc) o dono do objeto.
Para que outro usurio tenha acesso ao mesmo deve receber privilgios.
Existem vrios privilgios diferentes: SELECT, NSERT, UPDATE, DELETE, RULE,
REFERENCES, TRGGER, CREATE, TEMPORARY, EXECUTE e USAGE.
Os privilgios aplicveis a um determinado tipo de objeto variam de acordo com o tipo do
objeto (tabela, funo, etc.).
O comando para conceder privilgios o GRANT. O de remover o REVOKE.
GRANT UPDATE ON contas TO joel;
D a joel o privilgio de executar consultas update no objeto contas.
GRANT SELECT ON contas TO GROUP contabilidade;
REVOKE ALL ON contas FROM PUBLC;
Os privilgios especiais do dono da tabela (ou seja, os direitos de DROP, GRANT, REVOKE,
etc.) so sempre inerentes condio de ser o dono, no podendo ser concedidos ou
revogados. Porm, o dono do objeto pode decidir revogar seus prprios privilgios comuns
como, por exemplo, tornar a tabela somente para leitura para o prprio, assim como para os
outros.
Normalmente, s o dono do objeto (ou um superusurio) pode conceder ou revogar
privilgios para um objeto.
** "ri$+o dos gr'%os
CREATE GROUP adm;
CREATE USER paulo ENCRYPTED PASSWORD 'paulo' CREATEDB CREATEUSER;
** "ri$+o dos =s'rios do .r'%o $dm
CREATE USER andre ENCRYPTED PASSWORD 'andre' CREATEDB N GROUP adm;
CREATE USER michela ENCRYPTED PASSWORD 'michela' CREATEDB N GROUP adm;
O usurio de sistema (super usurio) deve ser um usurio criado exclusivamente para o
PostgreSQL. Nunca devemos torn-lo dono de nenhum executvel.
71
Os nomes de usurios so globais para todo o agrupamento de bancos de dados, ou seja,
podemos utilizar um usurio com qualquer dos bancos.
Os privilgios DROP, GRANT, REVOKE, etc pertencem ao dono do objeto no podendo ser
concedidos ou revogados. O mximo que um dono pode fazer abdicar de seus privilgios e
com isso ningum mais teria os mesmos e o objeto seria somente leitura para todos.
!ando &ri'il(ios
8/5NT 7#6#<T,09*5T#,IN7#/T =N nometabela T= nomeusuarioD
/etiran!o 9rivilCgios
/#E=F# 566 =N nometabela 4/=B nomeusuarioD
9ara garantir, sempre remova to!os os privilCgios antes !e !elegar algum"
P$is det$(7es2
7tt%2FF%gdoc%tbr.so'rce0orge.)etF%g80F'ser*m$)$g.7tm(
7tt%2FF%gdoc%tbr.so'rce0orge.)etF%g80Fs3(*revoGe.7tm(
7tt%2FF%gdoc%tbr.so'rce0orge.)etF%g80Fs3(*gr$)t.7tm(
72
8 4 5r$)s$+;es
=m$ tr$)s$+o $co)tece %or com%(eto (tod$s $s o%er$+;es) o' )$d$ $co)tece.
Tambm a transao deve garantir um nvel de isolamento das demais transaes, de
maneira que as demais transaes somente enxerguem as operaes aps a transao
concluda.
Caso haja um erro qualquer na transao ou falha no sistema o SGBR ir executar um
comando ROLLBACK.
Transaes so uma forma de dar suporte s operaes concorrentes, garantindo a
segurana e integridade das informaes.
Garantir que duas solicitaes diferentes no efetuaro uma mesma operao ao mesmo
tempo.
Ao consultar o banco de dados, uma transao enxerga um snapshot (instantneo) dos
dados, como estes eram no exato momento em que a consulta foi solicitada, desprezando as
mudanas ocorridas depois disso.
O PostgreSQL trata a execuo de qualquer comando SQL como sendo executado dentro de
uma transao.
Na verso 8 apareceram os SAVEPONTS (pontos de salvamento) , que guardam as
informaes at eles. sso salva as operaes existentes antes do SAVEPONT e basta um
ROLLBACK TO para continuar com as demais operaes.
O PostgreSQL mantm a consistncia dos dados utilizando o modelo multiverso MVCC
(Multiversion Concurrency Control), que permite que leitura no bloqueie escrita nem escrita
bloqueie leitura.
O PostgreSQL tambm conta com um nvel de isolamento chamado seriali4able
(serializvel), que mais rigoroso e emula execuo serial das transaes.
BEGN;
UPDATE contas SET saldo = saldo 100.00 WHERE codigo = 5;
SAVEPONT meu_ponto_de_salvamento;
UPDATE contas SET saldo = saldo + 100.00 WHERE codigo = 5;
-- ops ... o certo na conta 6
ROLLBACK TO meu_ponto_de_salvamento;
UPDATE contas SET saldo = saldo + 100.00 WHERE conta = 6;
COMMT;
#<em%(os2
CREATE TABLE contas(codigo NT2 PRMARY KEY, nome VARCHAR(40), saldo
NUMERC());
NSERT NTO contas values (5, 'Ribamar', 500.45);
Uma transao dita um processo atmico, o que significa que ou acontecem todas as suas
operaes ou ento nenhuma ser salva.
Vamos iniciar a seguinte transao na tabela acima:
BEGN; -- niciar uma transao
UPDATE contas SET saldo = 800.35 WHERE codigo= 5;
73
SELECT nome,saldo FROM contas WHERE codigo = 5;
COMMT; -- Executar todos os comandos da transao
Agora para testar se de fato todas as operaes foram salvas execute:
SELECT nome,saldo FROM contas WHERE codigo = 5;
Vamos a outro teste da atomicidade das transaes. ntencionalmente vamos cometer um
erro no SELECT (FRON):
BEGN; -- niciar uma transao
UPDATE contas SET saldo = 50.85 WHERE codigo= 5;
SELECT nome,saldo FRON contas WHERE codigo = 5;
COMMT; -- Executar todos os comandos da transao
sso causar um erro e o comando ROLLBACK ser automaticamente executado, o que
garante que nenhuma das operaes ser realizada.
Ento execute a consulta para testar se houve a atualizao:
SELECT nome,saldo FRON contas WHERE codigo = 5;
Lemover "$m%o (verses anteriores a 7.3 no contam com esse recurso):
BEGN;
LOCK TABLE nometabela;
NTO TABLE nomenovo FROM nometabela;
DROP TABLE nometabela;
ALTER TABLE nomenovo RENAME TO nometabela;
COMMT;
>(ter$r 5i%os de $dos (verses antigas):
BEGN;
ALTER TABLE tabela ADD COLUMN novocampo novotipodados;
UPDATE tabela SET novocampo = CAST (antigocampo novotipodados);
ALTER TABLE tabela DROP COLUMN antigocampo;
COMMT;
5r$)s$+;es 3'e )o se "o)creti6$m
BEGN; -- niciar uma transao
UPDATE contas SET saldo = 50.85 WHERE codigo= 5;
SELECT nome,saldo FRON contas WHERE codigo = 5;
ROLLBACK; -- Cancelando todos os comandos da transao
BEGN;
CREATE TABLE teste (id integer, nome text);
NSERT NTO teste VALUES (1, 'Teste1');
NSERT NTO teste VALUES (2, 'Teste2');
DELETE FROM teste;
COMMT;
BEGN;
74
CREATE TABLE teste (id integer, nome text);
NSERT NTO teste VALUES (3, 'Teste3');
NSERT NTO teste VALUES (4, 'Teste4');
DELETE FROM teste;
ROLLBACK;
et$(7es sobre co)0(itos de b(o3'eios2
7tt%2FFAAA.%ostgres3(.orgFdocsFc'rre)tFst$ticFe<%(icit*(ocGi)g.7tm(
!so($me)to de 5r$)s$+;es
O nvel de isolamento padro do PostgreSQL o Read Committed (leitura efetivada). Uma
consulta SELECT realizada com este nvel perceber os registros existente no incio da
consulta. Este o nvel mais flexvel.
Existe tambm o nvel serializable, mais rigoroso. Os nveis Read uncommitted e Repeatable
read so suportados, mas assumem a forma de um dos dois anteriores.
Set$)do o N&ve( de !so($me)to de 'm$ tr$)s$+o2
banco=# \h set transaction
Comando: SET TRANSACTON
Descrio: define as caractersticas da transao atual
Sintaxe:
SET TRANSACTON modo_transao [, ...]
SET SESSON CHARACTERSTCS AS TRANSACTON modo_transao [, ...]
onde modo_transao um dos:
SOLATON LEVEL { SERALZABLE | REPEATABLE READ | READ COMMTTED | READ
UNCOMMTTED }
READ WRTE | READ ONLY
#<em%(o2
BEGN;
SET TRANSACTON SOLATON LEVEL SERALZABLE;
Aqui as consultas da transao;
...
COMMT;
"o)tro(e de Sim'(t$)eid$de )o "$%&t'(o 12 do m$)'$( o0ici$(.
75
W * >dmi)istr$+o
W.1 * /$cG'% e Lestore
Especialmente quem j teve problemas em HDs e no pode recuperar os dados, sabe da
importncia dos backups.
Para efetuar backup e restore utilizamos o comando pg_dump em conjunto com o psql.
Obs.: O pg_dump no faz backup de objetos grandes (lo) por default. Caso desejemos
tambm estes objetos no backup devemos utilizar uma sada no formato tar e utilizar a opo
-b.
pg_dump -Ftb banco > banco.tar
/$cG'% (oc$( de 'm I)ico b$)co2
pg_dump -U usuario -d banco > banco.sql
pg_dump -Ft banco > banco.tar
O script normalmente leva a extenso .sql, por conveno, mas pode ser qualquer extenso
e o script ter contedo texto puro.
Lestore de 'm b$)co (oc$(2
psql -U usuario -d banco < banco.sql
pg_restore -d banco banco.sql
pg_restore -d banco banco.tar
8bs.: Cuidado ao restaurar um banco, especialmente se existirem tabelas sem integridade.
Corre-se o risco de duplicar os registros.
escom%$ct$r e 0$6er o restore em 'm s- com$)do2
gunzip -c backup.tar.gz | pg_restore -d banco
ou
cat backup.tar.gz | gunzip | pg_restore -d banco
(o cat envia um stream do arquivo para o gunzip que passa para o pg_restore)
/$cG'% (oc$( de $%e)$s 'm$ t$be($ de 'm b$)co2
pg_dump -U nomeusuario -d nomebanco -t nometabela > nomescript
Lest$'r$r $%e)$s 'm$ t$be($
Para conseguir restaurar apenas uma tabela uma forma gerar o dump do tipo com tar:
pg_dump -Ft banco -f arquivo.sql.tar
pg_restore -d banco -t tabela banco.sql.tar
/$cG'% (oc$( de todos os b$)cos2
pg_dumpall -U nomeusuario -d nomebanco > nomescript
/$cG'% remoto de 'm b$)co2
pg_dump -h hostremoto -d nomebanco | psql -h hostlocal -d banco
/$cG'% em m'(tivo('mes (vo('mes de 200P/)2
pg_dump nomebanco | split -m 200 nomearquivo
76
m para 1Mega, k para 1K, b para 512bytes
!m%ort$)do b$cG'% de verso $)terior do PostgreSQL
nstala-se a nova verso com porta diferente (ex.: 5433) e conectar ambos
pg_dumpall -p 5432 | psql -d template1 -p 5433
?is'$(i6$r com$)do $t'$( e P! de todos os %rocessos do servidor2
SELECT pg_stat_get_backend_pid(s.backendid) AS procpid,
pg_stat_get_backend_activity(s.backendid) AS current_query
FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;
etermi)$+o d$ 'ti(i6$+o em disco %e($s 5$be($s
Tendo um banco com cadastro de CEPs e apenas uma tabela "cep_tabela, mostrar o uso do
disco por esta tabela. Precisamos filtrar as tabelas de sistema, veja:
?>"==P >N>L]b#c
8 'ti(itrio ?>"==P recupera espao em disco ocupado pelos registros excludos e
atualizados, atualiza os dados para as estatsticas usadas pelo planejador de consultas e
tambm protege contra perca de dados quando atingir um bilho de transaes.
SELECT relname, relfilenode, relpages FROM pg_class WHERE relname LKE 'cep_%'
ORDER BY relname;
relname | relfilenode | relpages
------------+-------------+----------
cep_pk | 25140 | 2441
cep_tabela | 16949 | 27540
8 d$emo) do $'to*v$c''m
niciando na verso 8.1 um processo opcional do servidor, chamado de autovacuum
daemon, cujo uso para automatizar a execuo dos comandos VACUUM e ANALYZE.
Roda periodicamente e checa o uso em baixo nvel do coletor de estatsticas.
No pode ser usado enquanto st$tsMst$rtMco((ector e st$tsMroAM(eve( forem alterados para
true. Portanto o postgresql.conf deve ficar assim:
stats_start_collector = on
stats_row_level = on
autovacuum = on
Por default ser executado a casa 60 segundos. Para alterar descomente e mude a linha:
#autovacuum_naptime = 60
etermi)$r o 'so do disco %or t$be($
SELECT relfinenode, relpages FROM pg_class WHERE relname = 'nometabela'
Cada pgina usa 8kb.
77
5$m$)7o de )dices
SELECT c2.relname, c2.relpages
FROM pg_class c, pg_class c2, pg_index i
WHERE c.relname = 'customer'
AND c.oid = i.indrelid
AND c2.oid = i.indexrelid
ORDER BY c2.relname;
#)co)tr$r $s m$iores t$be($s e &)dices
SELECT relname, relpages FROM pg_class ORDER BY relpages DESC;
?eC$ 3'e )o res'(t$do t$mb:m $%$rece $ t$be($ de &)dices1 e com 'so sig)i0ic$tivo.
Oerr$me)t$s "o)trib
pgbench testa desempenho do SGBD.
dbsize mostra o tamanho de tabelas e bancos
oid2name retorna ODs, fileinode e nomes de tabelas
D:\ARQUV~1\POSTGR~1\8.1\bin>oid2name -U postgres -P ********
All databases:
Oid Database Name Tablespace
-------------------------------------
33375 bdcluster ncluster
16948 cep_brasil pg_default
25146 cep_full pg_default
33360 controle_estoque pg_default
16879 municipios pg_default
33340 pgbench pg_default
10793 postgres pg_default
10792 template0 pg_default
33377 template1 pg_default
16898 testes pg_default
No README desta contrib existe uma boa sugesto para encontrar o tamanho aproximados
dos dados de cada objeto interno do PostgreSQL com:
SELECT relpages, relfilenode, relname FROM pg_class ORDER BY relpages DESC;
Cada pgina tem tipicamente 8KB e o relpages atualizado pelo comando VACUUM.
/$cG'% >'tomtico de /$)cos )o @i)doAs com o >ge)d$dor de 5$re0$s
"ri$+o do scri%t b$cG'%%g.b$t2
rem Adaptao de Ribamar FS do original de vlison Souza para a lista PostgreSQL Brasil
@echo off
rem (Nome do Usurio do banco para realizar o backup)
REM Dados que precisa alterar:
REM PGUSER
REM PGPASSWORD
REM nome pasta de backup
78
REM nome pasta de instalao do PostgreSQL se diferente de C:\Arquivos de
programas\PostgreSQL\8.1\
REM
REM (Nome do usurio do PostgreSQL que executar o script)
SET PGUSER=postgres
rem (Senha do usurio acima)
SET PGPASSWORD=******
rem (ndo para a raiz do disco)
C:
rem (Selecionando a pasta onde ser realizada o backup)
chdir C:\backup
rem (banco.sql o nome que defini para o meu backup
rem (Deletando o backup existente)
del banco*.sql
echo "Aguarde, realizando o backup do Banco de Dados"
rem C:\Arquiv~1\Postgr~1\8.1\bin\pg_dump -i -U postgres -b -o -f "C:\backup\banco.sql"
condominio
rem Observao: Caso queira colocar o nome do backup seguindo de uma data s usar:
for /f "tokens=1,2,3,4 delims=/ " %%a in ('DATE /T') do set Date=%%b-%%c-%%d
rem O comando acima serve para armazenar a data no formato dia-mes-ano na varivel
Date;
C:\Arquiv~1\Postgr~1\8.1\bin\pg_dump -i -U postgres -b -o -f "C:\backup\banco%Date%.sql"
condominio
rem (sair da tela depois do backup)
exit
"o)0ig'r$+o do >ge)d$dor de 5$re0$s %$r$ e<ec't$r o scri%t di$ri$me)te2
- niciar - Programas - Acessrios - Ferramentas de Sistema - Tarefas agendadas
- Adicionar tarefa agendada
- Avanar
- Clique em procurar e indique o backuppg.bat
- Em executar esta tarefa escolha como achar mais adequado (diariamente) e clique em
Avanar
- Clique em Avanar e OK. Na prxima tela marque "Executar somente se conectado".
- Ento clique em Concluir
- No prximo boot o backup ser efetuado a cada dia.
=m bom $rtigo sobre b$cG'% e rest$'r$+o )o PostgreSQL e)co)tr$*se )o site o0ici$(
do PostgreSQL do /r$si(2 7tt%s2FFAiGi.%ostgres3(.org.brFAiGiF/$cG'%>)dLestore
?eC$ t$mb:m $ doc'me)t$+o em i)g(9s2
7tt%2FFAAA.%ostgres3(.orgFdocsF8.1Fst$ticF$%%*%grestore.7tm(
7tt%2FFAAA.%ostgres3(.orgFdocsF8.1Fst$ticF$%%*%gd'm%.7tm(
7tt%2FFAAA.%ostgres3(.orgFdocsF8.1Fst$ticF$%%*%g*d'm%$((.7tm(
79
W.2 * !m%ort$r e #<%ort$r
Para importar scripts gerados via pg_dump de dentro do banco devemos utilizar o comando
\i /path/script.sql
\i ./script.sql -- No windows com o arquivo no diretrio atual
Para importar arquivos texto com delimitadores, tipo TXT, CSV ou binrios utilizamos os
comandos do banco (psql), como usurio do banco:
!m%ort$)do2
\COPY tabela FROM 'script.csv'
\COPY paises FROM 'clientes.csv';
#<%ort$)do2
CREATE TEMP TABLE paises AS SELECT * FROM teste WHERE nome LKE '%a%';
\COPY paises TO '/usr/teste.copy';
"om e(imit$dores
\COPY tabela FROM '/arquivo.csv' DELMTERS '|';
\COPY tabela TO '/arquivo.txt' DELMTERS '|';
Obs.: O arquivo teste.copy deve ter permisso de escrita para o user do banco.
!m%ort$r 'm$ %($)i(7$ do #<ce( o' do "$(c do 8%e)800ice %$r$ 'm$ t$be($2
.er$)do 'm $r3'ivo "S? )o 8%e)800ice "$(c
- Abrir calc e selecionar e copiar a rea a importar
- Abrir uma nova planilha
- Clicar com o boto direito sobre a primeira clula e Colar Especial
- Desmarque Colar tudo, marque Nmeros, desmarque Frmulas e OK
- Tecle Ctrl+S para salvar
- Em Tipo de arquivo escolha Texto CSV, digite o nome e Salvar. Confirme
- Como Delimitador de Campo escolha Tabulao
- Em Delimitador de texto delete as aspas e OK
- gnore a mensagem de erro, caso aparea.
mportar o arquivo texto CSV para uma tabela com estrutura semelhante do arquivo csv:
su - postgres
psql nomebanco
\copy nometabela from /home/nomearquivo.csv
No Windows
\copy nometabela from ./arquivo.csv -- o arquivo estando no path do usurio
#<%ort$r 'm /$)co >ccess %$r$ 'so )o PostgreSQL o' o'tros b$)cos
Selecionar a tabela e Exportar
- Escolher o tipo de arquivos Texto (txt, csv, ...)
- Em avanado: Delimitador de campos Tabulao
- Qualificador de texto remover (deixar em branco)
80
W.K * "o)verter
Uma boa forma de converter bancos MySQL para bancos PostgreSQL no Windows
instalando o driver ODBC para o MySQL e para o PostgreSQL.
Ento cria-se a comunicao com os dois bancos e exporta-se para o PostgreSQL.
Existem ferramentas comerciais com muitos recursos, como o caso do EMS Data Export e
mport for PostgreSQL: http://www.sqlmanager.net/en/products/postgresql/dataexport
Veja: export to MS Excel, MS Word / RTF, MS Access, HTML, TXT, CSV, PDF, XML and SQL.
Outra opo exportar para CSV do MySQL e importar pelo PostgreSQL.
W.4 * 8timi6$+o e esem%e)7o
Para isso ajusta-se bem o postgresql.conf, utiliza-se o vacuum, analyze e explain.
Lembrando que na verso 8.1 o vacuum no mais um programa separado e vem embutido
no executvel. Mesmo embutido ele configurvel e podemos utilizar ou no e se usar,
podemos tambm configurar sua periodicidade.
=m$ -tim$ 0o)te de co)s'(t$2
http://www.metatrontech.com/wpapers/mysql2postgresql.pdf
"$%&t'(o 21 do m$)'$(2
http://pgdocptbr.sourceforge.net/pg80/maintenance.html
?$c''m2
http://pgdocptbr.sourceforge.net/pg80/sql-vacuum.html
>)$(H6e2
http://pgdocptbr.sourceforge.net/pg80/sql-analyze.html
?>"==P
O comando Vacuum tanto recupera espao em disco, quanto otimiza o desempenho do
banco e previne contra perda de dados muito antigos devido ao recomeo do D das
transaes, portanto deve ser utilizado constantemente, como tambm atualiza as
estatsticas dos dados utilizados pelo planejador de comandos. Lembrando que na verso
8.1 j vem embutido no executvel, podendo apenas ser configurado para que seja
executado automaticamente.
Na linha de comando:
vacuumdb -faze ou vacuumdb -fazq.
>N>L]b#
O comando ANALYZE coleta estatsticas sobre o contedo das tabelas do banco de dados e
armazena os resultados na tabela do sistema pg_statistic. Posteriormente, o planejador de
comandos utiliza estas estatsticas para ajudar a determinar o plano de execuo mais
eficiente para os comandos. Caso no atualizemos estas estatsticas com freqncia
podemos comprometer o desempenho do banco de dados por uma escolha errada do plano
de comandos.
Normalmente operaes DELETE ou UPDATE no removem os registros automaticamente.
Somente aps a execuo do VACUUM isso acontece.
Lecome)d$+o
Para a maioria das instalaes executar o comando VACUUM ANALYZE para todo o banco
de dadosuma vez ao dia em horrio de pouca utilizao. Tambm podemos utilizar o
comando:
81
v$c''mdb *0$63.
Quando foi excluda a maioria dos registros de uma tabela sugere-se a execuo do
comando VACUUM FULL. Este comando gera um forte bloqueio nas tabelas em que
executado.
Em tabelas cujo contedo excludo periodicamente, como tabelas temporrias, indicado o
uso do comando TRUNCATE ao invs de DELETE.
#<em%(o de 'so do v$c''m. >cesse o b$)co e e<ec'te2
VACUUM VERBOSE ANALYZE nometabela;
De fora do psql usar o comando "vacuumdb -faze ou "vacuumdb -fazq (silencioso).
VACUUM VERBOSE ANALYZE autor;
NFO: vacuuming "public.autor"
NFO: "autor": found 0 removable, 0 nonremovable row versions in 0 pages
DETAL: 0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
NFO: analyzing "public.autor"
NFO: "autor": scanned 0 of 0 pages, containing 0 live rows and 0 dead rows; 0 rows in
sample, 0 estimated total rows
#m 'm /$)co "om%(eto
S VACUUM
Ou
VACUUM FULL ANALYZE;
ic$s de esem%e)7o2
- Adicionar ndice tabela (toda chave primria j contm um ndice)
- Adicionar ndices aos campos de clusulas WHERE;
- Evitar campos com tamanho varivel. Preferir o CHAR ao VARCHAR.
- Evitar muitos ndices
- Evitar ndice em tabela muito pequena (poucos registros, no compensa)
- Evitar, sempre que possvel, chaves compostas
- Separar bancos em um HD e logs em outro HD
- Aumentar shared buffers (postgresql.conf) de acordo com RAM disponvel.
Recomendaes: 25% da RAM para shared buffers cache e 2-4% para sort buffer.
bancos em /usr/local/pgsql/data (hda)
logs em /usr/local/pgsql/data/pg_xlog (hdb)
Utilizar links simblicos para mover tabelas, ndices, ... para outro HD.
Ativar o chip DMA
Testar: hdparm -Tr /dev/hda
Ativar o chip: hdparm -d 1 /dev/hda
Desativar: hdparm -d 0 /dev/hda
82
No postgresql.conf existem configuraes para shared_buffers, que quanto maior melhor,
respeitando-se a RAM.
O default da verso 8.1.3 :
shared_buffers = 1000 # min 16 ou max_connections*2 (8KB cada)
P($)o de "o)s'(t$
O PostgreSQL concebe um plano de comando para cada comando recebido. A escolha do
plano correto, correspondendo estrutura do comando e s propriedades dos dados,
absolutamente crtico para o bom desempenho. Pode ser utilizado o comando EXPLAN para
ver o plano criado pelo sistema para qualquer comando (conjunto executvel de instrues).
A leitura do plano uma arte que merece um tutorial extenso, o que este no ; porm, aqui
so fornecidas algumas informaes bsicas.
8s )Imeros $%rese)t$dos $t'$(me)te %e(o #BPL>!N so2
d 8 c'sto de %$rtid$ estim$do (O tempo gasto antes de poder comear a varrer a sada
como, por exemplo, o tempo para fazer a classificao em um n de classificao).
d 8 c'sto tot$( estim$do (Se todas as linhas fossem buscadas, o que pode no acontecer:
uma consulta contendo a clusula LMT pra antes de gastar o custo total, por exemplo).
d NImero de (i)7$s de s$&d$ estim$do %$r$ este )- do %($)o (Novamente, somente se for
executado at o fim).
d L$rg'r$ m:di$ estim$d$ (em bHtes) das linhas de sada deste n do plano.
EXPLAN SELECT * FROM NOMETABELA;
Postr$ %($)o de e<ec'+o i)ter)$ d$ co)s'(t$1 $c's$)do tem%o g$sto
EXPLAN SELECT sum(i) FROM tabela1 WHERE i = 4;
Agora a consulta ser modificada para incluir uma condio WHERE:
EXPLAN SELECT * FROM tenk1 WHERE unique1 < 1000;
Modificando-se a consulta para restringir mais ainda a condio
EXPLAN SELECT * FROM tenk1 WHERE unique1 < 50;
Adio de outra condio clusula WHERE:
EXPLAN SELECT * FROM tenk1 WHERE unique1 < 50 AND stringu1 = 'xxx';
A seguir feita a juno de duas tabelas, utilizando as colunas sendo discutidas:
EXPLAN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50 AND t1.unique2 =
t2.unique2;
Uma forma de ver outros planos forar o planejador a no considerar a estratgia que sairia
vencedora, habilitando e desabilitando sinalizadores de cada tipo de plano (Esta uma
ferramenta deselegante, mas til.
SET enable_nestloop = off;
EXPLAN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50 AND t1.unique2 =
t2.unique2;
possvel verificar a preciso dos custos estimados pelo planejador utilizando o comando
EXPLAN ANALYZE. Na verdade este comando executa a consulta, e depois mostra o tempo
real acumulado dentro de cada n do plano junto com os custos estimados que o comando
EXPLAN simples mostraria. Por exemplo, poderia ser obtido um resultado como este:
EXPLAN ANALYZE SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50 AND
t1.unique2 = t2.unique2;
83
Lei)&cio do ! de 5r$)s$+;es
Para prevenir com segurana o recomeo do D das Transaes devemos utilizar o
comando VACUUM em todas as tabelas do banco de dados pelo menos uma vez a cada
meio bilho de transaes. Caso o VACUUM no seja executado pelo menos uma vez a
cada 2 bilhes de transaes ocorrer a perca de todos os dados do banco. De fato eles no
se perdem, voltando dentro de mais 2 bilhes de transaes, mas isso no serve de consolo.
"omo s$ber 3'$)t$s tr$)s$+;es $i)d$ 0$(t$ %$r$ $ %erc$ dos d$dos2
S#L#"5 d$t)$me >S b$)co1 >.#(d$t0ro6e)<id) >S id$de OL8P %gMd$t$b$sec
Sempre que se executa o comando VACUUM em um banco, a coluna com age comea de 1
bilho. Ao se aproximar de 2 bilhes devemos executar novamente o comando VACUUM.
>(ert$
Caso um banco j esteja com mais de 1,5 bilhes de transaes, ao executar o comando
VACUUM para o banco inteiro receber um alerta sobre a necessidade de execuo do
VACUUM.
84
10 * Le%(ic$+o
o processo de compartilhar e distribuir informaes entre diferentes bancos de dados.
Estes dados sero mantidos sincronizados e ntegros em relao s regras de integridade
referencial e de negcios.
No PostgreSQL algumas formas de realizar replicao so atravs do contrib dblink e das
ferramenta slony e pgcluster.
P$r$ im%ort$r o db(i)G )o b$)co o)de 3'eremos re%(ic$r2
\i /usr/local/pgsql/contrib/dblink.sql
#<em%(o dbLi)G * Se(ect
select *
from dblink
(
'dbname=pgteste
hostaddr=200.174.40.63
user=paulo
password=paulo
port=5432',
'select nome
from clientes
'
) as t1(nome varchar(30));
Exemplo dbLink - nsert
select
dblink_exec(
'dbname=pgteste
hostaddr=200.174.40.63
user=paulo
password=paulo
port=5432',

'insert into clientes(nome)
values(''roger'')
'
);
Exemplo dbLink - Update
select
dblink_exec(
'dbname=pgteste
hostaddr=200.174.40.63
user=paulo
password=paulo
port=5432',

'update clientes
set nome=''Paulo Rogerio''
where id = 18
85
'
);
Exemplo dbLink - Delete
select
dblink_exec(
'dbname=pgteste
hostaddr=200.174.40.63
user=paulo
password=paulo
port=5432',

'delete from clientes
where id = 18
'
);
5emos o co)trib db(i)G e o %roCerto s(o)H %$r$ re%(ic$+o de b$)cos do PostgreSQL.
O dblink no vem ativo por default.
>tiv$)do o db(i)G2
e 0or$ do b$)co2
psql -U nomeuser nomebanco < /usr/local/pgsql/contrib/dblink.sql
8' de de)tro do b$)co2
\i /usr/local/pgsql/contrib/dblink.sql
O')+;es do db(i)G2
dblink - para SELECT
dblinkexec - para NSERT, UPDATE e DELETE (remotos)
Tutorial sobre replicao no site da dbExperts - www.dbexperts.com.br
Usado para fazer consultas remotas em bancos do PG
db(i)G *S select
db(i)Ge<ec *S insert, update e delete (remotos)
Dica: Remover postmarter.pid em caso de queda anormal do SGBD
/o)s doc'me)tos sobre re%(ic$+o2
- Replicao do PostgreSQL com Slony do Marlon Petry
- Backup Quente no PostgreSQL com Replicao do Slvio Csar
- Replicando banco de dados PostgreSQL do Rafael Donato
86
11 4 "o)0ig'r$+;es
Ao instalar o PostgreSQL 8.1.4 via fontes ele cria (e alerta) o arquivo pg_hba.conf com
autenticao do tipo trust (conexo local sem senha).
P$r$ $'te)tic$r e<igi)do 'm dos ti%os com se)7$1 devemos $)tes1 $i)d$ )o tr'st1
$(ter$r os 's'rios $dicio)$)do se)7$2
ALTER ROLE nomeuser WTH PASSWORD 'senhadopg';
Some)te e)to devemos $(ter$r o %gM7b$.co)0 %$r$ %edir se)7$ e rest$rt$r o
PostgreSQL.
Numa instalao via fontes da verso 8.1.4 a autenticao padro do tipo trust
(pg_hba.conf), o que permite acesso local sem senha.
Caso queiramos alterar para que os usurios sejam autenticados com o tipo password, md5
ou crypt, temos que dar a devida senha ao usurio, ainda usando trust e somente aps ter
criado as senhas dentro do psql ou outra interface, s ento mudar o tipo de autenticao no
pg_hba.conf.
As configuraes principais so feitas nos arquivos pg_hba.conf e postgresql.conf. Se
instalado atravs dos fontes ficam no subdiretrio data de instalao do PostgreSQL,
normalmente em /usr/local/pgsql. Se instalado via binrios da distribuio vai variar com a
distribuio. No Slackware esto no diretrio /usr/share/postgresql.
O pg_hba.conf controla que mquinas tero acesso ao PostgreSQL e a autenticao dessas
mquinas clientes (sem autenticao ou atravs de outras formas, trust, md5, crypt, etc).
O pg_hba.conf muito rico e podemos controlar o acesso pelo P, pela mscara, pelo banco,
pelo usurio, pelo mtodo (trust, md5, password, etc).
5rec7os do %gM7b$.co)02
...
Mtodos: "trust", "reject", "md5", "crypt", "password", "krb5", "ident" ou "pam".
O mtodo "password" envia senhas em texto claro; "md5" deve ser preferido j que envia
senhas criptografadas. Configurando aqui como md5 as conexes em um cliente como o
PHP devero acontecer com a senha do usurio trazendo o hash md5 respectivo a sua
senha e no em texto claro.
Dica: para conexo local, o TYPE local no pode estar comentado, ou seja, abaixo deveria
aparecer uma linha com local ao invs de host.
# TYPE DATABASE USER CDR-ADDRESS METHOD
# Pv4 local connections:
host all all 127.0.0.1/32 trust
host all all 10.0.0.16/32 password
host all all 10.0.2.113/32 md5
host all all 0.0.0.0/0.0.0.0 reject
No exemplo acima diz que:
- as conexes que vierem de 127.0.0.1 via TCP, so confiveis e tem acesso garantido.
- As que vierem de 10.0.0.16 devero vir com senha em texto claro
87
- As que vierem de 10.0.2.113 devero vir os hashs md5 das senhas e no texto claro.
- Todas as demais mquinas tem acesso negado (reject).
#<em%(os do m$)'$( o0ici$( (tr$d'6ido %$r$ o %ort'g'9s do /r$si( %e(o ,$((eH
P$c7eco)2
Exemplo 19-1. Exemplo de registros do arquivo pg_hba.conf
# Permitir qualquer usurio do sistema local se conectar a qualquer banco
# de dados sob qualquer nome de usurio utilizando os soquetes do domnio
# Unix (o padro para conexes locais).
#
# TYPE DATABASE USER CDR-ADDRESS METHOD
local all all trust
# A mesma coisa utilizando conexes locais TCP/P retornantes (loopback).
#
# TYPE DATABASE USER CDR-ADDRESS METHOD
host all all 127.0.0.1/32 trust
# O mesmo que o exemplo anterior mas utilizando uma coluna em separado para
# mscara de rede.
#
# TYPE DATABASE USER P-ADDRESS P-MASK METHOD
host all all 127.0.0.1 255.255.255.255 trust
# Permitir qualquer usurio de qualquer hospedeiro com endereo de P 192.168.93.x
# se conectar ao banco de dados "template1" com o mesmo nome de usurio que "ident"
# informa para a conexo (normalmente o nome de usurio do Unix).
#
# TYPE DATABASE USER CDR-ADDRESS METHOD
host template1 all 192.168.93.0/24 ident sameuser
# Permitir o usurio do hospedeiro 192.168.12.10 se conectar ao banco de dados
# "template1" se a senha do usurio for fornecida corretamente.
#
# TYPE DATABASE USER CDR-ADDRESS METHOD
host template1 all 192.168.12.10/32 md5
# Na ausncia das linhas "host" precedentes, estas duas linhas rejeitam todas
# as conexes oriundas de 192.168.54.1 (uma vez que esta entrada ser
# correspondida primeiro), mas permite conexes Kerberos V de qualquer ponto
# da nternet. A mscara zero significa que no considerado nenhum bit do
# endereo de P do hospedeiro e, portanto, corresponde a qualquer hospedeiro.
#
# TYPE DATABASE USER CDR-ADDRESS METHOD
host all all 192.168.54.1/32 reject
host all all 0.0.0.0/0 krb5
# Permite os usurios dos hospedeiros 192.168.x.x se conectarem a qualquer
# banco de dados se passarem na verificao de "ident". Se, por exemplo, "ident"
# informar que o usurio "oliveira" e este requerer se conectar como o usurio
# do PostgreSQL "guest1", a conexo ser permitida se houver uma entrada
# em pg_ident.conf para o mapa "omicron" informando que "oliveira" pode se
88
# conectar como "guest1".
#
# TYPE DATABASE USER CDR-ADDRESS METHOD
host all all 192.168.0.0/16 ident omicron
# Se as linhas abaixo forem as nicas trs linhas para conexo local, vo
# permitir os usurios locais se conectarem somente aos seus prprios bancos de
# dados (bancos de dados com o mesmo nome que seus nomes de usurio), exceto
# para os administradores e membros do grupo "suporte" que podem se conectar a
# todos os bancos de dados. O arquivo $PGDATA/admins contm a lista de nomes de
# usurios. A senha requerida em todos os casos.
#
# TYPE DATABASE USER CDR-ADDRESS METHOD
local sameuser all md5
local all @admins md5
local all +suporte md5
# As duas ltimas linhas acima podem ser combinadas em uma nica linha:
local all @admins,+suporte md5
Obs.: @admins - lista de usurios em arquivo
+suporte - grupo de usurios
Local para conexo usando apenas Socket UNX, local.
# A coluna banco de dados tambm pode utilizar listas e nomes de arquivos,
# mas no grupos:
local db1,db2,@demodbs all md5
Um arquivo pg_ident.conf que pode ser utilizado em conjunto com o arquivo pg_hba.conf do
Exemplo 19-1 est mostrado no Exemplo 19-2. Nesta configurao de exemplo, qualquer
usurio autenticado em uma mquina da rede 192.168 que no possua o nome de usurio
Unix oliveira, lia ou andre no vai ter o acesso permitido. O usurio Unix andre somente
poder acessar quando tentar se conectar como o usurio do PostgreSQL pacheco, e no
como andre ou algum outro. A usuria lia somente poder se conectar como lia. O usurio
oliveira poder se conectar como o
prprio oliveira ou como guest1.
Exemplo 19-2. Arquivo pg_ident.conf de exemplo
# MAPNAME DENT-USERNAME PG-USERNAME
omicron oliveira oliveira
omicron lia lia
# pacheco possui o nome de usurio andre nestas mquinas
omicron andre pacheco
# oliveira tambm pode se conectar como guest1
omicron oliveira guest1
host conexes remotas usando TCP/P. Conexes host aceitam conexes SSL e no SSL,
mas conexes hostssl somente aceitam conexes SSL
hostssl - via SSL em TCP/P
P address e P MASK - do cliente
md5 - requer cliente com senha md5
password - requer senha mas texto claro
89
Se houver preocupao com relao aos ataques de "farejamento (sniffing) de senhas,
ento md5 o mtodo preferido, com crypt como a segunda opo se for necessrio
suportar clientes pr-7.2. O mtodo password deve ser evitado, especialmente em conexes
pela nternet aberta (a menos que seja utilizado SSL, SSH ou outro mtodo de segurana
para proteger a conexo).
ide)t
Obtm o nome de usurio do sistema operacional do cliente (para conexes TCP/P fazendo
contato com o servidor de identificao no cliente, para conexes locais obtendo a partir do
sistema operacional) e verifica se o usurio possui permisso para se conectar como o
usurio de banco de dados solicitado consultando o mapa especificado aps a palavra chave
ident.
P$is det$(7es sobre o %gM7b$.co)0 em2
http://pgdocptbr.sourceforge.net/pg80/client-authentication.html
O postgresql.conf permite configurar as demais funcionalidades do PostgreSQL
Liberando acesso via rede TCP/P na verso 7.4.x:
tcp_socket = true (default = false)
No 8.0.x:
listen_address = '10.0.0.16'
>(g')s co)0ig'r$+;es do %ostgres3(.co)02
Regra geral: os valores que vm comentados com # so os valores default. Se formos alterar
algum idealmente devemos fazer uma cpia da linha e descomentar, para sempre saber o
valor default.
sameuser o usurio padro no ident.conf (significa o mesmo user do sistema operacional).
# FLE LOCATONS
#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file
# CONNECTONS AND AUTHENTCATON
# O parmetro listen_address indica as mquinas que tero acesso via TCP/P
# - Connection Settings Aqui as mquinas que tero acesso via TCP/P
#listen_addresses = 'localhost' # Que P ou nome para escutar;
# lista de endereos separados por vrgula;
# defaults para 'localhost', '*' = all '*' permite acesso a todos
# Por default aceita somente conexes locais
#port = 5432
max_connections = 100 (duas so reservadas para o superusurio)
# note: increasing max_connections costs ~400 bytes of shared memory per
#superuser_reserved_connections = 2
# - Security & Authentication -
#authentication_timeout = 60 # 1-600, in seconds
#ssl = off
#password_encryption = on
# RESOURCE USAGE (except WAL)
# - Memory -
shared_buffers = 1000 # min 16 or max_connections*2, 8KB each
#temp_buffers = 1000 # min 100, 8KB each
#max_prepared_transactions = 5 # can be 0 or more
90
# note: increasing max_prepared_transactions costs ~600 bytes of shared memory
# per transaction slot, plus lock space (see max_locks_per_transaction).
#work_mem = 1024 # min 64, size in KB
#maintenance_work_mem = 16384 # min 1024, size in KB
#max_stack_depth = 2048 # min 100, size in KB
# - Free Space Map -
#max_fsm_pages = 20000 # min max_fsm_relations*16, 6 bytes each
#max_fsm_relations = 1000 # min 100, ~70 bytes each
5lgumas 6onfigura-7es no postgresql.conf
...
# AUTOVACUUM PARAMETERS
#autovacuum = off # enable autovacuum subprocess?
...
# - Locale and Formatting -
#datestyle = 'iso, mdy' # Era o original
datestyle = 'sql, european' # Formato dd/mm/yyyy
...
#client_encoding = sql_ascii
#client_encoding = latin1 # Suporte acentuao do Brasil
...
"o)s'(t$)do )o %s3(2
SHOW DATESTYLE;
Retorna -> SQL, DMY
>C'st$)do o esti(o d$ d$t$ )o %s3(2
SET DATESTYLE TO SQL, DMY;
ALTER ROLE nomeuser SET datestyle TO SQL, DMY;
8 c$mi)7o de e)tr$d$ )'m b$)co do PostgreSQL2
-> postgresql.conf -> ph_hba.conf -> ident.conf (caso este exista e seja citado no
pg_hba.conf)
O encoding e outros recursos podem ser passados para cada banco, no momento de sua
criao, como por exemplo:
e 0or$ do b$)co2
createdb -E LATN1 nomebanco.
e de)tro do b$)co (%s3()2
CREATE DATABASE nomebanco WTH ENCODNG 'LATN1';
P$r$ $ re($+o com%(et$ dos e)codi)g s'%ort$dos veC$ t$be($ 21*2.
P$r$ vis'$(i6$r $ codi0ic$+o )o %s3( digite
\encoding.
P$r$ m'd$r $ codi0ic$+o de 'm b$)co di)$mic$me)te1 est$)do )e(e 'ti(i6e2
\encoding novoencoding
91
"omo t$mb:m %odemos 'ti(i6$r o com$)do S#52
SET CLENT_ENCODNG 'LATN1';
"o)s'(t$)do o e)codi)g e<iste)te
SHOW CLENT_ENCODNG;
P>L> #SO>b#L >S >L5#L>ef#S # ?8L5>L g "8!O!">e`8 P>L`82
RESET CLENT_ENCODNG;
P$is det$(7es2
7tt%2FFAAA.%ostgres3(.orgFdocsF8.1Fi)ter$ctiveFr')time*co)0ig.7tm(h"8NO!.*S#55!N.
P$r$ s$ber os (oc$(es e<iste)tes e<ec'te de de)tro do %s3(2
\l -- Exibe bancos, donos e locales (Codificao)
#m c$d$ co)e<o com o PostgreSQL1 some)te se %ode $cess$r 'm I)ico b$)co.
No %ostgres3(.co)0 %odemos de0i)ir o e)codi)g $tr$v:s d$ v$rive( c(ie)tMe)codi)g.
92
12 Pet$d$dos ("$t(ogo)
Pet$d$dos so d$dos sobre d$dos.
Uma consulta normal retorna informaes existentes em tabelas, j uma consulta sobre os
metadados retorna informaes sobre os bancos, os objetos dos bancos, os campos de
tabelas, seus tipos de dados, seus atributos, suas constraints, etc.
Letor)$r 5od$s $s 5$be($s do b$)co e es3'em$ $t'$(
SELECT schemaname AS esquema, tablename AS tabela, tableowner AS dono
FROM pg_catalog.pg_tables
WHERE schemaname NOT N ('pg_catalog', 'information_schema', 'pg_toast')
ORDER BY schemaname, tablename
!)0orm$+;es de 5odos os 5$b(es%$ces
SELECT spcname, pg_catalog.pg_get_userbyid(spcowner) AS spcowner, spclocation
FROM pg_catalog.pg_tablespace
Letor)$r b$)co1 do)o1 codi0ic$+o1 come)trios e t$b(es%$ce
SELECT pdb.datname AS banco,
pu.usename AS dono,
pg_encoding_to_char(encoding) AS codificacao,
(SELECT description FROM pg_description pd WHERE pdb.oid=pd.objoid) AS comentario,
(SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE pt.oid=pdb.dattablespace)
AS tablespace
FROM pg_database pdb, pg_user pu WHERE pdb.datdba = pu.usesysid ORDER BY
pdb.datname
5$be($s1 do)os1 come)trios1 registros e t$b(es%$ces de 'm sc7em$
SELECT c.relname as tabela,
pg_catalog.pg_get_userbyid(c.relowner) AS dono,
pg_catalog.obj_description(c.oid, 'pg_class') AS comentario, reltuples::integer as registros,
(SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE pt.oid=c.reltablespace) AS
tablespace
FROM pg_catalog.pg_class c
LEFT JON pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND nspname='public'
ORDER BY c.relname
Postr$r Se3'e)ces de 'm #s3'em$
SELECT c.relname AS seqname, u.usename AS seqowner, pg_catalog.obj_description(c.oid,
'pg_class') AS seqcomment,
(SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE
pt.oid=c.reltablespace) AS tablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_namespace n
WHERE c.relowner=u.usesysid AND c.relnamespace=n.oid
AND c.relkind = 'S' AND n.nspname='public' ORDER BY seqname

93
Postr$r 5$b(es%$ces
SELECT spcname, pg_catalog.pg_get_userbyid(spcowner) AS spcowner, spclocation
FROM pg_catalog.pg_tablespace
Postr$r det$(7es de 'm$ 0')ctio)
SELECT
pc.oid AS prooid,
proname,
lanname as prolanguage,
pg_catalog.format_type(prorettype, NULL) as proresult,
prosrc,
probin,
proretset,
proisstrict,
provolatile,
prosecdef,
pg_catalog.oidvectortypes(pc.proargtypes) AS proarguments,
proargnames AS proargnames,
pg_catalog.obj_description(pc.oid, 'pg_proc') AS procomment
FROM pg_catalog.pg_proc pc, pg_catalog.pg_language pl
WHERE pc.oid = 'oid_da_function'::oid
AND pc.prolang = pl.oid
Este exemplo mostra uma consulta que lista os nomes dos esquemas, tabelas,
colunas e chaves das chaves estrangeiras, e os nomes dos esquemas, tabelas e
colunas referenciadas. Exemplo tirado da lista de discusso pgsql-sql
CREATE TEMPORARY TABLE t1 (id SERAL PRMARY KEY, nome TEXT);
CREATE TEMPORARY TABLE t2 (id NT REFERENCES t1, nome TEXT);
SELECT
n.nspname AS esquema,
cl.relname AS tabela,
a.attname AS coluna,
ct.conname AS chave,
nf.nspname AS esquema_ref,
clf.relname AS tabela_ref,
af.attname AS coluna_ref,
pg_get_constraintdef(ct.oid) AS criar_sql
FROM pg_catalog.pg_attribute a
JON pg_catalog.pg_class cl ON (a.attrelid = cl.oid AND cl.relkind = 'r')
JON pg_catalog.pg_namespace n ON (n.oid = cl.relnamespace)
JON pg_catalog.pg_constraint ct ON (a.attrelid = ct.conrelid AND
ct.confrelid != 0 AND ct.conkey[1] = a.attnum)
JON pg_catalog.pg_class clf ON (ct.confrelid = clf.oid AND clf.relkind = 'r')
JON pg_catalog.pg_namespace nf ON (nf.oid = clf.relnamespace)
JON pg_catalog.pg_attribute af ON (af.attrelid = ct.confrelid AND
af.attnum = ct.confkey[1]);
94
Postr$r #s3'em$s e 5$be($s
SELECT n.nspname as esquema, c.relname as tabela, a.attname as campo,
format_type(t.oid, null) as tipo_de_dado
FROM pg_namespace n, pg_class c,
pg_attribute a, pg_type t
WHERE n.oid = c.relnamespace
and c.relkind = 'r' -- no indices
and n.nspname not like 'pg\\_%' -- no catalogs
and n.nspname != 'information_schema' -- no information_schema
and a.attnum > 0 -- no system att's
and not a.attisdropped -- no dropped columns
and a.attrelid = c.oid
and a.atttypid = t.oid
ORDER BY nspname, relname, attname;
Postr$r #s3'em$s e res%ectiv$s t$be($s do /$)co $t'$(2
SELECT n.nspname as esquema, c.relname as tabela FROM pg_namespace n, pg_class c
WHERE n.oid = c.relnamespace
and c.relkind = 'r' -- no indices
and n.nspname not like 'pg\\_%' -- no catalogs
and n.nspname != 'information_schema' -- no information_schema
ORDER BY nspname, relname

"o)t$r 5odos os Legistros de tod$s $s t$be($s de todos os b$)cos2
<?php
$conexao=pg_connect("host=127.0.0.1 user=postgres password=postabir");
$sql="SELECT datname AS banco FROM pg_database ORDER BY datname";
$consulta=pg_query($conexao,$sql);
$banco = array();
$c=0;
while ($data = @pg_fetch_object($consulta,$c)) {
$cons=$data->banco;
$banco[] .= $cons;
$c++;
}
$sql2="SELECT n.nspname as esquema,c.relname as tabela FROM pg_namespace n,
pg_class c
WHERE n.oid = c.relnamespace
and c.relkind = 'r' -- no indices
and n.nspname not like 'pg\\_%' -- no catalogs
and n.nspname != 'information_schema' -- no information_schema
ORDER BY nspname, relname";
for ($x=0; $x < count($banco);$x++){
if ($banco[$x] !="template0" && $banco[$x] != "template1" && $banco[$x] !
="postgres"){
$conexao2=pg_connect("host=127.0.0.1 dbname=$banco[$x] user=postgres
95
password=postabir");
$consulta2=pg_query( $conexao2, $sql2 );

while ($data = pg_fetch_object($consulta2)) {
$esquematab=$data->esquema.'.'.$data->tabela;
$sql3="SELECT count(*) FROM $esquematab";
$consulta3=pg_query($conexao2,$sql3);
$res=@pg_fetch_array($consulta3);
print 'Banco.Esquema.Tabela -> '.$banco[$x].'.'.$data->esquema.'.'.$data-
>tabela.' - Registro(s) - '.$res[0].'<br>';
$total += $res[0];
}
}
}
print "Total de Registro de todas as tabelas de todos os bancos ". $total;
?>
$do o b$)co de d$dos1 3'$( o se' diret-rio2
select datname, oid from pg_database;
$do $ t$be($1 3'$( o se' $r3'ivo2
select relname, relfilenode from pg_class;
Postr$r c7$ves %rimri$s d$s t$be($s do es3'em$ %'b(ic
select indexrelname as indice, relname as tabela from pg_catalog.pg_statio_user_indexes as
A NNER JON pg_catalog.pg_index as B ON A.indexrelid=B.indexrelid WHERE
A.schemaname='public' AND B.indisprimary = true;
P$r$ vis'$(i6$r como $s co)s'(t$s so 0eit$s i)ter)$me)te vi$ %s3( 's$mos o com$)do
$ssim2
psql -U user banco -E
Vamos usar o banco municipios, criado com os municpios do Brasil. A tabela opt_cidades.
Veja Um Exemplo Que Retorna a Chave Primria da Tabela opt_cidades
SELECT
ic.relname AS index_name,
bc.relname AS tab_name,
ta.attname AS column_name,
i.indisunique AS unique_key,
i.indisprimary AS primary_key
FROM
pg_class bc,
pg_class ic,
pg_index i,
pg_attribute ta,
pg_attribute ia
WHERE
bc.oid = i.indrelid
AND ic.oid = i.indexrelid
96
AND ia.attrelid = i.indexrelid
AND ta.attrelid = bc.oid
AND bc.relname = 'opt_cidades'
AND ta.attrelid = i.indrelid
AND ta.attnum = i.indkey[ia.attnum-1]
ORDER BY
index_name, tab_name, column_name;
Letor)$r2
index_name | tab_name | column_name | unique_key | primary_key
opt_cidades_pkey | opt_cidades | id | t | t
Letor)$)do o Nome do #s3'em$
SELECT n.nspname AS "Esquema"
FROM pg_catalog.pg_namespace AS n,
pg_catalog.pg_class AS c
WHERE c.relnamespace = n.oid AND c.relname='opt_cidades';
Retorno: Esquema
Letor)$r )omes de b$)cos2
SELECT datname AS banco FROM pg_database
WHERE datname != 'template0' and datname != 'template1' and datname != 'postgres'
ORDER BY datname
Letor)$r )omes e 8!s dos b$)cos2
SELECT oid, datname FROM pg_database;
$do $ t$be($1 3'$( o se' $r3'ivo2
select relname, relfilenode from pg_class;
No @i)doAs
Podemos passar parmetros para as macros, por exemplo:
doskey /exename=psql.exe dbinfo=SELECT datname,pg_encoding_to_char(encoding) FROM
pg_database WHERE datname='$1';
E ento apenas passar o parmetro na linha de comando:
postgres=# dbinfo postgres
List$r t$be($s1 e do)o do es3'em$ $t'$(2
SELECT n.nspname as "Schema",
c.relname as "Tabela",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' THEN
'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' END as "Tipo",
u.usename as "Dono"
FROM pg_catalog.pg_class c
LEFT JON pg_catalog.pg_user u ON u.usesysid = c.relowner
LEFT JON pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind N ('r','')
AND n.nspname NOT N ('pg_catalog', 'pg_toast')
AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
97
List$r 5$be($s
select c.relname FROM pg_catalog.pg_class c
LEFT JON pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind N ('r','') AND n.nspname NOT N ('pg_catalog', 'pg_toast')
AND pg_catalog.pg_table_is_visible(c.oid);
SELECT tablename FROM pg_tables WHERE tablename NOT LKE 'pg%' AND tablename
NOT LKE 'sql\_%'
List$r tod$s $s t$be($s1 &)dices1 t$m$)7o em N/ e 8!s2
VACUUM; --Executar antes este comando
SELECT c1.relname AS tabela, c2.relname AS indice,
c2.relpages * 8 AS tamanho_kb, c2.relfilenode AS arquivo
FROM pg_class c1, pg_class c2, pg_index i
WHERE c1.oid = i.indrelid AND i.indexrelid = c2.oid
UNON
SELECT relname, NULL, relpages * 8, relfilenode
FROM pg_class
WHERE relkind = 'r'
ORDER BY tabela, indice DESC, tamanho_kb;
5$be($s e Som$
SELECT tablename, SUM( size_kb )
FROM
( SELECT c1.relname AS "tablename",
c2.relpages * 8 AS "size_kb"
FROM pg_class c1, pg_class c2, pg_index i
WHERE c1.oid = i.indrelid
AND i.indexrelid = c2.oid
UNON
SELECT relname, relpages * 8
FROM pg_class
WHERE relkind = 'r' ) AS relations
GROUP BY tablename;
-- r = ordinary table, i = index, S = sequence, v = view, c = composite type,
-- s = special, t = TOAST table
5$m$)7o em bHtes de 'm b$)co2
select pg_database_size('banco');
5$m$)7o em bHtes de 'm$ t$be($2
pg_total_relation_size('tabela')
5$m$)7o em bHtes de t$be($ o' &)dice2
pg_relation_size('tabelaouindice')
List$ do)os e b$)cos2
SELECT rolname as dono, datname as banco
FROM pg_roles, pg_database
WHERE pg_roles.oid = datdba
ORDER BY rolname, datname;
98
Nomes de b$)cos2
select datname from pg_database where datname not in ('template0','template1') order by 1
Nomes e co(')$s2
select tablename,'T' from pg_tables where tablename not like 'pg\_%'
and tablename not in ('sql_features', 'sql_implementation_info', 'sql_languages',
'sql_packages', 'sql_sizing', 'sql_sizing_profiles')
union
select viewname,'V' from pg_views where viewname not like 'pg\_%'
5$m$)7o de es3'em$ e &)dice2
SELECT nspname,
sum(relpages * cast( 8192 AS bigint )) as "table size",
sum( ( select sum(relpages)
from pg_class i, pg_index idx
where i.oid = idx.indexrelid
and t.oid=idx.indrelid ) ) * cast( 8192 AS bigint ) as "index size",
sum ( relpages * cast( 8192 AS bigint ) + ( select sum(relpages)
from pg_class i, pg_index idx
where i.oid = idx.indexrelid
and t.oid=idx.indrelid ) * cast( 8192 AS bigint ) ) as "size"
FROM pg_class t, pg_namespace
WHERE relnamespace = pg_namespace.oid
and pg_namespace.nspname not like 'pg_%'
and pg_namespace.nspname != 'information_schema'
and relkind = 'r' group by nspname;
Letor)$)do 5$be($s e Se's o)os de 'm #s3'em$
SELECT n.nspname as "public",
c.relname as "opt_cidades",
CASE c.relkind WHEN 'r' THEN 'tabela' WHEN 'v' THEN 'view' WHEN 'i' THEN 'ndice'
WHEN 'S' THEN 'sequencia' WHEN 's' THEN 'especial' END as "Tipo", u.usename as "Dono"
FROM pg_catalog.pg_class c
LEFT JON pg_catalog.pg_user u ON u.usesysid = c.relowner
LEFT JON pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind N ('r','')
AND n.nspname NOT N ('pg_catalog', 'pg_toast')
AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 1,2;
Retorno:
public | opt_cidades | Tipo | Dono
--------+------------------+--------+----------
public | opt_cidades | tabela | postgres
public | opt_estado | tabela | postgres
Letor)$)do o 8! e o #s3'em$ de 'm$ 5$be($
SELECT c.oid AS "OD",
n.nspname AS "Esquema",
c.relname AS "Tabela"
FROM pg_catalog.pg_class c
LEFT JON pg_catalog.pg_namespace n ON n.oid = c.relnamespace
99
WHERE pg_catalog.pg_table_is_visible(c.oid)
AND c.relname ~ '^opt_cidades$'
ORDER BY 2, 3;
Retorno:
OD | Esquema | Tabela
#ste e<em%(o mostr$ 'm$ co)s'(t$ 3'e (ist$ os es3'em$s1 )omes d$s t$be($s e )omes
d$s co(')$s d$s c7$ves %rimri$s de 'm b$)co de d$dos. #<em%(o tir$do d$ (ist$ de
disc'sso %gs3(*s3( .
CREATE TEMP TABLE teste1 (id NT, texto TEXT, PRMARY KEY (id));
CREATE TEMP TABLE teste2 (id1 NT, id2 NT, texto TEXT, PRMARY KEY (id1,id2));
\dt
SELECT
pg_namespace.nspname AS esquema,
pg_class.relname AS tabela,
pg_attribute.attname AS coluna_pk
FROM pg_class
JON pg_namespace ON pg_namespace.oid=pg_class.relnamespace AND
pg_namespace.nspname NOT LKE 'pg_%'
JON pg_attribute ON pg_attribute.attrelid=pg_class.oid AND
pg_attribute.attisdropped='f'
JON pg_index ON pg_index.indrelid=pg_class.oid AND
pg_index.indisprimary='t' AND
(
pg_index.indkey[0]=pg_attribute.attnum OR
pg_index.indkey[1]=pg_attribute.attnum OR
pg_index.indkey[2]=pg_attribute.attnum OR
pg_index.indkey[3]=pg_attribute.attnum OR
pg_index.indkey[4]=pg_attribute.attnum OR
pg_index.indkey[5]=pg_attribute.attnum OR
pg_index.indkey[6]=pg_attribute.attnum OR
pg_index.indkey[7]=pg_attribute.attnum OR
pg_index.indkey[8]=pg_attribute.attnum OR
pg_index.indkey[9]=pg_attribute.attnum
)
ORDER BY pg_namespace.nspname, pg_class.relname,pg_attribute.attname;
#ste e<em%(o mostr$ 'm$ co)s'(t$ 3'e (ist$ os )omes dos es3'em$s1 t$be($s1
co(')$s e c7$ves d$s c7$ves estr$)geir$s1 e os )omes dos es3'em$s1 t$be($s e
co(')$s re0ere)ci$d$s. #<em%(o tir$do d$ (ist$ de disc'sso %gs3(*s3(
CREATE TEMPORARY TABLE t1 (id SERAL PRMARY KEY, nome TEXT);
CREATE TEMPORARY TABLE t2 (id NT REFERENCES t1, nome TEXT);
SELECT
n.nspname AS esquema,
cl.relname AS tabela,
a.attname AS coluna,
ct.conname AS chave,
nf.nspname AS esquema_ref,
clf.relname AS tabela_ref,
af.attname AS coluna_ref,
100
pg_get_constraintdef(ct.oid) AS criar_sql
FROM pg_catalog.pg_attribute a
JON pg_catalog.pg_class cl ON (a.attrelid = cl.oid AND cl.relkind = 'r')
JON pg_catalog.pg_namespace n ON (n.oid = cl.relnamespace)
JON pg_catalog.pg_constraint ct ON (a.attrelid = ct.conrelid AND
ct.confrelid != 0 AND ct.conkey[1] = a.attnum)
JON pg_catalog.pg_class clf ON (ct.confrelid = clf.oid AND clf.relkind = 'r')
JON pg_catalog.pg_namespace nf ON (nf.oid = clf.relnamespace)
JON pg_catalog.pg_attribute af ON (af.attrelid = ct.confrelid AND
af.attnum = ct.confkey[1]);
Retorno:
esquema | tabela | coluna | chave | esquema_ref | tabela_ref | coluna_ref |
criar_sql
pg_temp_1 | t2 | id | t2_id_fkey | pg_temp_1 | t1 | id | FOREGN KEY (id)
REFERENCES t1(id)
SELECT a.attnum, a.attname AS field, t.typname as type, a.attlen AS length, a.atttypmod-4 as
lengthvar, a.attnotnull as notnull
FROM pg_class c, pg_attribute a, pg_type t
WHERE c.relname = 'apagar' AND a.attnum > 0 AND a.attrelid = c.oid AND a.atttypid =
t.oid
ORDER BY a.attnum;
Sada:
D do campo, nomecampo, tipo, tamanho, nulo/nonulo
8'tros
SELECT ic.relname AS index_name, bc.relname AS tab_name, ta.attname AS column_name,
i.indisunique AS unique_key, i.indisprimary AS primary_key
FROM pg_class bc, pg_class ic, pg_index i, pg_attribute ta, pg_attribute ia
WHERE (bc.oid = i.indrelid)
AND (ic.oid = i.indexrelid)
AND (ia.attrelid = i.indexrelid)
AND (ta.attrelid = bc.oid)
AND (bc.relname = 'apagar')
AND (ta.attrelid = i.indrelid)
AND (ta.attnum = i.indkey[ia.attnum-1])
ORDER BY index_name, tab_name, column_name
S$&d$2
nomeindex/chave, nometabela, nomecampo, unique(t/f), nomepk (t/f)
SELECT rcname as index_name, rcsrc
FROM pg_relcheck, pg_class bc
WHERE rcrelid = bc.oid
AND bc.relname = 'apagar'
AND NOT EXSTS (
SELECT *
FROM pg_relcheck as c, pg_inherits as i
WHERE i.inhrelid = pg_relcheck.rcrelid
AND c.rcname = pg_relcheck.rcname
AND c.rcsrc = pg_relcheck.rcsrc
AND c.rcrelid = i.inhparent
)
101
S$&d$2 retor)$ $s co)str$i)ts c7ecG.
SELECT pg_class.relname, pg_attribute.attname, pg_type.typname,
pg_attribute.atttypmod-4
FROM pg_class, pg_attribute, pg_type
WHERE pg_attribute.attrelid = pg_class.oid
AND pg_attribute.atttypid = pg_type.oid
AND pg_class.relname = 'apagar'
AND pg_attribute.attname = 'descricao'
S$&d$2 t$be($1 c$m%o1 ti%o1 t$m$)7o (v$rc7$r)
8'tros #<em%(os
create table tabela_exemplo (
campo_1 integer default 5, campo_2 text default 'exemplo', campo_3 float(10),
campo_4 serial, campo_5 double precision, campo_6 int8, campo_7 Point,
campo_8 char(3), campo_9 varchar(17) );
e%ois de cri$d$ $ t$be($ v$mos cri$r $ co)s'(t$ 3'e )os retor)$r $s i)0orm$+;es d$
t$be($2
SELECT
rel.nspname AS Esquema, rel.relname AS Tabela, attrs.attname AS Campo, "Type",
"Default", attrs.attnotnull AS "NOT NULL"
FROM (
SELECT c.oid, n.nspname, c.relname
FROM pg_catalog.pg_class c
LEFT JON pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE pg_catalog.pg_table_is_visible(c.oid) ) rel
JON (
SELECT a.attname, a.attrelid, pg_catalog.format_type(a.atttypid, a.atttypmod) as
"Type",
(SELECT substring(d.adsrc for 128) FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) as "Default",
a.attnotnull, a.attnum
FROM pg_catalog.pg_attribute a WHERE a.attnum > 0 AND NOT a.attisdropped )
attrs
ON (attrs.attrelid = rel.oid )
WHERE relname = 'tabela_exemplo' ORDER BY attrs.attnum;
Letor)o2
testes-# WHERE relname = 'tabela_exemplo' ORDER BY attrs.attnum;
esquema | tabela | campo | Type | Default | NOT
NULL

>)tes de t'do devemos cri$r 'm )ovo ti%o de d$do re($cio)$do $o retor)o 3'e
obteremos d$ 0')+o2
CREATE TYPE tabela_estrutura AS (Esquema text, Tabela text, Campo text, Tipo text,
Valor text, Autoncremento bool);
102
> 0')+o $b$i<o : de0i)id$ em PLFPgSQL1 (i)g'$gem %roced'r$( m'ito seme(7$)te $o
PLFSQL do 8r$c(e. > 0')+o 0oi cri$d$ )est$ (i)g'$gem devido $ cert$s (imit$+;es 3'e
$s 0')+;es em SQL %oss'em.
CREATE OR REPLACE FUNCTON Dados_Tabela(varchar(30))
RETURNS SETOF tabela_estrutura AS '
DECLARE
r tabela_estrutura%ROWTYPE;
rec RECORD;
vTabela alias for $1;
eSql TEXT;
BEGN
eSql := ''SELECT
CAST(rel.nspname as TEXT), CAST(rel.relname AS TEXT) , CAST(attrs.attname AS
TEXT), CAST("Type" AS TEXT), CAST("Default" AS TEXT), attrs.attnotnull
FROM
(SELECT c.oid, n.nspname, c.relname
FROM pg_catalog.pg_class c
LEFT JON pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE pg_catalog.pg_table_is_visible(c.oid) ) rel
JON
(SELECT a.attname, a.attrelid,
pg_catalog.format_type(a.atttypid, a.atttypmod) as "Type",
(SELECT substring(d.adsrc for 128) FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)
as "Default", a.attnotnull, a.attnum
FROM pg_catalog.pg_attribute a
WHERE a.attnum > 0 AND NOT a.attisdropped ) attrs
ON (attrs.attrelid = rel.oid )
WHERE relname LKE ''''%'' || vTabela || ''%''''
ORDER BY attrs.attnum'';
FOR r N EXECUTE eSql
LOOP
RETURN NEXT r;
END LOOP;
F NOT FOUND THEN
RASE EXCEPTON ''Tabela % no encontrada'', vTabela;
END F;
RETURN;
END
'
LANGUAGE 'plpgsql';
P$r$ 'ti(i6$r est$ 0')+o1 'ti(i6e o seg'i)te com$)do2
SELECT * FROM Dados_Tabela('tabela');
Retorno:
esquema | tabela | campo | tipo | valor | autoincremento
Exemplos contidos no arquivo:
/usr/local/src/postgresql-8.1.3/src/tutorial/syscat.sql
SELECT rolname as "Donos", datname as Bancos
FROM pg_roles, pg_database
WHERE pg_roles.oid = datdba
103
ORDER BY rolname, datname;
Letor)o2 o)os e /$)cos
SELECT n.nspname as esquema, c.relname as tabela
FROM pg_class c, pg_namespace n
WHERE c.relnamespace=n.oid
and c.relkind = 'r' -- not indices, 8ies, etc
and n.nspname not like 'pg\\_%' -- not catalogs
and n.nspname != 'information_schema' -- not information)schema
ORDER BY nspname, relname;
Letor)o2 #s3'em$s e 5$be($s
SELECT n.nspname as esquema, c.relname as tabela, a.attname as campo,
format_type(t.oid, null) as tipo_de_dado
FROM pg_namespace n, pg_class c,
pg_attribute a, pg_type t
WHERE n.oid = c.relnamespace
and c.relkind = 'r' -- no indices
and n.nspname not like 'pg\\_%' -- no catalogs
and n.nspname != 'information_schema' -- no information)schema
and a.attnum > 0 -- no s2stem att9s
and not a.attisdropped -- no dropped columns
and a.attrelid = c.oid
and a.atttypid = t.oid
ORDER BY nspname, relname, attname;
Letor)o2 es3'em$s1 t$be($s1 c$m%os1 ti%os de d$dos
SELECT n.nspname, o.oprname AS binary_op,
format_type(left_type.oid, null) AS left_opr,
format_type(right_type.oid, null) AS right_opr,
format_type(result.oid, null) AS return_type
FROM pg_namespace n, pg_operator o, pg_type left_type,
pg_type right_type, pg_type result
WHERE o.oprnamespace = n.oid
and o.oprkind = 'b' -- binar2
and o.oprleft = left_type.oid
and o.oprright = right_type.oid
and o.oprresult = result.oid
ORDER BY nspname, left_opr, right_opr;
Letor)o2 o%er$dores bi)rios
Baypassar os de sistema:
and n.nspname not like 'pg\\_%' -- no catalogs
SELECT n.nspname, p.proname, format_type(t.oid, null) as typname
FROM pg_namespace n, pg_aggregate a,
pg_proc p, pg_type t
WHERE p.pronamespace = n.oid
and a.aggfnoid = p.oid
and p.proargtypes[0] = t.oid
ORDER BY nspname, proname, typname;
104
Letor)o2 (ist$ tod$s $s 0')+;es $greg$d$s e os ti%os 3'e %odem ser $%(ic$dos
$do o b$)co de d$dos1 3'$( o se' diret-rio2
select datname, oid from pg_database;
$do $ t$be($1 3'$( o se' $r3'ivo2
select relname, relfilenode from pg_class;
#<em%(o 3'e retor)$ &)dice1 c$m%o1 ti%o1 com%rime)to1 )'((1 de0$'(t2
SELECT pg_attribute.attnum AS index,
attname AS field,
typname AS type,
atttypmod-4 as length,
NOT attnotnull AS "null",
adsrc AS default
FROM pg_attribute,
pg_class,
pg_type,
pg_attrdef
WHERE pg_class.oid=attrelid
AND pg_type.oid=atttypid
AND attnum >0
AND pg_class.oid=adrelid
AND adnum=attnum
AND atthasdef='t'
AND lower(relname)='datas'
UNON
SELECT pg_attribute.attnum AS index,
attname AS field,
typname AS type,
atttypmod-4 as length,
NOT attnotnull AS "null",
'' AS default
FROM pg_attribute,
pg_class,
pg_type
WHERE pg_class.oid=attrelid
AND pg_type.oid=atttypid
AND attnum>0
AND atthasdef='f'
AND lower(relname)='datas';
105
1K 4"o)ectivid$de
Vou mostrar a conectividade do PostgreSQL com o PHP, com o Java e com o Visual BASC.
Tambm mostrarei a conectividade atravs do ODBC com o Access.
"o)ect$)do com o P,P
Com o PHP existe uma conexo nativa. Veja um exemplo:
$conexao = pg_connect("host=127.0.0.1 dbname=testes user=postgres password=*******
port=5432");
if (!$conexao){
echo "Falha na conexo com o banco. Veja detalhes tcnicos: " .
pg_last_error($conexao);
}
"o)e<o com Y$v$
A conexo do PostgreSQL com Java utilizada por diversos clientes de gerenciamento ou
modelagem do PostgreSQL. Neste caso utiliza-se o driver JDBC do PostgreSQL. Vide pasta
\jdbc da instalao.
/$i<$r de $cordo com s'$ verso do PostgreSQL1 o driver Y/" %$r$ o PostgreSQL
d$3'i2
http://jdbc.postgresql.org/download.html#jdbcselection
Aqui para o PostgreSQL verso 8.1.3 baixei o arquivo 8.1-405 JDBC 3.
?/ >cess$)do PostgreSQL vi$ 8/"
O PGODBC deve ser instalado no micro cliente e encontra-se em:
http://www.postgresql.org/ftp/odbc/versions/msi
Criar uma conexo ODBC ao banco do PostgreSQL e no cdigo:
Global Conex As New ADODB.Connection
Global AccessConnect As String
Public Sub Conexao()
AccessConnect =
"driver={PostgreSQL};server=10.10.10.10;database=maubanco;uid=postgres;pwd=postgres;"
Conex.ConnectionString = AccessConnect
Conex.Open AtivConex.ActiveConnection = Conex
End Sub
#<em%(o /sico de Y$v$ >cess$)do PostgreSQL ?i$ Y/"
Crie no PostgreSQL um pequeno banco de dados chamado agenda com uma nica tabela
chamada amigos.
Esta tabela contendo os campos nome e email apenas. Cadastre um ou mais registros para
melhor visualizao dos resultados.
import java.sql.*;
public class SQLStatement {
public static void main(String args[]) {
//String url = "jdbc:postgresql://10.0.1.53:5432/agenda";
String url = "jdbc:postgresql://localhost:5432/agenda";
106
//String url = "jdbc:postgresql:agenda"; //Assim pega os defaults
Connection con;
String query = "select * from amigos;
Statement stmt;
try {
Class.forName("org.postgresql.Driver");
} catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try {
con = DriverManager.getConnection(url,"postgres", "postgres");
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
int rowCount = 1;
while (rs.next()) {
System.out.println("Registro " + rowCount + ": ");
for (int i = 1; i <= numberOfColumns; i++) {
System.out.print(" Campo " + i + ": ");
System.out.println(rs.getString(i));
}
System.out.println("");
rowCount++;
}
stmt.close();
con.close();
} catch(SQLException ex) {
System.err.print("SQLException: ");
System.err.println(ex.getMessage());
}
}
}
"o)e<o "om o ?is'$( />S!"
Podemos nos conectar a uma base de dados PostgreSQL usando o Visual Basic via ADO.
Para isto temos que usar um driver ODBC para a plataforma Windows.
Voce vai precisar ter o PostgreSQL instalado e o driver ODBC tambm.
nstala-se o psqlODBC e configura-se a conexo com o banco desejado.
f so then use something like
CurrentProject.Connection.Execute StrSql2
f not linked tables then use something like
Dim cnn as new ADODB.Connection
cnn.Open "DSN=my_dbs_dsn_name" 'or a full PostgreSQL connection string to save a trip
to the registry
cnn.Execute StrSql2
107
8'tro e<em%(o2
Criar um DSN ODBC "pgresearch" via ADO e use:
Dim gcnResearch As ADODB.Connection
Dim rsUd As ADODB.Recordset
' open the database
Set gcnResearch =3D New ADODB.Connection
With gcnResearch
.ConnectionString =3D "dsn=3Dpgresearch"
.Properties("User D") =3D txtUsername
.Properties("Password") =3D txtPassword
.Open
End With
>cess$)do com o ?is'$( "h.)et1 ver (i)G2
http://www.linhadecodigo.com.br/artigos.asp?id_ac=355
108
14 * Oerr$me)t$s
14.1 4 %s3(
A ferramenta bsica de administrao do PostgreSQL o psql, mas uma ferramenta de
administrao capaz de administrar praticamente tudo do PostgreSQL.
P$r$ $cess*(o e<ec'te2
su postgresql
psql U nomeuser nomebanco (tanto no Linux quanto em outros SOs).
.er$(2
psql -h host -P port -U user -W (perguntar pela senha)
>(g')s com$)dos do PostgreSQL d$ (i)7$ de com$)do do S82
Se num UNX faa login como usurio do PostgreSQL, se no Windows execute passando -U
nomeusuario.
8bte)do $C'd$ sobre 'm com$)do2
comando help
Se )'m =N!B e<istem t$mb:m $s m$)%$ges (%gi)$s do m$)'$()2
man comando
psql -l -> lista os bancos de dados
psql -U nomeusuario nomebanco -> conectar console psql no banco de dados
psql banco -E -> (debug) mostra internamente como cada consulta realizada
psql version -> mostra verso do PostgreSQL
8'tros com$)dos vi$ (i)7$ de com$)do2
pg_dump, pg_dumpall, pg_restote, createdb, dropdb, createrole, droprole
>(g')s "om$)dos do %s3(2
P$r$ $cess$r1 est$)do )'m =N!B2
su nomeuserpg
psql -U nomeuserpg nomebanco
#st$)do )o @i)doAs
psql -U nomeuserpg nomebanco
8 %s3( $ceit$ 3'ebr$ de (i)7$s )'m$ co)s'(t$.
O ponto e vrgula (ou <g) indica ordem de execuo.
8bserve $te)t$me)te o %rom%t e s'$s v$ri$+;es2
=# - este prompt indica um superusurio
=> - este indica um usurio comum
-# - indica comando no finalizado. Aguardando o ponto e vrgula
(# - aguardando o fecha parnteses )
'# - aguardando um fecha apstrofo '
8bs.2 #m c$so de erro tec($r "tr(i" %$r$ e)cerr$r. Lembr$)do 3'e isso )o @i)doAs
s$i do %s3(.
109
\q - sair
\c nomebanco nomeuser Conectar a outro banco
\i /path/script.sql -- importar script.sql
\timing -- iniciar/parar o cronmetro para atividades
\dT+ -- lista os tipos de dados do PG com detalhes
\cd -- mudar para outro diretrio
\d lista tabelas, ndices, sequncias ou views
\d nometabela mostra estrutura da tabela
\dt lista tabelas
\di lista indices
\ds lista sequncias
\dv lista views
\dS lista tabelas do sistema
\dn lista esquemas
\dp lista privilgios
\du lista usurios
\dg lista grupos
\l - lista todos os bancos do servidor, juntamente com seus donos e codificaes
\e - abre o editor vi com a ltima consulta
\o - inicia/termina a criao de arquivo. Ex.: \o arquivo.sql
\! comando_do_sistemaoperacional -- executa o arquivo do sistema operacional
\? - ajuda geral dos comandos do psql
\h * - exibe ajuda de todos os comandos
\h comandosql ajuda especfica sobre o comando SQL, ex.: \h alter table
\H ativa/desativa sada em HTML
\encoding exibe codificao atual
/o$ s'gesto2
\h CREATE DATABASE
\h CREATE ROLE
#<em%(o de s$&d$ de co)s'(t$ em ,5PL %e(o PostgreSQL2
.er$)do 'm re($t-rio em ,5PL diret$me)te $tr$v:s do PostgreSQL
\o relatorio.html
SELECT * FROM cep_tabela WHERE uf='CE';
Obs.: Lembre que o PostgreSQL case sensitive.
"om isso teremos 'm $r3'ivo ,5PL co)te)do todos os registros retor)$dos %e($
co)s'(t$ em 'm$ t$be($ ,5PL1 como )o e<em%(o $b$i<o2
<table border="1">
<tr>
<th align="center">cep</th>
<th align="center">tipo</th>
<th align="center">logradouro</th>
<th align="center">bairro</th>
<th align="center">municipio</th>
<th align="center">uf</th>
</tr>
<tr valign="top">
<td align="left">60420440</td>
<td align="left">Rua
110
<td align="left">Vasco da Gama
<td align="left">Montese
<td align="left">Fortaleza
<td align="left">CE</td>
</tr>
</table>
Console do psql
14.2 * %7%Pg>dmi)
Baixar de - http://phppgadmin.sourceforge.net/
- Copiar para o diretrio web
- Editar o arquivo conf/config.inc.php e alterar para dois servidores (um local e outro remoto):
...
// Display name for the server on the login screen
$conf['servers'][0]['desc'] = 'Local';
// Hostname or P address for server. Use '' for UNX domain socket.
// use 'localhost' for TCP/P connection on this computer
$conf['servers'][0]['host'] = '127.0.0.1';
...
// Example for a second server (PostgreSQL Remoto)
$conf['servers'][1]['desc'] = 'Remoto';
$conf['servers'][1]['host'] = '10.99.00.11';
$conf['servers'][1]['port'] = 5432;
$conf['servers'][1]['defaultdb'] = 'nomebancodefault';
...
// f extra login security is true, then logins via phpPgAdmin with no
// password or certain usernames (pgsql, postgres, root, administrator)
// will be denied. Only set this false once you have read the FAQ and
// understand how to change PostgreSQL's pg_hba.conf to enable
111
// passworded local connections.
$conf['extra_login_security'] = false;
Com isso teremos um login do phppgadmin assim:
14.K 4 Pg>dmi)
Pg>dmi)
Site para download, caso sua distribuio no traga ou no tenha como instalar (apt, synaptic
ou outro gerenciador de pacotes).
http://www.pgadmin.org/download/
uma ferramenta grfica desenvolvida pela equipe de desenvolvimento do PostgreSQL.
Muitos recursos. Traz um help sobre si e a documentao do PostgreSQL. Tecle F1 para
exibir.
Ao executar consultas na ferramenta SQL, tecle F7 para visualizar graficamente a consulta
na aba Explain.
112
14.4 * #PS PostgreSQL
O EMS um timo gerenciador de diversos tipos de bancos, inclusive do PostgreSQL.
Download http://www.sqlmanager.net/en/products/postgresql/manager (para Windows
existe uma verso free, a lite)
Aqui vou abordar as atividades principais e bsicas de uso do EMS:
- Abrir em banco
- Criar em novo banco
- Criar tabelas
- Criar campos
- Criar chave primria
- Criar chave estrangeira (relacionamento)
- mportar script .sql para um banco existente
- Exportar banco como script sql
- Executar consultas sql
Aps executar aparece algo como (verso 3.1.5.2 lite for Windows):
113
"L!>L =P N8?8 />N"8
- Em Getting Starting (acima e direita) clique no boto Create new database
- Ento digite o nome do novo banco:
- E clique no boto Next
- Ento entre com os dados do servidor (como abaixo):
- Na prxima tela mude algo somente se tiver certeza:
- Clique em Next
114
- Ento clique em Finish
- Ento clique em OK.
- Ento vemos o banco junto ao servidor (abaixo e direita)
Para abri-lo e criar tabelas basta um duplo clique nele.
115
"L!>L 5>/#L>S
- Execute um duplo clique no novo banco
- Observe a estrutura criada para o novo banco:
- Clique sobre Tables com o boto direito e New Table (ou tecle Ctrl+N)
- Acima digitamos o nome da tabela onde existe table1
- Ento clicamos na aba Fields.
116
- Mais um duplo clique, agora em Column Name, para que aparea o Wizard de Campos:
- Veja que o nome do campo "codigo. Que ele do tipo BGNT e tambm chave
primria.
- Veja agora como aparece nosso campo (com uma pequena chave direita):
sso mostra que este campo nossa chave primria.
117
- Clique em Compile e veja como fica:
- Vamos adicionar mais um campo (nome varchar(40)):
- Adicione os demais campos de forma semelhante.
- Veja que sempre depois de um OK vem um boto de Commit, com a sintaxe SQL do
comando que estamos executando no banco. sso um controle de transaes do EMS
atravs do recurso existente no PostgreSQL.
Add Cha'e )sran(eira Add Cha'e )sran(eira
Banco e Host
Tabela
Adicionar Campo
Add Chave
ndice
Campo
Add Chave Dados
DDL
118
>/L!L =P />N"8 #B!S5#N5#
Caso queiramos trabalhar em um banco que j exista no servidor, vamos apenas abri-lo:
- Aps abrir o EMS apenas executamos um duplo clique sobre o nome do banco.
- Caso o nome do banco no esteja aparecendo no EMS clicamos no primeiro boto da barra
de ferramentas (Register Database) e informamos os dados do servidor
- Clicamos em Next.
119
- E selecionamos o banco na lista Database Name:
- E clicamos em Finish
"8P8 "L!>L =P> ",>?# #S5L>N.#!L> (O8L#!.N N#])
- Aps criar a tabela e os campos, devemos criar a segunda tabela, que ir se relacionar com
a primeira atravs de um campo (chave estrangeira).
- Vamos supor duas tabelas: pedidos e pedido_itens, que iro se relacionar atravs do
campo cdigo em pedido e cod_pedido em pedido_itens, como abaixo:
pedido (codigo, descricao, data, preco_unitario)
pedido_itens (codigo, cod_pedido, quantidade)
- Para que um campo de uma tabela se relacione com outro, ele deve ser do mesmo tipo que
o outro.
- Abra a tabela pedido_itens
120
- Estando na aba Fields, clique em Foreign Key na coluna do meio com o boto direito e New
Foreign Key. Veja o dilogo abaixo:
- Acima e direita selecione o campo que ir se relacionar com a outra tabela (cod_pedido)
- Em Foreign Table selecione a tabela do relacionamento (pedidos)
121
- Ento abaixo e direita selecione o campo que vai se relacionar com este (codigo) e clique
na seta para a direita. Ento clique em OK. Veja que em OnDelete action e em On Update
Action existem diversas opes. Veja meu tutorial sobre o assunto em:
http://ribafs.clanshosting.com
- Ento clique em Commit.
Agora vejamos como fica o cdigo SQL da nossa tabela pedido_itens. Clique na aba DDL e
ver:
CREATE TABLE "public"."pedido_itens" (
"codigo" BGNT NOT NULL,
"cod_pedido" BGNT,
"quantidade" NTEGER,
CONSTRANT "pedido_itens_pkey" PRMARY KEY("codigo"),
CONSTRANT "pedido_itens_fk" FOREGN KEY ("cod_pedido")
REFERENCES "public"."pedidos"("codigo")
ON DELETE NO ACTON
ON UPDATE NO ACTON
NOT DEFERRABLE
) WTH ODS;
122
#BP8L5>N8 =P />N"8 "8P8 S"L!P5
Uma forma muito comum de se exportar um banco na forma de script, especialmente para
abrir num outro servidor do mesmo tipo:
- Clique no menu Tools Extract Metadata
- Selecione o banco que deseja exportar e clique em Next
- Na combo File name selecione o diretrio e nome de arquivo para onde deseja exportar e
clique em Salvar. Ento clique em Next.
- Escolha se quer exportar somente dados, somente estrutura ou ambos e clique em Next.
- Apenas clique em Finish e ao terminar em Close.
!PP8L5>N8 =P />N"8 # =P S"L!P5
Esta a operao inversa da anterior mas com algumas diferenas. Se formos importar tudo,
devemos ter aqui apenas um banco vazio.
- Abrir o banco no EMS
- Clicar em Tools SQL Script
- Ao centro clique em Open script e indique onde est o script a ser importado.
- Se tudo for importado a contendo clique no boto Refresh Tables direita do boto Create
para visualizar a importao.
#B#"=5>N8 "8NS=L5>S SQL N8 #PS
Uma boa utilidade para o gerenciador EMS a de teste de consultas SQL.
- Abra o banco, abra o executor de script, digite a consulta em SQL e execute para saber os
resultados.
- Sempre que tiver alguma dvida sobre uma consulta execute aqui para testar antes.
123
14.J * >66'rrH "($H (mode($gem)
Oerr$me)t$ de Pode($gem >66'rrH "($H2
http://www.azzurri.jp/en/software/clay/index.jsp
Visualizador de Objetos e gerador de Diagramas de Entidade Relacionamento (DER), alm
de fazer engenharia reversa nos bancos existentes.
=m -timo t'tori$( o)(i)e2
http://www.azzurri.jp/en/software/clay/quick_start_guide.jsp?print=on
Uma boa relao de ferramentas para o PostgreSQL pode ser encontrada no site do
PostgreSQL Brasil:
https://wiki.postgresql.org.br/wiki/Ferramentas
8'tr$ bo$ re($+o )o site $t$ Pode(i)g 5oo(s2
http://www.databaseanswers.com/modelling_tools.htm
14.6 4 b?is'$(i6er
tima ferramenta para visualizar bancos e montar o diagrama entidades-relacionamento.
http://www.dbvis.com/products/dbvis/download.html
14.7 4 8%e)o00ice2 /$se
Usando o OpenOffice para abrir, editar bancos de dados PostgreSQL, como tambm criar
consultas, formulrios e relatrios.
Uma das formas de conectar o OpenOffice ao PostgreSQL usando um driver JDBC do
PostgreSQL.
- Antes devemos ter instalado o OpenOffice com suporte a Java
- Baixe daqui:
7tt%2FFCdbc.%ostgres3(.orgFdoA)(o$d.7tm(hC$rs
Para o PostgreSQL 8.1 podemos pegar o JDBC3 -
http://jdbc.postgresql.org/download/postgresql-8.1-405.jdbc3.jar
- Abrir o OpenOffice, pode ser at o Writer Ferramentas Opes Java Class Path
Adicionar Arquivo (indicar o arquivo postgresql-8.0-313.jdbc2.jar baixado) e OK.
- Abrir o OOBase
- Conectar a um banco de dados existente
- Selecionar JDBC - Prximo
- URL da fonte de dados:
jdbc:postgresql://127.0.0.1:5432/bdteste
"($sse do driver Y/"2
org.postgresql.Driver
Nome do 's'rio * %ostgres
password required (marque, caso use senha)
"o)c('ir
Digitar um nome para o banco do OOBase
Pronto. Agora todas as tabelas do banco bdteste esto disponveis no banco criado no
OOBase.
Tambm podemos agora criar consulta com assistentes, criar formulrios e relatrios com
facilidade.
124
1J * >%9)dices
1J.1 4 P($)eC$me)to e ProCeto de /$)cos de $dos
Projeto de bancos de dados genrico e se aplica a qualquer SGBDR.
com um bom planejamento do banco de dados que se determina o quo eficaz foi o
processo de anlise.
!)trod'+o
O projeto do banco de dados e tambm os testes so muito importantes para a eficincia e
consistncia das informaes e do aplicativo. muito importante gastar algum tempo nesta
etapa, pois depois de algum tempo de implantado fica muito trabalhoso alterar estruturas de
bancos e aplicativos.
Projetos de banco de dados ineficazes geram consultas que retornam dados inesperados,
relatrios que retornam valores sem sentido, etc. Um banco de dados bem projetado fornece
um acesso conveniente s informaes desejadas e resultados mais rpidos e precisos.
Exemplo de software de administrao de SGBD para o PostgreSQL - PGAdmin
nformaes de bancos de dados relacionais so armazenadas em tabelas ou entidades no
Modelo Entidade Relacionamento (MER).
ic$s sobre "$m%os
No armazenar resultado de clculos ou dados derivados de outros
Armazenar todas as informaes (campos) separadamente. Cuidado com campos que
contm duas ou mais informaes.
Se(ecio)$)do o "$m%o %$r$ $ "7$ve Primri$
A chave primria o campo ou campos que identificam de forma exclusiva cada registro.
No permitido valores nulos na chave nem duplicados
Caso a tabela no tenha um campo que a identifique, pode-se usar um campo que numere
os registros seqencialmente
ic$ de esem%e)7o2 O tamanho da chave primria afeta o desempenho das operaes,
portanto usar o menor tamanho que possa acomodar os dados do campo.
#<em%(o
Tabela - Clientes
Campo - Nome (atributo)
Chave Primria (Primary-Key) - CPF
Todos os campos correspondentes a um nico CPF juntamente com seus valores formam um
Registro ou Linha (Row)
A correta determinao das tabelas, bem como dos campos algo primordial no sucesso do
projeto do banco de dados.
Chave Primria - obriga que todos os registros tero o campo correspondente chave
primria exclusivo (nicos - unique). Num cadastro de clientes, todos os clientes cadastrados
tero um campo CPF exclisivo. Caso se tente inserir dois clientes com o mesmo CPF o
banco no permitir e emitir uma mensagem de erro acusando tentativa de violao da
chave primria.
#<em%(os de "$m%os i)dic$dos %$r$ c7$ve %rimri$2
CPF
125
CNPJ
Matrcula de aluno
Matrcula de funcionrio
Uma chave primria pode ser formada por mais de um campo, quando um nico campo no
capaz de caracterizar a tabela.
Cada tabela somente pode conter uma nica chave primria.
Relacionamentos - Um banco de dados formado por vrias tabelas. dealmente essas
tabelas devem ser relacionadas entre si para facilitar a troca de informaes e garantir a
integridade. Para relacionar tabelas usamos chaves existentes nas mesmas.
5i%os de Le($cio)$me)tos
Um para um
Um para vrios
Vrios para vrios
Le($cio)$me)to =m %$r$ =m
Aquele onde os campos que fazem o relacionamento so chaves primrias. Cada registro de
uma tabela se relaciona com apenas um registro da outra tabela. Este relacionamento no
muito comum.
#<em%(o2 "orre)tist$/$)co * "o)C'ge
Relacionamento Um para Vrios ou Vrios para Um
Aquele onde uma tabela tem um campo chave primria que se relaciona com outra tabela
atravs de um campo chave estrangeira. o tipo de relacionamento mais utilizado.
#<em%(os2
Clientes - Pedidos
Produtos - tens
Categorias - tens
Fornecedores - Produtos
NotaFiscal - Produtos
Veja que cada um da esquerda se relaciona com vrios do da direita.
!m%ort$)te2
O nmero de campos do relacionamento no precisa ser o mesmo
O tipo de dados dos campos do relacionamento deve ser igual, assim como o tamanho dos
campos e formatos
j "7$ve %rimri$ * "7$ve estr$)geir$ ('m * vrios)
Le($cio)$me)to ?rios %$r$ ?rios
Este tipo de relacionamento no d para ser implementado no modelo relacional, portanto
sempre que nos deparamos com um deles devemos dividir em dois relacionamentos um para
vrios (criando uma terceira tabela, que armazenar o lado vrios dos relacionamentos).
#<em%(o2
Pedidos * Prod'tos
Cada pedido pode conter vrios produtos, assim como cada produto pode estar em vrios
126
pedidos. A sada criar uma tabela que contenha os itens do pedido.
Pedidos - Pedidos_tens - Produtos
Pedidos 1 - N Pedidos_tens N - 1 Produtos
!)tegrid$de Le0ere)ci$(
Ela garante a integridade dos dados nas tabelas relacionadas. Um bom exemplo quando o
banco impede que se cadastre um pedido para um cliente inexistente, ou impede que se
remova um cliente que tem pedidos em seu nome.
Tambm se pode criar o banco de forma que quando atualizamos o CPF de um cliente ele
seja atualizado em todos os seus pedidos.
Norm$(i6$+o de 5$be($s
Normalizar bancos tem o objetivo de tornar o banco mais eficiente.
Uma regra muito importante ao criar tabelas atentar para que cada tabela contenha
informaes sobre um nico assunto, de um nico tipo.
1$ Oorm$ Norm$(
Os campos no devem conter grupos de campos que se repetem nos registros.
#<em%(o2
Alunos: matricula, nome, data_nasc, serie, pai, mae
Se a escola tem vrios filhos de um mesmo casal haver repetio do nome dos pais. Esto
para atender primeira regra, criamos outra tabela com os nomes dos pais e a matrcula do
aluno.
2k Oorm$ Norm$(
Quando a chave primria composta por mais de um campo.
Devemos observar se todos os campos que no fazem parte da chave
dependem de todos os campos que fazem parte da chave.
Caso algum campo dependa somente de parte da chave, ento devemos colocar este campo
em outra tabela.
#<em%(o2
TabelaAlunos
"7$ve (m$tric'($1 codigoMc'rso)
$v$(i$c$o descric$oMc'rso
Neste caso o campo descricao_curso depende apenas do codigo_curso, ou seja, tendo o
cdigo do curso conseguimos sua descrio. Ento esta tabela no est na 2 Forma
Normal.
So('+o2
Dividir a tabela em duas (alunos e cursos):
TabelaAlunos
Chave (matricula, codigo_curso)
avaliacao
127
TabelaCursos
codigo_curso
descricao_curso
Kk Oorm$ Norm$(
Quando um campo no dependente diretamente da chave primria ou de parte dela, mas
de outro campo da tabela que no pertence chave primria. Quando isso ocorre esta tabela
no est na terceira forma normal e a soluo dividir a tabela.
Lembr$)do2 Engenharia Reversa (parte de um banco ou de um script sql e gera o modelo).
ProCeto
Fases do Projeto do Banco de Dados
Modelagem Conceitual
Projeto Lgico
8bserv$+o.2 Trataremos apenas de novos projetos.
Pode(o "o)ceit'$( * Define apenas quais os dados que aparecero no banco de dados,
sem se importar com a implementao do banco. Para essa fase o que mais se utiliza o
DER (Diagrama Entidade-Relacionamento).
Pode(o L-gico * Define quais as tabelas e os campos que formaro as tabelas, como
tambm os campos-chave, mas ainda no se preocupa com detalhes como o tipo de dados
dos campos, tamanho, etc.
#t$%$s )$ #str't'r$+o e ProCeto de 'm /$)co de $dos
Problemas a serem solucionados com o banco de dados
Determinar o objetivo do banco de dados
Determinar as tabelas necessrias (cada uma com um nico assunto exclusivo)
Determinar os campos de cada tabela
Criar um DER
Verificar a estimativa do crescimento do banco e preparar-se para isso
nvestigar como so armazenadas as informaes atualmente e recolher a maior
quantidade de informaes para o projeto
Adotar um modelo e justific-lo
(Os itens acima fazem parte do Modelo Conceitual, abaixo do Lgico)
Determinar a chave primria de cada tabela. Pode haver tabela sem chave primria.
Determinar os relacionamentos e seus tipos
8bs.2 Somente quando da implementao (modelo fsico) sero tratados os detalhes
internos de armazenamento. O modelo fsico a traduo do modelo lgico para a
linguagem do SGBDR a ser utilizado no sistema.
128
1J.2 4 !m%(eme)t$+o de /$)co de $dos com o PostgreSQL * Pode(o O&sico
So0tA$res 0ree de Pode($gem e .ere)ci$me)to do PostgreSQL
PGAdmin: (http://www.postgresql.org/ftp/pgadmin3/release/)
EMS: (http://www.sqlmanager.net/en/products/postgresql/manager/download)
DBDesigner: (http://fabforce.net/downloads.php)
DbVisualizer: http://www.dbvis.com/products/dbvis/
Em forma de Plug-ins para Eclipse
QuantumDB: (http://quantum.sourceforge.net/)
Azzurri/Clay: (http://www.azzurri.jp/en/software/clay/download.jsp)
SQLExplorer: (http://sourceforge.net/projects/eclipsesql)
Uma grande e boa relao de softwares de projeto, modelagem e gerenciamento para o
PostgreSQL, free e comercial pode ser encontrada em no site oficial so PostgreSQL Brasil:
https://wiki.postgresql.org.br/wiki/Ferramentas.
S'%orte l >ce)t'$+o )$ "ri$+o de /$)cos )o PostgreSQL
A codificao default do PG 7.X a SQL_ASC
A do PG 8.X a UNCODE
Ambas tem suporte a acentuao, mas geram problemas no backup/importao.
"odi0ic$+o
Para um suporte estvel acentuao em portugus do Brasil uma boa opo criar o
banco passando a codificao (Encoding) LATN1
ENCODNG = 'LATN1'
"ri$+o do /$)co
Criaremos o banco do projeto de testes com o PGAdmin, contendo esquemas, tabelas,
views, funes do tipo SQL e Pl/PgSQL, usurios, privilgios, consultas, etc. para ilustrar
nosso projeto e servir de base para os testes (em seguida).
Analisar o modelo sugerido e detalhar o banco, tipos de dados de cada campo, tamanho,
esquemas do banco, usurios e senhas, privilgios de cada um (cuidados com a segurana),
etc.
>tiv$r o S'%orte ls O')+;es P(FPgs3( (Stored Proced'res)
Aps ter criado o banco, podemos ativar o suporte a plpgsql.
Ativar suporte a Pl/PgSQL requer dois passos:
- instalar a biblioteca Pl/PgSQL, que do tipo contrib
- definir a linguagem (como sugerido abaixo)
- Ativando na console do PG depois de conectar ao banco onde ficar o suporte:
CREATE LANGUAGE 'plpgsql' HANDLER plpgsql_call_handler LANCOMPLER 'PL/pgSQL'
- Ativando como superusurio na console (fora dos bancos)
su - postgres
$ createlang plpgsql -U nomesuperuser nomebanco
Ou simplesmente:
$ createlang plpgsql nomebanco
Y/"
Alguns programas em Java o utilizam, como o plugin QuantumDB.
129
8 Y/" %$r$ o PostgreSQL e)co)tr$*se em2
http://jdbc.postgresql.org/download.html#jars
?eC$ 3'e %$r$ se(ecio)$r o $r3'ivo .C$r correto1 %recis$mos cr'6$r $ verso do
PostgreSQL esquerda com a verso do JDBC desejado.
#<em%(o2 Para uso como cliente em sua mquina pelo Quantum DB (no Eclipse) e com
PostgreSQL 8.1 baixar o arquivo: 8.1-405 JDBC 3
#s3'em$s
e0i)ir os es3'em$s do b$)co.
Quando o cliente precisa de muitas tabelas, organizadas em vrias reas a sada imediata
a criao de vrios bancos de dados. Mas quando da implementao do aplicativo que ir
utilizar estes bancos os desenvolvedores se depararo com a dificuldade de comunicao e
acesso entre os bancos, j que com uma nica conexo tero acesso a todos os objetos do
banco. muito til para estes casos criar um nico banco e neste criar vrios esquemas,
organizados por reas: pessoal, administracao, contabilidade, engenharia, etc.
Mas e quando uma destas reas tem outras sub-reas, como por exemplo a engenharia, que
tem reservatrios, obras, custos e cada um destes tem diversas tabelas. O esquema
engenharia ficar muito desorganizado. Em termos de organizao o ideal seria criar um
banco para cada rea, engenharia, contabilidade, administrao, etc. E para engenharia, por
exemplo, criar esquemas para cada subarea, custos, obras, etc. Mas no o ideal em termos
de comunicao e acesso entre todos os bancos.
"ri$r #s3'em$
Num gerenciador do PG entra-se no banco e nesse cria-se o esquema.
8'
CREATE SCHEMA nomeesquema;
>cess$)do 8bCetos de #s3'em$s
Para acessar um esquema devemos passar seu caminho:
nomeesquema.nometabela
Ou
nomebanco. nomeesquema.nometabela
"ri$)do 5$be($ em #s3'em$
CREATE TABLE nomeesquema.nometabela (
...
)
"ri$)do #s3'em$ e tor)$)do 'm =s'rio do)o
CREATE SCHEMA nomeesquema AUTHORZATON nomeusuario;
Lemove)do %rivi(:gios de $cesso $ 's'rio em es3'em$
REVOKE CREATE ON SCHEMA public FROM PUBLC
Com isso estamos tirando o privilgio de todos os usurios acessarem o esquema public.
130
>cesso $os #s3'em$s
Quando se cria um banco no PostgreSQL, por default, ele cria um esquema pblico (public)
no mesmo e neste esquema que so criados todos os objetos quando no especificamos o
esquema. A este esquema public todos os usurios do banco tm livre acesso, mas aos
demais existe a necessidade de se dar permisso para que os mesmos acessem.
5$be($s
O PostgreSQL permite adicionar privilgios por objeto do banco: tabela, esquema, banco,
etc. Em termos de segurana importante, em geral, que os privilgios sejam adicionados ao
usurio por tabela, cada tabela tendo um dono e cada dono tendo seus especficos
privilgios.
ic$ de esem%e)7o2 Na criao das tabelas alertar para a criao de ndices para os
campos envolvidos na clusula WHERE. sso tornar essas consultas mais rpidas.
?ieAs
Juntamente com as funes armazenadas (stored procedures) as views so boas
alternativas para tornar o cdigo mais simples e o aplicativo mais eficientes, j que parte do
processamento feito pelo cdigo agora j est pronto e debugado no banco, o que torna o
cdigo mais rpido e eficiente. O uso de views e de funes armazenadas em bancos
semelhante ao uso de funes e classes no cdigo.
ic$2 para uso de views, sintaxe de funes internas e uso de clusulas SQL no
PostgreSQL, tutoriais de EMS e vrios outros sobre PostgreSQL, alm de PHP, JavaScript,
etc, confira o site abaixo:
http://ribafs.byethost2.com ou
http://ribafs.tk
"ri$+o do /$)co 5'tori$( sobre P.>dmi) %$r$ cri$r o b$)co 0')cio)$rios.
Bem, de posse do script .sql acima, praticamente o que teremos de fazer criar um banco
vazio no PGAdmin.
>brir o P.>dmi)
Caso no tenha salvado a senha ele pedir sempre que iniciar
Ao abrir clique com o boto direito direita em Databases e em New Database.
- No dilogo New Database entre com o Name do banco (funcionarios), o Owner (postgres).
dealmente mudar o nome do superusuario default para um nome mais seguro, assim como a
senha (mnimo de 8 caracteres, misturando letras e algarismos e idealmente com smbolos).
5$mb:m $(tere #)codi)g (codi0ic$+o) %$r$ L>5!N1.
- Ento selecione o banco funcionarios e clique no boto SQL acima.
- Clique no boto open file para indicar o nosso script sql gerado anteriormente.
Clique na setinha verde (Execute query)
131
#ve)t'$is "orre+;es2
Caso receba mensagens de erro sobre tipo UNSGNED, verifique o script e remova todas as
ocorrncias de UNSGNED e execute novamente. Como o DBDesigner foi projetado para o
MySQL um outro erro que pode ocorrer com a string AUTO_NCREMENT, que tambm
deve ser removida e novamente devemos executar o script. Feitas estas correes o script
executa normalmente e cria o nosso banco funcionarios.
Ento verifique esquerda que o banco j contm as 3 tabelas de acordo com o script.
#)ge)7$ri$ Levers$
Um timo software para conexo ao PostgreSQL, engenharia reversa (gera diagramas ER
dos bancos existentes) e exporta os diagramas em forma de imagens: DbVisualizer.
1J.K * !)tegrid$de Le0ere)ci$( * Postgres3(
5r$d'+o (ivre do doc'me)t$+o R"/5 !)tegritH Le0ere)ti$(R2
7tt%2FFtec7docs.%ostgres3(.orgFco((egeF002Mre0ere)ti$(i)tegritHF.
!)tegrid$de Le0ere)ci$( (re($cio)$me)to) : o)de 'm$ i)0orm$+o em 'm$ t$be($ se
re0ere l i)0orm$+;es em o'tr$ t$be($ e o b$)co de d$dos re0or+$ $ i)tegrid$de.
Tabela1 ------------> Tabela2
Onde Utilizado?
Onde pelo menos em uma tabela precisa se referir para informaes em outra tabela e
ambas precisam ter seus dados sincronizados.
Exemplo: uma tabela com uma lista de clientes e outra tabela com uma lista dos pedidos
efetuados por eles.
Com integridade referencial devidamente implantada nestas tabelas, o banco ir garantir que
voc nunca ir cadastrar um pedido na tabela pedidos de um cliente que no exista na tabela
clientes.
O banco pode ser instrudo para automaticamente atualizar ou excluir entradas nas tabelas
quando necessrio.
Primary Key (Chave Primria) * o campo de uma tabela criado para que as outras tabelas
relacionadas se refiram a ela por este campo. mpede mais de um registro com valores
iguais. a combinao interna de UNQUE e NOT NULL.
Qualquer campo em outra tabela do banco pode se referir ao campo chave primria, desde
que tenham o mesmo tipo de dados e tamanho da chave primria.
#<em%(o2
clientes (codigo NTEGER, nome_cliente VARCHAR(60))
codigo nome_cliente
1 PostgreSQL inc.
2 RedHat inc.
pedidos (relaciona-se Clientes pelo campo cod_cliente)
cod_pedido cod_cliente descricao
132
Caso tentemos cadastrar um pedido com cod_cliente 2 ele ser aceito.
Mas caso tentemos cadastrar um pedido com cod_cliente 3 ele ser recusado pelo banco.
"ri$)do 'm$ "7$ve Primri$
Deve ser criada quando da criao da tabela, para garantir valores exclusivos no campo.
CREATE TABLE clientes(cod_cliente BGNT, nome_cliente VARCHAR(60)
PRMARY KEY (cod_cliente));
"ri$)do 'm$ "7$ve #str$)geir$ (Ooreig) NeHs)
o campo de uma tabela que se refere ao campo Primary Key de outra.
O campo pedidos.cod_cliente refere-se ao campo clientes.codigo, ento pedidos.cod_cliente
uma chave estrangeira, que o campo que liga esta tabela a uma outra.
CREATE TABLE pedidos(
cod_pedido BGNT,
cod_cliente BGNT REFERENCES clientes,
descricao VARCHAR(60)
);
8'tro e<em%(o2
FOREGN KEY (campoa, campob)
REFERENCES tabela1 (campoa, campob)
ON UPDATE CASCADE
ON DELETE CASCADE);
Cuidado com excluso em cascata. Somente utilize com certeza do que faz.
Dica: Caso desejemos fazer o relacionamento com um campo que no seja a chave primria,
devemos passar este campo entre parnteses aps o nome da tabela e o mesmo deve
obrigatoriamente ser UNQUE.
...
cod_cliente BGNT REFERENCES clientes(nomecampo),
...
Parmetros Opcionais: ON UPDATE parametro e ON DELETE parametro.
8N =P>5# %$r$me)tros2
! "C#$! (%&S#%$C#) * quando o campo chave primria est para ser atualizado a
atualizao abortada caso um registro em uma tabela referenciada tenha um valor mais
antigo. Este parmetro o default quando esta clusula no recebe nenhum parmetro.
#<em%(o2 ERRO Ao tentar usar "UPDATE clientes SET codigo = 5 WHERE codigo = 2. Ele
vai tentar atualizar o cdigo para 5 mas como em pedidos existem registros do cliente 2
haver o erro.
C"SC"D& (#m "$sc$t$) * Quando o campo da chave primria atualizado, registros na
tabela referenciada so atualizados.
#<em%(o2 Funciona: Ao tentar usar "UPDATE clientes SET codigo = 5 WHERE codigo = 2.
Ele vai tentar atualizar o cdigo para 5 e vai atualizar esta chave tambm na tabela pedidos.
S&# '(( (atri)uir '(() * Quando um registro na chave primria atualizado, todos os
campos dos registros referenciados a este so setados para NULL.
133
#<em%(o2 UPDATE clientes SET codigo = 9 WHERE codigo = 5;
Na clientes o codigo vai para 5 e em pedidos, todos os campos cod_cliente com valor 5
sero setados para NULL.
S&# D&*"'(# (assumir o De+ault) * Quando um registro na chave primria atualizado,
todos os campos nos registros relacionados so setados para seu valor DEFAULT.
#<em%(o2 se o valor default do codigo de clientes 999, ento
UPDATE clientes SET codigo = 10 WHERE codigo = 2. Aps esta consulta o campo cdigo
com valor 2 em clientes vai para 999 e tambm todos os campos cod_cliente em pedidos.
8N #L#5# %$r$metros2
! "C#$! (%&S#%$C#) * Q'$)do 'm campo de chave primria est para ser deletado, a
excluso ser abortada caso o valor de um registro na tabela referenciada seja mais velho.
Este parmetro o default quando esta clusula no recebe nenhum parmetro.
#<em%(o2 ERRO em DELETE FROM clientes WHERE codigo = 2. No funcionar caso o
cod_cliente em pedidos contenha um valor mais antigo que codigo em clientes.
C"SC"D& * Quando um registro com a chave primria excludo, todos os registros
relacionados com aquela chave so excludos.
S&# '(( * Q'$)do 'm registro com a chave primria excludo, os respectivos campos
na tabela relacionada so setados para NULL.
S&# D&*"'(# * Quando um registro com a chave primria excludo, os campos
respectivos da tabela relacionada so setados para seu valor DEFAULT.
#<c('i)do 5$be($s Le($cio)$d$s
Para excluir tabelas relacionadas, antes devemos excluir a tabela com chave estrangeira.
5'do isso est )$ doc'me)t$+o sobre "L#>5# 5>/L#2
7tt%2FFAAA.%ostgres3(.orgFdocsF8.0Fi)ter$ctiveFs3(*cre$tet$b(e.7tm(
>L5#L 5>/L#
7tt%2FFAAA.%ostgres3(.orgFdocsF8.0Fi)ter$ctiveFs3(*$(tert$b(e.7tm(
"7$ve Primri$ "om%ost$ (dois c$m%os)
CREATE TABLE tabela (
codigo NTEGER,
data DATE,
nome VARCHAR(40),
PRMARY KEY (codigo, data)
);
1J.4 * ic$s Prtic$s de 'so do SQL
>rm$6e)$r >r3'ivos /i)rios )o Pr-%rio /$)co
134
Utilize a contrib LO para esta finalidade.
Lembre que como uma contrib normalmente no vem ligada e temos que ligar
especificamente ao banco onde queremos utilizar.
Ligando, de dentro do banco usar o comando \i:
>cesse o diret-rio (o d$s co)tribs do PostgreSQL2
/usr/local/src/postgresql-8.1.3/contrib/lo
Ento execute o comando "make install".
Acesse o banco e:
\i /usr/local/src/postgresql-8.1.3/contrib/lo/lo.sql
P$r$ 's$r veC$ o L#>P#.(o )o diret-rio (o e t$mb:m $ doc'me)t$+o o0ici$( do
PostgreSQL2
Port'g'9s do /r$si( * "$%&t'(o 282
7tt%2FF%gdoc%tbr.so'rce0orge.)etF%g80F($rgeobCects.7tm(
!)g(9s * "$%&t'(o 2W2 7tt%2FFAAA.%ostgres3(.orgFdocsF8.1Fi)ter$ctiveF($rgeobCects.7tm(
Nomes de "$m%os com es%$+o o' $ce)to
Devem vir entre aspas duplas.
"ome)trios
Em SQL os comentrios mais utilizados so da seguinte forma:
SELECT * FROM tabela; - - Este um comentrio
- - Este outro comentrio
Tambm so aceitos os comentrios herdados do C:
/* Comentrio herdado do C e vlido em SQL */
ic$s Prtic$s de =so do SQL
Testar se campo de e-mail, ou seja, se contm um @:
SELECT POSTON('@' N 'ribafs@gmail.com') > 0
select 'ribafs@gmail.com' ~ '@'
select 'ribafs@gmail.com' like '%@%'
select 'ribafs@gmail.com' similar to '%@%.%';
Alguns da lista de PHP (phpfortaleza@yahoogrupos.com.br - groups.yahoo.com).
135
5emos 'm c$m%o (i)s'mo) com v$(ores T 11 21 K1 ... 87
Q'eremos $t'$(i6$r %$r$ 00011 00021 000K1 ... 0087
UPDATE equipamentos SET insumo = '000' || insumo WHERE LENGTH(insumo) = 1;
UPDATE equipamentos SET insumo = '00' || insumo WHERE LENGTH(insumo) = 2;
Outra sada mais elegante ainda:
UPDATE equipamentos SET insumo = REPEAT('0', 4-LENGTH(insumo)) || insumo;
!NS#L!N8 "8P S#L#"5
Tendo uma tabela com registros e outra para onde desejo incluir registros daquela
NSERT NTO equipamentos2 SELECT grupo, insumo, descricao, unidade from
equipamentos2;
insert into engenharia.precos (insumo_grupo,insumo) select grupo,insumo from engenharia;
"om ">S5
insert into engenharia.insumos (grupo,insumo,descricao,unidade) select
grupo,insumo,descricao, CAST(unidade AS int2) AS "unidade" from engenharia.apagar
insert into engenharia.insumos (grupo,insumo,descricao,unidade) select
grupo,insumo,descricao, cast(unidade AS NT2) AS unidade from engenharia.apagar
select trim(length(bairro)) from cep_tabela where cep='60420440'; -- Montese, Retorna 7
>tr$v:s do P,P
$conn = pg_connect("host=10.40.100.186 dbname=apoena user=_postgresql");
for($x=10;$x<=87;$x++){
$sql="update engenharia.precos set custo_produtivo = (select custo_produtivo from
engenharia.apagar where insumo='$x') where insumo='00' || '$x'";
$ret=pg_query($conn,$sql);
}
i0ere)+$ em i$s e)tre d'$s $t$s
SELECT DATE '2006-03-29' DATE '2006-01-12';
SELECT (CAST('10/02/2005' AS DATE) - CAST('10/01/2006'));
136
P8P=L>L />N"8 "8P P>SS> # 5#S5#S
Script el Perl
#!/usr/bin/perl
$count = 1;
$arquivosaida = "populate.sql";
@chars = ("A" .. "Z", "a" .. "z", 0 .. 9);
@numbers = (1 .. 9);
@single_chars = ("a" .. "e");
$totalrecords = 5000; # 5 milhoes
open(OUTPUT, "> $arquivosaida");
print OUTPUT "DROP TABLE index_teste;\n";
print OUTPUT "CREATE TABLE index_teste (";
print OUTPUT "codigo NT, nome VARCHAR(10), numero NT, letra CHAR(1)";
print OUTPUT ");\n";
print OUTPUT "COPY index_teste (codigo, nome, numero, letra) FROM stdin;\n";
while ($count <= $totalrecords){
$randstring = join("", @chars [map{rand @chars} ( 1 .. 8 ) ]);
$randnum = join("", @numbers [map{rand @numbers} ( 1 .. 8 ) ]);
$randletter = join("", @single_chars [map{rand @single_chars} (1)]);
print OUTPUT
#print OUTPUT "NSERT NTO index_teste
VALUES($count,'$randstring',$randnum,'$randletter');\n";
$count."\t".$randstring."\t".$randnum."\t".$randletter."\n";
$count++;
};
#print OUTPUT "\n";
#print OUTPUT "\nCREATE NDEX indexteste_codigo_index ON index_teste(codigo);\n";
#print OUTPUT "CREATE NDEX indexteste_numero_index ON index_teste(numero);\n";
#print OUTPUT "VACUUM ANALYZE index_teste;\n";
close OUTPUT;
?i$ P,P
$con=pg_connect("host=127.0.0.1 user=postgres password=postgres");
function datediff($data_final, $data_inicial){
global $con;
$str="SELECT DATE '$data_final' - DATE '$data_inicial'";
$recordset = pg_query($con, $str);
$diferena=pg_fetch_array($recordset);
return $diferena[0];
}
echo "Diferena: " . datediff("1969-01-08", "1968-10-16");
137
>C'st$)do o 0orm$to d$ $t$ do Sistem$
SHOW DATESTYLE;
SET DATESTYLE TO SO; YYYY-MM-DD HH:MM:SS
SET DATESTYLE TO PostgreSQL; Formato tradicional do PostgreSQL (
SET DATESTYLE TO US; MM/DD/YYYY
SET DATESTYLE TO NONEUROPEAN, GERMAN; DD.MM.YYYY
SET DATESTYLE TO EUROPEAN; DD/MM/YYYY
Obs.: De forma permanente ajustar o postgresql.conf.
Outros usos para SHOW:
SHOW server_version;
SHOW server_encoding; -- dioma para ordenao do texto (definido pelo initdb)
SHOW lc_collate; -- dioma para classificao de caracteres (definido pelo initdb)
SHOW all; -- Mostra todos os parmetros
5$mb:m %odemos set$r o d$testH(e 3'$)do $(ter$mos 'm b$)co2
ALTER DATABASE nomebanco SET DATESTYLE = SQL, DMY;
5$mb:m %ode ser $trib'&do C')t$me)te com o =s'rio2
ALTER ROLE nomeuser SET DATESTYLE TO SQL, DMY;
>C'st$)do 'm$ O$i<$ de Legistros com L!P!5 $)d 8OOS#5
SELECT isbn, title, publication FROM editions NATURAL JON books AS b (book_id)
ORDER BY publication DESC LMT 5;
SELECT isbn, title, publication FROM editions NATURAL JON books AS b (book_id)
ORDER BY publication DESC LMT 5 OFFSET 2;
5r$r J registros1 i)ici$)do do seg')do.
0sH)c * checa integridade dos dados gravados no banco, vindos dos logs. Vem ligado por
padro
.$rg$(o de S./s * leitura/gravao (/O) de discos.
Ligar/Desligar fsync no:
postgresql.conf, setar para
fsync=true Nunca deve ficar false
L#8L#N>L ">PP8S # 5>/#L>
Se voc estiver falando da ordem dos campos na tabela no existe razo para isso no
modelo relacional.
Voc sempre pode especificar os campos desejados, e na ordem desejada,
no SELECT.
Se necessrio voc pode criar uma view:
CREATE VEW nome_view AS SELECT id,cpf,nome FROM sua_tabela;
138
Se ainda no estiver satisfeito pois quer suas tabelas "bonitinhas" e organizadas:
1. CREATE TABLE novo_nome AS SELECT id,cpf,nome FROM sua_tabela;
2. DROP TABLE sua_tabela;
3. ALTER TABLE novo_nome RENAME TO sua_tabela;
Osvaldo (Na lista &os(re*+,-$rasil).
"$(c'($)do $ Pem-ri$ $ ser 's$d$ %e(o PostgreSQL
* Shared Buffers
Exemplo de 1GB RAM
A shared buffers ser 25% da RAM
256 * 1024 / 8 = 32768
logo shared_buffers = 32768
* Shared Memory
A Shared Memory ser igual a shared buffer + (de 10 a 20)%
Shared Memory = 256MB + 15%
256MB + 15% = 295 MB
295MB = 295 * 1024 * 1024 = 309329920
No Linux:
/etc/sysctl.conf
kernel.shmmax = 309329920
kernel.shmall = 309329920
kernel.shmmni = 1
Comando para alterar as variveis do kernel sem re-iniciar o Linux:
sysctl -w kernel.shmmax=309329920
sysctl -w kernel.shmall=309329920
sysctl -w kernel.shmmni=1
Dicas de instalao do PostgreSQL em GNU/Linux.
* Utilizar HD do tipo SATA
* Criar uma partio exclusiva para os dados. Ex: /database
* Utilizar nesta partio o sistema de arquivos XFS
* Deixar nesta partio apenas os flags: RW,NOATME
Do site: http://www.gescla.com.br/oficina_postgre.asp
"ri$+o de 5i%os de $dos
CREATE TYPE "img" (input = "int4in", output = "int4out", internallength = 4, externallength =
10, delimiter = ",", send = "int4out", receive = "int4in", passedbyvalue, alignment = int,
storage = plain);
=so2
create table imagens (codigo int8, descricao varchar(60), imagem img);
"o)str'tor de P$tri6
Matriz unidimensional - array[2,4,6+2]
SELECT array[2,4,6+2]; -- Retorna 2,4,8
Multidimensional - composta por duas ou mais matrizes unidimensionais:
Obs.: O ndice do valor da matriz construdo com ARRAY sempre comea com um.
139
Ao criar uma tabela podemos usar matriz em seus tipos de dados, ao invs de tipos
simples.
Exemplo:
CREATE TABLE testematriz (codigo NT [], nome char[30][30]);
array[array[2,4,6],array[1,3,5]] ou
array[[2,4,6],[1,3,5]]
Com subconsultas. Entre parnteses e no concletes.
select array(select oid from pg_proc where proname like 'bytea%');
Retorna:
1244,31,1948,1949,1950,1951,1952,1953,1954,2005,2006,2011,2412,2413,16823
#N"8N5L>L L#.!S5L8S =PL!">8S
SELECT DSTNCT cep FROM cep_tabela
WHERE cep N (SELECT cep FROM cep_tabela AS Tmp GROUP BY cep,tipo,logradouro,
bairro, municipio,uf HAVNG Count(*) >1 ) ORDER BY cep;
(Adaptao de consulta gerada pelo assistente Encontrar duplicadas do Access).
Ou:
select count(*) as quantos, cep from cep_tabela group by cep having count(*) > 1;
L#P8?#L =PL!">8S
Para tabelas criadas WTH ODS:
DELETE FROM cep_tabela2 WHERE oid NOT N
(SELECT min(oid) FROM cep_tabela2 GROUP BY cep, tipo, logradouro, bairro, municipio,
uf);
Do exemplo 8.10 do manual em portugus do Brasil.
Ou:
Criando uma segunda tabela que conter somente os registros exclusivos e ainda guarda
uma cpia da tabela original:
CREATE TABLE cep_tabela2 AS SELECT cep, tipo, logradouro, bairro, municipio, uf FROM
cep_tabela GROUP BY cep, tipo, logradouro, bairro, municipio, uf ORDER BY cep;
"$so )o im%orte 3'$( d$s d'%(ic$t$s ir %erm$)ecer2
CREATE TABLE tab_temp AS SELECT DSTNCT * FROM tabela;
DROP tabela;
ALTER TABLE tab_temp RENAME TO tabela;
(Dica de Osvaldo Rosario Kussama na lista de PostgreSQL Brasil)
140
e(imit$dores
A maioria dos tipos de dados tem seus valores delimitados por apstrofos ('), a exemplo de:
- caracteres
- data/hora
- monetrio
- boleanos
- binrios
- geomtricos
- arrays
A exceo para os demais tipos numricos: date '18/12/2005' numeric 12345.45
"$r$cteres #s%eci$is
Para poder escrever uma barra no valor de uma constante, usa-se duas barras:
SELECT '\\Barra';
Para escrever um apstrofo usa-se dois apstrofos:
SELECT 'Editora O''Reyle';
P PostgreSQL tambm permite o uso de caracteres de escape para escrever caracteres
especiais:
SELECT 'Editora O\'Reyle';
Concatenao de expresses no terminal:
SELECT 'Concate'
'nao';
Equivale a:
SELECT 'Concatenao';
Quando resolvendo expresses matemticas usar parnteses para tornar mais claras as
precedncias.
"o)verte)do %$r$ NImeros
SELECT TO_NUMBER('0' || '1,500.64',99999999.99);
Total de 8 dgitos com 2 decimais.
?$riveis )o %s3(
\pset null '(nulo)' -- traduzindo null por nulo
SELECT NULL;
\set variavel 14 -- Dando valor 14 varivel
SELECT :variavel;
"8P!>L 5>/#L> "8P L#.!S5L8S
CREATE TABLE tabeladestino AS SELECT * FROM tabelaorigem;
Teremos que recriar as constraints.
141
%7%Pg.!S
http://www.geolivre.org.br/modules/news/
Em mais um grande lanamento, a OpenGEO coloca disposio da comunidade uma
ferramenta extremamente ltil para gerncia de dados geogrficos no PostgreSQL. O
phpPgGS mais um produto da OpenGEO que contempla uma demanda na rea de
Geotecnologias e visa atender usurios do mundo inteiro.
Desenvolvido com base no phpPgAdmin, o phpPgGS utiliza o MapServer para visualizar o
contedo espacial dos campos do PostGS com muita simplicidade (um clique). Seqncias
de cdigos complexos (campo de geometria) agora podem ser vistos num mapa.
O OpenGEO tem atuado no mercado brasileiro de Geotecnologias com solues inovadoras
com base em software livre e j ganhou referncia internacional com alguns importantes
projetos como o Open 3D GS e o GeoLivre Linux.
Este sistema vai integrar a soluo de Hosting que a empresa dever lanar nas prximas
semanas.
>(g'm$s e0i)i+;es
"'rsor
um ponteiro para uma linha (registro).
Le%(ic$+o
a distribuio de dados corporativos para vrios locais ou filiais de uma empresa,
oferecendo confiabilidade, tolerncia a falhas, melhor desempenho e capacidade de
gerenciamento.
"ri%togr$0i$
Seu objetivo tornar os dados comuns em bits de aparncia completamente aleatria.
P>!US"=L>S # P!NUS"=L>S N8 P8L5.L#SQL
Ao digitar nomes de tabelas e campos em Maisculas eles sero convertidos
automaticamente para minsculas, a no ser que sejam digitados entre aspas duplas:
SELECT * FROM "CLENTES";
Recomendao: evitar o uso de maisculas e de acentos em nomes de bancos, tabelas e
campos.
P8S5.L#SQL N`8 "8N#"5>Q
Do site do Rodrigo (HJort)
- Pingar no P
- Verificar o pg_hba.conf - host, banco, usurio P e senha
- Caso aparea "s the server running on host.."
- Testar com telnet P porta (Ctrl+C para sair)
- No postgresql.conf - listen_addresses = 'P'
- Salvar e restartar o SGBD.
"o)t$dor de Les'(t$dos
142
ndicado para consultas e relatrios (no grava)
CREATE TEMP SEQUENCE seq;
SELECT nexval('seq'), * FROM esquema.tabela;
(Salvador S. Scardua na lista PostgreSQL Brasil)
L!P!5#S 8 P8S5.L#SQL
Tamanho de um Banco de Dados - ilimitado
Tamanho de uma tabela - 32 TB
Quantidade de registros por tabela - ilimitados
Quantidade de campos por tabela - 250 a 1600 (depende do tipo)
Quantidade de ndices por tabela - ilimitados
1J.J 4 ic$s sobre esem%e)7o e 8timi6$+;es do PostgreSQL
Existem duas principais formas de melhorar o desempenho de SGBDs: uma melhorando o
hardware, com CPUs, RAM, Discos mais novos, rpidos e confiveis. A outra otimizando as
consultas realizadas nos bancos (usando VACUUM, VACUUM ANALYZE, EXPLAN, criando
CLUSTERS, entre outros).
Uma das medidas bsicas adotada para melhorar o desempenho de tabelas com grandes
quantidades de registros e especialmente com muitos acessos, a incluso de ndices
estratgicos. Alm da chave primria importante inserir ndices em campos que compem a
clusula WHERE, que fazem parte de clusulas ORDER BY, GROUP BY entre outras. Em
consultas com WHERE de vrios campos usando OR, no adianta inserir ndice, pois no
ser utilizado pelo PostgreSQL, somente usando AND.
Na criao do banco de dados e especialmente na criao das consultas muito importante
atentar para um bom planejamento, normalizao, consultas otimizadas tendo em vista o
planejador de consultas do PostgreSQL atravs do uso dos comandos EXPLAN e ANALYZE.
A administrao do PostgreSQL tambm muito importante para tornar o SGBD mais
eficiente e rpido. Desde a instalao e configurao temos cuidados que ajudam a otimizar
o PostgreSQL.
"da,tao do "rtigo so)re otimi-ao do PostgreS.( do Diogo /ia-us e do original
do /ruce 0om1ian (htt,2334445ca5,ostgres6l5org3docs3mom1ian3h47,er+ormance)5
,$rdA$re
No computador as informaes so manipuladas pelos registradores da CPU, pelo cache da
CPU, pela memria RAM e pelos discos rgidos.
Na prtica as informaes utilizadas com mais freqncia so colocadas prximas CPU.
Quem determina que informaes devem ficar nos registradores so os compiladores.
Cache da CPU guarda ar informaes utilizadas recentemente.
O Sistema Operacional controla o que est armazenado na RAM e o que mandar para o
disco rgido.
143
Cache e Registradores da CPU no podem ser otimizados diretamente pelo administrador do
SGBD. Efetivamente otimizao em bancos de dados envolvem aumento da quantidade de
informaes teis na RAM, prevenindo acesso a disco sempre que possvel.
No tarefa simples de ser colocada em prtica, pois a memria RAM guarda muitas outras
informaes: programas em execuo, pilhas e dados de programas, memria cache
compartilhada do PostgreSQL, cache do buffer de disco do kernel e kernel.
Otimizao correta de bancos de dados procura manter a maior quantidade possvel de
informaes do banco na memria RAM ao mesmo tempo que no afeta as demais reas do
sistema operacional.
Existem dois tipos de configurao de memria no PostgreSQL, a compartilhada e a
individual. A compartilhada tem um tamanho fixo, ela alocada sempre que o PostgreSQL
inicializa e ento compartilhada por todos os clientes. J a memria individual tem um
tamanho varivel e alocada separadamente para cada conexo feita ao SGBD.
:em;ria 6ache 6ompartilhada do <ostgre/=0
O PostgreSQL no altera as informaes diretamente no disco. Ao invs disso ele solicita
que os dados sejam lidos da memria cache compartilhada do PostgreSQL. O cliente
PostgreSQL ento l e escreve os blocos e finalmente escreve no disco.
Clientes que precisam acessar tabelas primeiro procuram pelos blocos necessrios no
cache. Caso estejam a ento continuam processando normalmente. Caso contrrio feita
uma solicitao ao sistema operacional para carregar os blocos. Os blocos so carregados
do cache de buffer de disco do kernel ou diretamente do disco. Estas operaes podem ser
onerosas (lentas).
Na configurao default do PostgreSQL 8.1.3 ele aloca 1000 shared buffers. Cada buffer usa
8KB, o que soma 8MB. Aumentando o nmero de buffers far com que os clientes encontrem
as informaes que procuram em cache e evita requisies onerosas ao sistema
operacional. Mas cuidado, pois se aumentar muito a memria compartilhada (shared buffers)
pode acarretar uso da memria virtual (swap). As alteraes podem ser feitas atravs do
comando postmaster na linha de comando ou atravs da configurao do valor do
shared_buffers no postgresql.conf.
=ue <or-.o da +5: +eser8ar para o <ostgre/=0>
A maior poro til que no atrapalhe os outros programas.
Nos sistemas UNX as informaes saem da RAM (quando insuficiente) para o swap. Ruim
quando as informaes voltam do swap para a RAM, pois ento os programas so
suspensos at que as mesmas sejam carregadas.
?amanho da 6ache
maginemos que o PostgreSQL shared buffer cache seja suficiente para manipular uma
tabela inteira. Repetidas buscas seqenciais da tabela no devem necessitar de acesso ao
disco j que todos os dados j esto em cache. Agora vamos imaginar que o cache menor
que a tabela, ento neste caso as informaes iro para o disco (swap) e tero um
desempenho bem inferior.
?amanho 5dequado da /hared *uffer 6ache
144
dealmente a PostgreSQL shared buffer cache (:em;ria 6ache 6ompartilhada do
<ostgre/=0) deve ser:
Grande o suficiente para conseguir manipular as tabelas mais comumente acessadas.
Pequena o bastante para evitar atividades de swap pagein.
Exemplo:
Por exemplo queremos x MB para memria compartilhada
( x / 8 ) * 1024 = Resultado a ser configurado em shared_buffer
Se x = 768 MB
(768 / 8) * 1024
Resultado a ser configurado em shared_buffer = 98304
Para informaes sobre uma configurao do kernel para que vrios sistemas operacionais
trabalharem com o PostgreSQL:
http://developer.postgresql.org/docs/postgres/kernel-resources.html
:em;ria @ndi8idual (/ort :emor2)
Principalmente utilizada em ordenaes de registros das tabelas, em operaes de criao
de ndices, ordenao (order by), merge join, etc.
Esta memria pode ser configurada atravs do parmetro sort_mem do postgresql.conf.
Para a configurao leve em conta sua memria disponvel (incluindo a memria j alocada
para o shared buffers), tambm o nmero mdio de conexes e o uso da memria virtual
(swap).
Exemplo:
Considerando um servidor dedicado (rodando somente o servidor PostgreSQL), com
memria RAM de 1,5GB e com at 10 conexes simultneas com o SGBD:
shared_buffers = 80000 # 80.000 blocos de 8KB = 625 MB
sort_mem = 64000 # tamanho em KB = 62,5 MB, para cada usurio com
# 10 usurios = 526 MB
vacuum_mem = 2000
Por exemplo: queremos x KB para memria individual sort_men
( x * 1024 ) = resultado para memria individual
x = 16
(16 * 1024) = sort_mem = 16384
Seria bom mudar tambm memria para vaccum
vacuum_mem = 131072 (mesmo clculo do sort_mem)
145
Uso de Arios !iscos
Em sistemas com mais de um disco podemos melhorar a performance do mesmo
distribuindo algumas tarefas entre discos diferentes.
Supondo que temos dois HDs, hda e hdb:
0ovendo os logs de transao ,ara outro disco2
- Parar o PostgreSQL
- Montar hdb em /mnt/hdb
- Mover a pasta /usr/local/pgsql/data/pg_xlog para o /mnt/hdb
- Criar um link simblico para o diretrio original:
ln -s /mnt/hdb/pg_xlog /usr/local/pgsql/data/pg_xlog
- Banco - /usr/local/pgsql/data (no hda)
- Logs - /usr/local/pgsql/data/pg_xlog (link simblico para /mnt/hdb/pg_xlog).
Os logs de transao so os nicos registros que no podem ter o seu salvamento em disco
adiado sem comprometer a segurana do sistema.
:o8er os Bndices para um C! diferente de onde esto as tabelas:
- Parar PostgreSQL
- Mover os ndices para o hdb
- Criar link simblico para o local original
Para recriar os ndices em outro Tablespace:
ALTER TABLE nometabela DROP CONSTRANT nomeconstraint;
CREATE NDEX nome_idx ON nometabela (nomecampo) TABLESPACE nometablespace;
ALTER TABLE nometabela ADD CONSTRANT nome_pk PRMARY KEY (nomecampo);
ALTER NDEX nome_idx SET TABLESPACE nometablespace;
Ainda podemos separar astabelas mais utilizadas para o hdb, utilizando o comando
tablespace no PostgreSQL 8.1.3 podemos fazer isso:
- Criar diretrio /mnt/hdb/hotcluster e tornar postgres seu dono
CREATE TABLESPACE hotcluster OWNER postgres LOCATON '/mnt/hdb/hotcluster';
Criando um banco no novo cluster:
CREATE DATABASE hotbanco TABLESPACE = hotcluster;
Exportar as tabelas para este banco.
Uso de :ais de Um <rocessador
Atualmente o PostgreSQL est otimizado para uso de vrios processadores, reforando que
cada conexo gerenciada por um processo diferente.
/istemas de 5rqui8os
Para sistemas BSD usa-se o tradicional UFS, que robusto, rpido e tem a vantagem em
relao ao PostgreSQL, de possuir os blocos de disco com um tamanho padro de 8KB.
Para quem utiliza Linux as sugestes vo para EXT3 e ReiserFS.
146
6heckpoints
O wal_files o parmetro do postgresq.lconf que determina o nmero de arquivos usados
pelo PostgreSQL para armazenar os logs de transao. Estes arquivos focam em pg_xlog,
na pasta de dados.
Para que apaream as datas e horas nos arquivos de logs usa-se no postgresql.conf:
log_timestamp = true
Para reduzir a freqncia dos checkpoints devemos aumentar o parmetro do
postgresql.conf:
checkpoint_segments = 3 (valor default)
O PostgreSQL no precisa de muito ajuste. Boa parte dos parmetros automaticamente
ajustada para uma performance tima. O cache size e sort size so dois parmetros que o
administrador pode controlar para ter um melhor uso da memria.
5r$d'+o do 5'tori$( D5')i)g PostgreSQL 0or Per0orm$)ceE
De Shridhar Daithankar e John Berkus
/hared *uffers
Definem um bloco de memria que o PostgreSQL usar para lidar com requisies que esto
aguardando ateno no buffer do kernel e na CPU.
Deve ser manipulada com cuidado, pois simplesmente ampliada pode prejudicar a
performance. Esta a rea que o PostgreSQL usa atualmente para trabalhar. Ela deve ser
suficiente para controlar a carga do servidor do SGBD, do contrrio o PostgreSQL ir iniciar
empurrando dados para arquivos e isto ir prejudicar a performance geral. Esta a principal
configurao em termos de performance.
Seu valor deve ser configurado tendo em vista o tamanho do conjunto de bancos que se
supes que no mximo o servidor ir carregar e da memria RAM (ter em mente que a
memria RAM utilizada pelos demais aplicativos do servidor no estaro disponveis).
Recomendaes:
- niciar com 4MB (512) Workstation
- Mdio tamanho do conjunto de bancos de dados e 256 a 512MB disponvel de RAM:
16-32MB (2948 a 4096)
- Grande conjunto de bancos de dados e muita memria RAM disponvel (1 a 4GB):
64 -256MB (8192 a 32768)
Obs.: At para um conjunto de bancos de dados (dataset) que exceda 20GB, uma
configurao de 128MB deve ser muito, caso voc tenha apenas 1GB de RAM e um
agressivo sistema de cache em Sistema Linux.
/ort :emor2 (:em;ria para &rdena-.o)
Limite mximo de memria que uma conexo pode usar para executar sort (ordenao).
Caso suas consultas usem as clusulas ORDER BY ou GROUP BY que ordenem grandes
conjuntos de dados, incrementar este parmetro dever ajudar.
Uma Recomendao:
Ajustar o parmetro por conexo como e quando precisar: pouca para consultas mais
simples e muita para consultas complexas e para dumps de dados.
Dffecti8e 6ache /i4e (Tamanho do Cache Efetivo)
Permite ao PostgreSQL fazer melhor uso da RAM disponvel no servidor.
Exemplo:
Caso exista 1,5GB de RAM na mquina, shared buffers deve ser ajustado para 32MB e
147
effective cache size para 800MB.
Es2nc and the F50 files (Fsync e arquivos de WAL)
Caso no reste nenhuma opo, poder usar a proteo do WAL e melhor performance.
Simplesmente mova seus arquivos de WAL, montando outro dispositivo ou criando um link
simblico para o diretrio %gM<(og1 para um disco separado ou para o conjunto dos arquivos
do seu cluster principal de arquivos de dados.
random)page)cost (custo de pgina aleatria)
Configura o custo para trazer um registro aleatrio de um banco de dados, que influencia a
escolha do planejador em usar index ou table scan.
Caso tenha um disco razoavelmente rpido como SCS ou RAD, pode baixar o custo para 2.
Aacuum)mem
Configura a memria alocada para Vacuum. Deve acelerar permitindo que PostgreSQL copie
grandes quantidades para a memria.
Entre 16-32MB uma boa quantidade para muitos sistemas.
max)fsm)pages
PostgreSQL grava espao livre em cada uma de suas pginas de dados.
Caso tenha um banco que usa muitos updates e deletes, que ir gerar registros mortos,
devido ao sistema MVCC do PostgreSQL, ento expanda o FSM para cobrir todos estes
registros deads (mortos) e nunca mais precisar rodar vacuum full a no ser em feriados.
O mnimo FSM max)fsm)relations G %H.
max)fsm)relations
Diz quantas tabelas devem ser localizadas no mapa de espao livre.
al)buffers
Esta configurao decide a quantidade de buffers WAL (Write Ahead Log) que pode ter.
Para chegar a uma quantidade tima experimente e decida.
Um bom incio est em torno de 32 a 64 correspondendo a 256-516 KB de memria.
5ti8ar o subprocesso do auto Aacuum
Vem desabilitado por defualt (autovacuum = off no 8.1.3). Para ativar edite o arquivo de
configurao postgresq.conf e altere para autovacuum = on. r executar o vacuum quando
necessrio.
Melhor executar o comando vacuum juntamente com o comando analyze:
vacuumdb -U postgres -a, caso seja executado na linha de comando.
Para adquirir informaes sobre os ndices (tornando a performance ainda melhor):
vacuumdb -U postgres -a -z
148
#BPL>!N
#!/usr/bin/perl
$count = 1;
$arquivosaida = "populate.sql";
@chars = ("A" .. "Z", "a" .. "z", 0 .. 9);
@numbers = (1 .. 9);
@single_chars = ("a" .. "e");
$totalrecords = 5000; # 5 milhes
open(OUTPUT, "> $arquivosaida");
print OUTPUT "DROP TABLE index_teste;\n";
print OUTPUT "CREATE TABLE index_teste (";
print OUTPUT "codigo NT, nome VARCHAR(10), numero NT, letra CHAR(1)";
print OUTPUT ");\n";
print OUTPUT "COPY index_teste (codigo, nome, numero, letra) FROM stdin;\n";
while ($count <= $totalrecords){
$randstring = join("", @chars [map{rand @chars} ( 1 .. 8 ) ]);
$randnum = join("", @numbers [map{rand @numbers} ( 1 .. 8 ) ]);
$randletter = join("", @single_chars [map{rand @single_chars} (1)]);
print OUTPUT
#print OUTPUT "NSERT NTO index_teste
VALUES($count,'$randstring',$randnum,'$randletter');\n";
$count."\t".$randstring."\t".$randnum."\t".$randletter."\n";
$count++;
};
#print OUTPUT "\n";
#print OUTPUT "\nCREATE NDEX indexteste_codigo_index ON index_teste(codigo);\n";
#print OUTPUT "CREATE NDEX indexteste_numero_index ON index_teste(numero);\n";
#print OUTPUT "VACUUM ANALYZE index_teste;\n";
close OUTPUT;
=m bom $rtigo sobre %er0orm$)ce )o PostgreSQL DPostgreSQL 8.0 "7ecG(ist de
Per0orm$)ceE e)co)tr$*se )$ revist$ e(etrm)ic$ /Oree P$g$6i)e1 )Imero 02.
149
16 4 #<erc&cios
)xemplo &r.ico
Eamos criar um banco (clientesGe$), conten!o uma tabela (cliente) e um usurio (opera!or) que ter
apenas alguns privilCgios !e acesso H tabela cliente (IN7#/T, 7#6#<T, 09*5T#) e ser obriga!o a
utili.ar senha" EeIa que no ter privilCgio *#6#T#" #nto a!icionar alguns registros e e$ecutar
consultas !os quatro tipos3 IN7#/T, 7#6#<T, 09*5T# e *#6#T# (este apenas para veriicar se
realmente ele no tem este privilCgio)"
()
</#5T# *5T5J57# clientesGe$ KITL #N<=*IN8 Mlatin(MD
NN 9ara 78J*s que no esteIam com esta conigura1o, pelo menos este banco a usar
&ara )xi/ir a Codi0ica12o do lado do Cliene
7L=K <6I#NTG#N<=*IN8D
&ara 3olar 4 Codi0ica12o &adr2o
/#7#T <6I#NTG#N<=*IN8D
Alerando $anco para suporar !aas dd"mm"5555
56T#/ *5T5J57# clientesGe$ 7#T *5T#7TO6# P 7Q6, *BOD
NN No caso este banco apenas icar com esta conigura1o !e !ata
NN 9ara altera1o !einitiva para to!os os bancos alterar o script Rpostgresql"conR"
)xi/indo o !ae*5le Aual
7L=K *5T#7TO6#D
2)
</#5T# T5J6# cliente (
co!igo INT 9/IB5/O F#O,
nome E5/<L5/(4>) N=T N066,
!ataGnasc *5T# N=T N066,
bonus N0B#/I<((2,2),
observacao T#ST
)D
:)
</#5T# /=6# opera!or KITL 9577K=/* Mopera!orT(28M E56I* 0NTI6 M2'U>)U2>>VMD
= usurio somente ter os privilCgios atC a !ata !etermina!a"
/#E=F# 566 =N cliente 4/=B opera!orD
8/5NT 7#6#<T,09*5T#,IN7#/T =N cliente T= opera!orD
!ica6 <aso a tabela tenha campo tipo serial tambCm !evemos !ar acesso ao obIeto sequence gera!o3
8/5NT 7#6#<T,09*5T#,IN7#/T =N clienteGco!igoGseq T= opera!orD
NN <onsi!eran!o que o nome !a sequWncia seIa clienteGco!igoGseq"
&ara permiir ao usu.rio operador 7ue 0a1a lo(in8 use6
56T#/ /=6# opera!or KITL 6=8IND
150
=bs"3 EeIa como est aqui o pgGhba"con3
host all all (2V">">"(U:2 m!)
4)
Fa9er o lo(in como usu.rio operador para execuar as consulas a/aixo6
IN7#/T INT= cliente (co!igo, nome, !ataGnasc, bonus, observacao) E560#7 ((, MXoo 9e!roM,
M>(U>(U(T'VM, (8":), M5penas um te$to !e testeM)D
IN7#/T INT= cliente (co!igo, nome, !ataGnasc, bonus, observacao) E560#7 (2, M9e!ro 9aulo
/osa!oM, M>4U((U(TV:M, 2)":), MM)D
IN7#/T INT= cliente (co!igo, nome, !ataGnasc, bonus, observacao) E560#7 (:, MXosC /obertoM,
M2)U>'U(T:8M, (2"'), N066)D
:/ser'e 7ue para campos que no e$igem N=T N066, po!emos entrar apenas MM ou N066"
7#6#<T Y 4/=B clienteD
7#6#<T co!igo 4/=B clienteD
7#6#<T Y 4/=B cliente KL#/# co!igo P )D
7#6#<T Y 4/=B cliente KL#/# co!igo P ) 5N* nomePMXoo !e Jrito <unhaMD
09*5T# cliente 7#T nome P M/oberval TaylorM KL#/# co!igo P :D
09*5T# cliente 7#T nome P MXoo 5lmei!aM KL#/# nome P M9e!ro 9auloMD
NN #sta consulta no C eiciente, I que nomes po!em se repetir, melhor seria pela chave
:/ser'e ainda, que campos !o tipo numCrico no tWm !elimita!or, mas os !emais tem o !elimita!or
apZstroo, e$ceto palavrasNchaves e un12es como N066, T/0#, N=K(), etc"
*#6#T# 4/=B clienteD NN #sta apaga to!os os registros !a tabela
*#6#T# 4/=B cliente KL#/# co!igoP(D
*#6#T# 4/=B cliente KL#/# co!igoP2 5N* nome P M<hico BanoelMD
EeIa as mensaens quan!o o user opera!or tenta e$cluir algum registro3
clientesGe$P@ *#6#T# 4/=B cliente KL#/# co!igoP2 5N* nome P M<hico BanoelM
#//=/3 permission !enie! or relation cliente
=u seIa, alta privilCgio para e$cluir e as regras uncionaram"
0m pequeno teste !e cone$o cia 9L93
?[php
\conPpgGconnect(MhostP(2V">">"( userPopera!or pass-or!Popera!orT(28 !bnamePclientesGe$M)D
i (\con)]
echo R=FRD
^else]
echo RN=FRD
^
[@
151
#B#L""!8 # =P P#Q=#N8 "8N5L8L# # #S58Q=#
Utilizaremos somente minsculas para os nomes dos objetos (bancos, esquemas, tabelas,
campos, etc) e quando composto por duas ou mais palavras separar com sublinhado.
clientes
funcionarios
produtos
vendas
vendas_itens
bonus
comissoes
Por enquanto iremos criar apenas a tabela produtos, mais adiante criaremos as demais
tabelas.
Obs.: A tabela de produtos ir guardar tambm uma informao sobre a posio do produto
no local onde estocado.
Esta posio conter abscissa (x) e ordenada (y), ou seja a distncia horizontal da esquerda
e a distncia vertical de baixo para cima. Exemplo simplificado da disposio dos produtos:
ProdA
-----------------x,y----------------x+10,y --------------x+20,y
x | |
|
| |
|
|Y |Y
|Y
| |
|
| |
|

onde x=10cm e y=5cm
Existem tipos de dados geomtricos no PostgreSQL, para pontos, linhas, polgonos, crculos,
etc.
remos utilizar o ponto (point).
Vamos criar uma verso resumida da tabela Produtos:
CREATE TABLE produtos (codigo int, nome char(40), preco numeric(12,2));
Para excluir uma tabela:
DROP TABLE nometabela;
152
1 - nstalar o PostgreSQL (de acordo com seu sistema operacional) e realizar as
configuraes bsicas nos arquivos pg_hba.conf e no postgresql.conf. Mude o estilo da data
para um compatvel com o brasileiro, mude os locales para pt_BR, mude a codificao para
LATN1 e permita conexo TCP/P para uma mquina de P 10.1.1.1.
Configure tambm a autenticao desta mquina para md5;
2 - Criar um banco com nome controle_estoque;
3 Criar um esquema esq_estoque;
4 Criar um grupo de usurios grupo_estoque;
5 Criar dentro do esquema esq_estoque, tabelas, de acordo com as estruturas abaixo com
os devidos atributos (campos), tipos de dados, tamanhos e constraints:
clientes (cpf, nome, endereco, cidade, uf, cep, telefone, data_cadastro, data_nascimento);
funcionarios (cpf, nome, endereco, cidade, uf, cep, telefone, data_admissao,
data_nascimento);
produtos (codigo_produto, nome, unidade, quantidade, preco_unitario, estoque_minimo,
estoque_maximo); -- nome deve ser UNQUE
vendas (codigo_venda, data_venda, cpf_cliente, cpf_funcionario);
vendas_itens (codigo_item, codigo_venda, codigo_produto, quantidade_item);
bonus (codigo_bonus, cpf_cliente, codigo_venda, bonus);
comissoes (codigo_comissao, cpf_funcionario, codigo_venda, comissao);
6 Criar as chaves estrangeiras que faam os devidos relacionamentos entre as tabelas;
7 Remover somente a chave primria da tabela clientes e Adicionar novamente com nome
clientes_pk;
8 Adicionar a constraint NOT NULL no campo preco_unitrio de produtos;
9 Adicionar uma constraint CHECK que exija valores maiores que zero no estoque_minimo
do produtos;
10 Alterar o nome do campo nome da tabela produtos para descricao e o nome da tabela
clientes para clientes2. Renomeie novamente para clientes;
11 Alterar o tipo de dados do campo quantidade de produtos para NUMERC(12,2);
12 Criar trs usurios user_cli, user_prod e user_adm, todos no grupo grupo_teste, com os
seguintes privilgios:
- user_cli tem permisso de executar as consultas SELECT, UPDATE E NSERT na tabela
clientes;
- user_pro tem permisso de executar a consulta SELECT na tabela produtos;
- user adm pode fazer o que bem entender em todos os bancos do servidor.
153
13 Criar uma view que guarde a soma dos bonus por cliente. Receber um cliente e
retornar sua soma;
14 Criar uma view que guarde a soma das comisses por funcionrio. Receber um
funcionrio e retornar sua soma;
15 Criar uma transao com o bloco:
- Venda e Atualizao do estoque,
- Atualizao do bnus do cliente,
- Atualizao da comisso do vendedor
16 Cadastrar pelo menos trs registros em cada tabela;
17 Gerar um dump do banco e editar o script para ver seu contedo;
18 Consultar qual o produto mais caro e o mais barato;
19 Qual o cliente mais antigo;
20 Atualize o preo de um produto, adicionando R$ 3.85 ao mesmo;
21 Consulte qual o cliente que no tem bonus e o remova da tabela;
22 Crie um banco chamado cep_brasil, com uma nica tabela cep_tabela cuja estrutura
deve ser:
create table cep_full (cep char(8), tipo char(72), logradouro char(70),bairro char(72),
municipio char(60), uf char(2));
mporte o arquivo cep_brasil_unique.csv existente no CD ou no site:
http://ribafs.byethost2.com seo downloads PostgreSQL.
- Ento execute \timing,
- Faa uma consulta que retorne apenas o seu CEP
- E anote o tempo gasto.
23 Agora adicione uma chave primria na tabela. Ento faa a mesma consulta anterior e
veja a diferena de desempenho por conta do ndice adicionado;
22 Execute o PgAdmin, conecte ao banco controle_estoque para verificar o banco criado,
esquemas, grupo de usurios e usurios, esquema, tabelas, fazer algumas consultas,
visualizar os dados, a estrutura das tabelas e outras atividades;
23 Faa o mesmo com o EMS PostgreSQL Manazer;
24 Conecte ao banco com o DbVisualizer para verificar suas tabelas, esquema e veja o
DER (Diagrama Entidade-Relacionamento) e salve como imagem uma cpia do DER.
25 Criar uma tabela "site contendo um campo com ip do visitante, do tipo inet.
26 Criar uma tabela "geometria, contendo campos do tipo ponto, polgono e crculo.
154
17 * Le0er9)ci$s
Site 80ici$(
Site oficial http://www.postgresql.org
Site da comunidade brasileira http://www.postgresql.org.br
oc'me)t$+o 80ici$(
Online - http://www.postgresql.org/docs/8.1/interactive/index.html (Com busca)
PDF - http://www.postgresql.org/files/documentation/pdf/8.1/postgresql-8.1-A4.pdf
Brasil - Online - http://pgdocptbr.sourceforge.net/pg80/index.html
Brasil - PDF - http://ufpr.dl.sourceforge.net/sourceforge/pgdocptbr/pgdocptbr800-pdf-1.1.zip
Brasil - PDF Tutorial -
http://www.pythonbrasil.com.br/moin.cgi/NabucodonosorCoutinho?action=AttachFile&do=get
&target=tutorial_pg.pdf.tar.gz
PostgreSQL Technical Documentation - http://techdocs.postgresql.org/
Livros (#*booGs grtis)
- Practical PostgreSQL (ingls)
http://www.faqs.org/docs/ppbook/book1.htm
- PostgreSQL: ntroduction and Concepts (ingls)
http://www.postgresql.org/files/documentation/books/aw_pgsql/index.html
- PostgreSQL: Das offizielle Handbuch (alemo)
http://www.postgresql.org/docs/books/pghandbuch.html.de
- Lista de Livros sobre o PostgreSQL
http://www.postgresql.org/docs/books/
List$s
List$ 80ici$( do PostgreSQL1 com divers$s c$tegori$s
- Lista de News (freqncia semanal)
http://www.postgresql.org/community/weeklynews/
Cadastro - http://www.postgresql.org/community/lists/subscribe
- Cadastro e Descadastro em Uma das Vrias Listas
http://www.postgresql.org/community/lists/subscribe
Busca nos Arquivos das Listas do PostgreSQL
http://archives.postgresql.org/index.php?adv=1
- Lista da Comunidade Brasileira
http://pgfoundry.org/mailman/listinfo/brasil-usuarios/
Lista de Discusso no Yahoo
http://br.groups.yahoo.com/group/postgresql-br/
Para se cadastrar acesse o site acima e faa o cadastro.
PostgreSQL Users Groups Site
http://pugs.postgresql.org/
155
!L"
http://www.postgresql.org/community/irc
Existe um canal brasileiro
Sites do PostgreSQL em vrios pases
http://www.postgresql.org/community/international
#m%res$s 3'e 'ti(i6$m PostgreSQL
http://www.postgresql.org/about/casestudies/
Oe$t'red =sers (=s'rios "$r$cteri6$dos)
#sto $3'i $(g'm$s d$s ce)te)$s d$s com%$)7i$s 3'e co)str'&r$m %rod'tos1
so('+;es1 Aeb sites e 0err$me)t$s 's$)do o PostgreSQL
http://www.postgresql.org/about/users
.r$)des ProCetos do PostgreSQL
http://www.postgresql.org/community/resources
Projetos no PgFoundry
ftp://ftp2.br.postgresql.org/postgresql/projects/pgFoundry/
Projetos Gborg
ftp://ftp2.br.postgresql.org/postgresql/projects/gborg/
Anlise de Diversas Ferramentas para PostgreSQL
https://wiki.postgresql.org.br/wiki/Ferramentas
Diversos Logos do PostgreSQL para divulgao em Sites
http://www.postgresql.org/community/propaganda
Comunicar e Existncia de Bugs
http://www.postgresql.org/support/submitbug
Com formulrio online de envio de relato de bugs.
ivers$s Oerr$me)t$s %$r$ o PostgreSQL
Conversor de Script DDL para PostgreSQL
http://www.icewall.org/~hjort/conv2pg/
http://www.freedownloadscenter.com/Best/erd-postgresql.html
http://www.databaseanswers.com/modelling_tools.htm
http://top.softlandmark.com/Erd_postgresql.html
http://directory.fsf.org/autodia.html
http://www.datanamic.com/download/scripteditor.zip
http://tedia2sql.tigris.org/
http://tedia2sql.tigris.org/usingtedia2sql.html
http://www.fileboost.net/directory/development/databases_networks/cutesql/004405/review.html
http://www.fileboost.net/directory/development/databases_networks/case_studio_2_lite/013963/1/download.html
http://files.db3nf.com/download/DB3NF_Setup_1_4.exe
http://gborg.postgresql.org/project/pgxexplorer/download/download.php
http://gborg.postgresql.org/browse.php
http://gborg.postgresql.org/browse.php?83
Levist$s
Revista Sobre Bancos de Dados Free (Portugus)
156
http://www.dbfreemagazine.com.br/index.php
Cadastre-se e faa o download. J existem oito edies.
SQL Magazine (comercial)
http://www.sqlmagazine.com.br/revista.asp
"'rsos
- Curso de PostgreSQL da dbExpert (So Paulo) www.dbexpert.com.br
- Curso de PostgreSQL do Evoluo (Fortaleza-CE) www.evolucao.com.br
Pode($gem e Norm$(i6$+o
- O Modelo Relacional de Dados (em cinco artigos, de Jlio Battisti )
http://www.imasters.com.br/artigo.php?cn=2419&cc=149
- Conceitos Fundamentais de Banco de Dados (de Ricardo Rezende)
http://www.sqlmagazine.com.br/Colunistas/RicardoRezende/02_ConceitosBD.asp
8'tros2
- PostgreSQL no iMasters http://www.imasters.com.br /secao.php?cs=35
- Lozano http://www.lozano.eti.br
- Conversor de Script DDL para PostgreSQL - http://www.icewall.org/~hjort/conv2pg/
- Meu PostgreSQL no Conecta! - http://www.icewall.org/~hjort/pgsql/naoconecta.htm
- Juno entre Tabelas no Postgresql hp6"";;;<imasers<com</r"ari(o"2867
- Customize database queries using views in PostgreSQL - http://builder.com.com/5100-
6388_14-6032031.html
- PostgreSQL nteragindo com Banco de dados - http://www.imasters.com.br/artigo/954
O Tipo de Dados Serial hp6"";;;<imasers<com</r"ari(o"1804
RunAs - Utilitrio para rodar o PG no XP: http://www.softtreetech.com/24x7/archive/53.htm
PostgreSQL com LDAP - http://itc.musc.edu/wiki/PostgreSQL
FAQs - http://www.postgresql.org/docs/faqs.FAQ.html
FAQs - http://wiki.ael.be/index.php/PostgresQL101
Getting Started - http://postgresql.boeldt.net/getting_started.asp
Down and nstall - http://postgresql.boeldt.net/setup_postgresql.asp
Microsoft SQL to PostgreSQL - http://postgresql.boeldt.net/mssql_to_postgresql.asp
PG Configuration - http://postgresql.boeldt.net/postgres-linux-configuration.asp
Muitos links - http://sql-info.de/postgresql/links.html
General Bits - http://www.varlena.com/GeneralBits/
Notes - http://www.archonet.com/pgdocs/pgnotes.html
Presentations - http://candle.pha.pa.us/main/writings/computer.html
EnterpriseDB - http://www.osdb.org/
SQL-ish projects - http://docman.sourceforge.net/home_html/sql.html
Quick Reference Material - http://techdocs.postgresql.org/#quickref
Driver ODBC - http://www.postgresql.org/ftp/odbc/versions/msi/
Replication Project -
http://gborg.postgresql.org/project/pgreplication/download/download.php
157
8timi6$+o
http://www.powerpostgresql.com/PerfList
http://www.powerpostgresql.com/Downloads/annotated_conf_80.html
http://www.varlena.com/GeneralBits/Tidbits/perf.html
https://wiki.postgresql.org.br/wiki/Otimiza%C3%A7%C3%A3o
http://www.revsys.com/writings/postgresql-performance.html
http://www.linuxjournal.com/article/4791
http://www.budget-ha.com/postgres/
http://archives.postgresql.org/pgsql-performance/

You might also like