Você está na página 1de 193

1

PostgreSQLPrtico
(verso8.1.4)

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

Revisadoem03/10/2006

NDICE Captulo 1Introduo . . . . . . . . . Pgina . 4 8 13

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 . . . . . . . . . .

33

44

54

67 71 74

. . . .

. . . .

. . . .

. . .

83 85 92

11Configuraes . . . . . . 10.1Configuraracessos(pg_hba.conf) 10.2Configuraesdiversas(postgresql.conf) 12Metadados(Catlogo) . . . . 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 . . . . . . . . 17Referncias . . . . . . . .

5 108

124

. .

. .

149 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 InstalaonoWindowsXP Lembrarque:PrecisainstalaremsistemadearquivosNTFSenoinstalanoXPStart Edition(ondefaltasuportearedes).

11

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): 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

14

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).

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

19

TabelaT C1 1 2 C1 1 2 C1 1 2 C1 1 2 C2 a b C2 a b C2 a b C2 A B

Consulta SELECT*FROMT

Resultado C1 1 2 C2 a b

SELECTC1FROMT

C1 1 2

SELECT*FROMTWHEREC1=1

C1 1

C2 a

SELECTC1FROMTWHEREC2=b

C1 2

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

psqll(noprompt) SELECTdatnameFROMpg_database; 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]

20

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

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

23

);

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) ); CREATETABLEcapitais( estadochar(2) )INHERITS(cidades); capitaisassimpassaatertambmtodososcamposdatabelacidades.

26

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) ); CREATEVIEWclient_contact_listAS SELECTclient.clientid,clientname,name,emailaddressFROMclient,clientcontact WHEREclient.clientid=clientcontact.clientid; Estandonopsqledigitando\dpodemosvisualizartambmasviews.

28

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. RULES OcomandoCREATERULEcriaumaregraaplicadatabelaouvisoespecificada.

29

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...)} OcomandoCREATERULEcriaumaregraaplicadatabelaouvisoespecificada. evento EventoumentreSELECT,INSERT,UPDATEeDELETE.

30

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

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.

35

TiposdeDadosMaisComuns Numricos Tipo smallint(INT2) integer(INTouINT4) bigint(INT8) numeric(p,e) decimal(p,e) Taman ho Apelido 32768a+32767 2147483648at+2147483647 9223372036854775808a +9223372036854775807 tamanhovarivel,precisoespecificada pelousurio.Exatoesemlimite
eescala(casasdecimais) ppreciso(totaldedgitos,inclusiveestala)

Faixa

2bytes inteiropequeno 4bytes inteiro 8bytes inteirolongo

real(float) doubleprecision int(INT4)

4bytes pontoflutuante 8bytes duplapreciso

36 precisovarivel,noexatoeprecisode6 dgitos precisovarivel,noexatoeprecisode 15dgitos maisindicadoparandicesdeinteiros

Caracteres charactervarying(n) character(n) text Desempenhosemelhanteparaostiposcaractere. Data/Hora timestamp[(p)][witouttime zone] timestamp[(p)][withtime zone] interval date time[(p)][withouttime zone] time[(p)][withtimezone] 8bytes dataehorasem zona 8bytes dataehoracom zona 12 bytes intervalode tempo 4713ACa5874897DC 4713ACa5874897DC 178000000anosa178000000anos 4713ACat32767DC 00:00:00.00at23:59:59.99 00:00:00.00at23:59:59.99 varchar(n) char(n) comprimentovarivel,comlimite comprimentofixo,completacombrancos comprimentovariveleilimitado

4bytes somentedata 8bytes somenteahora 8bytes somenteahora

[(p)]apreciso,quevariade0a6eodefualt2. TiposdeDadosMaisComuns(Continuao) Boleanos Tipo TRUE FALSE Tamanho Apelido Faixa Representaes: 't','true','y','yes'e'1' 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 point line lseg box path path circle StorageSize 16bytes 32bytes 32bytes 32bytes Representation Pointontheplane Finitelinesegment Rectangularbox (x,y) ((x1,y1),(x2,y2)) ((x1,y1),(x2,y2)) ((x1,y1),...) [(x1,y1),...] ((x1,y1),...) <(x,y),r>(centerandradius) Description

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

16+16nbytes Closedpath(similartopolygon) 16+16nbytes Openpath 24bytes Circle

polygon 40+16nbytes Polygon(similartoclosedpath)

TiposdeDadosdeRedes NetworkAddressTypes Name cidr inet StorageSize Description 12or24bytes IPv4andIPv6networks 12or24bytes IPv4andIPv6hostsandnetworks MACaddresses

macaddr 6bytes TiposdeDadosArray

