Você está na página 1de 193

1

PostgreSQLPrtico
(verso8.1.4)

RibamarFSribafs@users.sourceforge.nethttp://ribafs.tk
17desetembrode2006

Revisadoem03/10/2006

NDICE
Captulo
1Introduo

Pgina
.

2Instalao
.
.
.
.
.
.
.
.
.
2.1NoLinux
2.2NoWindows
3DDL(DataDefinitionLanguage)
.
.
.
.
.
.
.
3.1Criaoeexclusodebancos,esquemas,tabelas,views,Constraints,etc
3.2Alteraesnosobjetosdosbancos
3.3ndices,TiposdeDadoseIntegridadeReferencial
4DML(DataManipulationLanguage) .
.
.
.
.
.
.
4.1Consultas(select,insert,updateedelete)
4.2ConsultasJOIN
4.3SubConsultas
5FunesInternas
.
.
.
.
.
.
.
.
5.1Strings
5.2Matemticas
5.3Agrupamento(Agregao)
5.4Data/Hora
5.5FormataodeTiposdeDados
5.6ConversodeTipos(CAST)
6FunesDefinidaspeloUsurioeTriggers .
.
.
.
.
.
6.1SQL
6.2PlpgSQL
6.3Triggers
7DCL(DataControlLanguage)Administrao
.
.
.
.
.
7.1Administraodeusurios,gruposeprivilgios
8Transaes
.
.
.
.
.
.
.
.
.
.

9Administrao .
.
.
.
9.1BackupeRestore
9.2ImportareExportar
9.3Converter
9.4OtimizaoeDesempenho
10Replicao
.
.
.
.

13

33

44

54

67
71

74

83

11Configuraes .
.
.
.
.
.
10.1Configuraracessos(pg_hba.conf)
10.2Configuraesdiversas(postgresql.conf)
12Metadados(Catlogo)
.
.
.
.

85

92

13Conectividade .
.
.
.
.
13.1ComJava(JDBC)
13.2ComaplicativosWindows(ODBC)

.105

13.3ComPHP
13.4ExemplosdeconexocomPHP,JavaeVB

14Ferramentas .
.
.
.
.
.
.
.
14.1psql
14.2phpPgAdmin
14.3PgAdmin
14.4EMSPostgreSQL
14.5AzzurryClay(modelagemcomoEclipse)
14.6dbVisualizer
14.7OpenOfficeBase
15Apndices
.
.
.
.
.
.
.
.
15.1PlanejamentoeProjetodeBancosdeDados
15.2ImplementaodeBancodeDadoscomoPostgreSQL
15.3IntegridadeReferencialPostgreSQL
15.4DicasPrticasdeusodoSQL
15.5DicassobreDesempenhoeOtimizaesdoPostgreSQL
16Exerccios
.
.
.
.
.
.
.
.

5
108

124

149

17Referncias

154

1Introduo

HistriadosSGDBs
Anos60utilizadossistemasgerenciadoresdearquivos(ISAMeVSAM),usadosathoje.
Anos70GerenciadoresdeBancosdedadosderede.Desapareceramnosanos90.
Anos80SGBDRs(Oracle,DB2,SQLServer)
Anos90SGBDOR(Oracle,DB2,PostgreSQLeInformix)
Anos90SGBDOO(Cach)
SGBD=Compostoporprogramasdegerenciamento,armazenamentoeacessoaosdados,
comafinalidadedetornargileeficienteamanipulaodosdados.
Dicionriodedadosmetadados,dadossobreosdados,ouseja,informaessobrea
estruturadosbancosdedados(nomesdetabelas,decampos,tiposdedados,etc).
DBADatabaseAdministrator,comasfunesde:
Definiremodificaresquemas,estruturasdearmazenamentoemtodosdeacesso
Liberarprivilgiosdeacesso
Especificaoderestriodeintegridade
Simplificandotemos(noPostgreSQL),emtermosdeestrutura:
OSGBDformadoporbancosdedados,tablespaces,usuriosealgunsprogramas
auxiliares;
Umbancodedadosformadopelosesquemaselinguagens;
Umesquemaformadoporfunesdeagrupamento,funesdousurio,triggers,
procedures,sequncias,tabelaseviews;
Tabelassoformadasporcampos,constraints,ndicesetriggers.
Emtermosdedadosumatabelaformadaporregistrosecampos.
SegundoaWikipedia(http://pt.wikipedia.org):
...
Aapresentaodosdadospodesersemelhantedeumaplanilhaeletrnica,pormos
sistemasdegestodebancodedadospossuemcaractersticasespeciaisparao
armazenamento,classificaoerecuperaodosdados.
Osbancosdedadossoutilizadosemmuitasaplicaes,abrangendopraticamentetodoo
campodosprogramasdecomputador.Osbancosdedadossoomtodode
armazenamentopreferencialparaaplicaesmultiusurio,nasquaisnecessriohaver
coordenaoentrevriosusurios.Entretanto,soconvenientestambmparaindivduos,e
muitosprogramasdecorreioeletrnicoeorganizadorespessoaisbaseiamseemtecnologias
padronizadasdebancosdedados.
EmMaro,2004,AMRResearch(comocitadoemumartigodaCNETNews.comlistadona
secode"Referncias")previuqueaplicaesdebancodedadosdecdigoabertoseriam
amplamenteaceitasem2006.
Esquemassosubdivisesdebancosdedados,cujafunopermitirummelhornvelde

organizao.

Projetosdemesmacategoria,queprecisemacessarunsaosoutrosdevemficaremum
mesmobanco,podendoficaremesquemasseparados.
Tabelassosubdivisesdeumesquema,nelasrealmenteficamarmazenadososdados
deumbanco.Umatabelaparecerealmentecomumatabelaempapel,tipoplanilha,com
linhasecolunas.Cadalinharepresentaumregistrodebancodedadosecadacruzamento
decolunacomlinharepresentaumcampodetabela.
TipodeDadosdeumcamporestringeoconjuntodevalores(domnio)quepodeseratribudo
aocampoeatribuisemnticaaosdadosarmazenados.Umcampodotiponumricono
aceitadadosdotipotextoousimilar.
CitaodaIntroduododocumentosobreotimizaodoPostgreSQL
POSTGRESQLumSGBDobjetorelational(SGBDOR)desenvolvidoviaInternetporum
grupodedesenvolvedoresespalhadospeloglobo.umaalternativadecdigofonteaberta
paraSGBDscomerciaiscomoOracleeInformix.
OPOSTGRESQLfoidesenvolvidooriginalmentenaUniversidadedeCalifrniaemBerkeley.
Em1996,umgrupocomeouodesenvolvimentodoSGBDnaInternet.Elesusamemail
paracompartilharidiaseservidoresdearquivosparacompartilharcdigo.POSTGRESQL
agoracomparvelSGBDscomerciaisemtermosdecaractersticas,desempenhoe
confiana.Hojetemtransaes,views,procedimentosarmazenados,econstranintsde
integridadereferencial.Apiaumnmerograndedeinterfacesdeprogramao,como
ODBC,Java(JDBC),TCL/TK,PHP,PerlePython,entreoutros.POSTGRESQLcontinua
avanandoaumtremendopasso,graasaumgrupotalentosodedesenvolvedoresvia
Internet.(Bruce Momjian - 16th January 2003)
ProjetoPOSTGRES(19861994):PartiudoprojetodoSGBDIngresdeBerkeley.Projetista:
MichaelStonebraker.
Em1995doisestudantesdeBerkeley(JollyCheneAndrewYu)adicionamsuporteaSQL.
Seunovonome:Postgres95.FoitotalmentereescritoemCetambmadotouaSQL.Foi
originalmentepatrocinadopeloDARPA,ARO,NSFeESLInc.
Em1996:DisponibilizadonaInternetsobonomedePostgreSQL.
OPostgreSQLaniversariounodia08/07/2006,quandocompletou10anos(08/07/1996).Seu
dcimoaniversriofoicomemoradonosdias08e09dejulhoprximo,emToronto,Canad,
comalgumasconfernciassobreomesmo.Atualmenteestnaverso8.1.4(14/09/2006).
ParasabermaissobreahistriadoPostgreSQLvisiteositeoficialem:
http://www.postgresql.org/docs/current/interactive/history.html
Ouemportugusem:
http://pgdocptbr.sourceforge.net/pg80/history.html
Caractersticas:
OPostgreSQLsuportagrandepartedoSQLANSI,inclusivedoSQL2003,almdeoferecer

outrosrecursosimportantes,como:
Comandoscomplexos
Chavesestrangeiras(ForeignKey)
Gatilhos(Triggers)
Vises(views)
IntegridadedeTransaes
ControledeSimultaneidadeMultiverso(MVCC)
Suportamltiplastransaesonlineconcorrentesentreusurios.
SuporteaRules(sistemaderegrasquereescrevediretivasSQL)
Criaodetabelastemporrias(CREATETEMPTABLEnome(listadecampostipos);)
Traztambmopesdeextensopelousuriopara:
Tiposdedados
Funes
Operadores
FunesdeAgregao(Agrupamento)
Mtodosdendice
LinguagensProcedurais(StoredProcedures)

Licena
SualicenaBSD,portantopodeserutilizado,modificadoedistribudoporqualquerpessoa
ouempresaparaqualquerfinalidade,semencargo,emquaisquerdossistemasoperacionais
suportados.
AlgumasEmpresasqueUtilizamPostgreSQL
BASF(PDFformat)
Fujitsu
Apple
RedHat
Sun
Pervasive
MohawkSoftware
Proximity
RadioParadise
ShannonMedicalCenter
SpirosLouisStadium
TheDravisGroupOSSReport
VantenInc.
SRA
Rambler
Netezza
VASoftware
TravelPost
NationalWeatherService
AplicaesCorporativasdeAltoVolume:UmaSoluocomoPostgreSQL
AutilizaodaduplaPostgreSQL+Linuxnasempresascrescerapidamenteeumexemplo
decomoprodutosOpenSourcepodemajudarempresasaracionalizaroscustosdeTI.Uma

9
dascaractersticasdoPostgreSQLasuacapacidadedelidarcomumgrandevolumede
dados.Existemaplicaesemproduocomtabelaspossuindomaisde100milhesde
linhas.NoBrasil,existemcasosdesucessodeempresaslidandocombasescomdezenas
demilhesderegistrosgerenciadaspeloPostgreSQL.
UmadasmaioresimplantaesdePostgreSQLnoBrasilnaAtriumTelecom,empresade
telefoniacorporativadeSoPaulo.OPostgreSQLutilizadocomobancodedadosdo
sistemadebillingetemumabasededadosdemaisde100GBeefetua1milhode
transaesdirias.Asmaiorestabelasdosistemacontamcommaisde70milhesdelinhas.
AutilizaodobancodedadosPostgreSQLcadavezmaisamplanasempresasque
buscamumservidordebancodedadosaltamentesofisticado,comaltaperformance,estvel
ecapacitadoparalidarcomgrandesvolumesdedados.OfatodeserumprodutoOpen
Source,semcustosdelicenaparanenhumuso,tornaoPostgreSQLumaalternativa
extremamenteatraenteparaempresasquebuscamumcustototaldepropriedade(TCO)
menorparaosativosdeTI.
Citaode:http://www.dib.com.br/dib%20cd/LC2003/P%C3%A1ginas/LC2003_Conf.html
MetrdeSoPauloeDATAPREVtambmutilizamoPostgreSQL.

SobreoAutor
RibamarFS
DesenvolvedordeaplicativoswebparaaIntranetdoDNOCS(DepartamentoNacionalde
ObrasContraasSecas).DesenvolveatualmenteemPHPcomPostgreSQL.
TrabalhounoDNOCSporalgumtempocomoadministradorderedesLinuxeFreeBSD.
graduadoemEngenhariaCivilpelaUniversidadedeFortaleza(UNIFOR)
ComespecializaoemIrrigaoeDrenagempelaUFC/IRYDA
CursandoEspecializaoemJavanaUNIFOR
ConcluiuoCursodePostgreSQLpeladbExpert(SoPaulo)epeloEvoluo(Fortaleza)
ConcluiuocursodeAdministraoLinuxpeloEvoluo(Fortaleza)
FoiescritorcolaboradordaRevistaForumAccess(nareadeAccess)
escritorcolaboradordaRevistaWebMobile(artigosobreJoomla02/2006)
FoiprofessordecursosdeextensonaUNIFOR(PHP+MySQLePHP+PostgreSQL)em
2005e2006
ApresentoupalestrasobrePostgreSQLnaUNIFORnodia29/03/2006.
ApresentoupalestrasobrePostgreSQLnaUFCnodia21/09/2006(IISemanadeSoftware
LivredaUFC).
Apresentouminicurso"DesenvolvendoAplicaesWebemPHPcomfocoemProdutividade"
naUNIFORnosdias20e21/10/2006(IIIForumdeSoftwareLivredoCear).
Compartilhaseusconhecimentosatravsdossites:
http://ribafs.tk(http://www.geocities.com/ribafsindex)ehttp://www.ribafs.net

10

PublicadosobalicenaCreativeCommons[http://creativecommons.org/worldwide/br/]

2Instalao

11

InstalaonoWindowsXP
Lembrarque:PrecisainstalaremsistemadearquivosNTFSenoinstalanoXPStart
Edition(ondefaltasuportearedes).
Fazerdownloaddositeoficial(www.postgresql.org)(hojepostgresql8.1.41.zip)
Executaroarquivopostgresql8.1.msi
SelecionaridiomaeStart.DepoisemPrximo.
Natela"InformaesdeInstalao"existemmuitasinformaesimportantes:
SugerealeituradaFAQ
Faladaslicenasdosdiversossoftwaresasereminstalados
Asverses95,98eMedoWindowsnososuportadaspeloPostgreSQL
UsarobrigatoriamenteemsistemadearquivosNTFS
Instalarcomoservio(mesmoquedeixecomomanual)
OPostgreSQLnoexecutacomusurioquetenhaprivilgiosde
administrador
Osdriversjdbcestonosubdiretrio\jdbc,quedeveseradicionadaao
CLASSPATH
NaTela"OpesdeInstalao"marque:
Suporteparaidiomanativo(importanteparaterasmensagensempt_BR)
EoutrosqueconsidereimportantesecliqueemPrximo
Natela"ConfiguraodoServio":
Poderoptarporinstalarcomoservioouno.Comoserviomaisprtico.
CliqueemPrximo(elecriarumasenha)
Obs.:CasojtenhainstaladooPostgreSQLantesnestamquinadever
removerousurio"postgres"antesdecontinuar:
PaineldecontroleFerramentasadministrativasGerenciamentodo
computadorUsuriosegruposlocaisUsurios.Removao"postgres"
AgoracliqueemPrximoeSim
Natela"Inicializaroagrupamentodebancosdedados":
CasopreciseacessarsuamquinadeoutraremotamarqueEndereos
EmLocaleselecionePortugusBrasil
EmCodificaoselecioneLATIN1
Entrecomumasenhaerepita.AltereousurioseforocasoePrximo.
Natela"HabilitarLinguagensProcedurais"deixemarcadaPL/pgsql(casopretendautilizar)
ePrximo
Natela"HabilitarMdulosContrib"marqueosdesejadosePrximo
Natela"HabilitarPostGISemtemplae1"marquesomenteseprecisarquetodososbancos
tragamoPostGISePrximoePrximonovamente.
Apsinstalar,natela"Instalaoconcluda"recomendasequevocsecadastrarna
listapgsqlannounce,queenviainformaessemanaissobrenovasversesecorreesde
erros.Bastaclicarnoboto,fazerocadastroeConcluir.

PrrequisitosparainstalaodoPostgreSQLnumUNIX:

12

makedoGNU(gmakeoumake)
compiladorC,preferidoGCCmaisrecente
gzip
bibliotecareadline(parapsql)
gettext(paraNLS)
kerberos,opensslepam(opcional,paraautenticao)

InstalaonoLinux
VriasdistribuiesjcontamcombinriosparainstalaodoPostgreSQL(Ubuntu,Debian,
Slackware,RedHat,Fedora,etc).
EmumainstalaopadrodoUbuntuvejaoqueprecisaparainstalarosfontes:
Antesdeinstalar:
sudoaptgetinstallbuildessential
sudoaptgetinstalllibreadlinedev
sudoaptgetinstallzlib1gdev
sudoaptgetinstallgettext
Eusemakeaoinvsdegmake.
Faaodownloaddehttp://www.postgresql.org/ftp/source/
edescompacte(gostodedescompactarem/usr/local/srceinstalarnodiretriodefault,que
/usr/local/pgsql).
Instalarpelosbinriosdadistribuiotemasvantagensdejinstalareconfigurar
praticamentetudoautomaticamente,masinstalardosfontesdummaiorcontrolesobreas
configuraes(vocsabequetudoficarno/usr/local/pgsql)etemosapossibilidadede
instalarsemprealtimaverso.Reflitasobreamelhoropoparavoc.
makedistclean(adicionei,paraocasodeterquerepetirosprocedimentos)
./configure
make(buildconstruir)
su(mudarparasuperusurio,senoUbuntunousesu,usarsudoparaaslinhasabaixo)
makeinstall(instalar)
groupaddpostgres(criarogrupopostgres)
useraddgpostgresd/usr/local/pgsqlpostgres(criarousuriopostgres)
mkdir/usr/local/pgsql/data
chownpostgres:postgres/usr/local/pgsql/data(tornaropostgresdonodapastadata)
passwdpostgres
supostgres
(fazerlogincomopostgres)
/usr/local/pgsql/bin/initdbD/usr/local/pgsql/data
/usr/local/pgsql/bin/postmasterD/usr/local/pgsql/data>logfile2>&1&(startar)
/usr/local/pgsql/bin/createdbtest

/usr/local/pgsql/bin/psqltest

13

Copiaroscriptdeinicializaolinuxparao/etc/init.d(NosDebians):

14

De/usr/local/src/postgresql8.1.4/contrib/startscript/linuxpara/etc/init.d/postgresql
Darpermissodeexecuo:chmodu+x/etc/init.d/postgresql
SenoUbuntuououtroDebian:
supostgres
gedit.bash_profile(eadicionealinha):
PATH=/usr/local/pgsql/bin:$PATH
PsInstalao(sh,bash,kshezsh):
LD_LIBRARY_PATH=/usr/local/pgsql/lib
exportLD_LIBRARY_PATH
Ouno~/.bash_profiledousuriopostgres
initdbinicializaocluster,criaosscriptsdeconfiguraodefault.
postmasteriniciaoprocessodoservidorresponsvelporescutarporpedidosdeconexo.
ParasuporteaoslocalesdoBrasilusar:
/usr/local/pgsql/bin/initdblocale=pt_BRD/usr/local/pgsql/data
Ainstalaoviafontes(sources)emalgumasdistribuiesmuitoenxutas,voltadasparapara
desktop,podenofuncionardaprimeiravez,poisfaltaroalgumasbibliotecas,compiladores,
etc.
Apsainstalaoestcriadooagrupamentoprincipal(clustermain)debancosdedadosdo
PostgreSQL.
CasonosetenhaconfiananosusurioslocaisrecomendvelutilizaraopoW,
pwpromptoupwfiledoinitdb,queatribuirumasenhaaosuperusurio.
Noarquivopg_hba.confutilizarautenticaotipomd5,passwordoucript,antesdeiniciaro
servidorpelaprimeiravez.
Quandooprogramaqueiniciaoservidor(postmaster)estemexecuo,criadoumPIDe
armazenadodentrodoarquivopostmaster.pid,dentrodosubdiretriodata.Eleimpedeque
maisdeumprocessopostmastersejaexecutadousandoomesmoclusterediretriode
dados.
BaixarPostgreSQLviaAnonymousCVS:
BaixarCVSdehttp://www.nongnu.org/cvs/
InstalareLogarcomqualquersenha:
cvsd:pserver:anoncvs@anoncvs.postgresql.org:/projects/cvsrootlogin
Baixarfontes:
cvsz3d:pserver:anoncvs@anoncvs.postgresql.org:/projects/cvsrootcoPpgsql
IstoirinstalaroPostgreSQLnumsubdiretriopgsqldodiretrioatual.

15
AtualizaraltimainstalaoviaCVS:
Acesseodiretriopgsqleexecutecvsz3updatedP
Istoirbaixarsomenteasalteraesocorridasapsaltimainstalao.
Tambmpodemoscriarumarquivo.cvsrcnohomedousuriocomasduaslinhas:
cvsz3
updatedP
AtualizaodoPostgreSQLentreVerses
Casovoctenhaumaversoquenoseja8.1.xeestejaquerendoinstalara8.1.4,ento
precisafazerumbackupdosseusdadoserestaurarlogoapsainstalaocomosugerido
emseguida.Serassumidoquesuainstalaofoiem:
/usr/local/pgsqleseusdadosnosubdiretriodata.Casocontrriofaaosdevidosajustes.
1Atenoparaqueseusbancosnoestejamrecebendoatualizaoduranteobackup.Se
precisoprobaacessonopg_hba.conf.
2Efetuandobackup:
pg_dumpall>bancos.sql.ParapreservarosOIDsuseaopoonopg_dumpall.
3Pareoservidor
pg_ctlstopououtrocomando
Casoqueirainstalaranovaversonomesmodiretriodaanterior
mv/usr/local/pgsql/usr/local/pgsql.old
Entoinstaleanovaverso,crieodiretriodedadoseeinicieonovoservidor.
/usr/local/pgsql/bin/initdbD/usr/local/pgsql/data
/usr/local/pgsql/bin/postmasterD/usr/local/pgsql/data
Finalmente,restoreseusdadosusandoonovoservidorcom:
/usr/local/pgsql/bin/psqldpostgresfbancos.sql
Paramaisdetalhessobreosprocedimentosdeinstalao,vejaitens14.5e14.6do
manual.
PlataformasSuportadas
AtualmenteoPostgreSQLsuportamuitasplataformas,entreelasoWindows,Linux,
FreeBSD,NetBSD,OpenBSD,MacOSediversosoutros.Plataformassuportadaseasno
suportadasnaseo14.7domanualoficial.
NoPostgreSQLoprocessopostmasterescutaporconexesdosclientes.
Existemmaisdoisprocessostambminiciados,amboscomnomepostgres.Elescuidamda
gravaodoslogsoutabelasedamanutenodasestatsticas.
Paracadaconexocomumaaplicaoclientecriadoumnovoprocessocomomesmo
nomedousuriodaconexo.Porissoimportantequecadaaplicativotenhaseuusurioe
setenhaummaiorcontrole.
Osarquivosdeconfigurao(postgresql.conf,pg_hba.confepg_ident.conf)apartirda

verso8podemficaremdiretriodiferentedoPGDATA.

16

SugestodePadro
Nomesdebancosnoplural
Nomesdetabelasnosingular
Exemplo:
bancoclientes
tabelacliente

17

CriarNovoCluster
Casosintanecessidadepodecriaroutrosclusters,especialmenteindicadoparagruposde
tabelascommuitoacesso.
Ocomandoparacriarumnovoclusternaversoatual(8.1.3)doPostgreSQL:
banco=#\hcreatetablespace
Comando:CREATETABLESPACE
Descrio:defineumanovatablespace
Sintaxe:
CREATETABLESPACEnome_tablespace[OWNERusurio]LOCATION'diretrio'
Exemplo:
CREATETABLESPACEnclusterOWNERusurioLOCATION'/usr/local/pgsql/nc';
CREATETABLESPACEncluster[OWNERpostgres]LOCATION'c:\\ncluster';
Odiretriodeveestarvazioepertenceraousurio.
Criandoumbancononovocluster:
CREATEDATABASEbdclusterTABLESPACE=ncluster;
Obs:Podemexistirnumamesmamquinavriosagrupamentosdebancosdedados(cluster)
gerenciadosporummesmooupordiferentespostmasters.
Seusandotablespaceogerenciamentoserdeummesmopostmaster,seinicializadospor
outroinitdbserporoutro.
SetaroTablespacedefault:
SETdefault_tablespace=tablespace1;
ListarosTablespacesexistentes:
\db
SELECTspcnameFROMpg_tablespace;
Detalhesextrasnoitem14.5domanualoficial.

3DDL(DataDefinitionLanguage)

18

DDLoconjuntodecomandosSQLresponsveispeladefiniodosdados,ouseja,pela
criaodebancos,esquemas,tabelas,campos,tiposdedados,constraints,etc.
3.1Criaoeexclusodebancos,esquemas,tabelas,views,etc
Obs.:Nomesdeobjetosecamposnopodemusarhfen().Alternativamenteusar
sublinhado(_).
campo1
campo_1

Invlido
Vlido

NomesdeIdentificadores
UtilizaseporconvenoaspalavraschavesdoSQLemmaisculaseosidentificadoresdos
objetosquecriamosemminsculas.
Identificadoresdigitadosemmaisculasserogravadosemminsculas,anoserque
venhamentreaspas.
RevisesdaLinguagemSQL
SQL1989
SQL1992
SQL1999
SQL2003
DivisesdaSQL
DMLLinguagemdeManipulaodeDados
DDLLinguagemdeDefiniodeDados
DCLLinguagemdeControledeDados(autorizaodedadoselicenadeusuriospara
controlarquemtemacessoaosdados).
DQLLinguagemdeConsultadeDados(Temapenasumcomando:SELECT).

19

ExemploGrficodeConsultas(Tabela,comcamposC1,C2)
(AdaptaodeexemplodaWikipedia(http://pt.wikipedia.org)

TabelaT

Consulta

Resultado

C1

C2

SELECT*FROMT

C1

C2

C1

C2

C1

C2

C1

C2

SELECTC1FROMT

SELECT*FROMTWHEREC1=1

SELECTC1FROMTWHEREC2=b

CriarBanco
banco=#\hcreatedatabase
Comando:CREATEDATABASE
Descrio:criaumnovobancodedados
Sintaxe:
CREATEDATABASEnome
[[WITH][OWNER[=]dono_bd]
[TEMPLATE[=]modelo]
[ENCODING[=]codificao]
[TABLESPACE[=]tablespace]]
[CONNECTIONLIMIT[=]limite_con]]
CREATEDATABASEnomebanco;
ExcluindoUmBanco
DROPDATABASEnomebanco;
Listarosbancosexistentes:
\lNopsql

C1

C1

C2

C1
2

psqll(noprompt)
SELECTdatnameFROMpg_database;

20

Quandosecriaumnovobancodedadossemindicaromodelo,oquedefatoestamos
fazendoclonarobancodedadostemplate1.
Criarumbancoparaoutrousurio:
CREATEDATABASEnomebancoOWNERnomeuser;
createdbOnomeusuarionomebanco
Obs.:requersersuperusurioparapodercriarbancoparaoutrousurio.
CriarTabela
postgres=#\hcreatetable
Comando:CREATETABLE
Descrio:defineumanovatabela
Sintaxe:
CREATE[[GLOBAL|LOCAL]{TEMPORARY|TEMP}]TABLEnome_tabela([
{nome_colunatipo_dado[DEFAULTexpresso_padro][restrio_coluna[...]]
|restrio_tabela
|LIKEtabela_pai[{INCLUDING|EXCLUDING}DEFAULTS]}
[,...]
])
[INHERITS(tabela_pai[,...])]
[WITHOIDS|WITHOUTOIDS]
[ONCOMMIT{PRESERVEROWS|DELETEROWS|DROP}]
[TABLESPACEtablespace]
onderestrio_coluna:
[CONSTRAINTnome_restrio]
{NOTNULL|
NULL|
UNIQUE[USINGINDEXTABLESPACEtablespace]|
PRIMARYKEY[USINGINDEXTABLESPACEtablespace]|
CHECK(expresso)|
REFERENCEStabela_ref[(coluna_ref)][MATCHFULL|MATCHPARTIAL|MATCH
SIMPLE]
[ONDELETEao][ONUPDATEao]}
[DEFERRABLE|NOTDEFERRABLE][INITIALLYDEFERRED|INITIALLYIMMEDIATE]
erestrio_tabela:
[CONSTRAINTnome_restrio]
{UNIQUE(nome_coluna[,...])[USINGINDEXTABLESPACEtablespace]|
PRIMARYKEY(nome_coluna[,...])[USINGINDEXTABLESPACEtablespace]|
CHECK(expresso)|
FOREIGNKEY(nome_coluna[,...])REFERENCEStabela_ref[(coluna_ref[,...])]
[MATCHFULL|MATCHPARTIAL|MATCHSIMPLE][ONDELETEao][ONUPDATE

21
ao]}
[DEFERRABLE|NOTDEFERRABLE][INITIALLYDEFERRED|INITIALLYIMMEDIATE]
Obs.:Ateno:nestaverso(8.1.3)WITHOIDopcional.AstabelassocriadassemOID.
\dvisualizartabelaseoutrosobjetos
\dnometabelavisualizarestruturadatabela
CREATETABLEtabela(
campo1integer,
campo2text
);
ExcluindoTabela
DROPTABLEprimeira_tabela;
ValorDefault(padro)ParaCampos
Aodefinirumvalordefaultparaumcampo,aosercadastradooregistroeestecamponofor
informado,ovalordefaultassumido.Casonosejadeclaradoexplicitamenteumvalor
default,ovalornulo(NULL)serovalordefault.
CREATETABLEprodutos(
produto_nointeger,
descricaotext,
preconumericDEFAULT9.99
);
Constraints(Restries)
CHECK
Aocriarumatabelapodemospreverqueobancoexijaqueovalordeumcamposatisfaa
umaexpresso
CREATETABLEprodutos(
produto_nointeger,
descricaotext,
preconumericCHECK(preco>0)
);
Dandonomerestriocheck.Issoajudaatornarmaisamigveisasmensagensde
erroeapoderreferenciardeumaconsulta.
CREATETABLEprodutos(
produto_nointeger,
descricaotext,
preconumericCONSTRAINTpreco_positivoCHECK(preco>0)
);

CREATETABLEprodutos(
produto_nointeger,
descricaotext,
descontonumericCHECK(desconto>0ANDdesconto<0.10),
preconumericCONSTRAINTpreco_positivoCHECK(preco>0),
check(preco>desconto)
);

22

23

ConstraintNOTNULL
Obrigaropreenchimentodeumcampo.Idealparacamposimportantesquenodevemficar
sempreenchimento.Masdevemosteremmentequeatumespaoembrancoatendea
estarestrio.
CREATETABLEprodutos(
cod_prodintegerNOTNULLCHECK(cod_prod>0),
nometextNOTNULL,
preconumericNOTNULL
);
Obsimportante:nulosnosochecados.UNIQUEnoaceitavaloresrepetidos,masaceita
vriosnulos(jqueestesnosochecados).CuidadocomNULLs.
UniqueConstraint
Obrigarvaloresexclusivosparacadacampoemtodososregistros
CREATETABLEprodutos(
cod_prodintegerUNIQUE,
nometext,
preconumeric
);
CREATETABLEprodutos(
cod_prodinteger,
nometext,
preconumeric,
UNIQUE(cod_prod)
);
CREATETABLEexemplo(
ainteger,
binteger,
cinteger,
UNIQUE(a,c)
);
CREATETABLEprodutos(
cod_prodintegerCONSTRAINTunq_cod_prodUNIQUE,
nometext,
preconumeric
);
Evitandoduplicaocomnulos:
createtableteste(
idserialnotnull,
parentintegernull,
componentintegernotnull

);

24

postgres=#createuniqueindexnaoduplicontesteusingbtree(component)where(parentis
null);
ChavesPrimrias(PrimaryKey)
Achaveprimriadeumatabelaformadainternamentepelacombinaodasconstraints
UNIQUEeNOTNULL.Umatabelapodeternomximoumachaveprimria.Ateoriade
bancosdedadosrelacionalditaquetodatabeladeveterumachaveprimria.OPostgreSQL
noobrigaqueumatabelatenhachaveprimria,masrecomendvel,anoserqueesteja
criandoumatabelaparaimportardeoutraquecontenharegistrosduplicadosparatratamento
futurooualgoparecidoouapenasparatestes.
CREATETABLEprodutos(
cod_prodintegerUNIQUENOTNULL,
nometext,
preconumeric
);
CREATETABLEprodutos(
cod_prodintegerPRIMARYKEY,
nometext,
preconumeric
);
Composta(formadapormaisdeumcampo)
CREATETABLEexemplo(
ainteger,
binteger,
cinteger,
PRIMARYKEY(a,c)
);
ChaveEstrangeira(ForeignKey)
Criadascomoobjetivoderelacionarduastabelas,mantendoaintegridadereferencialentre
ambas.Especificaqueovalordacoluna(ougrupodecolunas)devecorresponderaalgum
valorexistenteemumregistrodaoutratabela.Normalmentequeremosquenatabela
estrangeiraexistamsomenteregistrosquetenhamumregistrorelacionadonatabela
principal.Comotambmcontrolaaremooderegistrosnatabelaprincipalquetenha
registrosrelacionadosnaestrangeira.
Tabelaprincipal
CREATETABLEprodutos(
cod_prodintegerPRIMARYKEY,
nometext,
preconumeric

25

);

Tabelareferenciada
CREATETABLEpedidos(
cod_pedidointegerPRIMARYKEY,
cod_prodinteger,
quantidadeinteger,
CONSTRAINTpedidos_fkFOREIGNKEY(cod_prod)REFERENCESprodutos(cod_prod)
);
CREATETABLEt0(
aintegerPRIMARYKEY,
binteger,
cinteger,
FOREIGNKEY(b,c)REFERENCESoutra_tabela
);

acolunadedestinoseraPK

CREATETABLEt1(
aintegerPRIMARYKEY,
binteger,
cinteger,
FOREIGNKEY(b,c)REFERENCESoutra_tabela(c1,c2)
);
Obs.:Onmerodecolunasetiponarestriodevemsersemelhantesaonmeroetipodas
colunasreferenciadas.
SimulandoENUMnoPostgreSQL
ParasimularaconstraintenumdoMySQL,podemosusaraconstraintcheck.
Dicadosite"PostgreSQL&PHPTutorials".
CREATETABLEpessoa(
codigointnullprimarykey,
cor_favoritavarchar(255)notnull,
check(cor_favoritaIN('vermelha','verde','azul'))
);
INSERTINTOpessoa(codigo,cor_favorita)values(1,'vermelha');OK
INSERTINTOpessoa(codigo,cor_favorita)values(1,'amarela');Erro,amarelonoconsta
Herana
Podemoscriarumatabelaqueherdatodososcamposdeoutratabelaexistente.
CREATETABLEcidades(
nometext,
populacaofloat,

altitudeint(emps)
);

26

CREATETABLEcapitais(
estadochar(2)
)INHERITS(cidades);
capitaisassimpassaatertambmtodososcamposdatabelacidades.
Segundoumaentrevista(videDBFreeMagazineNo.2)comaequipede
desenvolvimentodoPostgreSQL,eviteutilizarheranadetabelas.
Esquemas(Schema)
\dnvisualizaresquemas
Umbancodedadospodecontervriosesquemasedentrodecadaumdessespodemos
criarvriastabelas.Aoinvsdecriarvriosbancosdedados,criamosumecriamos
esquemasdentrodesse.Issopermiteumamaiorflexibilidade,poisumanicaconexoao
bancopermiteacessartodososesquemasesuastabelas.Portantodevemosplanejarbem
parasaberquantosbancosprecisaremos,quantosesquemasemcadabancoequantas
tabelasemcadaesquema.
Cadabancoaosercriadotrazumesquemapublic,queondeficamtodasastabelas,caso
nosejacriadooutroesquema.EsteesquemapublicnopadroANSI.Casosepretenda
aoportveldevemosexcluiresteesquemapublicecriaroutros.Pordefaulttodososusurios
criadostemprivilgioCREATEeUSAGEparaoesquemapublic.
CriandoUmEsquema
CREATESCHEMAnomeesquema;
ExcluindoUmEsquema
DROPSCHEMAnomeesquema;
Aqui,quandooesquematemtabelasemseuinterior,nopossvelapagardessaforma,
temosqueutilizar:
DROPSCHEMAnomeesquemaCASCADE;
Queapagaoesquemaetodasassuastabelas,portantomuitocuidado.
Obs.:OpadroSQLexigequeseespecifiqueRESTRICT(defaultnoPostgreSQL)OU
CASCADE,masnenhumSGBDsegueestarecomendao.
Obs.:recomendadoserexplcitoquantoaoscamposaseremretornados,aoinvsdeusar
*paratodos,entrarcomosnomesdetodososcampos.Assimficamaisclaro.Almdomais
aconsultaterummelhordesempenho.
AcessandoTabelasEmEsquemas
SELECT*FROMnomeesquema.nometabela;
PrivilgiosEmEsquemas
\dpvisualizarpermisses

27
REVOKECREATEONSCHEMApublicFROMPUBLIC;RemoveoprivilgioCREATEde
todososusurios.
ObtendoInformaessobreosEsquemas:
\dn
\dfcurrent_schema*
SELECTcurrent_schema();
SELECTcurrent_schemas(true);
SELECTcurrent_schemas(false);
Vises(views)
\dpvisualizarviewseoutrosobjetos
QuesoVIEWS?
Soumamaneirasimplesdeexecutareexibirdadosselecionadosdeconsultascomplexas
embancos.
Emqueelassoteis?Elaseconomizamgrandequantidadededigitaoeesforoe
apresentamsomenteosdadosquedesejamos.
CriandoUmaView
CREATEVIEWrecent_shipments
ASSELECTcount(*)ASnum_shipped,max(ship_date),title
FROMshipments
JOINeditionsUSING(isbn)
NATURALJOINbooksASb(book_id)
GROUPBYb.title
ORDERBYnum_shippedDESC;
UsandoUmaView
SELECT*FROMrecent_shipments;
SELECT*FROMrecent_shipments
ORDERBYmaxDESC
LIMIT3;
DestruindoUmaView
DROPVIEWnomeview;
CriarasTabelasqueservirodeBase
CREATETABLEclient(
clientidSERIALNOTNULLPRIMARYKEY,
clientnameVARCHAR(255)
);
CREATETABLEclientcontact(
contactidSERIALNOTNULLPRIMARYKEY,

clientidintCONSTRAINTclient_contact_checkREFERENCESclient(clientid),
nameVARCHAR(255),
phoneVARCHAR(255),
faxVARCHAR(255),
emailaddressVARCHAR(255)

28

);
CREATEVIEWclient_contact_listAS
SELECTclient.clientid,clientname,name,emailaddressFROMclient,clientcontact
WHEREclient.clientid=clientcontact.clientid;
Estandonopsqledigitando\dpodemosvisualizartambmasviews.
Onomedavisodeveserdistintodonomedequalqueroutraviso,tabela,seqnciaou
ndicenomesmoesquema.
Avisonomaterializadafisicamente.Emvezdisso,aconsultaexecutadatodavezque
avisoreferenciadaemumaconsulta.
FazerlivreusodevisesumaspectochavedeumbomprojetodebancodedadosSQL.
Asvisespodemserutilizadasempraticamentetodososlugaresondeumatabelarealpode
serutilizada.Construirvisesbaseadasemvisesnoraro.
Atualmente,asvisessosomenteparaleitura:osistemanopermiteinsero,atualizao
ouexclusoemumaviso.possvelobteroefeitodeumavisoatualizvelcriandoregras
quereescrevemasinseres,etc.navisocomoaesapropriadasemoutrastabelas.Para
obterinformaesadicionaisconsulteocomandoCREATERULE.
CREATEVIEWvistaASSELECT'HelloWorld';
ruimpordoismotivos:onomepadrodacoluna?column?,eotipodedadopadroda
colunaunknown.Sefordesejadoumliteralcadeiadecaracteresnoresultadodaviso
deveserutilizadoalgocomoCREATEVIEWvistaASSELECTtext'HelloWorld'AShello;
Vejacaptulo4doLivro"PraticalPostgreSQL"
Supondoqueumaconsultasejadeparticularinteresseparaumaaplicao,masquenose
desejadigitarestaconsultatodavezquefornecessria,entopossvelcriarumaview
baseadanaconsulta,atribuindoumnomeaestaconsultapeloqualserpossvelreferenci
lacomosefosseumatabelacomum.
CREATEVIEWminha_viewAS
SELECTcidade,temp_min,temp_max,prcp,data,localizacao
FROMclima,cidades
WHEREcidade=nome;
SELECT*FROMminha_visao;
FazerlivreusodevisesumaspectochavedeumbomprojetodebancodedadosSQL.As
visespermitemencapsular,atrsdeinterfacesquenomudam,osdetalhesdaestrutura
dastabelas,quepodemmudarnamedidaemqueasaplicaesevoluem.
Asvisespodemserutilizadasempraticamentetodososlugaresondeumatabelarealpode

serutilizada.Construirvisesbaseadasemvisesnoraro.

29

RULES
OcomandoCREATERULEcriaumaregraaplicadatabelaouvisoespecificada.
Umaregrafazcomquecomandosadicionaissejamexecutadosquandoumdeterminado
comandoexecutadoemumadeterminadatabela.
importanteperceberquearegra,narealidade,ummecanismodetransformaode
comando,ouumamacrodecomando.
possvelcriarailusodeumavisoatualizveldefinindoregrasONINSERT,ONUPDATE
eONDELETE,ouqualquersubconjuntodestasquesejasuficienteparaasfinalidades
desejadas,parasubstituirasaesdeatualizaonavisoporatualizaesapropriadasem
outrastabelas.
Existealgoaserlembradoquandosetentautilizarregrascondicionaisparaatualizaode
vises:obrigatriohaverumaregraincondicionalINSTEADparacadaaoquesedeseja
permitirnaviso.Searegraforcondicional,ounoforINSTEAD,entoosistemacontinuar
arejeitarastentativasderealizaraaodeatualizao,porqueachaquepoderacabar
tentandorealizaraaosobreatabelafictciadavisoemalgunscasos.

banco=#\hcreaterule
Comando:CREATERULE
Descrio:defineumanovaregradereescrita
Sintaxe:
CREATE[ORREPLACE]RULEnomeASONevento
TOtabela[WHEREcondio]
DO[ALSO|INSTEAD]{NOTHING|comando|(comando;comando...)}

30

OcomandoCREATERULEcriaumaregraaplicadatabelaouvisoespecificada.
evento
EventoumentreSELECT,INSERT,UPDATEeDELETE.
condio
QualquerexpressocondicionalSQL(retornandoboolean).Aexpressocondicionalno
podefazerrefernciaanenhumatabela,excetoNEWeOLD,enopodeconterfunesde
agregao.
INSTEAD
INSTEADindicaqueoscomandosdevemserexecutadosemvezdos(insteadof)comandos
originais.
ALSO
ALSOindicaqueoscomandosdevemserexecutadosadicionalmenteaoscomandos
originais.
SenoforespecificadonemALSOnemINSTEAD,ALSOopadro.
comando
Ocomandooucomandosquecompemaaodaregra.Oscomandosvlidosso
SELECT,INSERT,UPDATE,DELETEeNOTIFY.
Dentrodacondioedocomando,osnomesespeciaisdetabelaNEWeOLDpodemser
usadosparafazerrefernciaaosvaloresnatabelareferenciada.ONEWvlidonasregras
ONINSERTeONUPDATE,parafazerreferncianovalinhasendoinseridaouatualizada.
O OLD vlido nas regras ON UPDATE e ON DELETE, para fazer referncia linha
existentesendoatualizadaouexcluda.
Obs.:necessriopossuiroprivilgioRULEnatabelaparapoderdefinirumaregraparaa
mesma.
Exemplos:
CREATERULEme_notifiqueASONUPDATETOdatasDOALSONOTIFYdatas;
CREATERULEr1ASONINSERTTOTBL1DO
(INSERTINTOTBL2VALUES(new.i);NOTIFYTBL2);
CREATERULE"_RETURN"ASONSELECTTOminha_visoDOINSTEAD
SELECT*FROMminha_tabela; Aoinvsdeselecionardavisoselecionadatabela.

31
Bancodedadosmodelointocado
Existeummodelodebancodedadosquesempresepreservaoriginal,queotemplate0.O
templatetemplate1podeincorporarobjetoseacabaalgumasvezesficandoinvivelseuuso
comomodelo.Quandoissoacontecepodemossubstituilocomumacpiadotemplate0.
Criandobancodedadosbaseadoemoutromodelo
CREATEDATABSASEnomebancoTEMPLATEtemplate0;
createdbTtemplate0nomebanco
Recriandootemplate1
\ctestes
postgres=#UPDATEpg_databaseSETdatistemplate=falseWHEREdatname='template1';
testes=#DROPDATABASEtemplate1;
testes=#CREATEDATABASEtemplate1TEMPLATEtemplate0ENCODING'latin1';
testes=#\ctemplate1
template1=#VACUUMFULLFREEZE;
template1=#VACUUMFULL;
template1=#UPDATEpg_databaseSETdatistemplate=trueWHEREdatname='template1';
Agoratemosumtemplate1originalelimpo.
3.2Alteraesnosobjetosdosbancos
Adicionarcampo,removercampo,adicionarconstraint,removerconstraint,alterarvalor
default,alterarnomedecampo,alterarnomedetabela,alterartipodedadodecampo
(>=8.0).
AdicionarUmCampo
ALTERTABLEtabelaADDCOLUMNcampotipo;
ALTERTABLEprodutosADDCOLUMNdescricaotext;
RemoverCampo
ALTERTABLEtabelaDROPCOLUMNcampo;
ALTERTABLEprodutosDROPCOLUMNdescricao;
ALTERTABLEprodutosDROPCOLUMNdescricaoCASCADE;CuidadocomCASCADE
AdicionarConstraint
ALTERTABLEtabelaADDCONSTRAINTnome;
ALTERTABLEprodutosADDCOLUMNdescricaotextCHECK(descricao<>'');
ALTERTABLEprodutosADDCHECK(nome<>'');
ALTERTABLEprodutosADDCONSTRAINTunique_cod_prodUNIQUE(cod_prod);
ALTERTABLEprodutosADDFOREIGNKEY(cod_produtos)REFERENCES
grupo_produtos;
ALTERTABLEprodutosADDCONSTRAINTvendas_fkFOREIGNKEY(cod_produtos)
REFERENCESprodutos(codigo);
RemoverConstraint

ALTERTABLEtabelaDROPCONSTRAINTnome;
ALTERTABLEprodutosDROPCONSTRAINTprodutos_pk;
ALTERARVALORDEFAULTDECAMPO:

32

MudarTipodeDadosdeCampo(S>=8.0):
ALTERTABLEtabelaALTERCOLUMNcampoTYPEtipo;
ALTERTABLEprodutosALTERCOLUMNprecoTYPEnumeric(10,2);
ALTERTABLEprodutosALTERCOLUMNdataTYPEDATEUSINGCAST(dataASDATE);
MudarNomeDeCampo
ALTERTABLEtabelaRENAMECOLUMNcampo_atualTOcampo_novo;
ALTERTABLEprodutosRENAMECOLUMNcod_prodTOcod_produto;
Setar/RemoverValorDefaultdeCampo
ALTERTABLEtabelaALTERCOLUMNcampoSETDEFAULTvalor;
ALTERTABLEprodutosALTERCOLUMNcod_prodSETDEFAULT0;
ALTERTABLEprodutosALTERCOLUMNprecoSETDEFAULT7.77;
ALTERTABLEtabelaALTERCOLUMNcampoDROPDEFAULT;
ALTERTABLEprodutosALTERCOLUMNprecoDROPDEFAULT;
Adicionar/RemoverNOTNULL
ALTERTABLEprodutosALTERCOLUMNcod_prodSETNOTNULL;
ALTERTABLEprodutosALTERCOLUMNcod_prodDROPNOTNULL;
RenomearTabela
ALTERTABLEtabelaRENAMETOnomenovo;
ALTERTABLEprodutosRENAMETOequipamentos;
AdicionarConstraint(Restrio)
ALTERTABLEprodutosADDCONSTRAINTprodutos_pkPRIMARYKEY(codigo);
ALTERTABLEvendasADDCONSTRAINTvendas_fkFOREIGNKEY(codigo)
REFERENCESprodutos(codigo_produto);
ALTERTABLEvendasADDCONSTRAINTvendas_fkFOREIGNKEY(codigo)
REFERENCESprodutos; Nestecasousaachaveprimriadatabelaprodutos
RemoverConstraint(Restrio)
ALTERTABLEprodutosDROPCONSTRAINTprodutos_pk;
ALTERTABLEvendasDROPCONSTRAINTvendas_fk;

3.3ndices,TiposdeDadoseIntegridadeReferencial
importanteconhecerbemomximoderecursosexistentesnobanco,especialmente
aquelesrelacionadossnossasnecessidades.Assimtrabalhamoscommaiseficinciae
criamosbancosmaislevesecommaispotencial.Ostiposdedadossofatoresde
desempenho.
Exemplo:
Seumcampotipointeiroirprecisardevaloresat100enuncamudarestafaixa.No

devemosusarestecampocomotipoINT8,quandooINT2atendeesobra.
Deformasemelhanteescolhertodososdemaiscamposdatabelacombomsenso.
MaisDetalhesnoCaptulo8doManual:
http://pgdocptbr.sourceforge.net/pg80/datatype.html
ndices

33

OsndicessorecursosdoSGBDparamelhorarodesempenhodeconsultas.Mascomoo
usodendicestambmtemumpreoimportanteplanejarbemeconheceras
particularidadesantesdeadicionarumndice.
Cadavezqueumregistroinseridoouatualizadoatabeladendicestambmatualizada.
QuandocriamosconsultasSQL,quepesquisamtabelascommuitosregistroseestaconsulta
usaaclusulaWHERE,entooscamposquefazempartedaclusulaWHEREsobastante
indicadosparandice,paraquemelhoreodesempenhodaconsulta.
Osndicessoumaformademelhorarodesempenhodebancosdedados.Aoinvsde
procurardeformasequencial,oservidorprocurapelondice,comosefazumabuscaem
ndicesdelivrosevaisediretamentepginaprocurada.
Ondicepassadoparacadaregistroadicionadoouremovido.
difcilcriarregrasgenricasparadeterminarquendicesdevemserdefinidos.Muita
experinciaporpartedoadministradoremuitaverificaoexperimentalnecessriana
maioriadoscasos.
Criarumndice:
CREATEINDEXnomeindiceONtabela(campo);
Regrageralparanomedendice:idx_nometabela_nomecampo
Obs.:ndicesnoimportantesounoutilizadosdevemserremovidos.
Removerndice:
DROPINDEXnomeindice;
Criarumndicenico:
CREATEUNIQUEINDEXnomeindiceONtabela(campo);
Obs.:SomenteosndicestipoBtreepodemserdotipoUnique.
Criarumndicecomvriascolunas:
CREATEINDEXidx_clientes_psONclientes(codigo,nome);
BoaindicaoparaconsultascomWHERE...AND.AousarORondicenoserutilizado
peloPostgreSQL:
SELECTnomeFROMclientesWHEREcodigo=12ANDnome='Joo';
Usarndicescomvriascolunascommoderao.ndicescommaisde3colunastem

grandespossibilidadesdenoseremutilizadosinternamente.

34

Tiposdendices
OPostgreSQLsuportaatualmentequatrotiposdendices:Btree(rvoreB),Rtree(rvore
R),HasheGiST.
Btree>otipopadro(assumequandonoindicamos).Sondicesquepodemtratar
consultasdeigualdadeedefaixa,emdadosquepodemserclassificados.
Indicadoparaconsultascomosoperadores:<,<=,=,>=,>.Tambmpodeserutilizadocom
LIKE,ILIKE,~e~*.
Rtree>tipomaisadequadoadadosespaciais.Adequadoparaconsultascomos
operadores:<<,&<,&>,>>,@,~=,&&.
Hash>indicadosparaconsultascomcomparaesdeigualdadesimples.desencorajado
seuuso.EmseulugarrecomendaseoBtree.
GiST>
Criandondicesdetiposdiferentes:
CREATEINDEXnomeONtabelaUSINGtipo(campo);
tipo:BTREE,RTREE,HASH,GIST
Obs.:SomenteostiposBtreeeGiSTsuportamndicescomvriascolunas.
ndicescommaisdeumcamposomenteserutilizadoseasclusulascomoscampos
indexadosforemligadosporAND.
Umndicecommaisde3camposdificilmenteserutilizado.
ndiceParcial
Criadoapenassobreumsubconjuntodosregistrosdeumatabela,definidonumaexpresso
duranteacriaodondiceparcial.umrecursoparamelhorarodesempenhodosndices,
jqueatualizasomentepartedosregistros.
Obs.:namaioriadoscasosavantagemdeumndiceparcialsobreumndiceintegralno
muita.
Exemplos:
ExaminandoaUtilizaodosndices
AverificaodeusodendicesdeveserfeitacomoscomandosEXPLAINeANALYZE,
sendoqueocomandoANALYZEsempredeveserexecutadoantes.OcomandoANALYZE
coletaestatsticassobreadistribuiodosvaloresnatabela.
Devemserutilizadosdadosreaiseoconjuntodedadosdetestenuncadeveserpequeno.
AtentarparausarndicesnoscamposdasClusulas
FOREIGNKEY
ORDERBY

35

WHERE
ON
GROUPBY
HAVING
Exemplosprticodavantagemdondice
UmatabelacontendoosCEPsdoBrasil,com633.401registros.
Estatabelasemnenhumndiceexecutaaconsultaabaixo:
\timing
SELECT*FROMcep_tabelaWHEREcep=60420440;
Em7691ms
Psadicionarumndice:
ALTERTABLEcep_tabelaADDCONSTRAINTcep_pkPRIMARYKEY(cep);
Amesmaconsultaanterioragoragastaapenas10ms.
IssonumAMDDuron1300,128MBdeRAM).
ndiceFuncional
CREATEINDEXnomeindiceONtabela(lower(nomecampo));
timoartigonoiMasters
http://www.imasters.com.br/artigo.php?cn=1897&cc=23
http://www.imasters.com.br/artigo.php?cn=1922&cc=23
http://www.imasters.com.br/artigo.php?cn=1959&cc=23
Videmanualoficial,captulo11paradetalhes.

TiposdeDadosMaisComuns
Numricos
Tipo

Taman
ho

Apelido

Faixa

smallint(INT2)

2bytes inteiropequeno

32768a+32767

integer(INTouINT4)

4bytes inteiro

2147483648at+2147483647

bigint(INT8)

8bytes inteirolongo

9223372036854775808a
+9223372036854775807

numeric(p,e)

tamanhovarivel,precisoespecificada
pelousurio.Exatoesemlimite

decimal(p,e)

eescala(casasdecimais)
ppreciso(totaldedgitos,inclusiveestala)

real(float)

4bytes pontoflutuante

doubleprecision

8bytes duplapreciso

int(INT4)

36
precisovarivel,noexatoeprecisode6
dgitos
precisovarivel,noexatoeprecisode
15dgitos
maisindicadoparandicesdeinteiros

Caracteres
charactervarying(n)

varchar(n)

comprimentovarivel,comlimite

character(n)

char(n)

comprimentofixo,completacombrancos

text

comprimentovariveleilimitado

Desempenhosemelhanteparaostiposcaractere.
Data/Hora
timestamp[(p)][witouttime
zone]

8bytes dataehorasem
zona

4713ACa5874897DC

timestamp[(p)][withtime
zone]

8bytes dataehoracom
zona

4713ACa5874897DC

interval

12
bytes

178000000anosa178000000anos

date

4bytes somentedata

4713ACat32767DC

time[(p)][withouttime
zone]

8bytes somenteahora

00:00:00.00at23:59:59.99

time[(p)][withtimezone]

8bytes somenteahora

00:00:00.00at23:59:59.99

intervalode
tempo

[(p)]apreciso,quevariade0a6eodefualt2.
TiposdeDadosMaisComuns(Continuao)
Boleanos
Tipo

Tamanho

Apelido

Faixa

TRUE

Representaes: 't','true','y','yes'e'1'

FALSE

Representaes: 'f','false','n','no','0'

Apenasumdosdoisestados.Oterceiroestado,desconhecido,representadopeloNULL.

Exemplodeconsultacomboolean:
CREATETABLEteste1(aboolean,btext);
INSERTINTOteste1VALUES(TRUE,'sicest');
INSERTINTOteste1VALUES(FALSE,'nonest');
SELECT*FROMteste1;
Retorno:
a|b
+
t|sicest
f|nonest

37
Alerta:aentradapodeser:1/0,t/f,true/false,TRUE/FALSE,masoretornosersempret/f.
Obs.:ParacampostipodataquepermitamNULL,devemospreverissonaconsultaSQLe
passarNULLsemdelimitadoresevaloresnoNULLcomdelimitadores.
Obs2:EviteotipoMONEYqueestemobsolescncia.EmseulugaruseNUMERIC.
PrefiraINT(INTEGER)emlugardeINT4,poisosprimeirossopadroSQL.Emgeralevitar
osnomesINT2,INT4eINT8,quenosopadro.OINT8oubigintnopadroSQL.
EmndicesutilizesomenteINT,evitandosmallintebigint,quenuncaseroutilizados.
TiposSQLPadro
bit,bitvarying,boolean,char,charactervarying,character,varchar,date,doubleprecision,
integer,interval,numeric,decimal,real,smallint,time(comousemzonahorria),timezone
(comousemzonahorria).
OtipoNUMERICpoderealizarclculosexatos.Recomendadoparaquantiasmonetriase
outrasquantidadesondeaexatidosejaimportante.Issopagaopreodequedade
desempenhocomparadoaosinteiroseflutuantes.
PensandoemportabilidadeevitausarNUMERIC(12)eusarNUMERIC(12,0).
Alerta:Acomparaodeigualdadededoisvaloresdepontoflutuantepodefuncionar
conformeoesperadoouno.
OPostgreSQLtrabalhacomdatasdocalendrioJuliano.
TrabalhacomafaixademeiodiadeJaneirode4713AC(anobisexto,domingodeluanova)
atumadatabemdistantenofuturo.Levaemcontaqueoanotem365,2425dias.
SERIAL
NoPostgreSQLumcampocriadodotipoSERIALinternamenteumaseqncia,inteiro
positivo.
OsprincipaisSGBDsutilizamalgumavariaodestetipodedados(autoincremento).
SerialotipoautoincrementodoPostgreSQL.QuandocriamosumcampodotipoSERIAL
aoinserirumnovoregistronatabelacomocomandoINSERTomitimosocampotipo
SERIAL,poiseleserinseridoautomaticamentepeloPostgreSQL.
CREATETABLEserial_teste(codigoSERIAL,nomeVARCHAR(45));
INSERTINTOserial_teste(nome)VALUES('RibamarFS');
Obs.:Aregranomearumaseqnciaserial_teste_codigo_seq,ouseja,
tabela_campo_seq.
select*fromserial_teste_codigo_seq;
Estaconsultaacimaretornamuitasinformaesimportantessobreaseqnciacriada:nome,

valorinicial,incremento,valorfinal,maioremenorvaloralmdeoutrasinformaes.

38

VejaquefoiomitidoocampocdigomasoPostgreSQLiratribuirparaomesmoovalordo
prximoregistrodecdigo.Pordefaultoprimeirovalordeumserial1,masseprecisarmos
comearcomumvalordiferentevejaasoluoabaixo:
SetandooValorInicialdoSerial
ALTERSEQUENCEtabela_campo_seqRESTARTWITH1000;
CHARcorrespondeaCHAR(1).
VARCHARcorrespondeaumacadeiadetamanhosemlimites.
DiferenadeDesempenho
InternamenteoPostgreSQLarmazenaemtabelasseparadososvaloreslongos,parano
interferiremnoacessodosvalorescurtosdacoluna.Omaiorvalorpermitidoparaumacadeia
decaracteresde1GB.ParavaloresmaioresusarTEXTouVARCHARsemespecificar
comprimento.
TiposdeDadosGeomtricos
GeometricTypes
Name

StorageSize

Representation

Description

point

16bytes

Pointontheplane

line

32bytes

Infiniteline(notfullyimplemented) ((x1,y1),(x2,y2))

lseg

32bytes

Finitelinesegment

((x1,y1),(x2,y2))

box

32bytes

Rectangularbox

((x1,y1),(x2,y2))

path

16+16nbytes Closedpath(similartopolygon)

((x1,y1),...)

path

16+16nbytes Openpath

[(x1,y1),...]

polygon 40+16nbytes Polygon(similartoclosedpath)


circle

24bytes

Circle

(x,y)

((x1,y1),...)
<(x,y),r>(centerandradius)

TiposdeDadosdeRedes
NetworkAddressTypes
Name

StorageSize

Description

cidr

12or24bytes IPv4andIPv6networks

inet

12or24bytes IPv4andIPv6hostsandnetworks

macaddr 6bytes

MACaddresses

TiposdeDadosArray
Podemostercamposcomtiposdedadosquenososimples,masarrays.
CREATE TABLE salario (

39
nome
text,
apgamento integer[],
agendamento
text[][]

);
CREATE TABLE tictactoe (
quadrado
integer[3][3]

);
Entrandoosvalores:
'{{1,2,3},{4,5,6},{7,8,9}}'
INSERT INTO sal_emp
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'{{"meeting", "lunch"}, {"meeting"}}');
ERROR: multidimensional arrays must have array expressions with matching
dimensions

