Escolar Documentos
Profissional Documentos
Cultura Documentos
Aula5 1 BD Postgres SQL
Aula5 1 BD Postgres SQL
PostgreSQLPrtico
(verso8.1.4)
RibamarFSribafs@users.sourceforge.nethttp://ribafs.tk 17desetembrode2006
Revisadoem03/10/2006
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
.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/]
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
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
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
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) );
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,
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,
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
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
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;
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
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
[(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.
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))
TiposdeDadosdeRedes NetworkAddressTypes Name cidr inet StorageSize Description 12or24bytes IPv4andIPv6networks 12or24bytes IPv4andIPv6hostsandnetworks MACaddresses
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];
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();
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:
44
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
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".
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
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
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.
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
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;
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
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.
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
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
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
82
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;
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;
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
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:
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
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 ' );
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:
102
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
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;
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
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
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
$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):
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:
Issomostraqueestecamponossachaveprimria.
AddChaveEstrangeira
AddChaveEstrangeira
Add Chave
Dados
CliqueemCompileevejacomofica:
137
Adicionar Campo
Vamosadicionarmaisumcampo(nomevarchar(40)):
138
ABRIRUMBANCOEXISTENTE
139
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
Acimaedireitaselecioneocampoqueirserelacionarcomaoutratabela(cod_pedido) EmForeignTableselecioneatabeladorelacionamento(pedidos)
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.
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
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
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
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
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
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
160
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'));
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
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
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
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.
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
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
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.
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:
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;
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
192
193
Correesesugestes: Pginas75e82,ondeest"perca"deveriaser"perda".RaulIavelbergraul_ibm[]yahoo.com.brem10/10/2006