Podemostercamposcomtiposdedadosquenososimples,masarrays.
CREATE TABLE salario (

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

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

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

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

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

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

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

SELECTpay_by_quarter[3]FROMsal_emp; Faixadevaloresinferior:superior: SELECTschedule[1:2][1:1]FROMsal_empWHEREname='Bill'; SELECTarray_dims(ARRAY[1,2]||3); SELECTarray_prepend(1,ARRAY[2,3]); SELECTarray_cat(ARRAY[1,2],ARRAY[3,4]); SELECT1||ARRAY[2,3]ASarray; SELECTARRAY[1,2]||ARRAY[[3,4]]ASarray;


SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2 FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;

40

4DML(DataManipulationLanguage)

41

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

psqllUpostgres Excluirobancocriado: dropdbcontrole_estoqueUpostgres 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.

42

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 Sintaxe: INSERTINTOtabela[(lista_de_campos)] {DEFAULTVALUES|VALUES({expresso|DEFAULT}[,...])|consulta}

46

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 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

48

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. SubconsultaescalarumcomandoSELECTcomum,entreparnteses,queretorna exatamenteumregistro,comumcampo. selectnome,(selectmax(preco)fromprodutoswherecodigo=1)as"maiorpreo"from produtos;

51

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'); selectnome, estado, case whenestado='PB'then'Fechado' whenestado='CE'orestado='SP'then'Funcionando' whenestado='MA'then'Funcionandoatodovapor' else'Menor' endasstatus fromamigosorderbynome;

53

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; Retornavalor1somentequandovalor1==valor2.

58

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]

63

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

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 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.

65

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; 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;

68

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. 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;

71

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; end 'language'plpgsql'; FunesqueRetornamConjuntodeRegistros(SETOF,ResultSet) Tambmrequeremacriaodeumavarivel(tipodefinidopelouser) CREATETYPEmedia_salAS returnr;

(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'; 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.

74

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; SELECT*FROMempregados_audit;

78

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''); end; ' language'plpgsql'; return''{''||empresaid||'',''||clienteid||''}'';

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) 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

80

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; Privilgios DandoPrivilgiosAUmUsurio GRANTUPDATEONnometabelaTOnomeusuario; DandoPrivilgiosAUmGrupoInteiro GRANTSELECTONnometabelaTOnomegrupo; RemovendoTodososPrivilgiosdeTodososUsers REVOKEALLONnometabelaFROMPUBLIC

83

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 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

87

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; Cadapginatemtipicamente8KBeorelpagesatualizadopelocomandoVACUUM. BackupAutomticodeBancosnoWindowscomoAgendadordeTarefas Criaodoscriptbackuppg.bat:

93

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 ConfiguraodoAgendadordeTarefasparaexecutaroscriptdiariamente:

94

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) Ativarochip:hdparmd1/dev/hda Desativar:hdparmd0/dev/hda

98

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

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

user=paulo password=paulo port=5432', 'updateclientes setnome=''PauloRogerio'' whereid=18 '

101

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 AoinstalaroPostgreSQL8.1.4viafonteselecria(ealerta)oarquivopg_hba.confcom autenticaodotipotrust(conexolocalsemsenha).

103

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

# Conexes locais via IPv6: host all all ::1/128 md5 # Conexes para todos os IPs de uma subrede (10.0.0.0) # TYPE DATABASE USER IP-ADDRESS IP-MASK host all all 10.43.0.0 255.0.0.0 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 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' METHOD reject md5 METHOD md5

107

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 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)

108

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]); 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:

112

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]; } } } ?> 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 print"TotaldeRegistrodetodasastabelasdetodososbancos".$total;

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; NoWindows Podemospassarparmetrosparaasmacros,porexemplo:

115

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; r=ordinarytable,i=index,S=sequence,v=view,c=compositetype, s=special,t=TOASTtable

116

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) 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));

120

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> Consoledopsql

130

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'; //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:

131

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

14.4EMSPostgreSQL OEMSumtimogerenciadordediversostiposdebancos,inclusivedoPostgreSQL.

132

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:

133

EcliquenobotoNext Entoentrecomosdadosdoservidor(comoabaixo):

Naprximatelamudealgosomentesetivercerteza:

CliqueemNext

134

EntocliqueemFinish

EntocliqueemOK. Entovemosobancojuntoaoservidor(abaixoedireita)

Paraabriloecriartabelasbastaumduplocliquenele.

CRIARTABELAS Executeumduplocliquenonovobanco

135

Observeaestruturacriadaparaonovobanco: CliquesobreTablescomobotodireitoeNewTable(outecleCtrl+N)

Acimadigitamosonomedatabelaondeexistetable1 EntoclicamosnaabaFields.

136 Maisumduploclique,agoraemColumnName,paraqueapareaoWizarddeCampos:

Vejaqueonomedocampocodigo.QueeledotipoBIGINTetambmchave primria. Vejaagoracomoaparecenossocampo(comumapequenachavedireita):

Issomostraqueestecamponossachaveprimria.

AddChaveEstrangeira

AddChaveEstrangeira

Add Chave

Dados