Precisateramesmaquantidadedeelementos.
INSERT INTO sal_emp
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'{{"meeting", "lunch"}, {"training", "presentation"}}');
INSERT INTO sal_emp
VALUES ('Carol',
'{20000, 25000, 25000, 25000}',
'{{"breakfast", "consulting"}, {"meeting", "lunch"}}');

SELECT * FROM sal_emp;


name |
pay_by_quarter
|
schedule
-------+---------------------------+------------------------------------------Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}}
Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}}
(2 rows)

OconstrutorARRAYtambmpodeserusado:
INSERT INTO sal_emp
VALUES ('Bill',
ARRAY[10000, 10000, 10000, 10000],
ARRAY[['meeting', 'lunch'], ['training', 'presentation']]);
INSERT INTO sal_emp
VALUES ('Carol',
ARRAY[20000, 25000, 25000, 25000],
ARRAY[['breakfast', 'consulting'], ['meeting', 'lunch']]);

Acessando:
SELECTnameFROMsal_empWHEREpay_by_quarter[1]<>pay_by_quarter[2];

SELECTpay_by_quarter[3]FROMsal_emp;
Faixadevaloresinferior:superior:
SELECTschedule[1:2][1:1]FROMsal_empWHEREname='Bill';
SELECTarray_dims(ARRAY[1,2]||3);
SELECTarray_prepend(1,ARRAY[2,3]);
SELECTarray_cat(ARRAY[1,2],ARRAY[3,4]);
SELECT1||ARRAY[2,3]ASarray;
SELECTARRAY[1,2]||ARRAY[[3,4]]ASarray;
SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;

40

4DML(DataManipulationLanguage)

41

DMLoconjuntodecomandosSQLresponsveispelamanipulaodosdados:inserir,
consultar,atualizareexcluir.
Atenteparaquesuasconsultassejam:
simpleseclaras
contenhamsomentecamposestritamentenecessrios
sejamotimizadasparaodesempenhomximo
SQL(StructureQueryLanguage)umalinguagemdeclarativa,ondevocdizao
computadoroquedesejafazeredeixaamquinadecidiraformacorretadechegarao
resultado.
ParaoprimeirocontatocomoPostgreSQLeparatercertezadequeomesmoest
corretamenteinstaladoeconfigurado,podemosdigitarnalinhadecomandodosistema
operacional(comousuriodopostgresql):
psqlversion
psqll
OpsqloprogramadegerenciamentoeusodoPostgreSQLpelousuriolocal.
ComelepodemosfazerpraticamentetudoquesepodefazercomoPG.
Algunsprogramasestodisponveisnalinhadecomandodosistemaoperacional,permitindo
criareexcluirbancos,criareexcluirusurios,entreoutros.Osprogramasadisponveis
dependemdaversoinstalada,dosistemaoperacionaledaformaquefoiinstalado.
Queminstalaatravsdosfontes(sources)temumsubdiretriochamadocontrib,ondeesto
osdemaisprogramasdesenvolvidospelacomunidadedeprogramadoresdoPG.Nestecaso
parainstalarumdestesprogramasexecute"make;makeinstall"estandonorespectivo
diretrio.Umexemploopgbench.
OscomandosvialinhadecomandosdoSO,normalmenteterminamcom"db"eso
formadoscomapenasumapalavra,createdb,porexemplo.Jdedentrodopsql,eles
normalmentesoformadosporduaspalavras,comoporexemplo,
CREATEDATABASE.
OscomandosaseguirseroexecutadosnalinhadecomandodoSO.Supondoqueosuper
usurioseja"postgres".
Formamaisgeraldeuso:
nome_comandoopoUnomeuser
Criarumbancodedados:
createdbcontrole_estoqueUpostgres
Visualizarobancocriado:

psqllUpostgres
Excluirobancocriado:
dropdbcontrole_estoqueUpostgres

42

Ajudasobreoscomandos:
nome_comandohelp
Acessarobancocriadoatravsdoterminalinterativodegerenciamentodo
PostgreSQL(psql):
psqlcontrole_estoqueUpostgres
D:\Arquivosdeprogramas\PostgreSQL\8.1\bin>psqlcontrole_estoqueUpostgres
Bemvindoaopsql8.1.3,oterminaliterativodoPostgreSQL.
Digite:\copyrightparamostrartermosdedistribuio
\hparaajudacomcomandosSQL
\?paraajudacomcomandosdopsql
\gouterminarcompontoevrgulaparaexecutaraconsulta
\qparasair
controle_estoque=#
Esteopromptdopsql.Vejaquejnosrecebecomboasvindasecomdicasdecomo
podemosaqualquermomentoreceberajuda.Especialmenteatenteparaoscomandos:
\hparareceberajudasobrecomandosSQL.\hcomandoajudasobreumcomando
\?ajudasobreoscomandosdeoperaodoterminalpsql
;ocomandoparaindicaraoPGqueexecutenossaseqnciadecomandos
\qparasairdopsql
Obs.:Aceitaquebrasdelinhaparaumaseqnciadecomandos.
MesmoquepossamosutilizarferramentasgrficasouWebparagerenciaroPG,altamente
recomendadoquenosfamiliarizemoscomasintaxedoscomandosparaentendercomoos
comandossoexecutadosinternamenteetermaiordomniosobreoPG.Depoisdessafase,
osqueresistemaosencantosdopsql:)podemusarumadascitadasferramentas.
Vamosexecutaralgunscomandosdopsqlealgumaspequenasconsultasparaficarmosmais
vontade.
\llistabancos,donosecodificao
\ddescrevetabela,ndice,seqnciaouview(viso)
\dulistausuriosepermisses
\dglistagrupos
\dplistaprivilgiosdeacessotabelas,views(vises)esequncias
psqlcontrole_estoqueUpostgres
controle_estoque=#SELECTversion();

version

PostgreSQL8.1.3oni686pcmingw32,compiledbyGCCgcc.exe(GCC)3.4.2(mingw
special)

43

ParadistinguirconvencionousequeaspalavraschavedoSQLsejamescritasem
maisculas,maspodemserescritasemminsculassemproblemaparaointerpretadorde
comandos.
SELECT25*4;
SELECTcurrent_date;
4.1ConsultasBsicasemSQL
SELECTselecionarregistrosdetabelas
banco=#\hselectdaajudaviapsql
Comando:SELECT
Descrio:recupera(retorna)registrosdeumatabelaouviso(view)
Sintaxe:
SELECT[ALL|DISTINCT[ON(expresso[,...])]]
*|expresso[ASnome_sada][,...]
[FROMitem_de[,...]]
[WHEREcondio]
[GROUPBYexpresso[,...]]
[HAVINGcondio[,...]]
[{UNION|INTERSECT|EXCEPT}[ALL]select]
[ORDERBYexpresso[ASC|DESC|USINGoperador][,...]]
[LIMIT{contador|ALL}]
[OFFSETincio]
[FOR{UPDATE|SHARE}[OFnome_tabela[,...]][NOWAIT]]
ASCodefault
Item_depodeserumdos:
[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_junoitem_de[ONcondio_juno|USING(coluna_juno
[,...])]
Sintaxeresumida:
SELECT*FROMtabela;retornatodososregistrosdatabelacomtodososcampos
Alista_de_camposoretornodaconsulta.
Exemplos:

1)SELECTsiapeASMatriculadoServidorFROMpessoal;
2)SELECTpessoal.siape,pessoal.senha,locacoes.lotacao
FROMpessoal,lotacoesWHEREpessoal.siape=lotacoes.siape
ORDERBYlotacoes.lotacao;

44

DISTINCTEscritalogoapsSELECTdesconsideraosregistrosduplicados,retornando
apenasregistrosexclusivos.
SELECTDISTINCTemailFROMclientes;
ALLocontrriodeDISTINCTeopadro,retornandotodososregistros,duplicadosou
no.
Aofazerumaconsulta,umregistroserconsideradoigualaoutrosepelomenosumcampo
fordiferente.EostodososvaloresNULLseroconsideradosiguais.

CLUSULAWHEREFiltraoretornodeconsultas.
Operadoresaceitos:
=,>,<,<>,!=,>=,<=
SELECTnomeFROMclientesWHEREemail='ribafs@ribafs.org';
SELECTnomeFROMclientesWHEREidade>18;
SELECTnomeFROMclientesWHEREidade<21;
SELECTnomeFROMclientesWHEREidade>=18;
SELECTnomeFROMclientesWHEREidade<=21;
SELECTnomeFROMclientesWHEREUPPER(estado)!='CE';
SELECTnomeFROMclientesWHEREemail='ribafs@ribafs.org';
BETWEEN,LIKE,OR,AND,NOT,EXISTS,ISNULL,ISNOTNULL,IN
SELECTnomeFROMclientesWHEREidadeBETWEEN18and45;
SELECTnomeFROMclientesWHEREemailLIKE'%@gmail.com';
SELECTnomeFROMclientesWHEREidade>1821ORidade<21;entre18e21
SELECTnomeFROMclientesWHEREidade>=18ANDUPPER(estado)='CE';
SELECTnomeFROMclientesWHEREidadeNOTBETWEEN18AND21;
SELECT*FROMdatasWHEREEXISTS(SELECT*FROMdatas2WHEREdatas.data=
datas2.data);
SELECTnomeFROMclientesWHEREestadoISNULL;
SELECTnomeFROMclientesWHEREestadoISNOTNULL;
SELECTnomeFROMclientesWHEREestadoIN('CE','RN');
GROUP BY Geralmente utilizada com funes de agrupamento (de agregao), como
tambmcomHAVING.Agrupaoresultadodosdadosporumoumaiscamposdeumatabela.
Utilizadoparaagruparregistros(linhas)databelaquecompartilhamosmesmosvaloresem
todasascolunas(campos)dalista.

Exemplos:

45

SELECTSUM(horas)FROMempregados;Trazasomadashorasdetodososempregados
SELECTempregado,SUM(horas)FROMempregadosGROUPBYempregado;Traza
somadashorasdecadaempregado.VejaqueempregadodeveapareceremGROUPBY,
jqueoscamposderetornodiferentesdousadonafunodeagrupamentodevemvirno
GROUPBY.
Dica:QuandoseutilizaumafunodeagrupamentonumcampodalistadoSELECT,os
demaiscamposdalistadeveroseragrupados.Exemplo:
SELECTcodigo,nome,count(valor)FROMvendasGROUPBYcodigo,nome.
Exemplo:
SELECTc.nome,COUNT(p.quant)ASquantos
FROMclientesc,pedidosp
WHEREc.codigo=p.cod_cliente
GROUPBY(p.cod_cliente);
HAVINGFiltraoretornodeGROUPBY.Noalteraoresultado,apenasfiltra.
Exemplo:
SELECTcliente,SUM(quant)AStotal
FROMpedidosGROUPBYcliente
HAVINGtotal>50;ouHAVINGSUM(quant)>50;
ORDERBYOrdenaoresultadodaconsultaporumoumaiscamposemordemascendente
(ASC,default)oudescendente(DESC).
Exemplos:
ORDERBYcliente;peloclienteeascendente
ORDERBYclienteDESC;descendente
ORDERBYcliente,quantidade;peloclienteesubordenadopelaquantidade
ORDERBYclienteDESC,quantASC;
Noexemploordenandopordoiscampos:
SELECT*FROMpedidosORDERBYcliente,quantidade;Asadaficariaalgocomo:
Antnio1
Antnio2
Joo 1
Pedro1
Pedro2
INSERTInserirregistrosemtabelas.
banco=#\hinsert
Comando:INSERT

