Escolar Documentos
Profissional Documentos
Cultura Documentos
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),...]
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"}}');
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
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