CliqueemCompileevejacomofica:

137

Banco e Host Campo Tabela DDL

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) FerramentadeModelagemAzzurryClay: http://www.azzurri.jp/en/software/clay/index.jsp

144

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 15.1PlanejamentoeProjetodeBancosdeDados ProjetodebancosdedadosgenricoeseaplicaaqualquerSGBDR. comumbomplanejamentodobancodedadosquesedeterminaoquoeficazfoio processodeanlise.

146

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. Exemplo: TabelaAlunos Chave(matricula,codigo_curso)

149

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 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)

151

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 JDBC AlgunsprogramasemJavaoutilizam,comoopluginQuantumDB. OJDBCparaoPostgreSQLencontraseem: http://jdbc.postgresql.org/download.html#jars Vejaqueparaselecionaroarquivo.jarcorreto,precisamoscruzaraversodo PostgreSQLesquerdacomaversodoJDBCdesejado.

152

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)

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

155

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) ); 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

159

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 UPDATEequipamentosSETinsumo='000'||insumoWHERELENGTH(insumo)=1; UPDATEequipamentosSETinsumo='00'||insumoWHERELENGTH(insumo)=2; Outrasadamaiseleganteainda: UPDATEequipamentosSETinsumo=REPEAT('0',4LENGTH(insumo))||insumo;

161

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 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

162

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 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.

164

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). 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

166

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.

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

170

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 Indicadoparaconsultaserelatrios(nograva) CREATETEMPSEQUENCEseq; SELECTnexval('seq'),*FROMesquema.tabela; (SalvadorS.ScarduanalistaPostgreSQLBrasil) LIMITESDOPOSTGRESQL TamanhodeumBancodeDadosilimitado Tamanhodeumatabela32TB Quantidadederegistrosportabelailimitados Quantidadedecamposportabela250a1600(dependedotipo) Quantidadedendicesportabelailimitados

171

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: 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).

176

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

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.

180

16Exerccios ExemploPrtico

181

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

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;

184

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 SiteOficial Siteoficialhttp://www.postgresql.org Sitedacomunidadebrasileirahttp://www.postgresql.org.br

188

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 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://files.db3nf.com/download/DB3NF_Setup_1_4.exe

190

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://gborg.postgresql.org/project/pgxexplorer/download/download.php http://gborg.postgresql.org/browse.php http://gborg.postgresql.org/browse.php?83 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

191

Outros: PostgreSQLnoiMastershttp://www.imasters.com.br /secao.php?cs=35 Lozanohttp://www.lozano.eti.br ConversordeScriptDDLparaPostgreSQLhttp://www.icewall.org/~hjort/conv2pg/ MeuPostgreSQLnoConecta!http://www.icewall.org/~hjort/pgsql/naoconecta.htm JunoentreTabelasnoPostgresqlhttp://www.imasters.com.br/artigo/2867 CustomizedatabasequeriesusingviewsinPostgreSQLhttp://builder.com.com/5100 6388_146032031.html PostgreSQLInteragindocomBancodedadoshttp://www.imasters.com.br/artigo/954 OTipodeDadosSerialhttp://www.imasters.com.br/artigo/1804 RunAsUtilitriopararodaroPGnoXP:http://www.softtreetech.com/24x7/archive/53.htm PostgreSQLcomLDAPhttp://itc.musc.edu/wiki/PostgreSQL FAQshttp://www.postgresql.org/docs/faqs.FAQ.html FAQshttp://wiki.ael.be/index.php/PostgresQL101 GettingStartedhttp://postgresql.boeldt.net/getting_started.asp DownandInstallhttp://postgresql.boeldt.net/setup_postgresql.asp MicrosoftSQLtoPostgreSQLhttp://postgresql.boeldt.net/mssql_to_postgresql.asp PGConfigurationhttp://postgresql.boeldt.net/postgreslinuxconfiguration.asp Muitoslinkshttp://sqlinfo.de/postgresql/links.html GeneralBitshttp://www.varlena.com/GeneralBits/ Noteshttp://www.archonet.com/pgdocs/pgnotes.html Presentationshttp://candle.pha.pa.us/main/writings/computer.html EnterpriseDBhttp://www.osdb.org/ SQLishprojectshttp://docman.sourceforge.net/home_html/sql.html QuickReferenceMaterialhttp://techdocs.postgresql.org/#quickref

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

192

Otimizao http://www.powerpostgresql.com/PerfList http://www.powerpostgresql.com/Downloads/annotated_conf_80.html http://www.varlena.com/GeneralBits/Tidbits/perf.html https://wiki.postgresql.org.br/wiki/Otimiza%C3%A7%C3%A3o http://www.revsys.com/writings/postgresqlperformance.html http://www.linuxjournal.com/article/4791 http://www.budgetha.com/postgres/ http://archives.postgresql.org/pgsqlperformance/

193

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

Você também pode gostar