Descrio:inserenovosregistrosemumatabela

46

Sintaxe:
INSERTINTOtabela[(lista_de_campos)]
{DEFAULTVALUES|VALUES({expresso|DEFAULT}[,...])|consulta}
DEFAULTSeaocriaratabeladefinirmoscamposcomvalordefault,aoinserirregistrose
omitirovalorparaestescampos,oservidoroscadastrarcomovalordefault.
Exemplo(formacompleta):
Natabelaocampoidadetemvalordefault18.
INSERTINTOclientes(codigo,nome,idade)VALUES(1,RibamarFS);
Nesteexemplosercadastradoparaaidadeovalor18.
FormaAbreviada:
INSERTINTOclientesVALUES(1,RibamarFS);
Norecomendada,pornoserclaranemadequadaparatrabalhoemgrupo.Caso
utilizemosestaformasomosobrigadosainseriroscamposnaordemoriginalemqueesto
natabela.
InserindocomSubConsulta:
INSERTINTOclientes(codigo,nome,idade)VALUES
(SELECTfnome,fidadeFROMfuncionariosWHEREcli='S');
SELECTfirstname,lastname,city,stateINTOnewfriendFROMfriend;
UPDATEAtualizarregistrosdetabelas
banco=#\hupdate
Comando:UPDATE
Descrio:atualizaregistrosdeumatabela
Sintaxe:
UPDATE[ONLY]tabelaSETcoluna={expresso|DEFAULT}[,...]
[FROMlista_de]
[WHEREcondio]
Exemplos:
UPDATEclientesSETidade=idade+1;Todososregistrosdeclientesseroatualizados
UPDATEpedidosSETquant=quant+3
WHEREclienteIN(SELECTcodigoFROMclientesWHEREidade>18);
DELETERemoverregistrosdetabelas
banco=#\hdelete
Comando:DELETE
Descrio:apagaregistrosdeumatabela

47
Sintaxe:
DELETEFROM[ONLY]tabela
[USINGlista_util]
[WHEREcondio]
Exemplos:
DELETEFROMpedidos;Cuidado,excluirtodososregistrosdatabelapedidos
DELETEFROMpedidosWHERE(codigoISNULL);Removesemconfirmaonemcom
opodedesfazer.
4.2JunesdeTabelasouConsultas
As junes SQL so utilizadas quando precisamos selecionar dados de duas ou mais
tabelas.
ExistemasjunescomestilononANSIoutheta(junocomWHERE)
EasjunesANSIjoin(comJOIN).AsjunesANSIpodemserdedoistipos,asINNER
JOINSeasOUTERJOINS.ApadroaINNERJOIN.INNERJOINpodeserescritocom
apenasJOIN.

ExemploANSI:
SELECTp.siape,p.senha,l.lotacaoFROMpessoalpCROSSJOINlotacoesl;
TiposdeJunes

48

INNERJOINOndetodososregistrosquesatisfazemcondioseroretornados.
Exemplo:
SELECTp.siape,p.nome,l.lotacao
FROMpessoalpINNERJOINlotacoesl
ONp.siape=l.siapeORDERBYp.siape;
Exemplonoestilotheta:
SELECTp.siape,p.nome,l.lotacao
FROMpessoalp,lotacoesl
WHEREp.siape=l.siapeORDERBYp.siape;
OUTERJOINquesedivideemLEFTOUTERJOINeRIGHTOUTERJOIN
LEFTOUTERJOINousimplesmenteLEFTJOINSomenteosregistrosdatabelada
esquerda(left)seroretornados,tendoounoregistrosrelacionadosnatabeladadireita.
Primeiro,realizadaumajunointerna.Depois,paracadalinhadeT1quenosatisfaza
condiodejunocomnenhumalinhadeT2,adicionadaumalinhajuntadacomvalores
nulosnascolunasdeT2.Portanto,atabelajuntadapossui,incondicionalmente,nomnimo
umalinhaparacadalinhadeT1.
Atabelaesquerdadooperadordejunoexibircadaumdosseusregistros,enquantoque
adadireitaexibirsomenteseusregistrosquetenhamcorrespondentesaosdatabelada
esquerda.
Paraosregistrosdadireitaquenotenhamcorrespondentesnaesquerdaserocolocados
valoresNULL.
Exemplo(voltartodossomentedepessoal):
SELECTp.siape,p.nome,l.lotacao
FROMpessoalpLEFTJOINlotacoesl
ONp.siape=l.siapeORDERBYp.siape;
VejaquepessoalficaesquerdaemFROMpessoalpLEFTJOINlotacoesl.
RIGHTOUTERJOIN
InversodoLEFT,esteretornatodososregistrossomentedatabeladadireita(right).
Primeiro,realizadaumajunointerna.Depois,paracadalinhadeT2quenosatisfaza
condiodejunocomnenhumalinhadeT1,adicionadaumalinhajuntadacomvalores
nulosnascolunasdeT1.oopostodajunoesquerda:atabelaresultantepossui,
incondicionalmente,umalinhaparacadalinhadeT2.
Exemplo(retornarsomenteosregistrosdelotacoes):

49
SELECTp.siape,p.nome,l.lotacao
FROMpessoalpRIGHTJOINlotacoesl
ONp.siape=l.siapeORDERBYp.nome;
FULLOUTERJOIN
Primeiro,realizadaumajunointerna.Depois,paracadalinhadeT1quenosatisfaza
condiodejunocomnenhumalinhadeT2,adicionadaumalinhajuntadacomvalores
nulosnascolunasdeT2.Tambm,paracadalinhadeT2quenosatisfazacondiode
junocomnenhumalinhadeT1,adicionadaumalinhajuntadacomvaloresnulosnas
colunasdeT1.
Etambmas:
CROSSJOINeSELFJOIN(parasimesmo).
Videitem7.2.1.1domanualoficialparamaisdetalheseexemplos.
LIMIT
LIMIT(limite)juntamentecomOFFSET(deslocamento)permitedizerquantaslinhas
desejamosretornardaconsulta.Podemosretornardesdeapenasumaattodas.
Sintaxe:
SELECTlista_de_campos
FROMexpresso
[LIMIT{nmero|ALL}][OFFSETinicio]
LIMITALLmesmoqueimitirLIMIT.
OFFSETinicioorientaparaqueaconsultaretornesomenteapartirdeinicio.
OFFSET0mesmoqueomitirOFFSET.
LIMIT50OFFSET11Devertrazer50registrosdo11ato60,casoexistam.
Obs.:QuandoseutilizaLIMITimportanteutilizaraclusulaORDERBYparaestabelecer
umaordemnicaparaaslinhasdoresultado.Casocontrrio,serretornadoumsubconjunto
imprevisveldelinhasdaconsulta;podesedesejarobterdadcimaavigsimalinha,masda
dcimaavigsimadequalordem?Aordemdesconhecidaanoserquesejaespecificado
ORDERBY.IstoumaconseqnciainerenteaofatodoSQLnoprometerretornaros
resultadosdeumaconsultaemqualquerordemespecfica,anoserqueORDERBYseja
utilizadoparaimporestaordem.
Exemplos:
SELECTid,nameFROMproductsORDERBYnameLIMIT20OFFSET1;
Irretornarosregistrosdo1ato20.
SELECT*FROMnews_mLIMIT$inicio,$n_resultados
Ocomando"SELECT*FROMnews_mLIMIT$n_resultadosOFFSET$inicio"
irpesquisarasnoticiasdatabela"news_m"comeandodoresultado"$inicio"eirlistar
"$n_resultados".

50
Exemplo:"SELECT*FROMnews_mLIMIT3OFFSET2"irexibir3notciasapartirda2a.
notciadatabela,ouseja,irexibirasnotcias2,3e4danossatabela"news_m".

4.3Subconsultas
Soconsultasdentrodeconsultas.

51

SubconsultaescalarumcomandoSELECTcomum,entreparnteses,queretorna
exatamenteumregistro,comumcampo.
selectnome,(selectmax(preco)fromprodutoswherecodigo=1)as"maiorpreo"from
produtos;
SELECT*FROMtabela1WHEREtabela1.col1=
(SELECTcol2FROMtabela2WHEREcol2=valor);
SELECTnameFROMcustomerWHEREcustomer_idNOTIN(SELECTcustomer_idFROM
salesorder);
SELECT'test'AStest,idFROM(SELECT*FROMbooks)ASexample_sub_query;
SELECTfirstname,state,
CASE
WHENstate='PA'THEN'close'
WHENstate='NJ'ORstate='MD'THEN'far'
ELSE'veryfar'
ENDASdistance
FROMfriend;
ExpressesdeSubConsultas
EXISTS
SELECTcampo1FROMtabela1WHEREEXISTS
(SELECT1FROMtabela2WHEREcampo2=tabela1.campo2);
CombinandoCASEeEXISTS
CREATETEMPORARYTABLEfrutas(idSERIALPRIMARYKEY,nomeTEXT);
INSERTINTOfrutasVALUES(DEFAULT,'banana');
INSERTINTOfrutasVALUES(DEFAULT,'ma');
CREATETEMPORARYTABLEalimentos(idSERIALPRIMARYKEY,nomeTEXT);
INSERTINTOalimentosVALUES(DEFAULT,'ma');
INSERTINTOalimentosVALUES(DEFAULT,'espinafre');
SELECTnome,CASEWHENEXISTS(SELECTnomeFROMfrutasWHEREnome=a.nome)
THEN'sim'
ELSE'no'
ENDASfruta
FROMalimentosa;
IN
SELECTnome,CASEWHENnomeIN(SELECTnomeFROMfrutas)
THEN'sim'
ELSE'no'
ENDASfruta

FROMalimentos;
NOTIN
ANY/SOME
SELECTnome,CASEWHENnome=ANY(SELECTnomeFROMfrutas)
THEN'sim'
ELSE'no'
ENDASfruta
FROMalimentos;
CASEWHEN
EXEMPLO1
createtableamigos(
codigoserialprimarykey,
nomechar(45),
idadeint
);
insertintoamigos(nome,idade)values('JooBrito',25);
insertintoamigos(nome,idade)values('Roberto',35);
insertintoamigos(nome,idade)values('Antnio',15);
insertintoamigos(nome,idade)values('FranciscoQueiroz',23);
insertintoamigos(nome,idade)values('BernardodosSantos',21);
insertintoamigos(nome,idade)values('FranciscaPinto',22);
insertintoamigos(nome,idade)values('Natanael',55);
selectnome,
idade,
case
whenidade>=21then'Adulto'
else'Menor'
endasstatus
fromamigosorderbynome;
CASEWHENcriaumacolunaapenasparaexibio
EXEMPLO2
createtableamigos(
codigoserialprimarykey,
nomechar(45),
estadochar(2)
);
insertintoamigos(nome,estado)values('JooBrito','CE');

52

insertintoamigos(nome,estado)values('Roberto','MA');
insertintoamigos(nome,estado)values('Antnio','CE');
insertintoamigos(nome,estado)values('FranciscoQueiroz','PB');
insertintoamigos(nome,estado)values('BernardodosSantos','MA');
insertintoamigos(nome,estado)values('FranciscaPinto','SP');
insertintoamigos(nome,estado)values('Natanael','SP');

53

selectnome,

estado,
case
whenestado='PB'then'Fechado'
whenestado='CE'orestado='SP'then'Funcionando'
whenestado='MA'then'Funcionandoatodovapor'
else'Menor'
endasstatus
fromamigosorderbynome;
Mostrarcadanotajuntocomamenornota,amaiornota,eamdiadetodasasnotas.
SELECTnota,
(SELECTMIN(nota)FROMnotas)ASmenor,
(SELECTMAX(nota)FROMnotas)ASmaior,
(ROUND(SELECTAVG(nota)FROMnotas))ASmedia
FROMnotas;

5FunesInternas
5.1FunesdeStrings
ConcatenaodeStringsdois||(pipes)
SELECT'ae'||'io'||'u'ASvogais;
vogaisaeiou
SELECTCHR(67)||CHR(65)||CHR(84)AS"Dog";DogCAT
QuantidadedeCaracteresdeString
char_lengthretornaonmerodecaracteres
SELECTCHAR_LENGTH('UNIFOR');Retorna6
OuSELECTLENGTH('Database');Retorna8
Converterparaminsculas
SELECTLOWER('UNIFOR');
Converterparamaisculas
SELECTUPPER('universidade');
Posiodecaractere
SELECTPOSITION('@'IN'ribafs@gmail.com');Retorna7
OuSELECTSTRPOS('Ribamar','mar');Retorna5
Substring
SUBSTRING(string[FROMinteiro][FORinteiro])
SELECTSUBSTRING('RibamarFS'FROM9FOR10);RetornaFS
SUBSTRING(stringFROMpadro);
SELECTSUBSTRING('PostgreSQL'FROM'.......');RetornaPostgre
SELECTSUBSTRING('PostgreSQL'FROM'...$');RetornaSQL
Primeiros.......eltimos...$
Ou
SUBSTR('string',inicio,quantidade);
SELECTSUBSTR('Ribamar',4,3);Retornamar
Substituirtodososcaracteressemelhantes
SELECTTRANSLATE(string,velho,novo);
SELECTTRANSLATE('Brasil','il','o');RetornaBraso
SELECTTRANSLATE('Brasileiro','eiro','eira');
RemoverEspaosdeStrings
SELECTTRIM('SQLPADRO');
CalcularMD5deString
SELECTMD5('ribafs');Retorna53cd5b2af18063bea8ddc804b21341d1

54

55
Repetirumastringnvezes
SELECTREPEAT('SQL',3);RetornaSQLSQLSQL
Sobrescreversubstringemstring
SELECTREPLACE('Postgresql','sql','SQL');RetornaPostgreSQL
DividirCadeiadeCaracterescomDelimitador
SELECTSPLIT_PART('PostgreSQL','gre',2);RetornaSQL
SELECTSPLIT_PART('PostgreSQL','gre',1);RetornaPost
<gre>
IniciaisMaisculas
INITCAP(text)INITCAP('olmundo')OlMundo
RemoverEspaosemBranco
TRIM([leading|trailing|both][characters]fromstring)removecaracteresdadireitaeda
esquerda.trim(both'b'from'babacatebbbb');abacate
RTRIM(stringtext,charstext)Removeoscaracterescharsdadireita(defaultespao)
rtrim('removarrrr','r')remova
LTRIM(stringtext,charstext)Removeoscaracterescharsdaesquerda
ltrim('abssssremova','abs')remova
Detalhesnoitem9.4doManual:
http://pgdocptbr.sourceforge.net/pg80/functionsstring.html
Likee%
SELECT*FROMFRIENDSWHERELASTNAMELIKE'M%';
OILIKEcaseINsensitiveeoLIKEcasesensitive.
~~equivaleaoLIKE
~~*equivaleequivaleaoILIKE
!~~equivaleaoNOTLIKE
!~~*equivaleequivaleaoNOTILIKE
...LIKE'[46]_6%'Pegaroprimeirosendode4a6,
osegundoqualquerdgito,
oterceirosendo6eosdemaisquaisquer
%similara*
_similara?(dearquivosnoDOS)
CorrespondnciacomumPadro
OPostgreSQLdisponibilizatrsabordagensdistintasparacorrespondnciacompadro:o

56
operadorLIKEtradicionaldoSQL;ooperadormaisrecenteSIMILARTO(adicionadoao
SQL:1999);easexpressesregularesnoestiloPOSIX.Almdisso,tambmestdisponvel
afunodecorrespondnciacompadrosubstring,queutilizaexpressesregularestantono
estiloSIMILARTOquantonoestiloPOSIX.
SELECTsubstring('XY1234Z','Y*([09]{1,3})');Resultado:123
SELECTsubstring('XY1234Z','Y*?([09]{1,3})');Resultado:1
SIMILARTO
OoperadorSIMILARTOretornaverdadeoufalsoconformeopadrocorrespondaouno
cadeiadecaracteresfornecida.EsteoperadormuitosemelhanteaoLIKE,excetopor
interpretaropadroutilizandoadefiniodeexpressoregulardopadroSQL.
'abc'SIMILARTO'abc'verdade
'abc'SIMILARTO'a'falso
'abc'SIMILARTO'%(b|d)%'verdade
'abc'SIMILARTO'(b|c)%'falso
SELECT'abc'SIMILARTO'%(b|d)%'; Procuraboudem'abc'enocasoretornaTRUE
REGEXP
SELECT'abc'~'.*ab.*';
~distingueadeA
~*nodistingueadeA
!~distingueexpressesdistingueadeA
!~*distingueexpressesnodistingueadeA
'abc'~'abc'TRUE
'abc'~'^a'TRUE
'abc'~'(b|j)'TRUE
'abc'~'^(b|c)'FALSE

5.2FunesMatemticas
OperadoresMatemticos
+,,*,/,%(mdulo,restodedivisodeinteiros),^(potncia),!(fatorial),@(valorabsoluto)
|/raisquadrada(|/25.0=5)
||/raizcbica(||/27.0=3)
AlgumasfunesMatemticas
ABS(x)valorabsolutodex
CEIL(numeric)arredondaparaoprximointeirosuperior
DEGREES(valor)convertevalorderadianosparagraus
FLOOR(numeric)arredondaparaoprximointeiroinferior
MOD(x,y)restodadivisodexpory
PI()constantePI(3,1415...)

POWER(x,y)xelevadoay
RADIANS(valor)convertevalordegrauspararadianos
RANDOM()valoraleatrioentre0e1
ROUND(numeric)arredondaparaointeiromaisprximo
ROUND(v,d)arredondavcomdcasasdecimais
SIGN(numeric)retornaosinaldaentrada,como1ou+1
SQRT(X)RaizquadradadeX
TRUNC(numeric)truncaparaonenhumacasadecimal
TRUNC(vnumeric,sint)truncaparascasasdecimais
OperadoresLgicos:
AND,OReNOT.TRUE,FALSEeNULL
OperadoresdeComparao:
<,>,<=,>=,=,<>ou!=
aBETWEENxANDy
aNOTBETWEENxANDy
expressoISNULL
expressoISNOTNULL
expressoISTRUE
expressoISNOTTRUE
expressoISFALSE
expressoISNOTFALSE
expressoISUNKNOWN
expressoISNOTUNKNOWN
OPERADORNULL
EmSQLNULLparavaloresinexistentes.Regrageral:NULLsepropaga,oque
significaquecomquemNULLsecombinaoresultadoserumNULL.
NULLnozero,nostringvazianemstringdecomprimentozero.
Umexemplo:numcadastrodealunos,paraoalunoqueaindanoseconheceanota,
nocorretousarzeroparasuanota,massimNULL.
NosepodeefetuarclculosdeexpressesondeumdoselementosNULL.
COMPARANDONULLs
NOTNULLcomNULLUnknown
NULLcomNULLUnknown
CONVERSODE/PARANULL
NULLIF()eCOALESCE()
NULLIF(valor1,valor2)
NULLIFRetornaNULLse,esomentese,valor1evalor2foremiguais,casocontrrio
retornavalor1.
Algocomo:

57

if(valor1==valor2){
thenNULL
elsevalor1;

58

Retornavalor1somentequandovalor1==valor2.
COALESCEretornaoprimeirodeseusargumentosquenoforNULL.SretornaNULL
quandotodososseusargumentosforemNULL.
Uso:mudarovalorpadrocujovalorsejaNULL.
createtablenulos(nuloint,nulo2int,nulo3int);
insertintonulosvalues(1,null,null);
selectcoalesce(nulo,nulo2,nulo3)fromnulos;Retorna1,valordocamponulo;
selectcoalesce(nulo2,nulo3)fromnulos;RetornaNULL,poisambossoNULL.
GREATESTRetornaomaiorvalordeumalistaSELECTGREATEST(1,4,6,8,2);8
LEASTRetornaomenorvalordeumalista.
Todososvaloresdalistadevemserdomesmotipoenulossoignorados.
Obs.:AmbasasfunesacimanopertencemaoSQLstandard,massoumaextensodo
PostgreSQL.
CONCATENANDONULLs
Aregra:NULLsepropaga.QualquerqueconcatenecomNULLgerarNULL.
STRING||NULLNULL
Usos:
Comovalordefaultparacamposquefuturamentereceberovalor.
Valordefaultparacamposquepoderosersempreinexistentes.

5.3FunesdeAgrupamento(Agregao)
Asfunesdeagrupamentosousadasparacontaronmeroderegistrosdeumatabela.
avg(expresso)
count(*)
count(expresso)
max(expresso)
min(expresso)
stddev(expresso)
sum(expresso)
variance(expresso)

59
Ondeexpresso,podeser"ALLexpresso"ouDISTINCTexpresso.
count(distinctexpresso)
AsfunesdeAgrupamento(agregao)nopodemserutilizadasnaclusulaWHERE.
DevemserutilizadasentreoSELECTeoFROM.NumSELECTqueusaumafuno
agregada,asdemaiscolunasdevemfazerpartedaclusulaGROUPBY.Somentepodem
aparecerapsoSELECTounaclusulaHAVING.Deusoproibidonasdemaisclusulas.
Obs.:AocontarosregistrosdeumatabelacomafunoCOUNT(campo)eessecampofor
nuloemalgunsregistros,estesregistrosnoserocomputados,porissocuidadocomos
nulostambmnasfunesdeagregao.
AclusulaHAVINGnormalmentevemprecedidadeumaclusulaGROUPBYe
obrigatoriamentecontmfunesdeagregao.
ALERTA:RetornamsomenteosregistrosondeocampopesquisadosejadiferentedeNULL.
NaNNotaNumber(Noumnmero)
UPDATEtabelaSETcampo1='NaN';
SELECTMIN(campo)AS"ValorMnimo"FROMtabela;
Casotenhaproblemacomestaconsultause:
SELECTcampoFROMtabelaORDERBYcampoASCLIMIT1;traromenor
SELECTMAN(campo)AS"ValorMximo"FROMtabela;
Casotenhaproblemacomestaconsultause:
SELECTcampoFROMtabelaORDERBYcampoDESCLIMIT1;traromaior

5.4FunesdeData/Hora
Operaescomdatas:
timestamp'2001092801:00'+interval'23hours'>timestamp'2001092900:00'
date'20010928'+interval'1hour'>timestamp'2001092801:00'
date'01/01/2006'date'31/01/2006'
time'01:00'+interval'3hours'time>'04:00'
interval'2hours'time'05:00'>time'03:00:00'
Funoage(retornaInterval)Diferenaentredatas
age(timestamp)interval (Subtraidehoje)
age(timestamp'19570613')>43years8mons3days
age(timestamp,timestamp)intervalSubtraiosargumentos
age('20010410',timestamp'19570613')>43years9mons27days

60
Funoextract(retornadouble)
Extraipartedadata:ano,ms,dia,hora,minuto,segundo.
selectextract(yearfromage('20010410',timestamp'19570613'))
selectextract(monthfromage('20010410',timestamp'19570613'))
selectextract(dayfromage('20010410',timestamp'19570613'))
DataeHoraatuais(retornamdataouhora)
SELECTCURRENT_DATE;
SELECTCURRENT_TIME;
SELECTCURRENT_TIME(0);
SELECTCURRENT_TIMESTAMP;
SELECTCURRENT_TIMESTAMP(0);
Somardiasehorasaumadata:
SELECTCAST('06/04/2006'ASDATE)+INTERVAL'27DAYS'ASData;
Funonow(retornatimestampwithzone)
now()Dataehoracorrente(timestampwithzone);
Nousaremcampossomentetimestamp.
Funodate_part(retornadouble)
SELECTdate_part('day',TIMESTAMP'2001021620:38:40');
Resultado:16(dayumastring,diferentedeextract)
Obtendoodiadadataatual:
SELECTDATE_PART('DAY',CURRENT_TIMESTAMP)ASdia;
Obtendoomsdadataatual:
SELECTDATE_PART('MONTH',CURRENT_TIMESTAMP)ASmes;
Obtendooanodadataatual:
SELECTDATE_PART('YEAR',CURRENT_TIMESTAMP)ASano;
Funodate_trunc(retornatimestamp)
SELECTdate_trunc('year',TIMESTAMP'2001021620:38:40');
Retorna2001021600:00:00
Convertendo(CAST)
selectto_date('19830718','YYYYMMDD')
selectto_date('19830718','YYYYMMDD')
Funotimeofday(retornatexto)
selecttimeofday()>FriFeb2410:07:32.0001262006BRT
Interval
interval[(p)]
to_char(interval'15h2m12s','HH24:MI:SS')
date'20010928'+interval'1hour'

61
interval'1day'+interval'1hour'
interval'1day'interval'1hour'
900*interval'1second'
Intervaltrabalhacomasunidades:second,minute,hour,day,week,month,year,decade,
century,milleniumouabreviaturasoupluraisdestasunidades.
Seinformadosemunidades'1310:38:14'serdevidamenteinterpretado'13days10hours38
minutes14seconds'.
CURRENTE_DATEINTERVAL'1'day;
TO_TIMESTAMP('2006010517:56:03','YYYYMMDDHH24:MI:SS')
TiposGeomtricos:
CREATETABLEgeometricos(pontoPOINT,segmentoLSEG,retanguloBOX,poligono
POLYGON,circuloCIRCLE);
ponto(0,0),
segmentode(0,0)at(0,1),
retngulo(baseinferior(0,0)at(1,0)ebasesuperior(0,1)at(1,1))e
crculocomcentroem(1,1)eraio1.
INSERTINTOgeometricosVALUES('(0,0)','((0,0),(0,1))','((0,0),(0,1))',
'((0,0),(0,1),(1,1),(1,0))','((1,1),1)');
TiposdeDadosparaRede:
ParatratarespecificamentederedesoPostgreSQLtemostiposdedadoscidr,inete
macaddr.
cidrpararedesIPV4eIPV6
inetpararedesehostsIPV4eIPV6
macaddrendereosMACdeplacasderede
Assimcomotiposdata,tiposderededevemserpreferidosaoinvsdeusartipostextopara
guardarIPs,MscarasouendereosMAC.
VejaumexemploemndicesParciaiseadocumentaooficialparamaisdetalhes.

5.5FormataodeTiposdeDados
TO_CHAREstafunodeveserevitada,poisestprevistasuadescontinuao.
TO_DATE
dateTO_DATE(text,text);Recebedoisparmetrostexteretornadate.
Umdosparmetrosadataeooutrooformato.
SELECTTO_DATE('29032006','DDMMYYYY');Retorna20060329
TO_TIMESTAMP
tmtTO_TIMESTAMP(text,text)Recebedoistexteretornatimestampwithzone

62
SELECTTO_TIMESTAMP('2903200614:23:05','DDMMYYYYHH:MI:SS');Retorna2006
032914:23:05+00
TO_NUMBER
numericTO_NUMBER(text,text)
SELECTTO_NUMBER('12,454.8','99G999D9S');Retorna12454.8
SELECTTO_NUMBER('12,454.8','99G999D9');Retorna12454.8
SELECTTO_NUMBER('12,454.8','99999D9');Retorna12454
Detalhesnoitem9.8domanual.
5.6ConversoExplcitadeTipos(CAST)
CAST(expressoAStipo)ASapelido;SintaxeSQLANSI
Outraforma:
Tipo(expresso);
Exemplo:
SELECTDATE'10/05/2002'DATE'10/05/2001';Retornaaquantidadededias
entreasduasdatas
Paraestetipodeconversodevemos:
Usarfloat8aoinvsdedoubleprecision;
Usarentreaspasalgunstiposcomointerval,timeetimestamp
Obs.:aplicaesportveisdevemevitarestaformadeconversoeemseulugarusaro
CASTexplicitamente.

AfunoCAST()utilizadaparaconverterexplicitamentetiposdedadosemoutros.
SELECTCAST(2ASdoubleprecision)^CAST(3ASdoubleprecision)AS"exp";
SELECT~CAST('20'ASint8)AS"negativo";Retorna21
SELECTround(CAST(4ASnumeric),4);Retorna4.0000
SELECTsubstr(CAST(1234AStext),3);
SELECT1AS"real"UNIONSELECTCAST('2.2'ASREAL);
FunesDiversas
SELECTCURRENT_DATABASE();
SELECTCURRENT_SCHEMA();
SELECTCURRENT_SCHEMA(boolean);
SELECTCURRENT_USER;
SELECTSESSION_USER;
SELECTVERSION();
SELECTCURRENT_SETTING('DATESTYLE');
SELECTHAS_TABLE_PRIVILEGE('usuario','tabela','privilegio');
SELECTHAS_TABLE_PRIVILEGE('postgres','nulos','insert');Retorna:t
SELECTHAS_DATABASE_PRIVILEGE('postgres','testes','create');Retorna:t
SELECTHAS_SCHEMA_PRIVILEGE('postgres','public','create');Retorna:t
SELECTrelnameFROMpg_classWHEREpg_table_is_visible(oid);
Arrays
SELECTARRAY[1.1,2.2,3.3]::INT[]=ARRAY[1,2,3];
SELECTARRAY[1,2,3]=ARRAY[1,2,8];
SELECTARRAY[1,3,5]||ARRAY[2,4,6];
SELECT0||ARRAY[2,4,6];
Arraydecharcom48posiesecadaumacom2:
campochar(2)[48]

FunesGeomtricos
area(objeto)area(box'((0,0),(1,1))');
center(objeto)center(box'((0,0),(1,2))');
diameter(circulodouble)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))');
FunesparaRedes
Funescidreinet

63

64
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
Funomacaddr
trunt(macaddr)trunc(maraddr'12:34:34:56:78:90:ab')12:34:56:00:00:00
FunesdeInformaodoSistema
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)dprivilgioaousernatabela
has_table_privilege(table,privilege)dprivilgioaousurioatualnatabela
has_database_privilege(user,database,privilege)dprivilgioaousernobanco
has_function_privilege(user,function,privilege)dprivilgioaousernafuno
has_language_privilege(user,language,privilege)dprivilgioaousernalinguagem
has_schema_privilege(user,schema,privilege)dprivilgioaousernoesquema
has_tablespace_privilege(user,tablespace,privilege)dprivilgioaousernotablespace
current_setting(nome)valoratualdaconfigurao
set_config(nome,novovalor,is_local)setaparmetroderetornanovovalor
pg_start_backup(labeltext)
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(arquivotext,offsetbigint,tamanhobigint)
pg_stat_file(arquivotext)

6FuneseTriggersDefinidaspeloUsurio

65

OPostgreSQLoferecequatrotiposdefunes:
FunesescritasemSQL
Funesemlinguagensdeprocedimento(PL/pgSQL,PL/Tcl,PL/php,PL/Java,etc)
Funesinternas(rount(),now(),max(),count(),etc).
FunesnalinguagemC
CREATE[ORREPLACE]FUNCTION
name([[argmode][argname]argtype[,...]])
[RETURNSrettype]
{LANGUAGElangname
|IMMUTABLE|STABLE|VOLATILE
|CALLEDONNULLINPUT|RETURNSNULLONNULLINPUT|STRICT
|[EXTERNAL]SECURITYINVOKER|[EXTERNAL]SECURITYDEFINER
|AS'definition'
|AS'obj_file','link_symbol'
}...
[WITH(attribute[,...])]
ParareforaraseguranainteressanteusaroparmetroSECURITYDEFINER,que
especificaqueafunoserexecutadacomosprivilgiosdousurioqueacriou.
SECURITYINVOKERindicaqueafunodeveserexecutadacomosprivilgiosdousurio
queachamou(padro).
SECURITYDEFINERespecificaqueafunodeveserexecutadacomosprivilgiosdo
usurioqueacriou.
UmagrandeforadoPostgreSQLqueelepermiteacriaodefunespelousurioem
diversaslinguagens:SQL,PlpgSQL,TCL,Perl,Phyton,Ruby.
Paraterexemplosadisposiovamosinstalarosdodiretrio"tutorial"dosfontesdo
PostgreSQL:
Acessar/usr/local/src/postgresql8.1.3/src/tutorialeexecutar:
makeinstall
Feitoissoteremos5arquivos.sql.
Osyscat.sqltrazconsultassobreocatlogodesistema,oquesechamademetadados
(metadata).
Obasic.sqleoadvanced.sqlsoconsultasSQL.
Ocomplex.sqltratadacriaodeumtipodedadospelousurioeseuuso.
Ofunc.sqltrazalgumasfunesemSQLeoutrasemC.

66

6.1FunesemSQL

67

OqueoutrosSGBDschamamdestoredproceduresoPostgreSQLchamadefunes,que
podemseremdiversaslinguagens.
CREATEORREPLACEFUNCTIONolamundo()RETURNSint4
AS'SELECT1'LANGUAGE'sql';
SELECTolamundo();
CREATEORREPLACEFUNCTIONadd_numeros(nr1int4,nr2int4)RETURNSint4
AS'SELECT$1+$2'LANGUAGE'sql';
SELECTadd_numeros(300,700)ASresposta;
Podemospassarcomoparmetroonomedeumatabela:
CREATETEMPTABLEempregados(
nometext,
salarionumeric,
idadeinteger,
baiapoint
);
INSERTINTOempregadosVALUES('Joo',2200,21,point('(1,1)'));
INSERTINTOempregadosVALUES('Jos',4200,30,point('(2,1)'));
CREATEFUNCTIONdobrar_salario(empregados)RETURNSnumericAS$$
SELECT$1.salario*2ASsalario;
$$LANGUAGESQL;
SELECTnome,dobrar_salario(emp.*)ASsonho
FROMempregados
WHEREempregados.baia~=point'(2,1)';
Algumasvezesprticogerarovalordoargumentocompostoemtempodeexecuo.Isto
podeserfeitoatravsdaconstruoROW.
SELECTnome,dobrar_salario(ROW(nome,salario*1.1,idade,baia))ASsonho
FROMempregados;
Funoqueretornaumtipocomposto.Funoqueretornaumanicalinhadatabela
empregados:
CREATEFUNCTIONnovo_empregado()RETURNSempregadosAS$$
SELECTtext'Nenhum'ASnome,
1000.0ASsalario,
25ASidade,

point'(2,2)'ASbaia;
$$LANGUAGESQL;

68

Ou
CREATEORREPLACEFUNCTIONnovo_empregado()RETURNSempregadosAS$$
SELECTROW('Nenhum',1000.0,25,'(2,2)')::empregados;
$$LANGUAGESQL;
Chamarassim:
SELECTnovo_empregado();
ou
SELECT*FROMnovo_empregado();
FunesSQLcomofontesdetabelas
CREATETEMPTABLEteste(testeidint,testesubidint,testenametext);
INSERTINTOtesteVALUES(1,1,'Joo');
INSERTINTOtesteVALUES(1,2,'Jos');
INSERTINTOtesteVALUES(2,1,'Maria');
CREATEFUNCTIONgetteste(int)RETURNStesteAS$$
SELECT*FROMtesteWHEREtesteid=$1;
$$LANGUAGESQL;
SELECT*,upper(testename)FROMgetteste(1)ASt1;
TabelasTemporriascriartabelastemporrias(TEMP),fazcomqueoservidorse
encarreguederemovla(oquefazlogoqueaconexosejaencerrada).
CREATETEMPTABLEnometabela(campotipo);
FunesSQLretornandoconjunto
CREATEFUNCTIONgetteste(int)RETURNSSETOFtesteAS$$
SELECT*FROMtesteWHEREtesteid=$1;
$$LANGUAGESQL;
SELECT*FROMgetteste(1)ASt1;
FunesSQLpolimrficas
AsfunesSQLpodemserdeclaradascomorecebendoeretornandoostipospolimrficos
anyelementeanyarray.
CREATEFUNCTIONconstroi_matriz(anyelement,anyelement)RETURNSanyarrayAS$$
SELECTARRAY[$1,$2];
$$LANGUAGESQL;

69
SELECTconstroi_matriz(1,2)ASintarray,constroi_matriz('a'::text,'b')AStextarray;
CREATEFUNCTIONeh_maior(anyelement,anyelement)RETURNSbooleanAS$$
SELECT$1>$2;
$$LANGUAGESQL;
SELECTeh_maior(1,2);
Maisdetalhesnocaptulo31domanual.
6.2FunesemPlpgSQL
AsfunesemlinguagensproceduraisnoPostgreSQL,comoaPlpgSQLso
correspondentesaoquesechamacomumentedeStoredProcedures.
PordefaultoPostgreSQLstrazsuportesfunesnalinguagemSQL.Paradarsuporte
funesemoutraslinguagenstemosqueefetuarprocedimentoscomoaseguir.
ParaqueobancopostgrestenhasuportelinguagemdeprocedimentoPlPgSQL
executamosnalinhadecomandocomosuperusuriodoPostgreSQL:
createlangplpgsqlUnomeusernomebanco
APlpgSQLalinguagemdeprocedimentosarmazenadosmaisutilizadanoPostgreSQL,
devidoseramaismaduraecommaisrecursos.
CREATEFUNCTIONfunc_escopo()RETURNSintegerAS$$
DECLARE
quantidadeinteger:=30;
BEGIN
RAISENOTICE'Aquiaquantidade%',quantidade;Aquantidadeaqui30
quantidade:=50;

Criarumsubbloco

DECLARE
quantidadeinteger:=80;
BEGIN
RAISENOTICE'Aquiaquantidade%',quantidade;Aquantidadeaqui80
END;
RAISENOTICE'Aquiaquantidade%',quantidade;Aquantidadeaqui50
RETURNquantidade;
END;
$$LANGUAGEplpgsql;
=>SELECTfunc_escopo();
CREATEFUNCTIONinstr(varchar,integer)RETURNSintegerAS$$
DECLARE
v_stringALIASFOR$1;
indexALIASFOR$2;

BEGIN
algumprocessamentonesteponto
END;
$$LANGUAGEplpgsql;

70

CREATEFUNCTIONconcatenar_campos_selecionados(in_tnome_da_tabela)RETURNS
textAS$$
BEGIN
RETURNin_t.f1||in_t.f3||in_t.f5||in_t.f7;
END;
$$LANGUAGEplpgsql;
CREATEFUNCTIONsomar_tres_valores(v1anyelement,v2anyelement,v3anyelement)
RETURNSanyelementAS$$
DECLARE
resultadoALIASFOR$0;
BEGIN
resultado:=v1+v2+v3;
RETURNresultado;
END;
$$LANGUAGEplpgsql;
SELECTsomar_tres_valores(10,20,30);
Utilizaodetipocomposto:
CREATEFUNCTIONmesclar_campos(t_linhanome_da_tabela)RETURNStextAS$$
DECLARE
t2_linhanome_tabela2%ROWTYPE;
BEGIN
SELECT*INTOt2_linhaFROMnome_tabela2WHERE...;
RETURNt_linha.f1||t2_linha.f3||t_linha.f5||t2_linha.f7;
END;
$$LANGUAGEplpgsql;
SELECTmesclar_campos(t.*)FROMnome_da_tabelatWHERE...;
Temosumatabela(datas)comdoiscampos(dataehora)equeremosusarumafunopara
manipularosdadosdestatabela:
CREATEorREPLACEFUNCTIONdata_ctl(opcaochar,fdatadate,fhoratime)RETURNS
char(10)AS'
DECLARE
opcaoALIASFOR$1;
vdataALIASFOR$2;
vhoraALIASFOR$3;
retornochar(10);
BEGIN

IFopcao=''I''THEN
insertintodatas(data,hora)values(vdata,vhora);
retorno:=''INSERT'';
ENDIF;
IFopcao=''U''THEN
updatedatassetdata=vdata,hora=vhorawheredata=''19951101'';
retorno:=''UPDATE'';
ENDIF;
IFopcao=''D''THEN
deletefromdataswheredata=vdata;
retorno:=''DELETE'';
ELSE
retorno:=''NENHUMA'';
ENDIF;
RETURNretorno;
END;
'LANGUAGEplpgsql;
//selectdata_ctl('I','19961101','08:15');
selectdata_ctl('U','19971101','06:36');
selectdata_ctl('U','19971101','06:36');
MaisDetalhesnocaptulo35domanualoficial.

71

FunesqueRetornamConjuntosdeRegistros(SETS)
CREATEORREPLACEFUNCTIONcodigo_empregado(codigoINTEGER)
RETURNSSETOFINTEGERAS'
DECLARE
registroRECORD;
retvalINTEGER;
BEGIN
FORregistroINSELECT*FROMempregadosWHEREsalario>=$1LOOP
RETURNNEXTregistro.departamento_cod;
ENDLOOP;
RETURN;
END;
'language'plpgsql';
select*fromcodigo_empregado(0);
selectcount(*),gfromcodigo_empregado(5000)ggroupbyg;
FunesqueretornamRegistro
Paracriarfunesemplpgsqlqueretornemumregistro,antesprecisamoscriarumavarivel
compostadotipoROWTYPE,descrevendooregistro(tupla)desada
dafuno.
CREATETABLEempregados(
nome_emptext,
salarioint4,

72
codigoint4NOTNULL,
departamento_codint4,
CONSTRAINTempregados_pkeyPRIMARYKEY(codigo),
CONSTRAINTempregados_departamento_cod_fkeyFOREIGNKEY(departamento_cod)
REFERENCESdepartamentos(codigo)MATCHSIMPLE
ONUPDATENOACTIONONDELETENOACTION
)
CREATETABLEdepartamentos(codigoINTprimarykey,nomevarchar);
CREATETYPEdept_mediaAS(minsalINT,maxsalINT,medsalINT);
createorreplacefunctionmedia_dept()returnsdept_mediaas
'
declare
rdept_media%rowtype;
deptrecord;
bucketint8;
counterint;
begin
bucket:=0;
counter:=0;
r.maxsal:=0;
r.minsal:=0;
fordeptinselectsum(salario)assalario,d.codigoasdepartamento
fromempregadose,departamentosdwheree.departamento_cod=d.codigo
groupbydepartamentoloop
counter:=counter+1;
bucket:=bucket+dept.salario;
ifr.maxsal<=dept.salarioorr.maxsal=0then
r.maxsal:=dept.salario;
endif;
ifr.minsal<=dept.salarioorr.minsal=0then
r.minsal:=dept.salario;
endif;
endloop;
r.medsal:=bucket/counter;
returnr;

end
'language'plpgsql';
FunesqueRetornamConjuntodeRegistros(SETOF,ResultSet)
Tambmrequeremacriaodeumavarivel(tipodefinidopelouser)
CREATETYPEmedia_salAS

(deptcodint,minsalint,maxsalint,medsalint);
CREATEORREPLACEFUNCTIONmedsal()RETURNSSETOFmedia_salAS
'
DECLARE
smedia_sal%ROWTYPE;
salrecRECORD;
bucketint;
counterint;
BEGIN
bucket:=0;
counter:=0;
s.maxsal:=0;
s.minsal:=0;
s.deptcod:=0;
FORsalrecINSELECTsalarioASsalario,d.codigoASdepartamento
FROMempregadose,departamentosdWHEREe.departamento_cod=
d.codigoORDERBYd.codigoLOOP
IFs.deptcod=0THEN
s.deptcod:=salrec.departamento;
s.minsal:=salrec.salario;
s.maxsal:=salrec.salario;
counter:=counter+1;
bucket:=bucket+salrec.salario;
ELSE
IFs.deptcod=salrec.departamentoTHEN
IFs.maxsal<=salrec.salarioTHEN
s.maxsal:=salrec.salario;
ENDIF;
IFs.minsal>=salrec.salarioTHEN
s.minsal:=salrec.salario;
ENDIF;
counter:=counter+1;
ELSE
s.medsal:=bucket/counter;
RETURNNEXTs;
s.deptcod:=salrec.departamento;
s.minsal:=salrec.salario;
s.maxsal:=salrec.salario;
counter:=1;
bucket:=salrec.salario;
ENDIF;
ENDIF;
ENDLOOP;

s.medsal:=bucket/counter;
RETURNNEXTs;
RETURN;
END'

73

LANGUAGE'plpgsql';

74

select*frommedsal()
Relacionando:
selectd.nome,a.minsal,a.maxsal,a.medsal
frommedsal()a,departamentosd
whered.codigo=a.deptcod
6.3Triggers(Gatilhos)
Captulo32domanualoficial.e:
http://pgdocptbr.sourceforge.net/pg80/sqlcreatetrigger.html
AtaversoatualnoexistecomocriarfunesdegatilhonalinguagemSQL.
Umafunodegatilhopodesercriadaparaexecutarantes(BEFORE)ouaps(AFTER)as
consultasINSERT,UPDATEOUDELETE,umavezparacadaregistro(linha)modificadoou
porinstruoSQL.Logoqueocorreumdesseseventosdogatilhoafunodogatilho
disparadaautomaticamenteparatrataroevento.
Afunodegatilhodeveserdeclaradacomoumafunoquenorecebeargumentoseque
retornaotipoTRIGGER.
Apscriarafunodegatilho,estabelecemosogatilhopelocomandoCREATETRIGGER.
Umafunodegatilhopodeserutilizadaporvriosgatilhos.
AsfunesdegatilhochamadasporgatilhosporinstruodevemsempreretornarNULL.
Asfunesdegatilhochamadasporgatilhosporlinhapodemretornarumalinhadatabela
(umvalordotipoHeapTuple)paraoexecutordachamada,seassimodecidirem.
Sintaxe:
CREATETRIGGERnome{BEFORE|AFTER}{evento[OR...]}
ONtabela[FOR[EACH]{ROW|STATEMENT}]
EXECUTEPROCEDUREnome_da_funo(argumentos)
Ogatilhoficaassociadotabelaespecificadaeexecutaafunoespecificada
nome_da_funoquandodeterminadoseventosocorrerem.
Ogatilhopodeserespecificadoparadispararantesdetentarrealizaraoperaonalinha
(antesdasrestriesseremverificadaseocomandoINSERT,UPDATEouDELETEser
tentado),ouapsaoperaoestarcompleta(apsasrestriesseremverificadaseo
INSERT,UPDATEouDELETEtercompletado).
evento
UmentreINSERT,UPDATEouDELETE;especificaoeventoquedisparaogatilho.Vrios
eventospodemserespecificadosutilizandoOR.

Exemplos:
CREATETABLEempregados(
codigoint4NOTNULL,
nomevarchar,
salarioint4,
departamento_codint4,
ultima_datatimestamp,
ultimo_usuariovarchar(50),
CONSTRAINTempregados_pkeyPRIMARYKEY(codigo))

75

CREATEFUNCTIONempregados_gatilho()RETURNStriggerAS$empregados_gatilho$
BEGIN
Verificarsefoifornecidoonomeeosalriodoempregado
IFNEW.nomeISNULLTHEN
RAISEEXCEPTION'Onomedoempregadonopodesernulo';
ENDIF;
IFNEW.salarioISNULLTHEN
RAISEEXCEPTION'%nopodeterumsalrionulo',NEW.nome;
ENDIF;
Quempagaparatrabalhar?
IFNEW.salario<0THEN
RAISEEXCEPTION'%nopodeterumsalrionegativo',NEW.nome;
ENDIF;
Registrarquemalterouafolhadepagamentoequando
NEW.ultima_data:='now';
NEW.ultimo_usuario:=current_user;
RETURNNEW;
END;
$empregados_gatilho$LANGUAGEplpgsql;
CREATETRIGGERempregados_gatilhoBEFOREINSERTORUPDATEONempregados
FOREACHROWEXECUTEPROCEDUREempregados_gatilho();
INSERTINTOempregados(codigo,nome,salario)VALUES(5,'Joo',1000);
INSERTINTOempregados(codigo,nome,salario)VALUES(6,'Jos',1500);
INSERTINTOempregados(codigo,nome,salario)VALUES(7,'Maria',2500);
SELECT*FROMempregados;
INSERTINTOempregados(codigo,nome,salario)VALUES(5,NULL,1000);
NEWParaINSERTeUPDATE
OLDParaDELETE
CREATETABLEempregados(
nomevarcharNOTNULL,

salariointeger
);
CREATETABLEempregados_audit(
operacaochar(1)NOTNULL,
usuariovarcharNOTNULL,
datatimestampNOTNULL,
nomevarcharNOTNULL,
salariointeger
);
CREATEORREPLACEFUNCTIONprocessa_emp_audit()RETURNSTRIGGERAS
$emp_audit$
BEGIN

Criaumalinhanatabelaemp_auditpararefletiraoperao
realizadanatabelaemp.UtilizaavarivelespecialTG_OP
paradescobriraoperaosendorealizada.

IF(TG_OP='DELETE')THEN
INSERTINTOemp_auditSELECT'E',user,now(),OLD.*;
RETURNOLD;
ELSIF(TG_OP='UPDATE')THEN
INSERTINTOemp_auditSELECT'A',user,now(),NEW.*;
RETURNNEW;
ELSIF(TG_OP='INSERT')THEN
INSERTINTOemp_auditSELECT'I',user,now(),NEW.*;
RETURNNEW;
ENDIF;
RETURNNULL;oresultadoignoradoumavezqueesteumgatilhoAFTER
END;
$emp_audit$languageplpgsql;
CREATETRIGGERemp_audit
AFTERINSERTORUPDATEORDELETEONempregados
FOREACHROWEXECUTEPROCEDUREprocessa_emp_audit();
INSERTINTOempregados(nome,salario)VALUES('Joo',1000);
INSERTINTOempregados(nome,salario)VALUES('Jos',1500);
INSERTINTOempregados(nome,salario)VALUES('Maria',250);
UPDATEempregadosSETsalario=2500WHEREnome='Maria';
DELETEFROMempregadosWHEREnome='Joo';
SELECT*FROMempregados;
SELECT*FROMempregados_audit;
Outroexemplo:

76

CREATETABLEempregados(
codigoserialPRIMARYKEY,
nomevarcharNOTNULL,
salariointeger
);
CREATETABLEempregados_audit(
usuariovarcharNOTNULL,
datatimestampNOTNULL,
idintegerNOTNULL,
colunatextNOTNULL,
valor_antigotextNOTNULL,
valor_novotextNOTNULL
);
CREATEORREPLACEFUNCTIONprocessa_emp_audit()RETURNSTRIGGERAS
$emp_audit$
BEGIN

Nopermitiratualizarachaveprimria

IF(NEW.codigo<>OLD.codigo)THEN
RAISEEXCEPTION'Nopermitidoatualizarocampocodigo';
ENDIF;

Inserirlinhasnatabelaemp_auditpararefletirasalteraes
realizadanatabelaemp.

IF(NEW.nome<>OLD.nome)THEN
INSERTINTOemp_auditSELECTcurrent_user,current_timestamp,
NEW.id,'nome',OLD.nome,NEW.nome;
ENDIF;
IF(NEW.salario<>OLD.salario)THEN
INSERTINTOemp_auditSELECTcurrent_user,current_timestamp,
NEW.codigo,'salario',OLD.salario,NEW.salario;
ENDIF;
RETURNNULL;oresultadoignoradoumavezqueesteumgatilhoAFTER
END;
$emp_audit$languageplpgsql;
CREATETRIGGERemp_audit
AFTERUPDATEONempregados
FOREACHROWEXECUTEPROCEDUREprocessa_emp_audit();
INSERTINTOempregados(nome,salario)VALUES('Joo',1000);
INSERTINTOempregados(nome,salario)VALUES('Jos',1500);
INSERTINTOempregados(nome,salario)VALUES('Maria',2500);
UPDATEempregadosSETsalario=2500WHEREid=2;

77

UPDATEempregadosSETnome='MariaCeclia'WHEREid=3;
UPDATEempregadosSETcodigo=100WHEREcodigo=1;
ERRO:Nopermitidoatualizarocampocodigo
SELECT*FROMempregados;

78

SELECT*FROMempregados_audit;
Crieamesmafunoqueinsiraonomedaempresaeonomedoclienteretornandooidde
ambos
createorreplacefunctionempresa_cliente_id(varchar,varchar)returns_int4as
'
declare
nempresaaliasfor$1;
nclientealiasfor$2;
empresaidinteger;
clienteidinteger;
begin
insertintoempresas(nome)values(nempresa);
insertintoclientes(fkempresa,nome)values(currval(''empresas_id_seq''),ncliente);
empresaid:=currval(''empresas_id_seq'');
clienteid:=currval(''clientes_id_seq'');
return''{''||empresaid||'',''||clienteid||''}'';

end;
'
language'plpgsql';

Crieumafunoondepassamoscomoparmetrooiddoclienteesejaretornadoo
seunome
createorreplacefunctionid_nome_cliente(integer)returnstextas
'
declare
rrecord;
begin
selectintor*fromclienteswhereid=$1;
ifnotfoundthen
raiseexception''Clientenoexistente!'';
endif;
returnr.nome;
end;
'
language'plpgsql';
Crieumafunoqueretorneosnomedetodaatabelaclientesconcatenadosemums
campo

createorreplacefunctionclientes_nomes()returnstextas
'
declare
xtext;
rrecord;
begin
x:=''Inicio'';
forrinselect*fromclientesorderbyidloop
x:=x||'':''||r.nome;
endloop;
returnx||'':fim'';
end;
'
language'plpgsql';

79

7DCL(DataControlLanguage)

80

DCLformadoporumgrupodecomandosSQL,responsveispelaadministraodos
usurios,dosgruposedaspermisses.
7.1Usurios,gruposeprivilgios
Deforadopsql(noprompt)utilizasecomandossemespao:createdb,dropdb,etc.
Dedentrodopsqloscomandossoformadosporduaspalavras:
CREATEDATABASE,DROPDATABASE,etc(sintaxeSQL).
Dedentrodobanco:
CREATEUSERagoraumaliasparaCREATEROLE,quetemmaisrecursos.
banco=#\hcreaterole
Comando:CREATEROLE
Descrio:defineumnovopapel(role)dobancodedados
Sintaxe:
CREATEROLEnome[[WITH]opo[...]]
ondeopopodeser:
SUPERUSER|NOSUPERUSER
|CREATEDB|NOCREATEDB
|CREATEROLE|NOCREATEROLE
|CREATEUSER|NOCREATEUSER
|INHERIT|NOINHERIT
|LOGIN|NOLOGIN
|CONNECTIONLIMITlimite_con
|[ENCRYPTED|UNENCRYPTED]PASSWORD'senha'
|VALIDUNTIL'tempo_absoluto'
|INROLEnome_role[,...]
|INGROUPnome_role[,...]
|ROLEnome_role[,...]
|ADMINnome_role[,...]
|USERnome_role[,...]
|SYSIDuid
CasonosejafornecidoENCRYPTEDouUNENCRYPTEDentoserusadoovalordo
parmetropassword_encryption(postgresql.conf).
CriarUsurio
CREATEROLEnomeusuario;
NasversesanterioresusavaseoparmetroCREATEUSERparaindicaracriaodeum
superusurio,agorausaseoparmetromaisadequadoSUPERUSER.
Parapodercriarumnovousuriolocal,comsenha,devemossetaranteso

pg_hba.conf:
local allall127.0.0.1/32password
Comentarasoutrasentradasparaconexolocal.
Issoparausuriolocal(conexoviasocketUNIX).
Criamosassim:
CREATEROLEnomeuserWITHENCRYPTEDPASSWORD'********';
Aoselogar:psqlUnomeusernomebanco.
CREATEROLEnomeusuarioVALIDUNTIL'data'
ExcluindoUsurio
DROPUSERnomeusuario;
Comousurio,foradobanco:
CriarUsurio
CREATEROLEnomeusuario;
ExcluindoUsurio
DROPUSERnomeusuario;
Detalhe:semespaos.
CriandoSuperusurio
CREATEROLEnomeuserWITHSUPERUSERENCRYPTEDPASSWORD'******';
usuriocompoderesdesuperusurio
AlterarContadeUsurio
ALTERROLEnomeuserENCRYPTEDPASSWORD'******'CREATEUSER
permissodecriarusurios
ALTERROLEnomeuserVALIDUNTIL'12/05/2006';
ALTERROLEfredVALIDUNTILinfinity;
ALTERROLEmiriamCREATEROLECREATEDB;poderesparacriarbancos
Obs.:LembrandoqueALTERROLEumaextensodoPostgreSQL.
Listandotodososusurios:
SELECTusenameFROMpg_user;
Atabelapg_userumatabeladesistema(_pg)queguardatodososusuriosdo
PostgreSQL.
Tambmpodemosutilizar:
\duou\dg
CriandoUmGrupodeusurios
CREATEGROUPnomedogrupo;
Adicionar/RemoverUsuriosdeumGrupo
ALTERGROUPnomegrupoADDUSERuser1,user2,user3;

81

ALTERGROUPnomegrupoDROPUSERuser1,user2;
ExcluindoGrupo
DROPGROUPnomegrupo;
Obs.:issoremovesomenteogrupo,noremoveosusurios.

82

Listandotodososgrupos:
SELECTgronameFROMpg_group;

83

Privilgios
DandoPrivilgiosAUmUsurio
GRANTUPDATEONnometabelaTOnomeusuario;
DandoPrivilgiosAUmGrupoInteiro
GRANTSELECTONnometabelaTOnomegrupo;
RemovendoTodososPrivilgiosdeTodososUsers
REVOKEALLONnometabelaFROMPUBLIC
Privilgios
Osuperusuriotemdireitoafazeroquebementenderemqualquerbancodedadosdo
SGBD.
Ousurioquecriaumobjeto(banco,tabela,view,etc)odonodoobjeto.
Paraqueoutrousuriotenhaacessoaomesmodevereceberprivilgios.
Existemvriosprivilgiosdiferentes:SELECT,INSERT,UPDATE,DELETE,RULE,
REFERENCES,TRIGGER,CREATE,TEMPORARY,EXECUTEeUSAGE.
Osprivilgiosaplicveisaumdeterminadotipodeobjetovariamdeacordocomotipodo
objeto(tabela,funo,etc.).
OcomandoparaconcederprivilgiosoGRANT.OderemoveroREVOKE.
GRANTUPDATEONcontasTOjoel;
Dajoeloprivilgiodeexecutarconsultasupdatenoobjetocontas.
GRANTSELECTONcontasTOGROUPcontabilidade;
REVOKEALLONcontasFROMPUBLIC;
Osprivilgiosespeciaisdodonodatabela(ouseja,osdireitosdeDROP,GRANT,REVOKE,
etc.)sosempreinerentescondiodeserodono,nopodendoserconcedidosou
revogados.Porm,odonodoobjetopodedecidirrevogarseusprpriosprivilgioscomuns
como,porexemplo,tornaratabelasomenteparaleituraparaoprprio,assimcomoparaos
outros.
Normalmente,sodonodoobjeto(ouumsuperusurio)podeconcederourevogar
privilgiosparaumobjeto.
Criaodosgrupos
CREATEGROUPadm;
CREATEUSERpauloENCRYPTEDPASSWORD'paulo'CREATEDBCREATEUSER;
CriaodosUsuriosdoGrupoadm

84
CREATEUSERandreENCRYPTEDPASSWORD'andre'CREATEDBINGROUPadm;
CREATEUSERmichelaENCRYPTEDPASSWORD'michela'CREATEDBINGROUPadm;
Ousuriodesistema(superusurio)deveserumusuriocriadoexclusivamenteparao
PostgreSQL.Nuncadevemostornlodonodenenhumexecutvel.
Osnomesdeusuriossoglobaisparatodooagrupamentodebancosdedados,ouseja,
podemosutilizarumusuriocomqualquerdosbancos.
OsprivilgiosDROP,GRANT,REVOKE,etcpertencemaodonodoobjetonopodendoser
concedidosourevogados.Omximoqueumdonopodefazerabdicardeseusprivilgiose
comissoningummaisteriaosmesmoseoobjetoseriasomenteleituraparatodos.
Exemplo:parapermitiraumusurioapenasosprivilgiosdeINSERT,UPDATEeSELECTe
nopermitirodeDELETEemumatabela,use:
REVOKEALLONtabelaFROMusuario;
GRANTSELECT,UPDATE,INSERTONtabelaTOusuario;

Maisdetalhes:
http://pgdocptbr.sourceforge.net/pg80/usermanag.html
http://pgdocptbr.sourceforge.net/pg80/sqlrevoke.html
http://pgdocptbr.sourceforge.net/pg80/sqlgrant.html

8Transaesarealizaodeumconjuntodecomandosdeumasvez.

85

Umatransaoaconteceporcompleto(todasasoperaes)ounadaacontece.
Tambmatransaodevegarantirumnveldeisolamentodasdemaistransaes,de
maneiraqueasdemaistransaessomenteenxerguemasoperaesapsatransao
concluda.
CasohajaumerroqualquernatransaooufalhanosistemaoSGBRirexecutarum
comandoROLLBACK.
Transaessoumaformadedarsuportesoperaesconcorrentes,garantindoa
seguranaeintegridadedasinformaes.
Garantirqueduassolicitaesdiferentesnoefetuaroumamesmaoperaoaomesmo
tempo.
Aoconsultarobancodedados,umatransaoenxergaumsnapshot(instantneo)dos
dados,comoesteseramnoexatomomentoemqueaconsultafoisolicitada,desprezandoas
mudanasocorridasdepoisdisso.
OPostgreSQLtrataaexecuodequalquercomandoSQLcomosendoexecutadodentrode
umatransao.
Naverso8apareceramosSAVEPOINTS(pontosdesalvamento),queguardamas
informaesateles.IssosalvaasoperaesexistentesantesdoSAVEPOINTebastaum
ROLLBACKTOparacontinuarcomasdemaisoperaes.
OPostgreSQLmantmaconsistnciadosdadosutilizandoomodelomultiversoMVCC
(MultiversionConcurrencyControl),quepermitequeleituranobloqueieescritanemescrita
bloqueieleitura.
OPostgreSQLtambmcontacomumnveldeisolamentochamadoserializable(serializvel),
quemaisrigorosoeemulaexecuoserialdastransaes.
BEGIN;
UPDATEcontasSETsaldo=saldo100.00WHEREcodigo=5;
SAVEPOINTmeu_ponto_de_salvamento;
UPDATEcontasSETsaldo=saldo+100.00WHEREcodigo=5;
ops...ocertonaconta6
ROLLBACKTOmeu_ponto_de_salvamento;
UPDATEcontasSETsaldo=saldo+100.00WHEREconta=6;
COMMIT;
Exemplos:
CREATETABLEcontas(codigoINT2PRIMARYKEY,nomeVARCHAR(40),saldo
NUMERIC());
INSERTINTOcontasvalues(5,'Ribamar',500.45);

86
Umatransaoditaumprocessoatmico,oquesignificaqueouacontecemtodasassuas
operaesouentonenhumasersalva.
Vamosiniciaraseguintetransaonatabelaacima:
BEGIN;Iniciarumatransao
UPDATEcontasSETsaldo=800.35WHEREcodigo=5;
SELECTnome,saldoFROMcontasWHEREcodigo=5;
COMMIT;Executartodososcomandosdatransao
Agoraparatestarsedefatotodasasoperaesforamsalvasexecute:
SELECTnome,saldoFROMcontasWHEREcodigo=5;
Vamosaoutrotestedaatomicidadedastransaes.Intencionalmentevamoscometerum
erronoSELECT(FRON)(ComN,quandodeveriasercomM):
BEGIN;Iniciarumatransao
UPDATEcontasSETsaldo=50.85WHEREcodigo=5;
SELECTnome,saldoFRONcontasWHEREcodigo=5;
COMMIT;Executartodososcomandosdatransao
IssocausarumerroeocomandoROLLBACKserautomaticamenteexecutado,oque
garantequenenhumadasoperaesserrealizada.
Entoexecuteaconsultaparatestarsehouveaatualizao:
SELECTnome,saldoFRONcontasWHEREcodigo=5;
RemoverCampo(versesanterioresa7.3nocontamcomesserecurso):
BEGIN;
LOCKTABLEnometabela;
INTOTABLEnomenovoFROMnometabela;
DROPTABLEnometabela;
ALTERTABLEnomenovoRENAMETOnometabela;
COMMIT;
AlterarTiposdeDados(versesantigas):
BEGIN;
ALTERTABLEtabelaADDCOLUMNnovocamponovotipodados;
UPDATEtabelaSETnovocampo=CAST(antigocamponovotipodados);
ALTERTABLEtabelaDROPCOLUMNantigocampo;
COMMIT;
TransaesquenoseConcretizam
BEGIN;Iniciarumatransao

UPDATEcontasSETsaldo=50.85WHEREcodigo=5;
SELECTnome,saldoFRONcontasWHEREcodigo=5;
ROLLBACK;Cancelandotodososcomandosdatransao

87

BEGIN;
CREATETABLEteste(idinteger,nometext);
INSERTINTOtesteVALUES(1,'Teste1');
INSERTINTOtesteVALUES(2,'Teste2');
DELETEFROMteste;
COMMIT;
BEGIN;
CREATETABLEteste(idinteger,nometext);
INSERTINTOtesteVALUES(3,'Teste3');
INSERTINTOtesteVALUES(4,'Teste4');
DELETEFROMteste;
ROLLBACK;
Detalhessobreconflitosdebloqueios:
http://www.postgresql.org/docs/current/static/explicitlocking.html

IsolamentodeTransaes
OnveldeisolamentopadrodoPostgreSQLoReadCommitted(leituraefetivada).Uma
consultaSELECTrealizadacomestenvelperceberosregistrosexistentenoincioda
consulta.Esteonvelmaisflexvel.
Existetambmonvelserializable,maisrigoroso.OsnveisReaduncommittedeRepeatable
readsosuportados,masassumemaformadeumdosdoisanteriores.
SetandooNveldeIsolamentodeumatransao:
banco=#\hsettransaction
Comando:SETTRANSACTION
Descrio:defineascaractersticasdatransaoatual
Sintaxe:
SETTRANSACTIONmodo_transao[,...]
SETSESSIONCHARACTERISTICSASTRANSACTIONmodo_transao[,...]
ondemodo_transaoumdos:
ISOLATIONLEVEL{SERIALIZABLE|REPEATABLEREAD|READCOMMITTED|READ
UNCOMMITTED}
READWRITE|READONLY
Exemplo:
BEGIN;
SETTRANSACTIONISOLATIONLEVELSERIALIZABLE;

Aquiasconsultasdatransao;
...
COMMIT;
ControledeSimultaneidadenoCaptulo12domanualoficial.

88

9Administrao

89

ComumaboamanutenooadministradormelhoraodesempenhodoSGBD,garantea
integridadedosdados,asuaseguranaeosprpriosdados.
9.1BackupeRestore
EspecialmentequemjteveproblemasemHDsenopoderecuperarosdados,sabeda
importnciadosbackups.
Paraefetuarbackuperestoreutilizamosocomandopg_dumpemconjuntocomopsql.
Obs.:Opg_dumpnofazbackupdeobjetosgrandes(lo)pordefault.Casodesejemos
tambmestesobjetosnobackupdevemosutilizarumasadanoformatotareutilizaraopo
b.
pg_dumpFtbbanco>banco.tar
Backuplocaldeumnicobanco:
pg_dumpUusuariodbanco>banco.sql
pg_dumpFtbanco>banco.tar
Oscriptnormalmentelevaaextenso.sql,porconveno,maspodeserqualquerextensoe
oscripttercontedotextopuro.
Restoredeumbancolocal:
psqlUusuariodbanco<banco.sql
pg_restoredbancobanco.sql
pg_restoredbancobanco.tar
Obs.:Cuidadoaorestaurarumbanco,especialmenteseexistiremtabelassemintegridade.
Correseoriscodeduplicarosregistros.
Descompactarefazerorestoreemumscomando:
gunzipcbackup.tar.gz|pg_restoredbanco
ou
catbackup.tar.gz|gunzip|pg_restoredbanco
(ocatenviaumstreamdoarquivoparaogunzipquepassaparaopg_restore)
Backuplocaldeapenasumatabeladeumbanco:
pg_dumpUnomeusuariodnomebancotnometabela>nomescript
Restaurarapenasumatabela
Paraconseguirrestaurarapenasumatabelaumaformagerarodumpdotipocomtar:
pg_dumpFtbancofarquivo.sql.tar
pg_restoredbancottabelabanco.sql.tar

90
Backuplocaldetodososbancos:
pg_dumpallUnomeusuariodnomebanco>nomescript
Backupremotodeumbanco:
pg_dumphhostremotodnomebanco|psqlhhostlocaldbanco
Backupemmultivolumes(volumesde200MB):
pg_dumpnomebanco|splitm200nomearquivo
mpara1Mega,kpara1K,bpara512bytes
ImportandobackupdeversoanteriordoPostgreSQL
Instalaseanovaversocomportadiferente(ex.:5433)econectarambos
pg_dumpallp5432|psqldtemplate1p5433
VisualizarcomandoatualePIDdetodososprocessosdoservidor:
SELECTpg_stat_get_backend_pid(s.backendid)ASprocpid,
pg_stat_get_backend_activity(s.backendid)AScurrent_query
FROM(SELECTpg_stat_get_backend_idset()ASbackendid)ASs;
DeterminaodautilizaoemdiscopelasTabelas
TendoumbancocomcadastrodeCEPseapenasumatabelacep_tabela,mostrarousodo
discoporestatabela.Precisamosfiltrarastabelasdesistema,veja:
VACUUMANALYZE;
OutilitrioVACUUMrecuperaespaoemdiscoocupadopelosregistrosexcludose
atualizados,atualizaosdadosparaasestatsticasusadaspeloplanejadordeconsultase
tambmprotegecontraperdadedadosquandoatingirumbilhodetransaes.
SELECTrelname,relfilenode,relpagesFROMpg_classWHERErelnameLIKE'cep_%'
ORDERBYrelname;
relname|relfilenode|relpages
++
cep_pk|25140|2441
cep_tabela|16949|27540
Odaemondoautovacuum
Iniciandonaverso8.1umprocessoopcionaldoservidor,chamadodeautovacuum
daemon,cujousoparaautomatizaraexecuodoscomandosVACUUMeANALYZE.
Rodaperiodicamenteechecaousoembaixonveldocoletordeestatsticas.
Nopodeserusadoenquantostats_start_collectorestats_row_levelforemalteradospara
true.Portantoopostgresql.confdeveficarassim:
stats_start_collector=on
stats_row_level=on
autovacuum=on

91
Pordefaultserexecutadoacasa60segundos.Paraalterardescomenteemudealinha:
#autovacuum_naptime=60
Paraumatabela
VACUUMANALYZEtabela;

Paratodoumbanco
\c
VACUUMFULLANALYZE;

92

Determinarousododiscoportabela
SELECTrelfinenode,relpagesFROMpg_classWHERErelname='nometabela'
Cadapginausa8kb.
Tamanhodendices
SELECTc2.relname,c2.relpages
FROMpg_classc,pg_classc2,pg_indexi
WHEREc.relname='customer'
ANDc.oid=i.indrelid
ANDc2.oid=i.indexrelid
ORDERBYc2.relname;
Encontrarasmaiorestabelasendices
SELECTrelname,relpagesFROMpg_classORDERBYrelpagesDESC;
Vejaquenoresultadotambmapareceatabeladendices,ecomusosignificativo.
FerramentasContrib
pgbenchtestadesempenhodoSGBD.
dbsizemostraotamanhodetabelasebancos
oid2nameretornaOIDs,fileinodeenomesdetabelas
D:\ARQUIV~1\POSTGR~1\8.1\bin>oid2nameUpostgresP********
Alldatabases:
OidDatabaseNameTablespace

33375bdcluster
ncluster
16948cep_brasil
pg_default
25146cep_full
pg_default
33360controle_estoquepg_default
16879municipios
pg_default
33340pgbench pg_default
10793postgres pg_default
10792template0
pg_default
33377template1
pg_default
16898testes
pg_default
NoREADMEdestacontribexisteumaboasugestoparaencontrarotamanhoaproximados
dosdadosdecadaobjetointernodoPostgreSQLcom:

SELECTrelpages,relfilenode,relnameFROMpg_classORDERBYrelpagesDESC;

93

Cadapginatemtipicamente8KBeorelpagesatualizadopelocomandoVACUUM.
BackupAutomticodeBancosnoWindowscomoAgendadordeTarefas
Criaodoscriptbackuppg.bat:
remAdaptaodeRibamarFSdooriginaldeIvlisonSouzaparaalistaPostgreSQLBrasil
@echooff
rem(NomedoUsuriodobancopararealizarobackup)
REMDadosqueprecisaalterar:
REMPGUSER
REMPGPASSWORD
REMnomepastadebackup
REMnomepastadeinstalaodoPostgreSQLsediferentedeC:\Arquivosde
programas\PostgreSQL\8.1\
REM
REM(NomedousuriodoPostgreSQLqueexecutaroscript)
SETPGUSER=postgres
rem(Senhadousurioacima)
SETPGPASSWORD=******
rem(Indoparaaraizdodisco)
C:
rem(Selecionandoapastaondeserrealizadaobackup)
chdirC:\backup
rem(banco.sqlonomequedefiniparaomeubackup
rem(Deletandoobackupexistente)
delbanco*.sql
echo"Aguarde,realizandoobackupdoBancodeDados"
remC:\Arquiv~1\Postgr~1\8.1\bin\pg_dumpiUpostgresbof"C:\backup\banco.sql"
condominio
remObservao:Casoqueiracolocaronomedobackupseguindodeumadatasusar:
for/f"tokens=1,2,3,4delims=/"%%ain('DATE/T')dosetDate=%%b%%c%%d
remOcomandoacimaserveparaarmazenaradatanoformatodiamesanonavarivel
Date;
C:\Arquiv~1\Postgr~1\8.1\bin\pg_dumpiUpostgresbof"C:\backup\banco%Date%.sql"
condominio
rem(sairdateladepoisdobackup)

exit

94

ConfiguraodoAgendadordeTarefasparaexecutaroscriptdiariamente:
IniciarProgramasAcessriosFerramentasdeSistemaTarefasagendadas
Adicionartarefaagendada
Avanar
Cliqueemprocurareindiqueobackuppg.bat
Emexecutarestatarefaescolhacomoacharmaisadequado(diariamente)ecliqueem
Avanar
CliqueemAvanareOK.Naprximatelamarque"Executarsomenteseconectado".
EntocliqueemConcluir
Noprximobootobackupserefetuadoacadadia.
UmbomartigosobrebackuperestauraonoPostgreSQLencontrasenositeoficial
doPostgreSQLdoBrasil:https://wiki.postgresql.org.br/wiki/BackupAndRestore
Vejatambmadocumentaoemingls:
http://www.postgresql.org/docs/8.1/static/apppgrestore.html
http://www.postgresql.org/docs/8.1/static/apppgdump.html
http://www.postgresql.org/docs/8.1/static/apppgdumpall.html

9.2ImportareExportar
Estandonaconsoleeusandopg_dumpallepsql:
Efetuandobackup:
pg_dumpall>bancos.sqlParapreservarosOIDsuseaopoonopg_dumpall.
Restoredeseusdados:
psqldpostgresfbancos.sql
Paraimportarscriptsgeradosviapg_dumpdedentrodopsqldevemosutilizarocomando
\i/path/script.sql
\i./script.sql Tambmparaowindowscomoarquivonodiretrioatual
Paraimportararquivostextocomdelimitadores,tipoTXT,CSVoubinriosutilizamosos
comandosdobanco(psql),comousuriodobanco:
Importando:
\COPYtabelaFROMscript.csv

\COPYpaisesFROM'paises.csv';

95

Exportando:
CREATETEMPTABLEpaisesASSELECT*FROMtesteWHEREnomeLIKE'%tina%';
\COPYpaisesTO'/usr/teste.copy';
ComDelimitadores
\COPYtabelaFROM'/arquivo.csv'DELIMITERS'|';
\COPYtabelaTO'/arquivo.txt'DELIMITERS'|';
Obs.:Oarquivoteste.copydeveterpermissodeescritaparaouserdobanco.
ImportarumaplanilhadoExceloudoCalcdoOpenOfficeparaumatabela:
GerandoumarquivoCSVnoOpenOfficeCalc
Abrircalceselecionarecopiarareaaimportar
Abrirumanovaplanilha
ClicarcomobotodireitosobreaprimeiraclulaeColarEspecial
DesmarqueColartudo,marqueNmeros,desmarqueFrmulaseOK
TecleCtrl+Sparasalvar
EmTipodearquivoescolhaTextoCSV,digiteonomeeSalvar.Confirme
ComoDelimitadordeCampoescolhaTabulao
EmDelimitadordetextodeleteasaspaseOK
Ignoreamensagemdeerro,casoaparea.
ImportaroarquivotextoCSVparaumatabelacomestruturasemelhantedoarquivocsv:
supostgres
psqlnomebanco
\copynometabelafrom/home/nomearquivo.csv
NoWindows
\copynometabelafrom./arquivo.csv
oarquivoestandonopathdousurio
ExportarumBancoAccessparausonoPostgreSQLououtrosbancos
SelecionaratabelaeExportar
- EscolherotipodearquivosTexto(txt,csv,...)
- Emavanado:DelimitadordecamposTabulao
- Qualificadordetextoremover(deixarembranco)
9.3Converter
UmaboaformadeconverterbancosMySQLparabancosPostgreSQLnoWindows
instalandoodriverODBCparaoMySQLeparaoPostgreSQL.
EntocriaseacomunicaocomosdoisbancoseexportaseparaoPostgreSQL.
Existemferramentascomerciaiscommuitosrecursos,comoocasodoEMSDataExporte
ImportforPostgreSQL:http://www.sqlmanager.net/en/products/postgresql/dataexport

96
Veja:exporttoMSExcel,MSWord/RTF,MSAccess,HTML,TXT,CSV,PDF,XMLandSQL.
OutraopoexportarparaCSVdoMySQLeimportarpeloPostgreSQL.
9.4OtimizaoeDesempenho
Paraissoajustasebemopostgresql.conf,utilizaseovacuum,analyzeeexplain.
Lembrandoquenaverso8.1ovacuumnomaisumprogramaseparadoevemembutido
noexecutvel.Mesmoembutidoeleconfigurvelepodemosutilizarounoeseusar,
podemostambmconfigurarsuaperiodicidade.
Umatimafontedeconsulta:
http://www.metatrontech.com/wpapers/mysql2postgresql.pdf
Captulo21domanual:
http://pgdocptbr.sourceforge.net/pg80/maintenance.html
Vacuum:
http://pgdocptbr.sourceforge.net/pg80/sqlvacuum.html
Analyze:
http://pgdocptbr.sourceforge.net/pg80/sqlanalyze.html
VACUUM
OcomandoVacuumtantorecuperaespaoemdisco,quantootimizaodesempenhodo
bancoeprevinecontraperdadedadosmuitoantigosdevidoaorecomeodoIDdas
transaes,portantodeveserutilizadoconstantemente,comotambmatualizaas
estatsticasdosdadosutilizadospeloplanejadordecomandos.Lembrandoquenaverso8.1
jvemembutidonoexecutvel,podendoapenasserconfiguradoparaquesejaexecutado
automaticamente.
Nalinhadecomando:
vacuumdbfazeouvacuumdbfazq.
ANALYZE
OcomandoANALYZEcoletaestatsticassobreocontedodastabelasdobancodedadose
armazenaosresultadosnatabeladosistemapg_statistic.Posteriormente,oplanejadorde
comandosutilizaestasestatsticasparaajudaradeterminaroplanodeexecuomais
eficienteparaoscomandos.Casonoatualizemosestasestatsticascomfreqncia
podemoscomprometerodesempenhodobancodedadosporumaescolhaerradadoplano
decomandos.
NormalmenteoperaesDELETEouUPDATEnoremovemosregistrosautomaticamente.
SomenteapsaexecuodoVACUUMissoacontece.
Recomendao
ParaamaioriadasinstalaesexecutarocomandoVACUUMANALYZEparatodoobanco
dedadosumavezaodiaemhorriodepoucautilizao.Tambmpodemosutilizaro
comando:
vacuumdbfazq.
Quandofoiexcludaamaioriadosregistrosdeumatabelasugereseaexecuodo
comandoVACUUMFULL.Estecomandogeraumfortebloqueionastabelasemque

executado.

97

Emtabelascujocontedoexcludoperiodicamente,comotabelastemporrias,indicadoo
usodocomandoTRUNCATEaoinvsdeDELETE.
Exemplodeusodovacuum.Acesseobancoeexecute:
VACUUMVERBOSEANALYZEnometabela;
Deforadopsqlusarocomandovacuumdbfazeouvacuumdbfazq(silencioso).
VACUUMVERBOSEANALYZEautor;
INFO:vacuuming"public.autor"
INFO:"autor":found0removable,0nonremovablerowversionsin0pages
DETAIL:0deadrowversionscannotberemovedyet.
Therewere0unuseditempointers.
0pagesareentirelyempty.
CPU0.00s/0.00usecelapsed0.00sec.
INFO:analyzing"public.autor"
INFO:"autor":scanned0of0pages,containing0liverowsand0deadrows;0rowsin
sample,0estimatedtotalrows
EmumBancoCompleto
SVACUUM
Ou
VACUUMFULLANALYZE;
DicasdeDesempenho:
Adicionarndicetabela(todachaveprimriajcontmumndice)
AdicionarndicesaoscamposdeclusulasWHERE;
Evitarcamposcomtamanhovarivel.PreferiroCHARaoVARCHAR.
Evitarmuitosndicesendicescommaisdeumcampo
Evitarndiceemtabelamuitopequena(poucosregistros,nocompensa)
Evitar,semprequepossvel,chavescompostas
SepararbancosemumHDelogsemoutroHD
Aumentarsharedbuffers(postgresql.conf)deacordocomRAMdisponvel.
Recomendaes:25%daRAMparasharedbufferscachee24%parasortbuffer.
SeparandobancoseLogs
bancosem/usr/local/pgsql/data(hda)
logsem/usr/local/pgsql/data/pg_xlog(hdb)
Utilizarlinkssimblicosparamovertabelas,ndices,...paraoutroHD.
AtivarochipDMAdoHD

Testar:hdparmTr/dev/hda(status)

98

Ativarochip:hdparmd1/dev/hda
Desativar:hdparmd0/dev/hda
Nopostgresql.confexistemconfiguraesparashared_buffers,quequantomaiormelhor,
respeitandoseaRAM.
Odefaultdaverso8.1.4:
shared_buffers=1000#min16oumax_connections*2(8KBcada)
PlanodeConsulta
OPostgreSQLconcebeumplanodecomandoparacadacomandorecebido.Aescolhado
planocorreto,correspondendoestruturadocomandoespropriedadesdosdados,
absolutamentecrticoparaobomdesempenho.PodeserutilizadoocomandoEXPLAINpara
veroplanocriadopelosistemaparaqualquercomando(conjuntoexecutveldeinstrues).
Aleituradoplanoumaartequemereceumtutorialextenso,oqueesteno;porm,aqui
sofornecidasalgumasinformaesbsicas.
OsnmerosapresentadosatualmentepeloEXPLAINso:
*Ocustodepartidaestimado(Otempogastoantesdepodercomearavarrerasada
como,porexemplo,otempoparafazeraclassificaoemumndeclassificao).
*Ocustototalestimado(Setodasaslinhasfossembuscadas,oquepodenoacontecer:
umaconsultacontendoaclusulaLIMITpraantesdegastarocustototal,porexemplo).
*Nmerodelinhasdesadaestimadoparaestendoplano(Novamente,somentesefor
executadoatofim).
*Larguramdiaestimada(embytes)daslinhasdesadadestendoplano.
EXPLAINSELECT*FROMNOMETABELA;
Mostraplanodeexecuointernadaconsulta,acusandotempogasto
EXPLAINSELECTsum(i)FROMtabela1WHEREi=4;
AgoraaconsultasermodificadaparaincluirumacondioWHERE:
EXPLAINSELECT*FROMtenk1WHEREunique1<1000;
Modificandoseaconsultapararestringirmaisaindaacondio
EXPLAINSELECT*FROMtenk1WHEREunique1<50;
AdiodeoutracondioclusulaWHERE:
EXPLAINSELECT*FROMtenk1WHEREunique1<50ANDstringu1='xxx';
Aseguirfeitaajunodeduastabelas,utilizandoascolunassendodiscutidas:
EXPLAINSELECT*FROMtenk1t1,tenk2t2WHEREt1.unique1<50ANDt1.unique2=
t2.unique2;
Umaformadeveroutrosplanosforaroplanejadoranoconsideraraestratgiaquesairia
vencedora,habilitandoedesabilitandosinalizadoresdecadatipodeplano(Estauma
ferramentadeselegante,mastil.

99
SETenable_nestloop=off;
EXPLAINSELECT*FROMtenk1t1,tenk2t2WHEREt1.unique1<50ANDt1.unique2=
t2.unique2;
possvelverificaraprecisodoscustosestimadospeloplanejadorutilizandoocomando
EXPLAINANALYZE.Naverdadeestecomandoexecutaaconsulta,edepoismostraotempo
realacumuladodentrodecadandoplanojuntocomoscustosestimadosqueocomando
EXPLAINsimplesmostraria.Porexemplo,poderiaserobtidoumresultadocomoeste:
EXPLAINANALYZESELECT*FROMtenk1t1,tenk2t2WHEREt1.unique1<50AND
t1.unique2=t2.unique2;
ReinciodoIDdeTransaes
ParaprevenircomseguranaorecomeodoIDdasTransaesdevemosutilizarocomando
VACUUMemtodasastabelasdobancodedadospelomenosumavezacadameiobilho
detransaes.CasooVACUUMnosejaexecutadopelomenosumavezacada2
bilhesdetransaesocorreraperdadetodososdadosdobanco.Defatoelesno
seperdem,voltandodentrodemais2bilhesdetransaes,masissonoajuda.
Comosaberquantastransaesaindafaltaparaaperdadosdados:
SELECTdatnameASbanco,AGE(datfrozenxid)ASidadeFROMpg_database;
SemprequeseexecutaocomandoVACUUMemumbanco,acolunacomagecomeade1
bilho.Aoexecutarastransaesvaiincrementando.Aoseaproximarde2bilhesdevemos
executarnovamenteocomandoVACUUM.
Alerta
Casoumbancojestejacommaisde1,5bilhesdetransaes,aoexecutarocomando
VACUUMparaobancointeiroreceberumalertasobreanecessidadedeexecuodo
VACUUM.

10Replicao

100

oprocessodecompartilharedistribuirinformaesentrediferentesbancosdedados.
Estesdadosseromantidossincronizadosentegrosemrelaosregrasdeintegridade
referencialedenegcios.
NoPostgreSQLalgumasformasderealizarreplicaosoatravsdocontribdblinkedas
ferramentaslonyepgcluster.
Paraimportarodblinknobancoondequeremosreplicar:
\i/usr/local/pgsql/contrib/dblink.sql
ExemplodbLinkSelect
select*
fromdblink
(
'dbname=pgteste
hostaddr=200.174.40.63
user=paulo
password=paulo
port=5432',
'selectnome
fromclientes
'
)ast1(nomevarchar(30));
ExemplodbLinkInsert
select
dblink_exec(
'dbname=pgteste
hostaddr=200.174.40.63
user=paulo
password=paulo
port=5432',

'insertintoclientes(nome)
values(''roger'')
'
);
ExemplodbLinkUpdate
select
dblink_exec(
'dbname=pgteste
hostaddr=200.174.40.63

101

user=paulo
password=paulo
port=5432',

'updateclientes
setnome=''PauloRogerio''
whereid=18
'

);
ExemplodbLinkDelete
select
dblink_exec(
'dbname=pgteste
hostaddr=200.174.40.63
user=paulo
password=paulo
port=5432',

'deletefromclientes
whereid=18
'
);

TemosocontribdblinkeoprojertoslonyparareplicaodebancosdoPostgreSQL.
Odblinknovemativopordefault.
Ativandoodblink:
Deforadobanco:
psqlUnomeusernomebanco</usr/local/pgsql/contrib/dblink.sql
Oudedentrodobanco:
\i/usr/local/pgsql/contrib/dblink.sql
Funesdodblink:
dblinkparaSELECT
dblinkexecparaINSERT,UPDATEeDELETE(remotos)
TutorialsobrereplicaonositedadbExpertswww.dbexperts.com.br
UsadoparafazerconsultasremotasembancosdoPG
dblink>select
dblinkexec>insert,updateedelete(remotos)
Dica:Removerpostmarter.pidemcasodequedaanormaldoSGBD

Bonsdocumentossobrereplicao:

ReplicaodoPostgreSQLcomSlonydoMarlonPetry
BackupQuentenoPostgreSQLcomReplicaodoSlvioCsar
ReplicandobancodedadosPostgreSQLdoRafaelDonato

102

11Configuraes

103

AoinstalaroPostgreSQL8.1.4viafonteselecria(ealerta)oarquivopg_hba.confcom
autenticaodotipotrust(conexolocalsemsenha).
Paraautenticarexigindoumdostiposcomsenha,devemosantes,aindanotrust,
alterarosusuriosadicionandosenha:
ALTERROLEnomeuserWITHPASSWORD'senhadopg';
Somenteentodevemosalteraropg_hba.confparapedirsenhaerestartaro
PostgreSQL.
Asconfiguraesprincipaissofeitasnosarquivospg_hba.confepostgresql.conf.Se
instaladoatravsdosfontesficamnosubdiretriodatadeinstalaodoPostgreSQL,
normalmenteem/usr/local/pgsql.Seinstaladoviabinriosdadistribuiovaivariarcoma
distribuio.NoSlackwareestonodiretrio/usr/share/postgresql.
Opg_hba.confcontrolaquemquinasteroacessoaoPostgreSQLeaautenticaodessas
mquinasclientes(semautenticaoouatravsdeoutrasformas,trust,md5,crypt,etc).
Opg_hba.confmuitoricoepodemoscontrolaroacessopeloIP,pelamscara,pelobanco,
pelousurio,pelomtodo(trust,md5,password,etc).
Resumosobreopg_hba.conf
ArquivodeconfiguraodaautenticaodosclientesdoPostgreSQL
Estearquivocontrola:
Quaishoststmpermissodeconectar
Comoosclientessoautenticados
Nomesdosusuriosquepodemusar
Quaisbancoselespodemacessar
Osregistrosdestearquivotmasformasseguintes:
#localDATABASEUSERMETHOD[OPTION]
EstemtododeconexoparausosomenteatravssocketsdedomnioUNIX
Semumregistrotipolocalessaconexonegada
#hostDATABASEUSERCIDRADDRESSMETHOD[OPTION]
ConexoviaTCP/IP.Estetipodeconexospossvelquandoovalordoparmetro
listen_address(IP)adequadonopostgresql.conf.Pordefaultsomentelocalhostpermitido.
SopermitidasconexescomousemSSL.
#hostsslDATABASEUSERCIDRADDRESSMETHOD[OPTION]
Semelhanteaohost,sendoquenesteusasecriptografiaSSL.

104
#hostnosslDATABASEUSERCIDRADDRESSMETHOD[OPTION]
ApenasparaconexesquenousamSSL.
#DATABASEcanbe"all","sameuser","samerole",adatabasename,or
#acommaseparatedlistthereof.
DATABASEpodeser:
"all"
"sameuser"(paraquandoousuriotiveromesmonomedobanco)
"samerole"(paraquandoousurioformembrodeumarole(papel)comomesmonomede
umbanco)
umnomedebancoou
umalistaseparadosporvrgula
USERpodeser:
"all"(paraqualquerusurio)
umnomedeusurio
umnomedegrupoprefixadopor"+"
umalistaseparadosporvrgula
TantonocampoDATABASEquantonoUSERpodemostambmescreverumnomede
arquivo
prefixadocom"@"paraincluirnomesemumarquivoseparado
CIDRADDRESSespecificaumafaixadeIPs.AtravsdeumendereodeIPede
umamscaraqueuminteiro(entre0e32paraIPV4oude128paraIPV6),que
especificaonmerodebitssignificativosdamscara.
AlternativamentepodemosescreveroIPseparadodamscaraemcolunasdiferentes
paraespecificaroconjuntodehosts.
Exemplos(IPV4):
172.20.143.89/32paraumnicohost
172.20.143.0/24paraumarede
OcampoCIDRADDRESSsomenteseaplicaaosregistroshost,hostsslehostnossl.
IPaddresseIPmask
EstescampospodemserutilizadoscomoalternativanotaoCIDRADDRESS.aoinvs
deespecificarocomprimentodamscara,aatualmscaraespecificadaemumacoluna
separada.
Exemplo:
255.0.0.0representaumamscaraCIDRemIPV4comcomprimenro8
255.255.255.255representaumamscaraCIDRcomcomprimenro32
172.20.143.89

255.255.255.255

Estescampossomenteseaplicaaosregistroshost,hostsslehostnossl.

105
METHODpodeser"trust","reject","md5","crypt","password",
#"krb5","ident",ou"pam"
trustpermiteconexoaqualquerumincondicionalmente(semsenha)
rejectrejeitaconexoincondicionalmenteparaouser/hostespecificado
cryptrecomendadasomenteparaversesinferioresa7.2.Atualmenterecomendasemd5
krb5somentedisponvelparaconexesviaTCP/IP
identObtmonomedousuriodosistemaoperacional.ParaconexesTCP/IPcontactao
servidoridentnocliente.Paraconexeslocais,recebendoestedosistemaoperacional.
pamusandooservioPAM(PluggableAuthenticationModules)dosistemaoperacional
passwordenviasenhaemtextoclaro
md5deveserpreferido,poisenviasenhascriptografadas
#TYPEDATABASEUSERCIDRADDRESSMETHOD
#IPv4localconnections:
hostallall127.0.0.1/32md5
#IPv6localconnections:
#hostallall::1/128md5
Alerta:estearquivoexaminadosequencialmenteparacadatentativadeconexo.
Aordemdosregistrossignificativa.
Casoumregistroquevenhaprimeiroentreemconflitocomoutroquevememseguida,
oprimeiroserexecutadoeosegundo,no.
Exemplos:
#TYPEDATABASEUSER CIDRADDRESSMETHOD
localall
all
md5
localall
all
trust
Acimatodasasconexeslocaisexigirosenhamd5.
localall
localall

all
all

trust
md5

Jesteacimaaceitartodasasconexeslocaisincondicionalmente(semsenha)
Asegundalinhaserignorada.
Vejavriosexemplosdopg_hba.confemaisdetlahesnocaptulo20domanualoficialdo
PostgreSQLem
ObservequeconexeslocaisnousamocampoCIDRADDRESS.
Exemplosnopg_hba.conf:

106
Conexolocalviasocket
localallall
md5
ConexolocalviaTCP/IP
hostallall 127.0.0.1/32md5
ConexolocalviaTCP/IPcommscaraseparada
hostallall 127.0.0.1
255.255.255.255md5
Conexoparaumarede(identsameuser)viaTCP/IP
hostbancousuario
192.168.93.0/24identsameuser
ConexorejeitadaviaTCP/IPparaoIP,usurioebanco
hostbancousuario
192.168.93.1/32reject
ident
Obtmonomedeusuriodosistemaoperacionaldocliente(paraconexesTCP/IPfazendo
contatocomoservidordeidentificaonocliente,paraconexeslocaisobtendoapartirdo
sistemaoperacional)everificaseousuriopossuipermissoparaseconectarcomoo
usuriodebancodedadossolicitadoconsultandoomapaespecificadoapsapalavrachave
ident.
ExemploparaUbuntu(facilmenteadaptvelparaoutrasdistroseSOs).
Seinstalsdopelorepositrio:
- sudo gedit /etc/postgresql/8.1/main/postgresql.conf
Altere:
#listen_addresses = 'localhost'
para:
listen_addresses = '*'
Aqui tambm existem outras importantes configuraes, como datestyle
= 'sql, dmy' # Datas no estilo brasileiro dd/mm/aaaa
client_encoding = latin1 # suporte nossa acentuao
- sudo gedit /etc/postgresql/8.1/main/pg_hba.conf
# TIPO BANCO USURIO CIDR-ADDRESS MTODO
# "local" para domnios Unix somente com conexes via socket
# no requer IP
local all
all
md5
# Conexes locais via IPv4:
host all all 127.0.0.1/32 md5

107

# Conexes locais via IPv6:


host all all ::1/128 md5
# Conexes para todos os IPs de uma subrede (10.0.0.0)
# TYPE DATABASE USER IP-ADDRESS
IP-MASK
host all
all 10.43.0.0
255.0.0.0

METHOD
md5

Opoparapermitiracessoatravsdetodaainternet:
# Aceitar toda a Internet, exceto 200.217.23.234
# TYPE DATABASE USER IP-ADDRESS
IP-MASK
host all
all 200.217.23.234
255.255.255.255
host all
all 0.0.0.0
0.0.0.0

METHOD
reject
md5

Maisdetalhessobreopg_hba.confem:
http://pgdocptbr.sourceforge.net/pg80/clientauthentication.html
Opostgresql.confpermiteconfigurarasdemaisfuncionalidadesdoPostgreSQL
LiberandoacessoviaredeTCP/IPnaverso7.4.x:
tcp_socket=true(default=false)
No8.0.x:
listen_address='10.0.0.16'
Algunsconfiguraesdopostgresql.conf:
Regrageral:osvaloresquevmcomentadoscom#soosvaloresdefault.Seformosalterar
algumidealmentedevemosfazerumacpiadalinhaedescomentar,parasempresabero
valordefault.
sameuserousuriopadronoident.conf(significaomesmouserdosistemaoperacional).
#FILELOCATIONS
#hba_file='ConfigDir/pg_hba.conf'#hostbasedauthenticationfile
#CONNECTIONSANDAUTHENTICATION
#Oparmetrolisten_addressindicaasmquinasqueteroacessoviaTCP/IP
#ConnectionSettingsAquiasmquinasqueteroacessoviaTCP/IP
#listen_addresses='localhost'#QueIPounomeparaescutar;
#listadeendereosseparadosporvrgula;
#defaultspara'localhost','*'=all
*permiteacessoatodos
#Pordefaultaceitasomenteconexeslocais
#port=5432
max_connections=100(duassoreservadasparaosuperusurio)
#note:increasingmax_connectionscosts~400bytesofsharedmemoryper
#superuser_reserved_connections=2
#Security&Authentication

#authentication_timeout=60#1600,inseconds
#ssl=off
#password_encryption=on
#RESOURCEUSAGE(exceptWAL)
#Memory
shared_buffers=1000#min16ormax_connections*2,8KBeach
#temp_buffers=1000#min100,8KBeach
#max_prepared_transactions=5#canbe0ormore
#note:increasingmax_prepared_transactionscosts~600bytesofsharedmemory
#pertransactionslot,pluslockspace(seemax_locks_per_transaction).
#work_mem=1024#min64,sizeinKB
#maintenance_work_mem=16384#min1024,sizeinKB
#max_stack_depth=2048#min100,sizeinKB
#FreeSpaceMap
#max_fsm_pages=20000#minmax_fsm_relations*16,6byteseach
#max_fsm_relations=1000#min100,~70byteseach

108

AlgumasConfiguraesnopostgresql.conf
...
#AUTOVACUUMPARAMETERS
#autovacuum=off
#enableautovacuumsubprocess?
...
#LocaleandFormatting
#datestyle='iso,mdy'#Eraooriginal
datestyle='sql,european'#
Formatodd/mm/yyyy
...
#client_encoding=sql_ascii
#client_encoding=latin1
#SuporteacentuaodoBrasil
...
Consultandonopsql:
SHOWDATESTYLE;
Retorna>SQL,DMY
Ajustandooestilodadatanopsql:
SETDATESTYLETOSQL,DMY;
ALTERROLEnomeuserSETdatestyleTOSQL,DMY;
OcaminhodeentradanumbancodoPostgreSQL:
>postgresql.conf>ph_hba.conf>ident.conf(casoesteexistaesejacitadono
pg_hba.conf)
Oencodingeoutrosrecursospodemserpassadosparacadabanco,nomomentodesua
criao,comoporexemplo:

109
Deforadobanco:
createdbELATIN1nomebanco.
Dedentrodobanco(psql):
CREATEDATABASEnomebancoWITHENCODING'LATIN1';
Paraarelaocompletadosencodingsuportadosvejatabela212.
Paravisualizaracodificaonopsqldigite
\encoding.
Paramudaracodificaodeumbancodinamicamente,estandoneleutilize:
\encodingnovoencoding
ComotambmpodemosutilizarocomandoSET:
SETCLIENT_ENCODING'LATIN1';
Consultandooencodingexistente
SHOWCLIENT_ENCODING;
PARADESFAZERASALTERAESEVOLTARCODIFICAOPADRO:
RESETCLIENT_ENCODING;
Maisdetalhes:
http://www.postgresql.org/docs/8.1/interactive/runtimeconfig.html#CONFIGSETTING
Parasaberoslocalesexistentesexecutededentrodopsql:
\l
Exibebancos,donoselocales(Codificao)
EmcadaconexocomoPostgreSQL,somentesepodeacessarumnicobanco.
Nopostgresql.confpodemosdefiniroencodingatravsdavarivelclient_encoding.

12Metadados(Catlogo)

110

Metadadossodadossobredados.
Umaconsultanormalretornainformaesexistentesemtabelas,jumaconsultasobreos
metadadosretornainformaessobreosbancos,osobjetosdosbancos,oscamposde
tabelas,seustiposdedados,seusatributos,suasconstraints,etc.
RetornarTodasasTabelasdobancoeesquemaatual
SELECTschemanameASesquema,tablenameAStabela,tableownerASdono
FROMpg_catalog.pg_tables
WHEREschemanameNOTIN('pg_catalog','information_schema','pg_toast')
ORDERBYschemaname,tablename
InformaesdeTodososTablespaces
SELECTspcname,pg_catalog.pg_get_userbyid(spcowner)ASspcowner,spclocation
FROMpg_catalog.pg_tablespace
Retornarbanco,dono,codificao,comentriosetablespace
SELECTpdb.datnameASbanco,
pu.usenameASdono,
pg_encoding_to_char(encoding)AScodificacao,
(SELECTdescriptionFROMpg_descriptionpdWHEREpdb.oid=pd.objoid)AScomentario,
(SELECTspcnameFROMpg_catalog.pg_tablespaceptWHEREpt.oid=pdb.dattablespace)
AStablespace
FROMpg_databasepdb,pg_userpuWHEREpdb.datdba=pu.usesysidORDERBY
pdb.datname
Tabelas,donos,comentrios,registrosetablespacesdeumschema
SELECTc.relnameastabela,
pg_catalog.pg_get_userbyid(c.relowner)ASdono,
pg_catalog.obj_description(c.oid,'pg_class')AScomentario,reltuples::integerasregistros,
(SELECTspcnameFROMpg_catalog.pg_tablespaceptWHEREpt.oid=c.reltablespace)AS
tablespace
FROMpg_catalog.pg_classc
LEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespace
WHEREc.relkind='r'
ANDnspname='public'
ORDERBYc.relname
MostrarSequencesdeumEsquema
SELECTc.relnameASseqname,u.usenameASseqowner,pg_catalog.obj_description(c.oid,
'pg_class')ASseqcomment,

(SELECTspcnameFROMpg_catalog.pg_tablespaceptWHERE
pt.oid=c.reltablespace)AStablespace
FROMpg_catalog.pg_classc,pg_catalog.pg_useru,pg_catalog.pg_namespacen
WHEREc.relowner=u.usesysidANDc.relnamespace=n.oid
ANDc.relkind='S'ANDn.nspname='public'ORDERBYseqname

MostrarTablespaces
SELECTspcname,pg_catalog.pg_get_userbyid(spcowner)ASspcowner,spclocation
FROMpg_catalog.pg_tablespace
Mostrardetalhesdeumafunction
SELECT
pc.oidASprooid,
proname,
lannameasprolanguage,
pg_catalog.format_type(prorettype,NULL)asproresult,
prosrc,
probin,
proretset,
proisstrict,
provolatile,
prosecdef,
pg_catalog.oidvectortypes(pc.proargtypes)ASproarguments,
proargnamesASproargnames,
pg_catalog.obj_description(pc.oid,'pg_proc')ASprocomment
FROMpg_catalog.pg_procpc,pg_catalog.pg_languagepl
WHEREpc.oid='oid_da_function'::oid
ANDpc.prolang=pl.oid
Esteexemplomostraumaconsultaquelistaosnomesdosesquemas,tabelas,
colunasechavesdaschavesestrangeiras,eosnomesdosesquemas,tabelase
colunasreferenciadas.Exemplotiradodalistadediscussopgsqlsql
CREATETEMPORARYTABLEt1(idSERIALPRIMARYKEY,nomeTEXT);
CREATETEMPORARYTABLEt2(idINTREFERENCESt1,nomeTEXT);
SELECT
n.nspnameASesquema,
cl.relnameAStabela,
a.attnameAScoluna,
ct.connameASchave,
nf.nspnameASesquema_ref,
clf.relnameAStabela_ref,
af.attnameAScoluna_ref,
pg_get_constraintdef(ct.oid)AScriar_sql
FROMpg_catalog.pg_attributea
JOINpg_catalog.pg_classclON(a.attrelid=cl.oidANDcl.relkind='r')

111

JOINpg_catalog.pg_namespacenON(n.oid=cl.relnamespace)
JOINpg_catalog.pg_constraintctON(a.attrelid=ct.conrelidAND
ct.confrelid!=0ANDct.conkey[1]=a.attnum)
JOINpg_catalog.pg_classclfON(ct.confrelid=clf.oidANDclf.relkind='r')
JOINpg_catalog.pg_namespacenfON(nf.oid=clf.relnamespace)
JOINpg_catalog.pg_attributeafON(af.attrelid=ct.confrelidAND
af.attnum=ct.confkey[1]);

112

MostrarEsquemaseTabelas
SELECTn.nspnameasesquema,c.relnameastabela,a.attnameascampo,
format_type(t.oid,null)astipo_de_dado
FROMpg_namespacen,pg_classc,
pg_attributea,pg_typet
WHEREn.oid=c.relnamespace
andc.relkind='r'noindices
andn.nspnamenotlike'pg\\_%'nocatalogs
andn.nspname!='information_schema'noinformation_schema
anda.attnum>0nosystematt's
andnota.attisdroppednodroppedcolumns
anda.attrelid=c.oid
anda.atttypid=t.oid
ORDERBYnspname,relname,attname;
MostrarEsquemaserespectivastabelasdoBancoatual:
SELECTn.nspnameasesquema,c.relnameastabelaFROMpg_namespacen,pg_classc
WHEREn.oid=c.relnamespace
andc.relkind='r'noindices
andn.nspnamenotlike'pg\\_%'nocatalogs
andn.nspname!='information_schema'noinformation_schema
ORDERBYnspname,relname

ContarTodososRegistrosdetodasastabelasdetodososbancos:
<?php
$conexao=pg_connect("host=127.0.0.1user=postgrespassword=postabir");
$sql="SELECTdatnameASbancoFROMpg_databaseORDERBYdatname";
$consulta=pg_query($conexao,$sql);
$banco=array();
$c=0;
while($data=@pg_fetch_object($consulta,$c)){
$cons=$data>banco;
$c++;

$banco[].=$cons;

113

$sql2="SELECTn.nspnameasesquema,c.relnameastabelaFROMpg_namespacen,
pg_classc
WHEREn.oid=c.relnamespace
andc.relkind='r'noindices
andn.nspnamenotlike'pg\\_%'nocatalogs
andn.nspname!='information_schema'noinformation_schema
ORDERBYnspname,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.1dbname=$banco[$x]user=postgres
password=postabir");

$consulta2=pg_query($conexao2,$sql2);

while($data=pg_fetch_object($consulta2)){
$esquematab=$data>esquema.'.'.$data>tabela;
$sql3="SELECTcount(*)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"TotaldeRegistrodetodasastabelasdetodososbancos".$total;

?>
Dadoobancodedados,qualoseudiretrio:
selectdatname,oidfrompg_database;
Dadoatabela,qualoseuarquivo:
selectrelname,relfilenodefrompg_class;
Mostrarchavesprimriasdastabelasdoesquemapublic
selectindexrelnameasindice,relnameastabelafrompg_catalog.pg_statio_user_indexesas
AINNERJOINpg_catalog.pg_indexasBONA.indexrelid=B.indexrelidWHERE
A.schemaname='public'ANDB.indisprimary=true;
Paravisualizarcomoasconsultassofeitasinternamenteviapsqlusamosocomando
assim:
psqlUuserbancoE

114
Vamosusarobancomunicipios,criadocomosmunicpiosdoBrasil.Atabelaopt_cidades.
VejaUmExemploQueRetornaaChavePrimriadaTabelaopt_cidades
SELECT
ic.relnameASindex_name,
bc.relnameAStab_name,
ta.attnameAScolumn_name,
i.indisuniqueASunique_key,
i.indisprimaryASprimary_key
FROM
pg_classbc,
pg_classic,
pg_indexi,
pg_attributeta,
pg_attributeia
WHERE
bc.oid=i.indrelid
ANDic.oid=i.indexrelid
ANDia.attrelid=i.indexrelid
ANDta.attrelid=bc.oid
ANDbc.relname='opt_cidades'
ANDta.attrelid=i.indrelid
ANDta.attnum=i.indkey[ia.attnum1]
ORDERBY
index_name,tab_name,column_name;
Retornar:
index_name|tab_name|column_name|unique_key|primary_key
opt_cidades_pkey|opt_cidades|id|t|t
RetornandooNomedoEsquema
SELECTn.nspnameAS"Esquema"
FROMpg_catalog.pg_namespaceASn,
pg_catalog.pg_classASc
WHEREc.relnamespace=n.oidANDc.relname='opt_cidades';
Retorno:Esquema
Retornarnomesdebancos:
SELECTdatnameASbancoFROMpg_database
WHEREdatname!='template0'anddatname!='template1'anddatname!='postgres'
ORDERBYdatname
RetornarnomeseOIDsdosbancos:
SELECToid,datnameFROMpg_database;

Dadoatabela,qualoseuarquivo:
selectrelname,relfilenodefrompg_class;

115

NoWindows
Podemospassarparmetrosparaasmacros,porexemplo:
doskey/exename=psql.exedbinfo=SELECTdatname,pg_encoding_to_char(encoding)FROM
pg_databaseWHEREdatname='$1';
Eentoapenaspassaroparmetronalinhadecomando:
postgres=#dbinfopostgres
Listartabelas,edonodoesquemaatual:
SELECTn.nspnameas"Schema",
c.relnameas"Tabela",
CASEc.relkindWHEN'r'THEN'table'WHEN'v'THEN'view'WHEN'i'THEN
'index'WHEN'S'THEN'sequence'WHEN's'THEN'special'ENDas"Tipo",
u.usenameas"Dono"
FROMpg_catalog.pg_classc
LEFTJOINpg_catalog.pg_useruONu.usesysid=c.relowner
LEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespace
WHEREc.relkindIN('r','')
ANDn.nspnameNOTIN('pg_catalog','pg_toast')
ANDpg_catalog.pg_table_is_visible(c.oid)
ORDERBY1,2;
ListarTabelas
selectc.relnameFROMpg_catalog.pg_classc
LEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespace
WHEREc.relkindIN('r','')ANDn.nspnameNOTIN('pg_catalog','pg_toast')
ANDpg_catalog.pg_table_is_visible(c.oid);
SELECTtablenameFROMpg_tablesWHEREtablenameNOTLIKE'pg%'ANDtablename
NOTLIKE'sql\_%'
Listartodasastabelas,ndices,tamanhoemKBeOIDs:
VACUUM;Executarantesestecomando
SELECTc1.relnameAStabela,c2.relnameASindice,
c2.relpages*8AStamanho_kb,c2.relfilenodeASarquivo
FROMpg_classc1,pg_classc2,pg_indexi
WHEREc1.oid=i.indrelidANDi.indexrelid=c2.oid
UNION
SELECTrelname,NULL,relpages*8,relfilenode
FROMpg_class
WHERErelkind='r'
ORDERBYtabela,indiceDESC,tamanho_kb;
TabelaseSoma

SELECTtablename,SUM(size_kb)
FROM
(SELECTc1.relnameAS"tablename",
c2.relpages*8AS"size_kb"
FROMpg_classc1,pg_classc2,pg_indexi
WHEREc1.oid=i.indrelid
ANDi.indexrelid=c2.oid
UNION
SELECTrelname,relpages*8
FROMpg_class
WHERErelkind='r')ASrelations
GROUPBYtablename;

116

r=ordinarytable,i=index,S=sequence,v=view,c=compositetype,
s=special,t=TOASTtable

Tamanhoembytesdeumbanco:
selectpg_database_size('banco');
Tamanhoembytesdeumatabela:
pg_total_relation_size('tabela')
Tamanhoembytesdetabelaoundice:
pg_relation_size('tabelaouindice')
Listadonosebancos:
SELECTrolnameasdono,datnameasbanco
FROMpg_roles,pg_database
WHEREpg_roles.oid=datdba
ORDERBYrolname,datname;
Nomesdebancos:
selectdatnamefrompg_databasewheredatnamenotin('template0','template1')orderby1
Nomesecolunas:
selecttablename,'T'frompg_tableswheretablenamenotlike'pg\_%'
andtablenamenotin('sql_features','sql_implementation_info','sql_languages',
'sql_packages','sql_sizing','sql_sizing_profiles')
union
selectviewname,'V'frompg_viewswhereviewnamenotlike'pg\_%'
Tamanhodeesquemaendice:
SELECTnspname,
sum(relpages*cast(8192ASbigint))as"tablesize",
sum((selectsum(relpages)
frompg_classi,pg_indexidx
wherei.oid=idx.indexrelid

andt.oid=idx.indrelid))*cast(8192ASbigint)as"indexsize",
sum(relpages*cast(8192ASbigint)+(selectsum(relpages)
frompg_classi,pg_indexidx
wherei.oid=idx.indexrelid
andt.oid=idx.indrelid)*cast(8192ASbigint))as"size"
FROMpg_classt,pg_namespace
WHERErelnamespace=pg_namespace.oid
andpg_namespace.nspnamenotlike'pg_%'
andpg_namespace.nspname!='information_schema'
andrelkind='r'groupbynspname;

117

RetornandoTabelaseSeusDonosdeumEsquema
SELECTn.nspnameas"public",
c.relnameas"opt_cidades",
CASEc.relkindWHEN'r'THEN'tabela'WHEN'v'THEN'view'WHEN'i'THEN'ndice'
WHEN'S'THEN'sequencia'WHEN's'THEN'especial'ENDas"Tipo",u.usenameas"Dono"
FROMpg_catalog.pg_classc
LEFTJOINpg_catalog.pg_useruONu.usesysid=c.relowner
LEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespace
WHEREc.relkindIN('r','')
ANDn.nspnameNOTIN('pg_catalog','pg_toast')
ANDpg_catalog.pg_table_is_visible(c.oid)
ORDERBY1,2;
Retorno:
public|opt_cidades|Tipo|Dono
+++
public|opt_cidades|tabela|postgres
public|opt_estado|tabela|postgres

RetornandooOIDeoEsquemadeumaTabela
SELECTc.oidAS"OID",
n.nspnameAS"Esquema",
c.relnameAS"Tabela"
FROMpg_catalog.pg_classc
LEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespace
WHEREpg_catalog.pg_table_is_visible(c.oid)
ANDc.relname~'^opt_cidades$'
ORDERBY2,3;
Retorno:
OID|Esquema|Tabela
Esteexemplomostraumaconsultaquelistaosesquemas,nomesdastabelasenomes
dascolunasdaschavesprimriasdeumbancodedados.Exemplotiradodalistade
discussopgsqlsql.

CREATETEMPTABLEteste1(idINT,textoTEXT,PRIMARYKEY(id));
CREATETEMPTABLEteste2(id1INT,id2INT,textoTEXT,PRIMARYKEY(id1,id2));
\dt
SELECT
pg_namespace.nspnameASesquema,
pg_class.relnameAStabela,
pg_attribute.attnameAScoluna_pk
FROMpg_class
JOINpg_namespaceONpg_namespace.oid=pg_class.relnamespaceAND
pg_namespace.nspnameNOTLIKE'pg_%'
JOINpg_attributeONpg_attribute.attrelid=pg_class.oidAND
pg_attribute.attisdropped='f'
JOINpg_indexONpg_index.indrelid=pg_class.oidAND
pg_index.indisprimary='t'AND
(
pg_index.indkey[0]=pg_attribute.attnumOR
pg_index.indkey[1]=pg_attribute.attnumOR
pg_index.indkey[2]=pg_attribute.attnumOR
pg_index.indkey[3]=pg_attribute.attnumOR
pg_index.indkey[4]=pg_attribute.attnumOR
pg_index.indkey[5]=pg_attribute.attnumOR
pg_index.indkey[6]=pg_attribute.attnumOR
pg_index.indkey[7]=pg_attribute.attnumOR
pg_index.indkey[8]=pg_attribute.attnumOR
pg_index.indkey[9]=pg_attribute.attnum
)
ORDERBYpg_namespace.nspname,pg_class.relname,pg_attribute.attname;
Esteexemplomostraumaconsultaquelistaosnomesdosesquemas,tabelas,
colunasechavesdaschavesestrangeiras,eosnomesdosesquemas,tabelase
colunasreferenciadas.Exemplotiradodalistadediscussopgsqlsql
CREATETEMPORARYTABLEt1(idSERIALPRIMARYKEY,nomeTEXT);
CREATETEMPORARYTABLEt2(idINTREFERENCESt1,nomeTEXT);
SELECT
n.nspnameASesquema,
cl.relnameAStabela,
a.attnameAScoluna,
ct.connameASchave,
nf.nspnameASesquema_ref,
clf.relnameAStabela_ref,
af.attnameAScoluna_ref,
pg_get_constraintdef(ct.oid)AScriar_sql
FROMpg_catalog.pg_attributea
JOINpg_catalog.pg_classclON(a.attrelid=cl.oidANDcl.relkind='r')
JOINpg_catalog.pg_namespacenON(n.oid=cl.relnamespace)

118

JOINpg_catalog.pg_constraintctON(a.attrelid=ct.conrelidAND
ct.confrelid!=0ANDct.conkey[1]=a.attnum)
JOINpg_catalog.pg_classclfON(ct.confrelid=clf.oidANDclf.relkind='r')
JOINpg_catalog.pg_namespacenfON(nf.oid=clf.relnamespace)
JOINpg_catalog.pg_attributeafON(af.attrelid=ct.confrelidAND
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|FOREIGNKEY(id)
REFERENCESt1(id)

119

SELECTa.attnum,a.attnameASfield,t.typnameastype,a.attlenASlength,a.atttypmod4
aslengthvar,a.attnotnullasnotnull
FROMpg_classc,pg_attributea,pg_typet
WHEREc.relname='apagar'ANDa.attnum>0ANDa.attrelid=c.oidANDa.atttypid=
t.oid
ORDERBYa.attnum;
Sada:
IDdocampo,nomecampo,tipo,tamanho,nulo/nonulo
Outros
SELECTic.relnameASindex_name,bc.relnameAStab_name,ta.attnameAS
column_name,i.indisuniqueASunique_key,i.indisprimaryASprimary_key
FROMpg_classbc,pg_classic,pg_indexi,pg_attributeta,pg_attributeia
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.attnum1])
ORDERBYindex_name,tab_name,column_name

Sada:
nomeindex/chave,nometabela,nomecampo,unique(t/f),nomepk(t/f)

120

SELECTrcnameasindex_name,rcsrc
FROMpg_relcheck,pg_classbc
WHERErcrelid=bc.oid
ANDbc.relname='apagar'
ANDNOTEXISTS(
SELECT*
FROMpg_relcheckasc,pg_inheritsasi
WHEREi.inhrelid=pg_relcheck.rcrelid
ANDc.rcname=pg_relcheck.rcname
ANDc.rcsrc=pg_relcheck.rcsrc
ANDc.rcrelid=i.inhparent
)
Sada:retornaasconstraintscheck.
SELECTpg_class.relname,pg_attribute.attname,pg_type.typname,
pg_attribute.atttypmod4
FROMpg_class,pg_attribute,pg_type
WHEREpg_attribute.attrelid=pg_class.oid
ANDpg_attribute.atttypid=pg_type.oid
ANDpg_class.relname='apagar'
ANDpg_attribute.attname='descricao'
Sada:tabela,campo,tipo,tamanho(varchar)
OutrosExemplos
createtabletabela_exemplo(
campo_1integerdefault5,campo_2textdefault'exemplo',campo_3float(10),
campo_4serial,campo_5doubleprecision,campo_6int8,campo_7Point,
campo_8char(3),campo_9varchar(17));
Depoisdecriadaatabelavamoscriaraconsultaquenosretornarasinformaesda
tabela:
SELECT
rel.nspnameASEsquema,rel.relnameASTabela,attrs.attnameASCampo,"Type",
"Default",attrs.attnotnullAS"NOTNULL"
FROM(
SELECTc.oid,n.nspname,c.relname
FROMpg_catalog.pg_classc
LEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespace
WHEREpg_catalog.pg_table_is_visible(c.oid))rel
JOIN(
SELECTa.attname,a.attrelid,pg_catalog.format_type(a.atttypid,a.atttypmod)as
"Type",
(SELECTsubstring(d.adsrcfor128)FROMpg_catalog.pg_attrdefd
WHEREd.adrelid=a.attrelidANDd.adnum=a.attnumANDa.atthasdef)as"Default",

121
a.attnotnull,a.attnum
FROMpg_catalog.pg_attributeaWHEREa.attnum>0ANDNOTa.attisdropped)
attrs
ON(attrs.attrelid=rel.oid)
WHERErelname='tabela_exemplo'ORDERBYattrs.attnum;
Retorno:
testes#WHERErelname='tabela_exemplo'ORDERBYattrs.attnum;
esquema|tabela|campo|Type|Default|NOT
NULL

Antesdetudodevemoscriarumnovotipodedadorelacionadoaoretornoque
obteremosdafuno:
CREATETYPEtabela_estruturaAS(Esquematext,Tabelatext,Campotext,Tipotext,
Valortext,AutoIncrementobool);
AfunoabaixodefinidaemPL/PgSQL,linguagemproceduralmuitosemelhanteao
PL/SQLdoOracle.Afunofoicriadanestalinguagemdevidoacertaslimitaesque
asfunesemSQLpossuem.
CREATEORREPLACEFUNCTIONDados_Tabela(varchar(30))
RETURNSSETOFtabela_estruturaAS'
DECLARE
rtabela_estrutura%ROWTYPE;
recRECORD;
vTabelaaliasfor$1;
eSqlTEXT;
BEGIN
eSql:=''SELECT
CAST(rel.nspnameasTEXT),CAST(rel.relnameASTEXT),CAST(attrs.attnameAS
TEXT),CAST("Type"ASTEXT),CAST("Default"ASTEXT),attrs.attnotnull
FROM
(SELECTc.oid,n.nspname,c.relname
FROMpg_catalog.pg_classc
LEFTJOINpg_catalog.pg_namespacenONn.oid=c.relnamespace
WHEREpg_catalog.pg_table_is_visible(c.oid))rel
JOIN
(SELECTa.attname,a.attrelid,
pg_catalog.format_type(a.atttypid,a.atttypmod)as"Type",
(SELECTsubstring(d.adsrcfor128)FROMpg_catalog.pg_attrdefd
WHEREd.adrelid=a.attrelidANDd.adnum=a.attnumANDa.atthasdef)
as"Default",a.attnotnull,a.attnum
FROMpg_catalog.pg_attributea
WHEREa.attnum>0ANDNOTa.attisdropped)attrs
ON(attrs.attrelid=rel.oid)
WHERErelnameLIKE''''%''||vTabela||''%''''

ORDERBYattrs.attnum'';
FORrINEXECUTEeSql
LOOP
RETURNNEXTr;
ENDLOOP;
IFNOTFOUNDTHEN
RAISEEXCEPTION''Tabela%noencontrada'',vTabela;
ENDIF;
RETURN;
END
'
LANGUAGE'plpgsql';
Parautilizarestafuno,utilizeoseguintecomando:
SELECT*FROMDados_Tabela('tabela');
Retorno:
esquema|tabela|campo|tipo|valor|autoincremento
Exemploscontidosnoarquivo:
/usr/local/src/postgresql8.1.3/src/tutorial/syscat.sql
SELECTrolnameas"Donos",datnameasBancos
FROMpg_roles,pg_database
WHEREpg_roles.oid=datdba
ORDERBYrolname,datname;
Retorno:DonoseBancos
SELECTn.nspnameasesquema,c.relnameastabela
FROMpg_classc,pg_namespacen
WHEREc.relnamespace=n.oid
andc.relkind='r'notindices,views,etc
andn.nspnamenotlike'pg\\_%'notcatalogs
andn.nspname!='information_schema'notinformation_schema
ORDERBYnspname,relname;
Retorno:EsquemaseTabelas
SELECTn.nspnameasesquema,c.relnameastabela,a.attnameascampo,
format_type(t.oid,null)astipo_de_dado
FROMpg_namespacen,pg_classc,
pg_attributea,pg_typet
WHEREn.oid=c.relnamespace
andc.relkind='r'noindices
andn.nspnamenotlike'pg\\_%'nocatalogs
andn.nspname!='information_schema'noinformation_schema
anda.attnum>0nosystematt's
andnota.attisdroppednodroppedcolumns
anda.attrelid=c.oid
anda.atttypid=t.oid

122

ORDERBYnspname,relname,attname;
Retorno:esquemas,tabelas,campos,tiposdedados
SELECTn.nspname,o.oprnameASbinary_op,
format_type(left_type.oid,null)ASleft_opr,
format_type(right_type.oid,null)ASright_opr,
format_type(result.oid,null)ASreturn_type
FROMpg_namespacen,pg_operatoro,pg_typeleft_type,
pg_typeright_type,pg_typeresult
WHEREo.oprnamespace=n.oid
ando.oprkind='b'binary
ando.oprleft=left_type.oid
ando.oprright=right_type.oid
ando.oprresult=result.oid
ORDERBYnspname,left_opr,right_opr;
Retorno:operadoresbinrios
Baypassarosdesistema:
andn.nspnamenotlike'pg\\_%'nocatalogs
SELECTn.nspname,p.proname,format_type(t.oid,null)astypname
FROMpg_namespacen,pg_aggregatea,
pg_procp,pg_typet
WHEREp.pronamespace=n.oid
anda.aggfnoid=p.oid
andp.proargtypes[0]=t.oid
ORDERBYnspname,proname,typname;
Retorno:listatodasasfunesagregadaseostiposquepodemseraplicados
Dadoobancodedados,qualoseudiretrio:
selectdatname,oidfrompg_database;
Dadoatabela,qualoseuarquivo:
selectrelname,relfilenodefrompg_class;
Exemploqueretornandice,campo,tipo,comprimento,null,default:
SELECTpg_attribute.attnumASindex,
attnameASfield,
typnameAStype,
atttypmod4aslength,
NOTattnotnullAS"null",
adsrcASdefault
FROMpg_attribute,
pg_class,
pg_type,

123

pg_attrdef
WHEREpg_class.oid=attrelid
ANDpg_type.oid=atttypid
ANDattnum>0
ANDpg_class.oid=adrelid
ANDadnum=attnum
ANDatthasdef='t'
ANDlower(relname)='datas'
UNION
SELECTpg_attribute.attnumASindex,
attnameASfield,
typnameAStype,
atttypmod4aslength,
NOTattnotnullAS"null",
''ASdefault
FROMpg_attribute,
pg_class,
pg_type
WHEREpg_class.oid=attrelid
ANDpg_type.oid=atttypid
ANDattnum>0
ANDatthasdef='f'
ANDlower(relname)='datas';

124

13Conectividade

125

VoumostraraconectividadedoPostgreSQLcomoPHP,comoJavaecomoVisualBASIC.
TambmmostrareiaconectividadeatravsdoODBCcomoAccess.
ConectandocomoPHP
ComoPHPexisteumaconexonativa.Vejaumexemplo:
$conexao=pg_connect("host=127.0.0.1dbname=testesuser=postgrespassword=*******
port=5432");
if(!$conexao){
echo"Falhanaconexocomobanco.Vejadetalhestcnicos:".
pg_last_error($conexao);
}
ConexocomJava
AconexodoPostgreSQLcomJavautilizadapordiversosclientesdegerenciamentoou
modelagemdoPostgreSQL.NestecasoutilizaseodriverJDBCdoPostgreSQL.Videpasta
\jdbcdainstalao.
BaixardeacordocomsuaversodoPostgreSQL,odriverJDBCparaoPostgreSQL
daqui:
http://jdbc.postgresql.org/download.html#jdbcselection
AquiparaoPostgreSQLverso8.1.3baixeioarquivo8.1405JDBC3.
VBAcessandoPostgreSQLviaODBC
OPGODBCdeveserinstaladonomicroclienteeencontraseem:
http://www.postgresql.org/ftp/odbc/versions/msi
CriarumaconexoODBCaobancodoPostgreSQLenocdigo:
GlobalConexAsNewADODB.Connection
GlobalAccessConnectAsString
PublicSubConexao()
AccessConnect=
"driver={PostgreSQL};server=10.10.10.10;database=maubanco;uid=postgres;pwd=postgres;"
Conex.ConnectionString=AccessConnect
Conex.OpenAtivConex.ActiveConnection=Conex
EndSub
ExemploBsicodeJavaAcessandoPostgreSQLViaJDBC
CrienoPostgreSQLumpequenobancodedadoschamadoagendacomumanicatabela
chamadaamigos.
Estatabelacontendooscamposnomeeemailapenas.Cadastreumoumaisregistrospara

melhorvisualizaodosresultados.
importjava.sql.*;
publicclassSQLStatement{
publicstaticvoidmain(Stringargs[]){
//Stringurl="jdbc:postgresql://10.0.1.53:5432/agenda";
Stringurl="jdbc:postgresql://localhost:5432/agenda";
//Stringurl="jdbc:postgresql:agenda";//Assimpegaosdefaults
Connectioncon;
Stringquery="select*fromamigos;
Statementstmt;
try{
Class.forName("org.postgresql.Driver");
}catch(java.lang.ClassNotFoundExceptione){
System.err.print("ClassNotFoundException:");
System.err.println(e.getMessage());
}
try{
con=DriverManager.getConnection(url,"postgres","postgres");
stmt=con.createStatement();
ResultSetrs=stmt.executeQuery(query);
ResultSetMetaDatarsmd=rs.getMetaData();
intnumberOfColumns=rsmd.getColumnCount();
introwCount=1;
while(rs.next()){
System.out.println("Registro"+rowCount+":");
for(inti=1;i<=numberOfColumns;i++){
System.out.print("Campo"+i+":");
System.out.println(rs.getString(i));
}
System.out.println("");
rowCount++;
}
stmt.close();
con.close();
}catch(SQLExceptionex){
System.err.print("SQLException:");
System.err.println(ex.getMessage());
}
}
}

126

ConexoComoVisualBASIC
PodemosnosconectaraumabasededadosPostgreSQLusandooVisualBasicviaADO.
ParaistotemosqueusarumdriverODBCparaaplataformaWindows.
VocevaiprecisarteroPostgreSQLinstaladoeodriverODBCtambm.
InstalaseopsqlODBCeconfiguraseaconexocomobancodesejado.

127
Ifsothenusesomethinglike
CurrentProject.Connection.ExecuteStrSql2
Ifnotlinkedtablesthenusesomethinglike
DimcnnasnewADODB.Connection
cnn.Open"DSN=my_dbs_dsn_name"'orafullPostgreSQLconnectionstringtosaveatripto
theregistry
cnn.ExecuteStrSql2
Outroexemplo:
CriarumDSNODBC"pgresearch"viaADOeuse:
DimgcnResearchAsADODB.Connection
DimrsUIdAsADODB.Recordset
'openthedatabase
SetgcnResearch=3DNewADODB.Connection
WithgcnResearch
.ConnectionString=3D"dsn=3Dpgresearch"
.Properties("UserID")=3DtxtUsername
.Properties("Password")=3DtxtPassword
.Open
EndWith
AcessandocomoVisualC#.net,verlink:
http://www.linhadecodigo.com.br/artigos.asp?id_ac=355

14Ferramentas

128

14.1psql
AferramentabsicadeadministraodoPostgreSQLopsql,masumaferramentade
administraocapazdeadministrarpraticamentetudodoPostgreSQL.
Paraacessloexecute:
supostgresql
psqlUnomeusernomebanco(tantonoLinuxquantoemoutrosSOs).
Geral:
psqlhhostPportUuserW(perguntarpelasenha)
AlgunscomandosdoPostgreSQLdalinhadecomandodoSO:
SenumUNIXfaalogincomousuriodoPostgreSQL,senoWindowsexecutepassandoU
nomeusuario.
Obtendoajudasobreumcomando:
comandohelp
SenumUNIXexistemtambmasmanpages(pginasdomanual):
mancomando
psqll>listaosbancosdedados
psqlUnomeusuarionomebanco>conectarconsolepsqlnobancodedados
psqlbancoE>(debug)mostrainternamentecomocadaconsultarealizada
psqlversion>mostraversodoPostgreSQL
Outroscomandosvialinhadecomando:
pg_dump,pg_dumpall,pg_restote,createdb,dropdb,createrole,droprole

AlgunsComandosdopsql:
Paraacessar,estandonumUNIX:
sunomeuserpg
psqlUnomeuserpgnomebanco
EstandonoWindows
psqlUnomeuserpgnomebanco
Opsqlaceitaquebradelinhasnumaconsulta.
Opontoevrgula(ou<g)indicaordemdeexecuo.
Observeatentamenteopromptesuasvariaes:
=#estepromptindicaumsuperusurio
=>esteindicaumusuriocomum

#indicacomandonofinalizado.Aguardandoopontoevrgula
(#aguardandoofechaparnteses)
'#aguardandoumfechaapstrofo'

129

Obs.:EmcasodeerroteclarCtrl+Cparaencerrar.LembrandoqueissonoWindows
saidopsql.
\qsair
\cnomebanconomeuserConectaraoutrobanco
\i/path/script.sqlimportarscript.sql
\timinginiciar/pararocronmetroparaatividades
\dT+listaostiposdedadosdoPGcomdetalhes
\cdmudarparaoutrodiretrio
\dlistatabelas,ndices,sequnciasouviews
\dnometabelamostraestruturadatabela
\dtlistatabelas
\dilistaindices
\dslistasequncias
\dvlistaviews
\dSlistatabelasdosistema
\dnlistaesquemas
\dplistaprivilgios
\dulistausurios
\dglistagrupos
\llistatodososbancosdoservidor,juntamentecomseusdonosecodificaes
\eabreoeditorvicomaltimaconsulta
\oinicia/terminaacriaodearquivo.Ex.:\oarquivo.sql
\!comando_do_sistemaoperacionalexecutaoarquivodosistemaoperacional
\?ajudageraldoscomandosdopsql
\h*exibeajudadetodososcomandos
\hcomandosqlajudaespecficasobreocomandoSQL,ex.:\haltertable
\Hativa/desativasadaemHTML
\encodingexibecodificaoatual
Boasugesto:
\hCREATEDATABASE
\hCREATEROLE
ExemplodesadadeconsultaemHTMLpeloPostgreSQL:
GerandoumrelatrioemHTMLdiretamenteatravsdoPostgreSQL
\orelatorio.html
SELECT*FROMcep_tabelaWHEREuf='CE';
Obs.:LembrequeoPostgreSQLcasesensitive.
ComissoteremosumarquivoHTMLcontendotodososregistrosretornadospela
consultaemumatabelaHTML,comonoexemploabaixo:

<tableborder="1">
<tr>
<thalign="center">cep</th>
<thalign="center">tipo</th>
<thalign="center">logradouro</th>
<thalign="center">bairro</th>
<thalign="center">municipio</th>
<thalign="center">uf</th>
</tr>
<trvalign="top">
<tdalign="left">60420440</td>
<tdalign="left">Rua
<tdalign="left">VascodaGama
<tdalign="left">Montese
<tdalign="left">Fortaleza
<tdalign="left">CE</td>
</tr>
</table>

130

Consoledopsql

14.2phpPgAdmin
Baixardehttp://phppgadmin.sourceforge.net/
Copiarparaodiretrioweb
Editaroarquivoconf/config.inc.phpealterarparadoisservidores(umlocaleoutroremoto):
...

//Displaynamefortheserverontheloginscreen

$conf['servers'][0]['desc']='Local';
$conf['servers'][0]['host']='127.0.0.1';
$conf['servers'][0]['defaultdb']='nomebancodefault';

131

//Exampleforasecondserver(PostgreSQLRemoto)
$conf['servers'][1]['desc']='Remoto';
$conf['servers'][1]['host']='10.99.00.11';
$conf['servers'][1]['port']=5432;
$conf['servers'][1]['defaultdb']='nomebancodefault';
...
...

//HostnameorIPaddressforserver.Use''forUNIXdomainsocket.
//use'localhost'forTCP/IPconnectiononthiscomputer
//Ifextraloginsecurityistrue,thenloginsviaphpPgAdminwithno
//passwordorcertainusernames(pgsql,postgres,root,administrator)
//willbedenied.OnlysetthisfalseonceyouhavereadtheFAQand
//understandhowtochangePostgreSQL'spg_hba.conftoenable
//passwordedlocalconnections.
$conf['extra_login_security']=false;

Comissoteremosumlogindophppgadminassim:

14.3PgAdmin
PgAdmin
Siteparadownload,casosuadistribuionotragaounotenhacomoinstalar(apt,synaptic
ououtrogerenciadordepacotes).
http://www.pgadmin.org/download/
umaferramentagrficadesenvolvidapelaequipededesenvolvimentodoPostgreSQL.
Muitosrecursos.TrazumhelpsobresieadocumentaodoPostgreSQL.TecleF1para
exibir.
AoexecutarconsultasnaferramentaSQL,tecleF7paravisualizargraficamenteaconsulta
naabaExplain.

132

14.4EMSPostgreSQL
OEMSumtimogerenciadordediversostiposdebancos,inclusivedoPostgreSQL.

Downloadhttp://www.sqlmanager.net/en/products/postgresql/manager(paraWindows
existeumaversofree,alite)
AquivouabordarasatividadesprincipaisebsicasdeusodoEMS:
Abrirembanco
Criaremnovobanco
Criartabelas
Criarcampos
Criarchaveprimria
Criarchaveestrangeira(relacionamento)
Importarscript.sqlparaumbancoexistente
Exportarbancocomoscriptsql
Executarconsultassql
Apsexecutaraparecealgocomo(verso3.1.5.2liteforWindows):

CRIARUMNOVOBANCO
EmGettingStarting(acimaedireita)cliquenobotoCreatenewdatabase
Entodigiteonomedonovobanco:

EcliquenobotoNext
Entoentrecomosdadosdoservidor(comoabaixo):

Naprximatelamudealgosomentesetivercerteza:

CliqueemNext

133

134

EntocliqueemFinish

EntocliqueemOK.
Entovemosobancojuntoaoservidor(abaixoedireita)

Paraabriloecriartabelasbastaumduplocliquenele.

CRIARTABELAS
Executeumduplocliquenonovobanco

Observeaestruturacriadaparaonovobanco:
CliquesobreTablescomobotodireitoeNewTable(outecleCtrl+N)

Acimadigitamosonomedatabelaondeexistetable1
EntoclicamosnaabaFields.

135

136
Maisumduploclique,agoraemColumnName,paraqueapareaoWizarddeCampos:

Vejaqueonomedocampocodigo.QueeledotipoBIGINTetambmchave
primria.
Vejaagoracomoaparecenossocampo(comumapequenachavedireita):

Issomostraqueestecamponossachaveprimria.

AddChaveEstrangeira

Add Chave

AddChaveEstrangeira

137

Dados

CliqueemCompileevejacomofica:

Banco e Host
Campo

DDL

Tabela

Adicionar Campo

Add Chave
ndice

Vamosadicionarmaisumcampo(nomevarchar(40)):

Adicioneosdemaiscamposdeformasemelhante.
VejaquesempredepoisdeumOKvemumbotodeCommit,comasintaxeSQLdo
comandoqueestamosexecutandonobanco.IssoumcontroledetransaesdoEMS
atravsdorecursoexistentenoPostgreSQL.

138

ABRIRUMBANCOEXISTENTE

139

Casoqueiramostrabalharemumbancoquejexistanoservidor,vamosapenasabrilo:
ApsabriroEMSapenasexecutamosumduplocliquesobreonomedobanco.
CasoonomedobanconoestejaaparecendonoEMSclicamosnoprimeirobotodabarra
deferramentas(RegisterDatabase)einformamososdadosdoservidor

ClicamosemNext.

EselecionamosobanconalistaDatabaseName:

140

EclicamosemFinish
COMOCRIARUMACHAVEESTRANGEIRA(FOREIGNKEY)
Apscriaratabelaeoscampos,devemoscriarasegundatabela,queirserelacionarcom
aprimeiraatravsdeumcampo(chaveestrangeira).
Vamossuporduastabelas:pedidosepedido_itens,queiroserelacionaratravsdocampo
cdigoempedidoecod_pedidoempedido_itens,comoabaixo:
pedido(codigo,descricao,data,preco_unitario)
pedido_itens(codigo,cod_pedido,quantidade)
Paraqueumcampodeumatabelaserelacionecomoutro,eledeveserdomesmotipoque
ooutro.
Abraatabelapedido_itens

141
EstandonaabaFields,cliqueemForeignKeynacolunadomeiocomobotodireitoeNew
ForeignKey.Vejaodilogoabaixo:

Acimaedireitaselecioneocampoqueirserelacionarcomaoutratabela(cod_pedido)
EmForeignTableselecioneatabeladorelacionamento(pedidos)

142
Entoabaixoedireitaselecioneocampoquevaiserelacionarcomeste(codigo)eclique
nasetaparaadireita.EntocliqueemOK.VejaqueemOnDeleteactioneemOnUpdate
Actionexistemdiversasopes.Vejameututorialsobreoassuntoem:
http://ribafs.clanshosting.com

EntocliqueemCommit.
AgoravejamoscomoficaocdigoSQLdanossatabelapedido_itens.CliquenaabaDDLe
ver:
CREATETABLE"public"."pedido_itens"(
"codigo"BIGINTNOTNULL,
"cod_pedido"BIGINT,
"quantidade"INTEGER,
CONSTRAINT"pedido_itens_pkey"PRIMARYKEY("codigo"),
CONSTRAINT"pedido_itens_fk"FOREIGNKEY("cod_pedido")
REFERENCES"public"."pedidos"("codigo")
ONDELETENOACTION
ONUPDATENOACTION
NOTDEFERRABLE
)WITHOIDS;

EXPORTANDOUMBANCOCOMOSCRIPT

143

Umaformamuitocomumdeseexportarumbanconaformadescript,especialmentepara
abrirnumoutroservidordomesmotipo:
CliquenomenuToolsExtractMetadata
SelecioneobancoquedesejaexportarecliqueemNext
NacomboFilenameselecioneodiretrioenomedearquivoparaondedesejaexportare
cliqueemSalvar.EntocliqueemNext.
Escolhasequerexportarsomentedados,somenteestruturaouambosecliqueemNext.
ApenascliqueemFinisheaoterminaremClose.
IMPORTANDOUMBANCODEUMSCRIPT
Estaaoperaoinversadaanteriormascomalgumasdiferenas.Seformosimportartudo,
devemosteraquiapenasumbancovazio.
AbrirobanconoEMS
ClicaremToolsSQLScript
AocentrocliqueemOpenscripteindiqueondeestoscriptaserimportado.
SetudoforimportadoacontendocliquenobotoRefreshTablesdireitadobotoCreate
paravisualizaraimportao.

EXECUTANDOCONSULTASSQLNOEMS
UmaboautilidadeparaogerenciadorEMSadetestedeconsultasSQL.
Abraobanco,abraoexecutordescript,digiteaconsultaemSQLeexecuteparasaberos
resultados.
Semprequetiveralgumadvidasobreumaconsultaexecuteaquiparatestarantes.

14.5AzzurryClay(modelagem)

144

FerramentadeModelagemAzzurryClay:
http://www.azzurri.jp/en/software/clay/index.jsp
VisualizadordeObjetosegeradordeDiagramasdeEntidadeRelacionamento(DER),alm
defazerengenhariareversanosbancosexistentes.
Umtimotutorialonline:
http://www.azzurri.jp/en/software/clay/quick_start_guide.jsp?print=on
UmaboarelaodeferramentasparaoPostgreSQLpodeserencontradanositedo
PostgreSQLBrasil:
https://wiki.postgresql.org.br/wiki/Ferramentas
OutraboarelaonositeDataModelingTools:
http://www.databaseanswers.com/modelling_tools.htm
14.6DbVisualizer
timaferramentaparavisualizarbancosemontarodiagramaentidadesrelacionamento.
http://www.dbvis.com/products/dbvis/download.html
14.7Openoffice2Base
UsandooOpenOfficeparaabrir,editarbancosdedadosPostgreSQL,comotambmcriar
consultas,formulrioserelatrios.
UmadasformasdeconectaroOpenOfficeaoPostgreSQLusandoumdriverJDBCdo
PostgreSQL.
AntesdevemosterinstaladooOpenOfficecomsuporteaJava
Baixedaqui:
http://jdbc.postgresql.org/download.html#jars
ParaoPostgreSQL8.1podemospegaroJDBC3
http://jdbc.postgresql.org/download/postgresql8.1405.jdbc3.jar
AbriroOpenOffice,podeseratoWriterFerramentasOpesJavaClassPath
AdicionarArquivo(indicaroarquivopostgresql8.0313.jdbc2.jarbaixado)eOK.
AbriroOOBase
Conectaraumbancodedadosexistente
SelecionarJDBCPrximo
URLdafontededados:
jdbc:postgresql://127.0.0.1:5432/bdteste
ClassedodriverJDBC:
org.postgresql.Driver
Nomedousuriopostgres
passwordrequired(marque,casousesenha)
Concluir
DigitarumnomeparaobancodoOOBase

145
Pronto.Agoratodasastabelasdobancobdtesteestodisponveisnobancocriadono
OOBase.
Tambmpodemosagoracriarconsultacomassistentes,criarformulrioserelatrioscom
facilidade.

15Apndices

146

15.1PlanejamentoeProjetodeBancosdeDados
ProjetodebancosdedadosgenricoeseaplicaaqualquerSGBDR.
comumbomplanejamentodobancodedadosquesedeterminaoquoeficazfoio
processodeanlise.
Introduo
Oprojetodobancodedadosetambmostestessomuitoimportantesparaaeficinciae
consistnciadasinformaesedoaplicativo.muitoimportantegastaralgumtemponesta
etapa,poisdepoisdealgumtempodeimplantadoficamuitotrabalhosoalterarestruturasde
bancoseaplicativos.
Projetosdebancodedadosineficazesgeramconsultasqueretornamdadosinesperados,
relatriosqueretornamvaloressemsentido,etc.Umbancodedadosbemprojetadofornece
umacessoconvenientesinformaesdesejadaseresultadosmaisrpidoseprecisos.
ExemplodesoftwaredeadministraodeSGBDparaoPostgreSQLPGAdmin
Informaesdebancosdedadosrelacionaissoarmazenadasemtabelasouentidadesno
ModeloEntidadeRelacionamento(MER).
DicassobreCampos
Noarmazenarresultadodeclculosoudadosderivadosdeoutros
Armazenartodasasinformaes(campos)separadamente.Cuidadocomcamposque
contmduasoumaisinformaes.
SelecionandooCampoparaaChavePrimria
Achaveprimriaocampooucamposqueidentificamdeformaexclusivacadaregistro.
Nopermitidovaloresnulosnachavenemduplicados
Casoatabelanotenhaumcampoqueaidentifique,podeseusarumcampoquenumere
osregistrosseqencialmente
DicadeDesempenho:Otamanhodachaveprimriaafetaodesempenhodasoperaes,
portantousaromenortamanhoquepossaacomodarosdadosdocampo.
Exemplo
TabelaClientes
CampoNome(atributo)
ChavePrimria(PrimaryKey)CPF
TodososcamposcorrespondentesaumnicoCPFjuntamentecomseusvaloresformamum
RegistroouLinha(Row)
Acorretadeterminaodastabelas,bemcomodoscamposalgoprimordialnosucessodo
projetodobancodedados.
ChavePrimriaobrigaquetodososregistrosteroocampocorrespondentechave

147
primriaexclusivo(nicosunique).Numcadastrodeclientes,todososclientescadastrados
teroumcampoCPFexclisivo.CasosetenteinserirdoisclientescomomesmoCPFo
banconopermitireemitirumamensagemdeerroacusandotentativadeviolaoda
chaveprimria.
ExemplosdeCamposindicadosparachaveprimria:
CPF
CNPJ
Matrculadealuno
Matrculadefuncionrio
Umachaveprimriapodeserformadapormaisdeumcampo,quandoumnicocampono
capazdecaracterizaratabela.
Cadatabelasomentepodeconterumanicachaveprimria.
RelacionamentosUmbancodedadosformadoporvriastabelas.Idealmenteessas
tabelasdevemserrelacionadasentresiparafacilitaratrocadeinformaesegarantira
integridade.Pararelacionartabelasusamoschavesexistentesnasmesmas.
TiposdeRelacionamentos
Umparaum
Umparavrios
Vriosparavrios
RelacionamentoUmparaUm
Aqueleondeoscamposquefazemorelacionamentosochavesprimrias.Cadaregistrode
umatabelaserelacionacomapenasumregistrodaoutratabela.Esterelacionamentono
muitocomum.
Exemplo:CorrentistaBancoConjuge
RelacionamentoUmparaVriosouVriosparaUm
Aqueleondeumatabelatemumcampochaveprimriaqueserelacionacomoutratabela
atravsdeumcampochaveestrangeira.otipoderelacionamentomaisutilizado.
Exemplos:
ClientesPedidos
ProdutosItens
CategoriasItens
FornecedoresProdutos
NotaFiscalProdutos
Vejaquecadaumdaesquerdaserelacionacomvriosdodadireita.
Importante:
Onmerodecamposdorelacionamentonoprecisaseromesmo
Otipodedadosdoscamposdorelacionamentodeveserigual,assimcomootamanhodos

camposeformatos

148

ChaveprimriaChaveestrangeira(umvrios)
RelacionamentoVriosparaVrios
Estetipoderelacionamentonodparaserimplementadonomodelorelacional,portanto
semprequenosdeparamoscomumdelesdevemosdividiremdoisrelacionamentosumpara
vrios(criandoumaterceiratabela,quearmazenaroladovriosdosrelacionamentos).
Exemplo:
PedidosProdutos
Cadapedidopodecontervriosprodutos,assimcomocadaprodutopodeestaremvrios
pedidos.Asadacriarumatabelaquecontenhaositensdopedido.
PedidosPedidos_ItensProdutos
Pedidos1NPedidos_ItensN1Produtos
IntegridadeReferencial
Elagaranteaintegridadedosdadosnastabelasrelacionadas.Umbomexemploquandoo
bancoimpedequesecadastreumpedidoparaumclienteinexistente,ouimpedequese
removaumclientequetempedidosemseunome.
TambmsepodecriarobancodeformaquequandoatualizamosoCPFdeumclienteele
sejaatualizadoemtodososseuspedidos.
NormalizaodeTabelas
Normalizarbancostemoobjetivodetornarobancomaiseficiente.
Umaregramuitoimportanteaocriartabelasatentarparaquecadatabelacontenha
informaessobreumnicoassunto,deumnicotipo.
1aFormaNormal
Oscamposnodevemcontergruposdecamposqueserepetemnosregistros.
Exemplo:
Alunos:matricula,nome,data_nasc,serie,pai,mae
Seaescolatemvriosfilhosdeummesmocasalhaverrepetiodonomedospais.Esto
paraatenderprimeiraregra,criamosoutratabelacomosnomesdospaiseamatrculado
aluno.
2FormaNormal
Quandoachaveprimriacompostapormaisdeumcampo.
Devemosobservarsetodososcamposquenofazempartedachave
dependemdetodososcamposquefazempartedachave.
Casoalgumcampodependasomentedepartedachave,entodevemoscolocarestecampo

emoutratabela.

149

Exemplo:
TabelaAlunos
Chave(matricula,codigo_curso)
avaliacaodescricao_curso
Nestecasoocampodescricao_cursodependeapenasdocodigo_curso,ouseja,tendoo
cdigodocursoconseguimossuadescrio.Entoestatabelanoestna2Forma
Normal.
Soluo:
Dividiratabelaemduas(alunosecursos):
TabelaAlunos
Chave(matricula,codigo_curso)
avaliacao
TabelaCursos
codigo_curso
descricao_curso
3FormaNormal
Quandoumcamponodependentediretamentedachaveprimriaoudepartedela,mas
deoutrocampodatabelaquenopertencechaveprimria.Quandoissoocorreestatabela
noestnaterceiraformanormaleasoluodividiratabela.
Lembrando:EngenhariaReversa(partedeumbancooudeumscriptsqlegeraomodelo).
Projeto
FasesdoProjetodoBancodeDados
ModelagemConceitual
ProjetoLgico
Observao.:Trataremosapenasdenovosprojetos.
ModeloConceitualDefineapenasquaisosdadosqueapareceronobancodedados,
semseimportarcomaimplementaodobanco.Paraessafaseoquemaisseutilizao
DER(DiagramaEntidadeRelacionamento).
ModeloLgicoDefinequaisastabelaseoscamposqueformaroastabelas,como
tambmoscamposchave,masaindanosepreocupacomdetalhescomootipodedados
doscampos,tamanho,etc.
EtapasnaEstruturaoeProjetodeumBancodeDados
Problemasaseremsolucionadoscomobancodedados
Determinaroobjetivodobancodedados

Determinarastabelasnecessrias(cadaumacomumnicoassuntoexclusivo)
Determinaroscamposdecadatabela
CriarumDER
Verificaraestimativadocrescimentodobancoeprepararseparaisso
Investigarcomosoarmazenadasasinformaesatualmenteerecolheramaior
quantidadedeinformaesparaoprojeto
Adotarummodeloejustificlo
(OsitensacimafazempartedoModeloConceitual,abaixodoLgico)
Determinarachaveprimriadecadatabela.Podehavertabelasemchaveprimria.
Determinarosrelacionamentoseseustipos

150

Obs.:Somentequandodaimplementao(modelofsico)serotratadososdetalhesinternos
dearmazenamento.Omodelofsicoatraduodomodelolgicoparaalinguagemdo
SGBDRaserutilizadonosistema.

15.2ImplementaodeBancodeDadoscomoPostgreSQLModeloFsico

151

SoftwaresfreedeModelagemeGerenciamentodoPostgreSQL
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/
EmformadePluginsparaEclipse
QuantumDB:(http://quantum.sourceforge.net/)
Azzurri/Clay:(http://www.azzurri.jp/en/software/clay/download.jsp)
SQLExplorer:(http://sourceforge.net/projects/eclipsesql)
Umagrandeeboarelaodesoftwaresdeprojeto,modelagemegerenciamentoparao
PostgreSQL,freeecomercialpodeserencontradaemnositeoficialsoPostgreSQLBrasil:
https://wiki.postgresql.org.br/wiki/Ferramentas.
SuporteAcentuaonaCriaodeBancosnoPostgreSQL
AcodificaodefaultdoPG7.XaSQL_ASCII
AdoPG8.XaUNICODE
Ambastemsuporteaacentuao,masgeramproblemasnobackup/importao.
Codificao
ParaumsuporteestvelacentuaoemportugusdoBrasilumaboaopocriaro
bancopassandoacodificao(Encoding)LATIN1
ENCODING='LATIN1'
CriaodoBanco
CriaremosobancodoprojetodetestescomoPGAdmin,contendoesquemas,tabelas,
views,funesdotipoSQLePl/PgSQL,usurios,privilgios,consultas,etc.parailustrar
nossoprojetoeservirdebaseparaostestes(emseguida).
Analisaromodelosugeridoedetalharobanco,tiposdedadosdecadacampo,tamanho,
esquemasdobanco,usuriosesenhas,privilgiosdecadaum(cuidadoscomasegurana),
etc.
AtivaroSuportesFunesPl/Pgsql(StoredProcedures)
Apstercriadoobanco,podemosativarosuporteaplpgsql.
AtivarsuporteaPl/PgSQLrequerdoispassos:
instalarabibliotecaPl/PgSQL,quedotipocontrib
definiralinguagem(comosugeridoabaixo)
- AtivandonaconsoledoPGdepoisdeconectaraobancoondeficarosuporte:
CREATELANGUAGE'plpgsql'HANDLERplpgsql_call_handlerLANCOMPILER'PL/pgSQL'
Ativandocomosuperusurionaconsole(foradosbancos)
supostgres

$createlangplpgsqlUnomesuperusernomebanco
Ousimplesmente:
$createlangplpgsqlnomebanco

152

JDBC
AlgunsprogramasemJavaoutilizam,comoopluginQuantumDB.
OJDBCparaoPostgreSQLencontraseem:
http://jdbc.postgresql.org/download.html#jars
Vejaqueparaselecionaroarquivo.jarcorreto,precisamoscruzaraversodo
PostgreSQLesquerdacomaversodoJDBCdesejado.
Exemplo:ParausocomoclienteemsuamquinapeloQuantumDB(noEclipse)ecom
PostgreSQL8.1baixaroarquivo:8.1405JDBC3
Esquemas
Definirosesquemasdobanco.
Quandooclienteprecisademuitastabelas,organizadasemvriasreasasadaimediata
acriaodevriosbancosdedados.Masquandodaimplementaodoaplicativoqueir
utilizarestesbancososdesenvolvedoressedepararocomadificuldadedecomunicaoe
acessoentreosbancos,jquecomumanicaconexoteroacessoatodososobjetosdo
banco.muitotilparaestescasoscriarumnicobancoenestecriarvriosesquemas,
organizadosporreas:pessoal,administracao,contabilidade,engenharia,etc.
Masequandoumadestasreastemoutrassubreas,comoporexemploaengenharia,que
temreservatrios,obras,custosecadaumdestestemdiversastabelas.Oesquema
engenhariaficarmuitodesorganizado.Emtermosdeorganizaooidealseriacriarum
bancoparacadarea,engenharia,contabilidade,administrao,etc.Eparaengenharia,por
exemplo,criaresquemasparacadasubarea,custos,obras,etc.Masnooidealemtermos
decomunicaoeacessoentretodososbancos.
CriarEsquema
NumgerenciadordoPGentrasenobancoenessecriaseoesquema.
Ou
CREATESCHEMAnomeesquema;
AcessandoObjetosdeEsquemas
Paraacessarumesquemadevemospassarseucaminho:
nomeesquema.nometabela
Ou
nomebanco.nomeesquema.nometabela

153
CriandoTabelaemEsquema
CREATETABLEnomeesquema.nometabela(
...
)
CriandoEsquemaetornandoumUsuriodono
CREATESCHEMAnomeesquemaAUTHORIZATIONnomeusuario;
Removendoprivilgiosdeacessoausurioemesquema
REVOKECREATEONSCHEMApublicFROMPUBLIC
Comissoestamostirandooprivilgiodetodososusuriosacessaremoesquemapublic.
AcessoaosEsquemas
QuandosecriaumbanconoPostgreSQL,pordefault,elecriaumesquemapblico(public)
nomesmoenesteesquemaquesocriadostodososobjetosquandonoespecificamoso
esquema.Aesteesquemapublictodososusuriosdobancotmlivreacesso,masaos
demaisexisteanecessidadedesedarpermissoparaqueosmesmosacessem.
Tabelas
OPostgreSQLpermiteadicionarprivilgiosporobjetodobanco:tabela,esquema,banco,etc.
Emtermosdeseguranaimportante,emgeral,queosprivilgiossejamadicionadosao
usurioportabela,cadatabelatendoumdonoecadadonotendoseusespecficos
privilgios.
DicadeDesempenho:Nacriaodastabelasalertarparaacriaodendicesparaos
camposenvolvidosnaclusulaWHERE.Issotornaressasconsultasmaisrpidas.
Views
Juntamentecomasfunesarmazenadas(storedprocedures)asviewssoboasalternativas
para tornar o cdigo mais simples e o aplicativo mais eficientes, j que parte do
processamentofeitopelocdigoagorajestprontoedebugadonobanco,oquetornao
cdigomaisrpidoeeficiente.Ousodeviewsedefunesarmazenadasembancos
semelhanteaousodefuneseclassesnocdigo.
Dica:parausodeviews,sintaxedefunesinternaseusodeclusulasSQLno
PostgreSQL,tutoriaisdeEMSevriosoutrossobrePostgreSQL,almdePHP,JavaScript,
etc,confiraositeabaixo:
http://ribafs.byethost2.comou
http://ribafs.tk
CriaodoBancoTutorialsobrePGAdminparacriarobancofuncionarios.
Bem,depossedoscript.sqlacima,praticamenteoqueteremosdefazercriarumbanco
vazionoPGAdmin.
AbriroPGAdmin
Casonotenhasalvadoasenhaelepedirsemprequeiniciar

154
AoabrircliquecomobotodireitodireitaemDatabaseseemNewDatabase.
NodilogoNewDatabaseentrecomoNamedobanco(funcionarios),oOwner(postgres).
Idealmentemudaronomedosuperusuariodefaultparaumnomemaisseguro,assimcomoa
senha(mnimode8caracteres,misturandoletrasealgarismoseidealmentecomsmbolos).
TambmaltereEncoding(codificao)paraLATIN1.
EntoselecioneobancofuncionariosecliquenobotoSQLacima.
Cliquenobotoopenfileparaindicaronossoscriptsqlgeradoanteriormente.
Cliquenasetinhaverde(Executequery)

155

EventuaisCorrees:
CasorecebamensagensdeerrosobretipoUNSIGNED,verifiqueoscripteremovatodasas
ocorrnciasdeUNSIGNEDeexecutenovamente.ComooDBDesignerfoiprojetadoparao
MySQLumoutroerroquepodeocorrercomastringAUTO_INCREMENT,quetambm
deveserremovidaenovamentedevemosexecutaroscript.Feitasestascorreesoscript
executanormalmenteecriaonossobancofuncionarios.
Entoverifiqueesquerdaqueobancojcontmas3tabelasdeacordocomoscript.
EngenhariaReversa
UmtimosoftwareparaconexoaoPostgreSQL,engenhariareversa(geradiagramasER
dosbancosexistentes)eexportaosdiagramasemformadeimagens:DbVisualizer.

15.3IntegridadeReferencialPostgresql
Traduolivredodocumentao"CBTIntegrityReferential":
http://techdocs.postgresql.org/college/002_referentialintegrity/.
IntegridadeReferencial(relacionamento)ondeumainformaoemumatabelase
refereinformaesemoutratabelaeobancodedadosreforaaintegridade.
Tabela1>Tabela2
OndeUtilizado?
Ondepelomenosemumatabelaprecisasereferirparainformaesemoutratabelae
ambasprecisamterseusdadossincronizados.
Exemplo:umatabelacomumalistadeclienteseoutratabelacomumalistadospedidos
efetuadosporeles.
Comintegridadereferencialdevidamenteimplantadanestastabelas,obancoirgarantirque
vocnuncaircadastrarumpedidonatabelapedidosdeumclientequenoexistanatabela
clientes.
Obancopodeserinstrudoparaautomaticamenteatualizarouexcluirentradasnastabelas
quandonecessrio.
PrimaryKey(ChavePrimria)ocampodeumatabelacriadoparaqueasoutrastabelas
relacionadasserefiramaelaporestecampo.Impedemaisdeumregistrocomvalores
iguais.acombinaointernadeUNIQUEeNOTNULL.
Qualquercampoemoutratabeladobancopodesereferiraocampochaveprimria,desde
quetenhamomesmotipodedadosetamanhodachaveprimria.
Exemplo:
clientes(codigoINTEGER,nome_clienteVARCHAR(60))
codigo
nome_cliente
1
PostgreSQLinc.
2
RedHatinc.

pedidos(relacionaseClientespelocampocod_cliente)
cod_pedidocod_clientedescricao

156

157
Casotentemoscadastrarumpedidocomcod_cliente2eleseraceito.
Mascasotentemoscadastrarumpedidocomcod_cliente3eleserrecusadopelobanco.
CriandoumaChavePrimria
Devesercriadaquandodacriaodatabela,paragarantirvaloresexclusivosnocampo.
CREATETABLEclientes(cod_clienteBIGINT,nome_clienteVARCHAR(60)
PRIMARYKEY(cod_cliente));
CriandoumaChaveEstrangeira(ForeignKeys)
ocampodeumatabelaqueserefereaocampoPrimaryKeydeoutra.
Ocampopedidos.cod_clienterefereseaocampoclientes.codigo,entopedidos.cod_cliente
umachaveestrangeira,queocampoqueligaestatabelaaumaoutra.
CREATETABLEpedidos(
cod_pedidoBIGINT,
cod_clienteBIGINTREFERENCESclientes,
descricaoVARCHAR(60)
);
Outroexemplo:
FOREIGNKEY(campoa,campob)
REFERENCEStabela1(campoa,campob)
ONUPDATECASCADE
ONDELETECASCADE);
Cuidadocomexclusoemcascata.Somenteutilizecomcertezadoquefaz.
Dica:Casodesejemosfazerorelacionamentocomumcampoquenosejaachaveprimria,
devemospassarestecampoentreparntesesapsonomedatabelaeomesmodeve
obrigatoriamenteserUNIQUE.
...
cod_clienteBIGINTREFERENCESclientes(nomecampo),
...
ParmetrosOpcionais:ONUPDATEparametroeONDELETEparametro.
ONUPDATEparamentros:
NOACTION(RESTRICT)quandoocampochaveprimriaestparaseratualizadoa
atualizaoabortadacasoumregistroemumatabelareferenciadatenhaumvalormais
antigo.Esteparmetroodefaultquandoestaclusulanorecebenenhumparmetro.
Exemplo:ERROAotentarusar"UPDATEclientesSETcodigo=5WHEREcodigo=2.Ele
vaitentaratualizarocdigopara5mascomoempedidosexistemregistrosdocliente2
haveroerro.
CASCADE(EmCascata)Quandoocampodachaveprimriaatualizado,registrosna

tabelareferenciadasoatualizados.

158

Exemplo:Funciona:Aotentarusar"UPDATEclientesSETcodigo=5WHEREcodigo=2.
Elevaitentaratualizarocdigopara5evaiatualizarestachavetambmnatabelapedidos.
SETNULL(atribuirNULL)Quandoumregistronachaveprimriaatualizado,todosos
camposdosregistrosreferenciadosaestesosetadosparaNULL.
Exemplo:UPDATEclientesSETcodigo=9WHEREcodigo=5;
Naclientesocodigovaipara5eempedidos,todososcamposcod_clientecomvalor5sero
setadosparaNULL.
SETDEFAULT(assumiroDefault)Quandoumregistronachaveprimriaatualizado,
todososcamposnosregistrosrelacionadossosetadosparaseuvalorDEFAULT.
Exemplo:seovalordefaultdocodigodeclientes999,ento
UPDATEclientesSETcodigo=10WHEREcodigo=2.Apsestaconsultaocampocdigo
comvalor2emclientesvaipara999etambmtodososcamposcod_clienteempedidos.
ONDELETEparametros:
NOACTION(RESTRICT)Quandoumcampodechaveprimriaestparaserdeletado,a
exclusoserabortadacasoovalordeumregistronatabelareferenciadasejamaisvelho.
Esteparmetroodefaultquandoestaclusulanorecebenenhumparmetro.
Exemplo:ERROemDELETEFROMclientesWHEREcodigo=2.Nofuncionarcasoo
cod_clienteempedidoscontenhaumvalormaisantigoquecodigoemclientes.
CASCADEQuandoumregistrocomachaveprimriaexcludo,todososregistros
relacionadoscomaquelachavesoexcludos.
SETNULLQuandoumregistrocomachaveprimriaexcludo,osrespectivoscamposna
tabelarelacionadasosetadosparaNULL.
SETDEFAULTQuandoumregistrocomachaveprimriaexcludo,oscampos
respectivosdatabelarelacionadasosetadosparaseuvalorDEFAULT.
ExcluindoTabelasRelacionadas
Paraexcluirtabelasrelacionadas,antesdevemosexcluiratabelacomchaveestrangeira.
TudoissoestnadocumentaosobreCREATETABLE:
http://www.postgresql.org/docs/8.0/interactive/sqlcreatetable.html
ALTERTABLE
http://www.postgresql.org/docs/8.0/interactive/sqlaltertable.html

ChavePrimriaComposta(doiscampos)
CREATETABLEtabela(
codigoINTEGER,
dataDATE,
nomeVARCHAR(40),
PRIMARYKEY(codigo,data)
);

159

15.4DicasPrticasdeusodoSQL
ArmazenarArquivosBinriosnoPrprioBanco
UtilizeacontribLOparaestafinalidade.
Lembrequecomoumacontribnormalmentenovemligadaetemosqueligar
especificamenteaobancoondequeremosutilizar.
Ligando,dedentrodobancousarocomando\i:
AcesseodiretriolodascontribsdoPostgreSQL:
/usr/local/src/postgresql8.1.3/contrib/lo
Entoexecuteocomando"makeinstall".
Acesseobancoe:
\i/usr/local/src/postgresql8.1.3/contrib/lo/lo.sql
ParausarvejaoREADME.lonodiretrioloetambmadocumentaooficialdo
PostgreSQL:
PortugusdoBrasilCaptulo28:
http://pgdocptbr.sourceforge.net/pg80/largeobjects.html
InglsCaptulo29:http://www.postgresql.org/docs/8.1/interactive/largeobjects.html

NomesdeCamposcomespaoouacento
Devemvirentreaspasduplas.
Comentrios
EmSQLoscomentriosmaisutilizadossodaseguinteforma:
SELECT*FROMtabela;Esteumcomentrio
Esteoutrocomentrio
TambmsoaceitososcomentriosherdadosdoC:
/*ComentrioherdadodoCevlidoemSQL*/
DicasPrticasdeUsodoSQL

Testarsecampodeemail,ouseja,secontmum@:
SELECTPOSITION('@'IN'ribafs@gmail.com')>0
select'ribafs@gmail.com'~'@'
select'ribafs@gmail.com'like'%@%'
select'ribafs@gmail.com'similarto'%@%.%';
AlgunsdalistadePHP(phpfortaleza@yahoogrupos.com.brgroups.yahoo.com).

160

Temosumcampo(insumo)comvalores=1,2,3,...87
Queremosatualizarpara0001,0002,0003,...0087

161

UPDATEequipamentosSETinsumo='000'||insumoWHERELENGTH(insumo)=1;
UPDATEequipamentosSETinsumo='00'||insumoWHERELENGTH(insumo)=2;
Outrasadamaiseleganteainda:
UPDATEequipamentosSETinsumo=REPEAT('0',4LENGTH(insumo))||insumo;

INSERINDOCOMSELECT
Tendoumatabelacomregistroseoutraparaondedesejoincluirregistrosdaquela
INSERTINTOequipamentos2SELECTgrupo,insumo,descricao,unidadefrom
equipamentos2;
insertintoengenharia.precos(insumo_grupo,insumo)selectgrupo,insumofromengenharia;
ComCAST
insertintoengenharia.insumos(grupo,insumo,descricao,unidade)select
grupo,insumo,descricao,CAST(unidadeASint2)AS"unidade"fromengenharia.apagar
insertintoengenharia.insumos(grupo,insumo,descricao,unidade)select
grupo,insumo,descricao,cast(unidadeASINT2)ASunidadefromengenharia.apagar
selecttrim(length(bairro))fromcep_tabelawherecep='60420440';Montese,Retorna7
AtravsdoPHP
$conn=pg_connect("host=10.40.100.186dbname=apoenauser=_postgresql");
for($x=10;$x<=87;$x++){
$sql="updateengenharia.precossetcusto_produtivo=(selectcusto_produtivofrom
engenharia.apagarwhereinsumo='$x')whereinsumo='00'||'$x'";
$ret=pg_query($conn,$sql);
}
DiferenaemDiasentreduasDatas
SELECTDATE'20060329'DATE'20060112';
SELECT(CAST('10/02/2005'ASDATE)CAST('10/01/2006'));

POPULARBANCOCOMMASSADETESTES

162

ScriptelPerl
#!/usr/bin/perl
$count=1;
$arquivosaida="populate.sql";
@chars=("A".."Z","a".."z",0..9);
@numbers=(1..9);
@single_chars=("a".."e");
$totalrecords=5000;#5milhoes
open(OUTPUT,">$arquivosaida");
printOUTPUT"DROPTABLEindex_teste;\n";
printOUTPUT"CREATETABLEindex_teste(";
printOUTPUT"codigoINT,nomeVARCHAR(10),numeroINT,letraCHAR(1)";
printOUTPUT");\n";
printOUTPUT"COPYindex_teste(codigo,nome,numero,letra)FROMstdin;\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)]);
printOUTPUT
#printOUTPUT"INSERTINTOindex_teste
VALUES($count,'$randstring',$randnum,'$randletter');\n";
$count."\t".$randstring."\t".$randnum."\t".$randletter."\n";
$count++;
};
#printOUTPUT"\n";
#printOUTPUT"\nCREATEINDEXindexteste_codigo_indexONindex_teste(codigo);\n";
#printOUTPUT"CREATEINDEXindexteste_numero_indexONindex_teste(numero);\n";
#printOUTPUT"VACUUMANALYZEindex_teste;\n";
closeOUTPUT;
ViaPHP
$con=pg_connect("host=127.0.0.1user=postgrespassword=postgres");
functiondatediff($data_final,$data_inicial){
global$con;
$str="SELECTDATE'$data_final'DATE'$data_inicial'";
$recordset=pg_query($con,$str);
$diferena=pg_fetch_array($recordset);
return$diferena[0];
}
echo"Diferena:".datediff("19690108","19681016");

163

AjustandooformatodaDatadoSistema

164

SHOWDATESTYLE;
SETDATESTYLETOISO;
YYYYMMDDHH:MM:SS
SETDATESTYLETOPostgreSQL;
FormatotradicionaldoPostgreSQL(
SETDATESTYLETOUS; MM/DD/YYYY
SETDATESTYLETONONEUROPEAN,GERMAN; DD.MM.YYYY
SETDATESTYLETOEUROPEAN;
DD/MM/YYYY
Obs.:Deformapermanenteajustaropostgresql.conf.
OutrosusosparaSHOW:
SHOWserver_version;
SHOWserver_encoding;Idiomaparaordenaodotexto(definidopeloinitdb)
SHOWlc_collate; Idiomaparaclassificaodecaracteres(definidopeloinitdb)
SHOWall; Mostratodososparmetros
Tambmpodemossetarodatestylequandoalteramosumbanco:
ALTERDATABASEnomebancoSETDATESTYLE=SQL,DMY;
TambmpodeseratribudojuntamentecomoUsurio:
ALTERROLEnomeuserSETDATESTYLETOSQL,DMY;
AjustandoumaFaixadeRegistroscomLIMITandOFFSET
SELECTisbn,title,publicationFROMeditionsNATURALJOINbooksASb(book_id)
ORDERBYpublicationDESCLIMIT5;
SELECTisbn,title,publicationFROMeditionsNATURALJOINbooksASb(book_id)
ORDERBYpublicationDESCLIMIT5OFFSET2;
Trar5registros,iniciandodosegundo.
fsyncchecaintegridadedosdadosgravadosnobanco,vindosdoslogs.Vemligadopor
padro

GargalodeSGBDsleitura/gravao(I/O)dediscos.
Ligar/Desligarfsyncno:
postgresql.conf,setarpara
fsync=trueNuncadeveficarfalse
REORDENARCAMPOSDETABELA
Sevocestiverfalandodaordemdoscamposnatabelanoexisterazoparaissono
modelorelacional.
Vocsemprepodeespecificaroscamposdesejados,enaordemdesejada,
noSELECT.

Senecessriovocpodecriarumaview:
CREATEVIEWnome_viewASSELECTid,cpf,nomeFROMsua_tabela;

165

Seaindanoestiversatisfeitopoisquersuastabelas"bonitinhas"eorganizadas:
1.CREATETABLEnovo_nomeASSELECTid,cpf,nomeFROMsua_tabela;
2.DROPTABLEsua_tabela;
3.ALTERTABLEnovo_nomeRENAMETOsua_tabela;
Osvaldo(NalistaPostgreSQLBrasil).

166

CalculandoaMemriaaserusadapeloPostgreSQL
*SharedBuffers
Exemplode1GBRAM
Asharedbuffersser25%daRAM
256*1024/8=32768
logoshared_buffers=32768
*SharedMemory
ASharedMemoryserigualasharedbuffer+(de10a20)%
SharedMemory=256MB+15%
256MB+15%=295MB
295MB=295*1024*1024=309329920
NoLinux:
/etc/sysctl.conf
kernel.shmmax=309329920
kernel.shmall=309329920
kernel.shmmni=1
ComandoparaalterarasvariveisdokernelsemreiniciaroLinux:
sysctlwkernel.shmmax=309329920
sysctlwkernel.shmall=309329920
sysctlwkernel.shmmni=1
DicasdeinstalaodoPostgreSQLemGNU/Linux.
*UtilizarHDdotipoSATA
*Criarumapartioexclusivaparaosdados.Ex:/database
*UtilizarnestapartioosistemadearquivosXFS
*Deixarnestapartioapenasosflags:RW,NOATIME
Dosite:http://www.gescla.com.br/oficina_postgre.asp
CriaodeTiposdeDados
CREATETYPE"img"(input="int4in",output="int4out",internallength=4,externallength=
10,delimiter=",",send="int4out",receive="int4in",passedbyvalue,alignment=int,storage
=plain);
Uso:
createtableimagens(codigoint8,descricaovarchar(60),imagemimg);
ConstrutordeMatriz
Matrizunidimensionalarray[2,4,6+2]

167

SELECTarray[2,4,6+2];Retorna2,4,8

Multidimensionalcompostaporduasoumaismatrizesunidimensionais:

Obs.:OndicedovalordamatrizconstrudocomARRAYsemprecomeacomum.

Aocriarumatabelapodemosusarmatrizemseustiposdedados,aoinvsdetipos
simples.

Exemplo:

CREATETABLEtestematriz(codigoINT[],nomechar[30][30]);

array[array[2,4,6],array[1,3,5]]ou
array[[2,4,6],[1,3,5]]
Comsubconsultas.Entreparntesesenoconcletes.
selectarray(selectoidfrompg_procwherepronamelike'bytea%');
Retorna:1244,31,1948,1949,1950,1951,1952,1953,1954,2005,2006,2011,2412,2413,16823

ENCONTRARREGISTROSDUPLICADOS
SELECTDISTINCTcepFROMcep_tabela
WHEREcepIN(SELECTcepFROMcep_tabelaASTmpGROUPBYcep,tipo,logradouro,
bairro,municipio,ufHAVINGCount(*)>1)ORDERBYcep;
(AdaptaodeconsultageradapeloassistenteEncontrarduplicadasdoAccess).
Ou:
selectcount(*)asquantos,cepfromcep_tabelagroupbycephavingcount(*)>1;
REMOVERDUPLICADOS
ParatabelascriadasWITHOIDS:
DELETEFROMcep_tabela2WHEREoidNOTIN
(SELECTmin(oid)FROMcep_tabela2GROUPBYcep,tipo,logradouro,bairro,municipio,
uf);
Doexemplo8.10domanualemportugusdoBrasil.
Ou:
Criandoumasegundatabelaquecontersomenteosregistrosexclusivoseaindaguarda
umacpiadatabelaoriginal:
CREATETABLEcep_tabela2ASSELECTcep,tipo,logradouro,bairro,municipio,ufFROM
cep_tabelaGROUPBYcep,tipo,logradouro,bairro,municipio,ufORDERBYcep;

168
Casonoimportequaldasduplicatasirpermanecer:
CREATETABLEtab_tempASSELECTDISTINCT*FROMtabela;
DROPtabela;
ALTERTABLEtab_tempRENAMETOtabela;
(DicadeOsvaldoRosarioKussamanalistadePostgreSQLBrasil)
Delimitadores
Amaioriadostiposdedadostemseusvaloresdelimitadosporapstrofos(),aexemplode:
- caracteres
- data/hora
- monetrio
- boleanos
- binrios
- geomtricos
- arrays
Aexceoparaosdemaistiposnumricos:date18/12/2005numeric12345.45
CaracteresEspeciais
Parapoderescreverumabarranovalordeumaconstante,usaseduasbarras:
SELECT'\\Barra';
Paraescreverumapstrofousasedoisapstrofos:
SELECT'EditoraO''Reyle';
PPostgreSQLtambmpermiteousodecaracteresdeescapeparaescrevercaracteres
especiais:
SELECT'EditoraO\'Reyle';
Concatenaodeexpressesnoterminal:
SELECT'Concate'
'nao';
Equivalea:
SELECT'Concatenao';
Quandoresolvendoexpressesmatemticasusarparntesesparatornarmaisclarasas
precedncias.
ConvertendoparaNmeros
SELECTTO_NUMBER('0'||'1,500.64',99999999.99);
Totalde8dgitoscom2decimais.
Variveisnopsql
\psetnull'(nulo)'
traduzindonullpornulo

169
SELECTNULL;
\setvariavel14
Dandovalor14varivel
SELECT:variavel;
COPIARTABELACOMREGISTROS
CREATETABLEtabeladestinoASSELECT*FROMtabelaorigem;
Teremosquerecriarasconstraints.

170

phpPgGIS
http://www.geolivre.org.br/modules/news/
Emmaisumgrandelanamento,aOpenGEOcolocadisposiodacomunidadeuma
ferramentaextremamenteltilparagernciadedadosgeogrficosnoPostgreSQL.O
phpPgGISmaisumprodutodaOpenGEOquecontemplaumademandanareade
Geotecnologiasevisaatenderusuriosdomundointeiro.

DesenvolvidocombasenophpPgAdmin,ophpPgGISutilizaoMapServerparavisualizaro
contedoespacialdoscamposdoPostGIScommuitasimplicidade(umclique).Seqncias
decdigoscomplexos(campodegeometria)agorapodemservistosnummapa.
OOpenGEOtematuadonomercadobrasileirodeGeotecnologiascomsoluesinovadoras
combaseemsoftwarelivreejganhourefernciainternacionalcomalgunsimportantes
projetoscomooOpen3DGISeoGeoLivreLinux.
EstesistemavaiintegrarasoluodeHostingqueaempresadeverlanarnasprximas
semanas.
AlgumasDefinies
Cursor
umponteiroparaumalinha(registro).
Replicao
adistribuiodedadoscorporativosparavrioslocaisoufiliaisdeumaempresa,
oferecendoconfiabilidade,tolernciaafalhas,melhordesempenhoecapacidadede
gerenciamento.
Criptografia
Seuobjetivotornarosdadoscomunsembitsdeaparnciacompletamentealeatria.
MAISCULASEMINSCULASNOPOSTGRESQL
AodigitarnomesdetabelasecamposemMaisculaselesseroconvertidos
automaticamenteparaminsculas,anoserquesejamdigitadosentreaspasduplas:
SELECT*FROM"CLIENTES";
Recomendao:evitarousodemaisculasedeacentosemnomesdebancos,tabelase
campos.
POSTGRESQLNOCONECTA?
DositedoRodrigo(HJort)
PingarnoIP
Verificaropg_hba.confhost,banco,usurioIPesenha

Casoaparea"Istheserverrunningonhost.."
TestarcomtelnetIPporta(Ctrl+Cparasair)
Nopostgresql.conflisten_addresses='IP'
SalvarerestartaroSGBD.
ContadordeResultados

171

Indicadoparaconsultaserelatrios(nograva)
CREATETEMPSEQUENCEseq;
SELECTnexval('seq'),*FROMesquema.tabela;
(SalvadorS.ScarduanalistaPostgreSQLBrasil)
LIMITESDOPOSTGRESQL
TamanhodeumBancodeDadosilimitado
Tamanhodeumatabela32TB
Quantidadederegistrosportabelailimitados
Quantidadedecamposportabela250a1600(dependedotipo)
Quantidadedendicesportabelailimitados
15.5DicassobreDesempenhoeOtimizaesdoPostgreSQL
ExistemduasprincipaisformasdemelhorarodesempenhodeSGBDs:umamelhorandoo
hardware,comCPUs,RAM,Discosmaisnovos,rpidoseconfiveis.Aoutraotimizandoas
consultasrealizadasnosbancos(usandoVACUUM,VACUUMANALYZE,EXPLAIN,criando
CLUSTERS,entreoutros).
Umadasmedidasbsicasadotadaparamelhorarodesempenhodetabelascomgrandes
quantidadesderegistroseespecialmentecommuitosacessos,ainclusodendices
estratgicos.Almdachaveprimriaimportanteinserirndicesemcamposquecompem
aclusulaWHERE,quefazempartedeclusulasORDERBY,GROUPBYentreoutras.Em
consultascomWHEREdevrioscamposusandoOR,noadiantainserirndice,poisno
serutilizadopeloPostgreSQL,somenteusandoAND.
Nacriaodobancodedadoseespecialmentenacriaodasconsultasmuitoimportante
atentarparaumbomplanejamento,normalizao,consultasotimizadastendoemvistao
planejadordeconsultasdoPostgreSQLatravsdousodoscomandosEXPLAINeANALYZE.
AadministraodoPostgreSQLtambmmuitoimportanteparatornaroSGBDmais
eficienteerpido.Desdeainstalaoeconfiguraotemoscuidadosqueajudamaotimizar
oPostgreSQL.
AdaptaodoArtigosobreotimizaodoPostgreSQLdoDiogoBiazusedooriginal
doBruceMomjian(http://www.ca.postgresql.org/docs/momjian/hw_performance).
Hardware
NocomputadorasinformaessomanipuladaspelosregistradoresdaCPU,pelocacheda
CPU,pelamemriaRAMepelosdiscosrgidos.

172
NaprticaasinformaesutilizadascommaisfreqnciasocolocadasprximasCPU.
Quemdeterminaqueinformaesdevemficarnosregistradoressooscompiladores.
CachedaCPUguardaarinformaesutilizadasrecentemente.
OSistemaOperacionalcontrolaoqueestarmazenadonaRAMeoquemandarparao
discorgido.

173
CacheeRegistradoresdaCPUnopodemserotimizadosdiretamentepeloadministradordo
SGBD.Efetivamenteotimizaoembancosdedadosenvolvemaumentodaquantidadede
informaesteisnaRAM,prevenindoacessoadiscosemprequepossvel.
Notarefasimplesdesercolocadaemprtica,poisamemriaRAMguardamuitasoutras
informaes:programasemexecuo,pilhasedadosdeprogramas,memriacache
compartilhadadoPostgreSQL,cachedobufferdediscodokernelekernel.
Otimizaocorretadebancosdedadosprocuramanteramaiorquantidadepossvelde
informaesdobanconamemriaRAMaomesmotempoquenoafetaasdemaisreasdo
sistemaoperacional.
ExistemdoistiposdeconfiguraodememrianoPostgreSQL,acompartilhadaea
individual.Acompartilhadatemumtamanhofixo,elaalocadasemprequeoPostgreSQL
inicializaeentocompartilhadaportodososclientes.Jamemriaindividualtemum
tamanhovarivelealocadaseparadamenteparacadaconexofeitaaoSGBD.
MemriaCacheCompartilhadadoPostgreSQL
OPostgreSQLnoalteraasinformaesdiretamentenodisco.Aoinvsdissoelesolicita
queosdadossejamlidosdamemriacachecompartilhadadoPostgreSQL.Ocliente
PostgreSQLentoleescreveosblocosefinalmenteescrevenodisco.
Clientesqueprecisamacessartabelasprimeiroprocurampelosblocosnecessriosnocache.
Casoestejamaentocontinuamprocessandonormalmente.Casocontrriofeitauma
solicitaoaosistemaoperacionalparacarregarosblocos.Osblocossocarregadosdo
cachedebufferdediscodokerneloudiretamentedodisco.Estasoperaespodemser
onerosas(lentas).
NaconfiguraodefaultdoPostgreSQL8.1.3elealoca1000sharedbuffers.Cadabufferusa
8KB,oquesoma8MB.Aumentandoonmerodebuffersfarcomqueosclientesencontrem
asinformaesqueprocuramemcacheeevitarequisiesonerosasaosistemaoperacional.
Mascuidado,poisseaumentarmuitoamemriacompartilhada(sharedbuffers)pode
acarretarusodamemriavirtual(swap).Asalteraespodemserfeitasatravsdocomando
postmasternalinhadecomandoouatravsdaconfiguraodovalordoshared_buffersno
postgresql.conf.
QuePorodaRAMReservarparaoPostgreSQL?
Amaiorporotilquenoatrapalheosoutrosprogramas.
NossistemasUNIXasinformaessaemdaRAM(quandoinsuficiente)paraoswap.Ruim
quandoasinformaesvoltamdoswapparaaRAM,poisentoosprogramasso
suspensosatqueasmesmassejamcarregadas.
TamanhodaCache
ImaginemosqueoPostgreSQLsharedbuffercachesejasuficienteparamanipularuma

174
tabelainteira.Repetidasbuscasseqenciaisdatabelanodevemnecessitardeacessoao
discojquetodososdadosjestoemcache.Agoravamosimaginarqueocachemenor
queatabela,entonestecasoasinformaesiroparaodisco(swap)eteroum
desempenhobeminferior.
TamanhoAdequadodaSharedBufferCache
IdealmenteaPostgreSQLsharedbuffercache(MemriaCacheCompartilhadado
PostgreSQL)deveser:

Grandeosuficienteparaconseguirmanipularastabelasmaiscomumenteacessadas.
Pequenaobastanteparaevitaratividadesdeswappagein.

Exemplo:
PorexemploqueremosxMBparamemriacompartilhada
(x/8)*1024=Resultadoaserconfiguradoemshared_buffer
Sex=768MB
(768/8)*1024
Resultadoaserconfiguradoemshared_buffer=98304
Parainformaessobreumaconfiguraodokernelparaquevriossistemasoperacionais
trabalharemcomoPostgreSQL:
http://developer.postgresql.org/docs/postgres/kernelresources.html
MemriaIndividual(SortMemory)
Principalmenteutilizadaemordenaesderegistrosdastabelas,emoperaesdecriao
dendices,ordenao(orderby),mergejoin,etc.
Estamemriapodeserconfiguradaatravsdoparmetrosort_memdopostgresql.conf.
Paraaconfiguraoleveemcontasuamemriadisponvel(incluindoamemriajalocada
paraosharedbuffers),tambmonmeromdiodeconexeseousodamemriavirtual
(swap).
Exemplo:
Considerandoumservidordedicado(rodandosomenteoservidorPostgreSQL),com
memriaRAMde1,5GBecomat10conexessimultneascomoSGBD:
shared_buffers=80000
sort_mem =64000
vacuum_mem=2000

#80.000blocosde8KB=625MB
#tamanhoemKB=62,5MB,paracadausuriocom
#10usurios=526MB

Porexemplo:queremosxKBparamemriaindividualsort_men
(x*1024)=resultadoparamemriaindividual
x=16

(16*1024)=sort_mem=16384
Seriabommudartambmmemriaparavaccum
vacuum_mem=131072(mesmoclculodosort_mem)

175

UsodeVriosDiscos
Emsistemascommaisdeumdiscopodemosmelhoraraperformancedomesmo
distribuindoalgumastarefasentrediscosdiferentes.
SupondoquetemosdoisHDs,hdaehdb:

176

Movendooslogsdetransaoparaoutrodisco:
PararoPostgreSQL
Montarhdbem/mnt/hdb
Moverapasta/usr/local/pgsql/data/pg_xlogparao/mnt/hdb
Criarumlinksimblicoparaodiretriooriginal:
lns/mnt/hdb/pg_xlog/usr/local/pgsql/data/pg_xlog
Banco/usr/local/pgsql/data
(nohda)
Logs/usr/local/pgsql/data/pg_xlog (linksimblicopara/mnt/hdb/pg_xlog).
Oslogsdetransaosoosnicosregistrosquenopodemteroseusalvamentoemdisco
adiadosemcomprometeraseguranadosistema.
MoverosndicesparaumHDdiferentedeondeestoastabelas:
PararPostgreSQL
Moverosndicesparaohdb
Criarlinksimblicoparaolocaloriginal
PararecriarosndicesemoutroTablespace:
ALTERTABLEnometabelaDROPCONSTRAINTnomeconstraint;
CREATEINDEXnome_idxONnometabela(nomecampo)TABLESPACEnometablespace;
ALTERTABLEnometabelaADDCONSTRAINTnome_pkPRIMARYKEY(nomecampo);
ALTERINDEXnome_idxSETTABLESPACEnometablespace;
Aindapodemossepararastabelasmaisutilizadasparaohdb,utilizandoocomando
tablespacenoPostgreSQL8.1.3podemosfazerisso:
Criardiretrio/mnt/hdb/hotclusteretornarpostgresseudono
CREATETABLESPACEhotclusterOWNERpostgresLOCATION'/mnt/hdb/hotcluster';
Criandoumbancononovocluster:
CREATEDATABASEhotbancoTABLESPACE=hotcluster;
Exportarastabelasparaestebanco.
UsodeMaisdeUmProcessador
AtualmenteoPostgreSQLestotimizadoparausodevriosprocessadores,reforandoque
cadaconexogerenciadaporumprocessodiferente.
SistemasdeArquivos

177
ParasistemasBSDusaseotradicionalUFS,querobusto,rpidoetemavantagemem
relaoaoPostgreSQL,depossuirosblocosdediscocomumtamanhopadrode8KB.
ParaquemutilizaLinuxassugestesvoparaEXT3eReiserFS.
Checkpoints
Owal_filesoparmetrodopostgresq.lconfquedeterminaonmerodearquivosusados
peloPostgreSQLparaarmazenaroslogsdetransao.Estesarquivosfocamempg_xlog,na
pastadedados.
Paraqueapareamasdatasehorasnosarquivosdelogsusasenopostgresql.conf:
log_timestamp=true
Parareduzirafreqnciadoscheckpointsdevemosaumentaroparmetrodo
postgresql.conf:
checkpoint_segments=3(valordefault)
OPostgreSQLnoprecisademuitoajuste.Boapartedosparmetrosautomaticamente
ajustadaparaumaperformancetima.Ocachesizeesortsizesodoisparmetrosqueo
administradorpodecontrolarparaterummelhorusodamemria.
TraduodoTutorialTuningPostgreSQLforPerformance
DeShridharDaithankareJohnBerkus
SharedBuffers
DefinemumblocodememriaqueoPostgreSQLusarparalidarcomrequisiesqueesto
aguardandoatenonobufferdokernelenaCPU.
Devesermanipuladacomcuidado,poissimplesmenteampliadapodeprejudicara
performance.EstaareaqueoPostgreSQLusaatualmenteparatrabalhar.Eladeveser
suficienteparacontrolaracargadoservidordoSGBD,docontrriooPostgreSQLiriniciar
empurrandodadosparaarquivoseistoirprejudicaraperformancegeral.Estaaprincipal
configuraoemtermosdeperformance.
Seuvalordeveserconfiguradotendoemvistaotamanhodoconjuntodebancosquese
supesquenomximooservidorircarregaredamemriaRAM(teremmentequea
memriaRAMutilizadapelosdemaisaplicativosdoservidornoestarodisponveis).
Recomendaes:
Iniciarcom4MB(512)Workstation
Mdiotamanhodoconjuntodebancosdedadose256a512MBdisponveldeRAM:
1632MB(2948a4096)
GrandeconjuntodebancosdedadosemuitamemriaRAMdisponvel(1a4GB):
64256MB(8192a32768)
Obs.:Atparaumconjuntodebancosdedados(dataset)queexceda20GB,uma
configuraode128MBdevesermuito,casovoctenhaapenas1GBdeRAMeum

178
agressivosistemadecacheemSistemaLinux.
SortMemory(MemriaparaOrdenao)
Limitemximodememriaqueumaconexopodeusarparaexecutarsort(ordenao).
CasosuasconsultasusemasclusulasORDERBYouGROUPBYqueordenemgrandes
conjuntosdedados,incrementaresteparmetrodeverajudar.
UmaRecomendao:
Ajustaroparmetroporconexocomoequandoprecisar:poucaparaconsultasmais
simplesemuitaparaconsultascomplexaseparadumpsdedados.
EffectiveCacheSize(TamanhodoCacheEfetivo)
PermiteaoPostgreSQLfazermelhorusodaRAMdisponvelnoservidor.
Exemplo:
Casoexista1,5GBdeRAMnamquina,sharedbuffersdeveserajustadopara32MBe
effectivecachesizepara800MB.
FsyncandtheWALfiles(FsyncearquivosdeWAL)
Casonorestenenhumaopo,poderusaraproteodoWALemelhorperformance.
SimplesmentemovaseusarquivosdeWAL,montandooutrodispositivooucriandoumlink
simblicoparaodiretriopg_xlog,paraumdiscoseparadoouparaoconjuntodosarquivos
doseuclusterprincipaldearquivosdedados.
random_page_cost(custodepginaaleatria)
Configuraocustoparatrazerumregistroaleatriodeumbancodedados,queinfluenciaa
escolhadoplanejadoremusarindexoutablescan.
CasotenhaumdiscorazoavelmenterpidocomoSCSIouRAID,podebaixarocustopara2.
Vacuum_mem
ConfiguraamemriaalocadaparaVacuum.DeveacelerarpermitindoquePostgreSQLcopie
grandesquantidadesparaamemria.
Entre1632MBumaboaquantidadeparamuitossistemas.
max_fsm_pages
PostgreSQLgravaespaolivreemcadaumadesuaspginasdedados.
Casotenhaumbancoqueusamuitosupdatesedeletes,queirgerarregistrosmortos,
devidoaosistemaMVCCdoPostgreSQL,entoexpandaoFSMparacobrirtodosestes
registrosdeads(mortos)enuncamaisprecisarrodarvacuumfullanoseremferiados.
OmnimoFSMmax_fsm_relations*16.
max_fsm_relations
Dizquantastabelasdevemserlocalizadasnomapadeespaolivre.
wal_buffers
EstaconfiguraodecideaquantidadedebuffersWAL(WriteAheadLog)quepodeter.
Parachegaraumaquantidadetimaexperimenteedecida.
Umbomincioestemtornode32a64correspondendoa256516KBdememria.
AtivarosubprocessodoautoVacuum
Vemdesabilitadopordefualt(autovacuum=offno8.1.3).Paraativarediteoarquivode
configuraopostgresq.confealtereparaautovacuum=on.Irexecutarovacuumquando
necessrio.

179
Melhorexecutarocomandovacuumjuntamentecomocomandoanalyze:
vacuumdbUpostgresa,casosejaexecutadonalinhadecomando.
Paraadquiririnformaessobreosndices(tornandoaperformanceaindamelhor):
vacuumdbUpostgresaz

180

EXPLAIN
#!/usr/bin/perl
$count=1;
$arquivosaida="populate.sql";
@chars=("A".."Z","a".."z",0..9);
@numbers=(1..9);
@single_chars=("a".."e");
$totalrecords=5000;#5milhes
open(OUTPUT,">$arquivosaida");
printOUTPUT"DROPTABLEindex_teste;\n";
printOUTPUT"CREATETABLEindex_teste(";
printOUTPUT"codigoINT,nomeVARCHAR(10),numeroINT,letraCHAR(1)";
printOUTPUT");\n";
printOUTPUT"COPYindex_teste(codigo,nome,numero,letra)FROMstdin;\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)]);
printOUTPUT
#printOUTPUT"INSERTINTOindex_teste
VALUES($count,'$randstring',$randnum,'$randletter');\n";
$count."\t".$randstring."\t".$randnum."\t".$randletter."\n";
$count++;
};
#printOUTPUT"\n";
#printOUTPUT"\nCREATEINDEXindexteste_codigo_indexONindex_teste(codigo);\n";
#printOUTPUT"CREATEINDEXindexteste_numero_indexONindex_teste(numero);\n";
#printOUTPUT"VACUUMANALYZEindex_teste;\n";
closeOUTPUT;
UmbomartigosobreperformancenoPostgreSQLPostgreSQL8.0Checklistde
PerformanceencontrasenarevistaeletrnicaDBFreeMagazine,nmero02.

16Exerccios

181

ExemploPrtico
Vamoscriarumbanco(clientes_ex),contendoumatabela(cliente)eumusurio(operador)queter
apenasalgunsprivilgiosdeacessotabelacliente(INSERT,SELECT,UPDATE)eserobrigadoa
utilizarsenha.VejaquenoterprivilgioDELETE.Entoadicionaralgunsregistroseexecutar
consultasdosquatrotipos:INSERT,SELECT,UPDATEeDELETE(esteapenasparaverificarse
realmenteelenotemesteprivilgio).
1)
CREATEDATABASEclientes_exWITHENCODING'latin1';
ParaSGBDsquenoestejamcomestaconfigurao,pelomenosestebancoausar
ParaExibiraCodificaodoladodoCliente
SHOWCLIENT_ENCODING;
ParaVoltarCodificaoPadro
RESETCLIENT_ENCODING;
AlterandoBancoparasuportarDatasdd/mm/yyyy
ALTERDATABASEclientes_exSETDATESTYLE=SQL,DMY;
Nocasoestebancoapenasficarcomestaconfiguraodedata
Paraalteraodefinitivaparatodososbancosalteraroscript"postgresql.conf".
ExibindooDateStyleAtual
SHOWDATESTYLE;
2)
CREATETABLEcliente(
codigoINTPRIMARYKEY,
nomeVARCHAR(40)NOTNULL,
data_nascDATENOTNULL,
bonusNUMERIC(12,2),
observacaoTEXT
);
3)
CREATEROLEoperadorWITHPASSWORD'operador9128'VALIDUNTIL'26/05/2007';
Ousuriosomenteterosprivilgiosatadatadeterminada.
REVOKEALLONclienteFROMoperador;
GRANTSELECT,UPDATE,INSERTONclienteTOoperador;
Dica:Casoatabelatenhacampotiposerialtambmdevemosdaracessoaoobjetosequencegerado:

182
GRANTSELECT,UPDATE,INSERTONcliente_codigo_seqTOoperador;
Considerandoqueonomedasequnciasejacliente_codigo_seq.
Parapermitiraousuriooperadorquefaalogin,use:
ALTERROLEoperadorWITHLOGIN;
Obs.:Vejacomoestaquiopg_hba.conf:
hostallall127.0.0.1/32md5
4)
Fazerologincomousuriooperadorparaexecutarasconsultasabaixo:
INSERTINTOcliente(codigo,nome,data_nasc,bonus,observacao)VALUES(1,'JooPedro',
'01/01/1967',18.35,'Apenasumtextodeteste');
INSERTINTOcliente(codigo,nome,data_nasc,bonus,observacao)VALUES(2,'PedroPaulo
Rosado','04/11/1973',25.35,'');
INSERTINTOcliente(codigo,nome,data_nasc,bonus,observacao)VALUES(3,'JosRoberto',
'25/06/1938',12.65,NULL);
ObservequeparacamposquenoexigemNOTNULL,podemosentrarapenas''ouNULL.
SELECT*FROMcliente;
SELECTcodigoFROMcliente;
SELECT*FROMclienteWHEREcodigo=5;
SELECT*FROMclienteWHEREcodigo=5ANDnome='JoodeBritoCunha';
UPDATEclienteSETnome='RobervalTaylor'WHEREcodigo=3;
UPDATEclienteSETnome='JooAlmeida'WHEREnome='PedroPaulo';
Estaconsultanoeficiente,jquenomespodemserepetir,melhorseriapelachave
Observeainda,quecamposdotiponumriconotmdelimitador,masosdemaistemodelimitador
apstrofo,excetopalavraschavesefunescomoNULL,TRUE,NOW(),etc.
DELETEFROMcliente;Estaapagatodososregistrosdatabela
DELETEFROMclienteWHEREcodigo=1;
DELETEFROMclienteWHEREcodigo=2ANDnome='ChicoManoel';
Vejaasmensaensquandoouseroperadortentaexcluiralgumregistro:
clientes_ex=>DELETEFROMclienteWHEREcodigo=2ANDnome='ChicoManoel'
ERROR:permissiondeniedforrelationcliente
Ouseja,faltaprivilgioparaexcluireasregrasfuncionaram.
UmpequenotestedeconexociaPHP:
<?php
$con=pg_connect('host=127.0.0.1user=operadorpassword=operador9128dbname=clientes_ex');
if($con){
echo"OK";
}else{
echo"NOK";
}
?>

183

184

EXERCCIODEUMPEQUENOCONTROLEDEESTOQUE
Utilizaremossomenteminsculasparaosnomesdosobjetos(bancos,esquemas,tabelas,
campos,etc)equandocompostoporduasoumaispalavrassepararcomsublinhado.
clientes
funcionarios
produtos
vendas
vendas_itens
bonus
comissoes
Porenquantoiremoscriarapenasatabelaprodutos,maisadiantecriaremosasdemais
tabelas.
Obs.:Atabeladeprodutosirguardartambmumainformaosobreaposiodoproduto
nolocalondeestocado.
Estaposioconterabscissa(x)eordenada(y),ousejaadistnciahorizontaldaesquerda
eadistnciaverticaldebaixoparacima.Exemplosimplificadodadisposiodosprodutos:
ProdA
x,yx+10,yx+20,y
x||
|
||
|
|Y|Y
|Y
||
|
||
|

ondex=10cmey=5cm
ExistemtiposdedadosgeomtricosnoPostgreSQL,parapontos,linhas,polgonos,crculos,
etc.
Iremosutilizaroponto(point).
VamoscriarumaversoresumidadatabelaProdutos:
CREATETABLEprodutos(codigoint,nomechar(40),preconumeric(12,2));
Paraexcluirumatabela:
DROPTABLEnometabela;

185
1 Instalar o PostgreSQL (de acordo com seu sistema operacional) e realizar as
configuraesbsicasnosarquivospg_hba.confenopostgresql.conf.Mudeoestilodadata
paraumcompatvelcomobrasileiro,mudeoslocalesparapt_BR,mudeacodificaopara
LATIN1epermitaconexoTCP/IPparaumamquinadeIP10.1.1.1.
Configuretambmaautenticaodestamquinaparamd5;
2Criarumbancocomnomecontrole_estoque;
3Criarumesquemaesq_estoque;
4Criarumgrupodeusuriosgrupo_estoque;
5Criardentrodoesquemaesq_estoque,tabelas,deacordocomasestruturasabaixocom
osdevidosatributos(campos),tiposdedados,tamanhoseconstraints:
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);nomedeveserUNIQUE
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);
6Criaraschavesestrangeirasquefaamosdevidosrelacionamentosentreastabelas;
7RemoversomenteachaveprimriadatabelaclienteseAdicionarnovamentecomnome
clientes_pk;
8AdicionaraconstraintNOTNULLnocampopreco_unitriodeprodutos;
9AdicionarumaconstraintCHECKqueexijavaloresmaioresquezeronoestoque_minimo
doprodutos;
10Alteraronomedocamponomedatabelaprodutosparadescricaoeonomedatabela
clientesparaclientes2.Renomeienovamenteparaclientes;
11AlterarotipodedadosdocampoquantidadedeprodutosparaNUMERIC(12,2);
12Criartrsusuriosuser_cli,user_prodeuser_adm,todosnogrupogrupo_teste,comos
seguintesprivilgios:

186
user_clitempermissodeexecutarasconsultasSELECT,UPDATEEINSERTnatabela
clientes;
user_protempermissodeexecutaraconsultaSELECTnatabelaprodutos;
useradmpodefazeroquebementenderemtodososbancosdoservidor.

13Criarumaviewqueguardeasomadosbonusporcliente.Receberumclientee
retornarsuasoma;
14Criarumaviewqueguardeasomadascomissesporfuncionrio.Receberum
funcionrioeretornarsuasoma;
15Criarumatransaocomobloco:
- VendaeAtualizaodoestoque,
- Atualizaodobnusdocliente,
- Atualizaodacomissodovendedor
16Cadastrarpelomenostrsregistrosemcadatabela;
17Gerarumdumpdobancoeeditaroscriptparaverseucontedo;
18Consultarqualoprodutomaiscaroeomaisbarato;
19Qualoclientemaisantigo;
20Atualizeopreodeumproduto,adicionandoR$3.85aomesmo;
21Consultequaloclientequenotembonuseoremovadatabela;
22Crieumbancochamadocep_brasil,comumanicatabelacep_tabelacujaestrutura
deveser:
createtablecep_full(cepchar(8),tipochar(72),logradourochar(70),bairrochar(72),
municipiochar(60),ufchar(2));
Importeoarquivocep_brasil_unique.csvexistentenoCDounosite:
http://ribafs.byethost2.comseodownloadsPostgreSQL.
Entoexecute\timing,
FaaumaconsultaqueretorneapenasoseuCEP
Eanoteotempogasto.
23Agoraadicioneumachaveprimrianatabela.Entofaaamesmaconsultaanteriore
vejaadiferenadedesempenhoporcontadondiceadicionado;
22ExecuteoPgAdmin,conecteaobancocontrole_estoqueparaverificarobancocriado,
esquemas,grupodeusurioseusurios,esquema,tabelas,fazeralgumasconsultas,
visualizarosdados,aestruturadastabelaseoutrasatividades;
23FaaomesmocomoEMSPostgreSQLManazer;

187
24ConecteaobancocomoDbVisualizerparaverificarsuastabelas,esquemaevejao
DER(DiagramaEntidadeRelacionamento)esalvecomoimagemumacpiadoDER.
25Criarumatabelasitecontendoumcampocomipdovisitante,dotipoinet.
26Criarumatabelageometria,contendocamposdotipoponto,polgonoecrculo.

17Referncias

188

SiteOficial
Siteoficialhttp://www.postgresql.org
Sitedacomunidadebrasileirahttp://www.postgresql.org.br
DocumentaoOficial
Onlinehttp://www.postgresql.org/docs/8.1/interactive/index.html(Combusca)
PDFhttp://www.postgresql.org/files/documentation/pdf/8.1/postgresql8.1A4.pdf
BrasilOnlinehttp://pgdocptbr.sourceforge.net/pg80/index.html
BrasilPDFhttp://ufpr.dl.sourceforge.net/sourceforge/pgdocptbr/pgdocptbr800pdf1.1.zip
BrasilPDFTutorial
http://www.pythonbrasil.com.br/moin.cgi/NabucodonosorCoutinho?action=AttachFile&do=get&
target=tutorial_pg.pdf.tar.gz
PostgreSQLTechnicalDocumentationhttp://techdocs.postgresql.org/
Livros(Ebooksgrtis)
PracticalPostgreSQL(ingls)
http://www.faqs.org/docs/ppbook/book1.htm
PostgreSQL:IntroductionandConcepts(ingls)
http://www.postgresql.org/files/documentation/books/aw_pgsql/index.html
PostgreSQL:DasoffizielleHandbuch(alemo)
http://www.postgresql.org/docs/books/pghandbuch.html.de
ListadeLivrossobreoPostgreSQL
http://www.postgresql.org/docs/books/

Listas
ListaOficialdoPostgreSQL,comdiversascategorias
ListadeNews(freqnciasemanal)
http://www.postgresql.org/community/weeklynews/
Cadastrohttp://www.postgresql.org/community/lists/subscribe
CadastroeDescadastroemUmadasVriasListas
http://www.postgresql.org/community/lists/subscribe
BuscanosArquivosdasListasdoPostgreSQL
http://archives.postgresql.org/index.php?adv=1
ListadaComunidadeBrasileira
http://pgfoundry.org/mailman/listinfo/brasilusuarios/
ListadeDiscussonoYahoo
http://br.groups.yahoo.com/group/postgresqlbr/
Parasecadastraracesseositeacimaefaaocadastro.
PostgreSQLUsersGroupsSite

http://pugs.postgresql.org/

189

IRC
http://www.postgresql.org/community/irc
Existeumcanalbrasileiro

190

SitesdoPostgreSQLemvriospases
http://www.postgresql.org/community/international
EmpresasqueutilizamPostgreSQL
http://www.postgresql.org/about/casestudies/
FeaturedUsers(UsuriosCaracterizados)
Estoaquialgumasdascentenasdascompanhiasqueconstruramprodutos,
solues,websiteseferramentasusandooPostgreSQL
http://www.postgresql.org/about/users
GrandesProjetosdoPostgreSQL
http://www.postgresql.org/community/resources
ProjetosnoPgFoundry
ftp://ftp2.br.postgresql.org/postgresql/projects/pgFoundry/
ProjetosGborg
ftp://ftp2.br.postgresql.org/postgresql/projects/gborg/
AnlisedeDiversasFerramentasparaPostgreSQL
https://wiki.postgresql.org.br/wiki/Ferramentas
DiversosLogosdoPostgreSQLparadivulgaoemSites
http://www.postgresql.org/community/propaganda
ComunicareExistnciadeBugs
http://www.postgresql.org/support/submitbug
Comformulrioonlinedeenvioderelatodebugs.
DiversasFerramentasparaoPostgreSQL
ConversordeScriptDDLparaPostgreSQL
http://www.icewall.org/~hjort/conv2pg/
http://www.freedownloadscenter.com/Best/erdpostgresql.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

191

Revistas
RevistaSobreBancosdeDadosFree(Portugus)
http://www.dbfreemagazine.com.br/index.php
Cadastreseefaaodownload.Jexistemoitoedies.
SQLMagazine(comercial)
http://www.sqlmagazine.com.br/revista.asp
Cursos
CursodePostgreSQLdadbExpert(SoPaulo)www.dbexpert.com.br
CursodePostgreSQLdoEvoluo(FortalezaCE)www.evolucao.com.br
ModelagemeNormalizao
OModeloRelacionaldeDados(emcincoartigos,deJlioBattisti)
http://www.imasters.com.br/artigo.php?cn=2419&cc=149
ConceitosFundamentaisdeBancodeDados(deRicardoRezende)
http://www.sqlmagazine.com.br/Colunistas/RicardoRezende/02_ConceitosBD.asp
Outros:
PostgreSQLnoiMastershttp://www.imasters.com.br

/secao.php?cs=35

Lozanohttp://www.lozano.eti.br
ConversordeScriptDDLparaPostgreSQLhttp://www.icewall.org/~hjort/conv2pg/
MeuPostgreSQLnoConecta!http://www.icewall.org/~hjort/pgsql/naoconecta.htm

JunoentreTabelasnoPostgresqlhttp://www.imasters.com.br/artigo/2867

CustomizedatabasequeriesusingviewsinPostgreSQLhttp://builder.com.com/5100
6388_146032031.html
PostgreSQLInteragindocomBancodedadoshttp://www.imasters.com.br/artigo/954
OTipodeDadosSerialhttp://www.imasters.com.br/artigo/1804

RunAsUtilitriopararodaroPGnoXP:http://www.softtreetech.com/24x7/archive/53.htm

PostgreSQLcomLDAPhttp://itc.musc.edu/wiki/PostgreSQL
FAQshttp://www.postgresql.org/docs/faqs.FAQ.html
FAQshttp://wiki.ael.be/index.php/PostgresQL101
GettingStartedhttp://postgresql.boeldt.net/getting_started.asp
DownandInstallhttp://postgresql.boeldt.net/setup_postgresql.asp
MicrosoftSQLtoPostgreSQLhttp://postgresql.boeldt.net/mssql_to_postgresql.asp
PGConfigurationhttp://postgresql.boeldt.net/postgreslinuxconfiguration.asp
Muitoslinkshttp://sqlinfo.de/postgresql/links.html
GeneralBitshttp://www.varlena.com/GeneralBits/
Noteshttp://www.archonet.com/pgdocs/pgnotes.html
Presentationshttp://candle.pha.pa.us/main/writings/computer.html
EnterpriseDBhttp://www.osdb.org/

SQLishprojectshttp://docman.sourceforge.net/home_html/sql.html
QuickReferenceMaterialhttp://techdocs.postgresql.org/#quickref

DriverODBChttp://www.postgresql.org/ftp/odbc/versions/msi/
ReplicationProject
http://gborg.postgresql.org/project/pgreplication/download/download.php

192

Otimizao
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/postgresqlperformance.html
http://www.linuxjournal.com/article/4791
http://www.budgetha.com/postgres/
http://archives.postgresql.org/pgsqlperformance/

193

Correesesugestes:
Pginas75e82,ondeest"perca"deveriaser"perda".RaulIavelbergraul_ibm[]yahoo.com.brem10/10/2006

Você também pode gostar