<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-37519337</id><updated>2011-07-07T23:10:26.838-07:00</updated><category term='especializa'/><category term='enum'/><category term='mdb2'/><category term='postgresql'/><category term='adodb'/><category term='mysql'/><category term='php'/><category term='patterns'/><category term='creole'/><category term='gof'/><category term='metabase'/><category term='persistencia'/><category term='pear'/><category term='oop'/><category term='pdo'/><category term='blog'/><category term='db'/><category term='abstracao'/><title type='text'>PHPando sem compromisso</title><subtitle type='html'>Meu blog antiguim sobre PHP
Hoje, acessem http://www.especializa.com.br/blog</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://joseberardo.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://joseberardo.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jose Berardo</name><uri>http://www.blogger.com/profile/12931771695642938128</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>6</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-37519337.post-5302665468163324978</id><published>2010-05-29T07:08:00.001-07:00</published><updated>2010-05-29T07:10:07.094-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='especializa'/><title type='text'>Blog descontinuado - Agora é o Blog da Especializa</title><content type='html'>Para quem encontrar esse blog de algum modo, saiba que ele está inativo desde 2006 e que ando escrevendo no &lt;a href="http://www.especializa.com.br/blog"&gt;Blog da Especializa&lt;/a&gt;, empresa a qual sou professor e diretor.&lt;br /&gt;&lt;br /&gt;No Blog da Especializa, pretendo falar de PHP e "otras cositas mas".&lt;br /&gt;&lt;br /&gt;Abraços&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37519337-5302665468163324978?l=joseberardo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joseberardo.blogspot.com/feeds/5302665468163324978/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37519337&amp;postID=5302665468163324978' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/5302665468163324978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/5302665468163324978'/><link rel='alternate' type='text/html' href='http://joseberardo.blogspot.com/2010/05/blog-descontinuado-agora-e-o-blog-da.html' title='Blog descontinuado - Agora é o Blog da Especializa'/><author><name>Jose Berardo</name><uri>http://www.blogger.com/profile/12931771695642938128</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37519337.post-160263237422557314</id><published>2007-05-12T10:25:00.000-07:00</published><updated>2007-05-12T12:14:18.832-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='persistencia'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='mdb2'/><category scheme='http://www.blogger.com/atom/ns#' term='abstracao'/><category scheme='http://www.blogger.com/atom/ns#' term='adodb'/><category scheme='http://www.blogger.com/atom/ns#' term='creole'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='pdo'/><category scheme='http://www.blogger.com/atom/ns#' term='metabase'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><category scheme='http://www.blogger.com/atom/ns#' term='pear'/><category scheme='http://www.blogger.com/atom/ns#' term='db'/><title type='text'>Abstração de SGBDs - Estudo comparativo - Parte 3 - Mais sobre desempenho</title><content type='html'>Opa, to de volta!&lt;br /&gt;Primeiramente, obrigado a Adriano Rivolli, Tiago Oliveira, Felipe, Marcos e alguns anônimos pelos posts nos artigos anteriores sobre o assunto. Vou insistir ainda no assunto desempenho devido à polêmica da metodologia adotada.&lt;br /&gt;&lt;br /&gt;Minha idéia (minto, não foi minha ...) foi executar uma consulta com pequeno volume de dados que, ao repetida 250 vezes poderia gerar um resultado mais expressivo. Poderia! Como disse Marcos, além de não ser algo que algum faria na prática, pode favorecer bibliotecas que utilizem mecanismos de cache de consultas mais eficientemente. Como ele mesmo questionou, "quem faria uma coisa dessas?", talvez alguém que desenvolveu uma dessas bibliotecas, com intuitos claros de manipular o resultado em seu favor, como sugeriu Manoel Lemos no faq do Metabase.&lt;br /&gt;&lt;br /&gt;Bom, resolvi então executar uma única consulta que trouxesse um volume maior de dados. Tá, tudo bem, ainda não é um caso real, quem iria consultar nomes de atores x titulos de filmes e exibiria 57.371 linhas, "vamo paginar essa bagaça aí né"? Mas enfim, se você está aqui é porque está interessado em saber o resultado.&lt;br /&gt;&lt;br /&gt;Para conhecer melhor a dinâmica dos testes, leia o &lt;a href="http://joseberardo.blogspot.com/2006/11/abstrao-de-sgbds-estudo-comparativo.html"&gt;artigo1&lt;/a&gt;, o &lt;a href="http://joseberardo.blogspot.com/2006/11/abstrao-de-sgbds-estudo-comparativo_11.html"&gt;artigo2&lt;/a&gt; ou baixe &lt;a href="http://www.especializa.com.br/berardo/estudo.zip"&gt;aqui&lt;/a&gt; um zipão com os scripts criados e as bibliotecas ADOdb, Metabase e Creole (DBX, PDO,  DB e MDB2 foram instaladas através do pear/pecl). Ahh, para aumentar a polêmica, os testes agora foram feitos no PostgreSQL e também no MySQL.&lt;br /&gt;&lt;br /&gt;Antes que alguém saia dizendo "tá vendo que o MySQL é mais rápido?" (ou mesmo faria isso se o resultado fosse em favor do PostgreSQL), queria deixar claro que não é o intuito desse estudo, verificar qual SGBD é o mais rápido. A questão é apenas avaliar através de qual biblioteca de abstração uma listagem de dados é feita de maneira mais eficiente. Testar em dois SGBDs torna o resultado mais autêntico. Para avaliar qual SGBD é o mais rápido, seriam necessárias diversas opções de otimização, tanto nos servidores quanto no próprio sistema operacional, o que foge totalmente da minha intenção.&lt;br /&gt;&lt;br /&gt;Segue abaixo o script base:&lt;br /&gt;&lt;br /&gt;$time_start = microtime(true);&lt;br /&gt;$db = pg_connect("host=localhost dbname=locadora user=postgres password=postgres");&lt;br /&gt;&lt;br /&gt;$sql = "select a.nome, f.titulo&lt;br /&gt;      from filmes f inner join filmesatores fa using(idfilme)&lt;br /&gt;              inner join atores a using (idator)&lt;br /&gt;      order by a.nome";&lt;br /&gt;$rs = pg_query($db, $sql);&lt;br /&gt;while($row = pg_fetch_row($rs)) {&lt;br /&gt;echo "$row[0]:  $row[1]\n";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$time_end = microtime(true);&lt;br /&gt;$time = $time_end - $time_start;&lt;br /&gt;print("\n\nTEMPO: {$time}\n");&lt;br /&gt;&lt;br /&gt;echo pg_num_rows($rs);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Os scripts das bibliotecas estão todos no zip.&lt;br /&gt;&lt;br /&gt;Os testes foram realizados num Sempron 2600+, 512Mb DDR400, HD 7200RPM, rodando Slackware Linux 10.2, numa partição Reiserfs, em igualdade de condições (num to roubando não, eu juro, a prova é o PostgreSQL ter ficado abaixo, quem me conhece sabe o quanto que eu "gosto" do MySQL =D).&lt;br /&gt;O PHP foi chamado diretamente do shell, pra não haver envolvimento do servidor Web no resultado.&lt;br /&gt;&lt;br /&gt;Abaixo segue o resultado médio no PostgreSQL:&lt;br /&gt;&lt;table str="" style="border-collapse: collapse; width: 763pt;" border="0" cellpadding="0" cellspacing="0" width="1016"&gt;&lt;col style="width: 80pt;" width="107"&gt;  &lt;col style="width: 79pt;" width="105"&gt;  &lt;col style="width: 92pt;" width="123"&gt;  &lt;col style="width: 102pt;" width="136"&gt;  &lt;col style="width: 83pt;" width="110"&gt;  &lt;col style="width: 82pt;" width="109"&gt;  &lt;col style="width: 83pt;" width="110"&gt;  &lt;col style="width: 83pt;" width="111"&gt;  &lt;col style="width: 79pt;" width="105"&gt;  &lt;tbody&gt;&lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl25" style="height: 12.75pt; width: 80pt;" height="17" width="107"&gt;Postgresql&lt;/td&gt;   &lt;td class="xl25" style="width: 79pt;" width="105"&gt;Pear DB&lt;/td&gt;   &lt;td class="xl25" style="width: 92pt;" width="123"&gt;PDO&lt;/td&gt;   &lt;td class="xl25" style="width: 102pt;" width="136"&gt;Pear MDB2&lt;/td&gt;   &lt;td class="xl25" style="width: 83pt;" width="110"&gt;DBX&lt;/td&gt;   &lt;td class="xl25" style="width: 82pt;" width="109"&gt;ADODB&lt;/td&gt;   &lt;td class="xl25" style="width: 83pt;" width="110"&gt;Creole JDBC&lt;/td&gt;   &lt;td class="xl25" style="width: 83pt;" width="111"&gt;Creole SPL&lt;/td&gt;   &lt;td class="xl25" style="width: 79pt;" width="105"&gt;Metabase&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4889956928250001" height="17"&gt;2,48900&lt;/td&gt;   &lt;td class="xl24" num="3.4228432178500001"&gt;3,42284&lt;/td&gt;   &lt;td class="xl24" num="2.4684340953800001"&gt;2,46843&lt;/td&gt;   &lt;td class="xl24" num="3.7812478542300001"&gt;3,78125&lt;/td&gt;   &lt;td class="xl24" num="2.7275121212000002"&gt;2,72751&lt;/td&gt;   &lt;td class="xl24" num="2.9850521087600002"&gt;2,98505&lt;/td&gt;   &lt;td class="xl24" num="3.3082489967300002"&gt;3,30825&lt;/td&gt;   &lt;td class="xl24" num="2.68212103844"&gt;2,68212&lt;/td&gt;   &lt;td class="xl24" num="3.3792569637300001"&gt;3,37926&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4934828281399999" height="17"&gt;2,49348&lt;/td&gt;   &lt;td class="xl24" num="3.4193661212899999"&gt;3,41937&lt;/td&gt;   &lt;td class="xl24" num="2.4700689315800002"&gt;2,47007&lt;/td&gt;   &lt;td class="xl24" num="3.7814478874200002"&gt;3,78145&lt;/td&gt;   &lt;td class="xl24" num="2.7332229614300001"&gt;2,73322&lt;/td&gt;   &lt;td class="xl24" num="2.9846210479700002"&gt;2,98462&lt;/td&gt;   &lt;td class="xl24" num="3.3067150116000001"&gt;3,30672&lt;/td&gt;   &lt;td class="xl24" num="2.6748020649000002"&gt;2,67480&lt;/td&gt;   &lt;td class="xl24" num="3.3821076200000002"&gt;3,38211&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4928140640300001" height="17"&gt;2,49281&lt;/td&gt;   &lt;td class="xl24" num="3.4179170131699999"&gt;3,41792&lt;/td&gt;   &lt;td class="xl24" num="2.4740250110600002"&gt;2,47403&lt;/td&gt;   &lt;td class="xl24" num="3.7775390148199999"&gt;3,77754&lt;/td&gt;   &lt;td class="xl24" num="2.7364280223800002"&gt;2,73643&lt;/td&gt;   &lt;td class="xl24" num="2.9893760681199999"&gt;2,98938&lt;/td&gt;   &lt;td class="xl24" num="3.3098618984199999"&gt;3,30986&lt;/td&gt;   &lt;td class="xl24" num="2.6853339672100001"&gt;2,68533&lt;/td&gt;   &lt;td class="xl24" num="3.3722920417800002"&gt;3,37229&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4891788959499999" height="17"&gt;2,48918&lt;/td&gt;   &lt;td class="xl24" num="3.41880822182"&gt;3,41881&lt;/td&gt;   &lt;td class="xl24" num="2.4743719100999999"&gt;2,47437&lt;/td&gt;   &lt;td class="xl24" num="3.7757329940800002"&gt;3,77573&lt;/td&gt;   &lt;td class="xl24" num="2.7342898845699999"&gt;2,73429&lt;/td&gt;   &lt;td class="xl24" num="2.98037695885"&gt;2,98038&lt;/td&gt;   &lt;td class="xl24" num="3.3159821033500001"&gt;3,31598&lt;/td&gt;   &lt;td class="xl24" num="2.68195390701"&gt;2,68195&lt;/td&gt;   &lt;td class="xl24" num="3.3720510006"&gt;3,37205&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4992790222200001" height="17"&gt;2,49928&lt;/td&gt;   &lt;td class="xl24" num="3.4109168052699999"&gt;3,41092&lt;/td&gt;   &lt;td class="xl24" num="2.46115899086"&gt;2,46116&lt;/td&gt;   &lt;td class="xl24" num="3.7775070667300001"&gt;3,77751&lt;/td&gt;   &lt;td class="xl24" num="2.7260558605199998"&gt;2,72606&lt;/td&gt;   &lt;td class="xl24" num="2.9888451099400002"&gt;2,98885&lt;/td&gt;   &lt;td class="xl24" num="3.3063158988999999"&gt;3,30632&lt;/td&gt;   &lt;td class="xl24" num="2.6742739665399999"&gt;2,67427&lt;/td&gt;   &lt;td class="xl24" num="3.3758280277299999"&gt;3,37583&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.5035309791599998" height="17"&gt;2,50353&lt;/td&gt;   &lt;td class="xl26" num="3.4135529994999998"&gt;3,41355&lt;/td&gt;   &lt;td class="xl24" num="2.4666039943700002"&gt;2,46660&lt;/td&gt;   &lt;td class="xl24" num="3.7711062033079998"&gt;3,77111&lt;/td&gt;   &lt;td class="xl24" num="2.7374920844999999"&gt;2,73749&lt;/td&gt;   &lt;td class="xl24" num="2.98402094841"&gt;2,98402&lt;/td&gt;   &lt;td class="xl24" num="3.3008480071999999"&gt;3,30085&lt;/td&gt;   &lt;td class="xl24" num="2.68511009216"&gt;2,68511&lt;/td&gt;   &lt;td class="xl24" num="3.3694620132400002"&gt;3,36946&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4942939281499998" height="17"&gt;2,49429&lt;/td&gt;   &lt;td class="xl26" num="3.4158990383100001"&gt;3,41590&lt;/td&gt;   &lt;td class="xl24" num="2.46945810318"&gt;2,46946&lt;/td&gt;   &lt;td class="xl24" num="3.7713389396700001"&gt;3,77134&lt;/td&gt;   &lt;td class="xl24" num="2.7282209396399999"&gt;2,72822&lt;/td&gt;   &lt;td class="xl24" num="2.9882690906499998"&gt;2,98827&lt;/td&gt;   &lt;td class="xl24" num="3.2987360954299998"&gt;3,29874&lt;/td&gt;   &lt;td class="xl24" num="2.6742610931400002"&gt;2,67426&lt;/td&gt;   &lt;td class="xl24" num="3.3697259426100001"&gt;3,36973&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4972851276400001" height="17"&gt;2,49729&lt;/td&gt;   &lt;td class="xl26" num="3.40894913673"&gt;3,40895&lt;/td&gt;   &lt;td class="xl24" num="2.4667870998399999"&gt;2,46679&lt;/td&gt;   &lt;td class="xl24" num="3.7713119983699999"&gt;3,77131&lt;/td&gt;   &lt;td class="xl24" num="2.7300000190699998"&gt;2,73000&lt;/td&gt;   &lt;td class="xl24" num="2.9879660606399998"&gt;2,98797&lt;/td&gt;   &lt;td class="xl24" num="3.3057429790500001"&gt;3,30574&lt;/td&gt;   &lt;td class="xl24" num="2.6787159442899999"&gt;2,67872&lt;/td&gt;   &lt;td class="xl24" num="3.3673141002700002"&gt;3,36731&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4913380146000002" height="17"&gt;2,49134&lt;/td&gt;   &lt;td class="xl26" num="3.43569302559"&gt;3,43569&lt;/td&gt;   &lt;td class="xl24" num="2.47649908066"&gt;2,47650&lt;/td&gt;   &lt;td class="xl24" num="3.7791929245000002"&gt;3,77919&lt;/td&gt;   &lt;td class="xl24" num="2.7229158878300002"&gt;2,72292&lt;/td&gt;   &lt;td class="xl24" num="2.9825780391699999"&gt;2,98258&lt;/td&gt;   &lt;td class="xl24" num="3.3177309076300001"&gt;3,31773&lt;/td&gt;   &lt;td class="xl24" num="2.6719279289200002"&gt;2,67193&lt;/td&gt;   &lt;td class="xl24" num="3.3664619922600001"&gt;3,36646&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4888560771899999" height="17"&gt;2,48886&lt;/td&gt;   &lt;td class="xl26" num="3.4174509048499999"&gt;3,41745&lt;/td&gt;   &lt;td class="xl24" num="2.4694619178799999"&gt;2,46946&lt;/td&gt;   &lt;td class="xl24" num="3.7769010067000002"&gt;3,77690&lt;/td&gt;   &lt;td class="xl24" num="2.73126912117"&gt;2,73127&lt;/td&gt;   &lt;td class="xl24" num="2.98862598969"&gt;2,98863&lt;/td&gt;   &lt;td class="xl24" num="3.3120300769800002"&gt;3,31203&lt;/td&gt;   &lt;td class="xl24" num="2.6800601482399999"&gt;2,68006&lt;/td&gt;   &lt;td class="xl24" num="3.3694491386399998"&gt;3,36945&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl27" style="height: 12.75pt;" height="17"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="24.939054629905002" fmla="=SUM(A2:A11)" height="17"&gt;24,939055&lt;/td&gt;   &lt;td class="xl28" num="34.181396484379995" fmla="=SUM(B2:B11)"&gt;34,181396&lt;/td&gt;   &lt;td class="xl28" num="24.696869134909999" fmla="=SUM(C2:C11)"&gt;24,696869&lt;/td&gt;   &lt;td class="xl28" num="37.763325889828003" fmla="=SUM(D2:D11)"&gt;37,763326&lt;/td&gt;   &lt;td class="xl28" num="27.307406902310007" fmla="=SUM(E2:E11)"&gt;27,307407&lt;/td&gt;   &lt;td class="xl28" num="29.859731422199999" fmla="=SUM(F2:F11)"&gt;29,859731&lt;/td&gt;   &lt;td class="xl28" num="33.082211975289994" fmla="=SUM(G2:G11)"&gt;33,082212&lt;/td&gt;   &lt;td class="xl28" num="26.78856015085" fmla="=SUM(H2:H11)"&gt;26,788560&lt;/td&gt;   &lt;td class="xl28" num="33.723948840859997" fmla="=SUM(I2:I11)"&gt;33,723949&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="2.4939054629905" fmla="=AVERAGE(A2:A11)" height="17"&gt;2,493905&lt;/td&gt;   &lt;td class="xl28" num="3.4181396484379993" fmla="=AVERAGE(B2:B11)"&gt;3,418140&lt;/td&gt;   &lt;td class="xl28" num="2.469686913491" fmla="=AVERAGE(C2:C11)"&gt;2,469687&lt;/td&gt;   &lt;td class="xl28" num="3.7763325889828003" fmla="=AVERAGE(D2:D11)"&gt;3,776333&lt;/td&gt;   &lt;td class="xl28" num="2.7307406902310007" fmla="=AVERAGE(E2:E11)"&gt;2,730741&lt;/td&gt;   &lt;td class="xl28" num="2.9859731422199998" fmla="=AVERAGE(F2:F11)"&gt;2,985973&lt;/td&gt;   &lt;td class="xl28" num="3.3082211975289995" fmla="=AVERAGE(G2:G11)"&gt;3,308221&lt;/td&gt;   &lt;td class="xl28" num="2.678856015085" fmla="=AVERAGE(H2:H11)"&gt;2,678856&lt;/td&gt;   &lt;td class="xl28" num="3.3723948840859999" fmla="=AVERAGE(I2:I11)"&gt;3,372395&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="2.5035309791599998" fmla="=LARGE(A2:A11,1)" height="17"&gt;2,503531&lt;/td&gt;   &lt;td class="xl28" num="3.43569302559" fmla="=LARGE(B2:B11,1)"&gt;3,435693&lt;/td&gt;   &lt;td class="xl28" num="2.47649908066" fmla="=LARGE(C2:C11,1)"&gt;2,476499&lt;/td&gt;   &lt;td class="xl28" num="3.7814478874200002" fmla="=LARGE(D2:D11,1)"&gt;3,781448&lt;/td&gt;   &lt;td class="xl28" num="2.7374920844999999" fmla="=LARGE(E2:E11,1)"&gt;2,737492&lt;/td&gt;   &lt;td class="xl28" num="2.9893760681199999" fmla="=LARGE(F2:F11,1)"&gt;2,989376&lt;/td&gt;   &lt;td class="xl28" num="3.3177309076300001" fmla="=LARGE(G2:G11,1)"&gt;3,317731&lt;/td&gt;   &lt;td class="xl28" num="2.6853339672100001" fmla="=LARGE(H2:H11,1)"&gt;2,685334&lt;/td&gt;   &lt;td class="xl28" num="3.3821076200000002" fmla="=LARGE(I2:I11,1)"&gt;3,382108&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="2.4888560771899999" fmla="=SMALL(A2:A11,1)" height="17"&gt;2,488856&lt;/td&gt;   &lt;td class="xl28" num="3.40894913673" fmla="=SMALL(B2:B11,1)"&gt;3,408949&lt;/td&gt;   &lt;td class="xl28" num="2.46115899086" fmla="=SMALL(C2:C11,1)"&gt;2,461159&lt;/td&gt;   &lt;td class="xl28" num="3.7711062033079998" fmla="=SMALL(D2:D11,1)"&gt;3,771106&lt;/td&gt;   &lt;td class="xl28" num="2.7229158878300002" fmla="=SMALL(E2:E11,1)"&gt;2,722916&lt;/td&gt;   &lt;td class="xl28" num="2.98037695885" fmla="=SMALL(F2:F11,1)"&gt;2,980377&lt;/td&gt;   &lt;td class="xl28" num="3.2987360954299998" fmla="=SMALL(G2:G11,1)"&gt;3,298736&lt;/td&gt;   &lt;td class="xl28" num="2.6719279289200002" fmla="=SMALL(H2:H11,1)"&gt;2,671928&lt;/td&gt;   &lt;td class="xl28" num="3.3664619922600001" fmla="=SMALL(I2:I11,1)"&gt;3,366462&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl27" style="height: 12.75pt;" height="17"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.3705971213276178" fmla="=-1+B13/A13"&gt;37,06%&lt;/td&gt;   &lt;td class="xl29" num="-9.7110936476554333E-3" fmla="=-1+C13/A13"&gt;-0,97%&lt;/td&gt;   &lt;td class="xl29" num="0.51422443433541853" fmla="=-1+D13/A13"&gt;51,42%&lt;/td&gt;   &lt;td class="xl29" num="9.4965599440367754E-2" fmla="=-1+E13/A13"&gt;9,50%&lt;/td&gt;   &lt;td class="xl29" num="0.1973080722311944" fmla="=-1+F13/A13"&gt;19,73%&lt;/td&gt;   &lt;td class="xl29" num="0.32652229469918814" fmla="=-1+G13/A13"&gt;32,65%&lt;/td&gt;   &lt;td class="xl29" num="7.4161011649864772E-2" fmla="=-1+H13/A13"&gt;7,42%&lt;/td&gt;   &lt;td class="xl29" num="0.3522544996722059" fmla="=-1+I13/A13"&gt;35,23%&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.3705971213276178" fmla="=-1+B14/A14"&gt;37,06%&lt;/td&gt;   &lt;td class="xl29" num="-9.7110936476553222E-3" fmla="=-1+C14/A14"&gt;-0,97%&lt;/td&gt;   &lt;td class="xl29" num="0.51422443433541876" fmla="=-1+D14/A14"&gt;51,42%&lt;/td&gt;   &lt;td class="xl29" num="9.4965599440367754E-2" fmla="=-1+E14/A14"&gt;9,50%&lt;/td&gt;   &lt;td class="xl29" num="0.1973080722311944" fmla="=-1+F14/A14"&gt;19,73%&lt;/td&gt;   &lt;td class="xl29" num="0.32652229469918814" fmla="=-1+G14/A14"&gt;32,65%&lt;/td&gt;   &lt;td class="xl29" num="7.4161011649864772E-2" fmla="=-1+H14/A14"&gt;7,42%&lt;/td&gt;   &lt;td class="xl29" num="0.35225449967220612" fmla="=-1+I14/A14"&gt;35,23%&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.37233893017084418" fmla="=-1+B15/A15"&gt;37,23%&lt;/td&gt;   &lt;td class="xl29" num="-1.0797509088171786E-2" fmla="=-1+C15/A15"&gt;-1,08%&lt;/td&gt;   &lt;td class="xl29" num="0.51044581389153598" fmla="=-1+D15/A15"&gt;51,04%&lt;/td&gt;   &lt;td class="xl29" num="9.3452450673688237E-2" fmla="=-1+E15/A15"&gt;9,35%&lt;/td&gt;   &lt;td class="xl29" num="0.19406394129103766" fmla="=-1+F15/A15"&gt;19,41%&lt;/td&gt;   &lt;td class="xl29" num="0.32522063247772781" fmla="=-1+G15/A15"&gt;32,52%&lt;/td&gt;   &lt;td class="xl29" num="7.2618629273363267E-2" fmla="=-1+H15/A15"&gt;7,26%&lt;/td&gt;   &lt;td class="xl29" num="0.3509349986692738" fmla="=-1+I15/A15"&gt;35,09%&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.36968512079606275" fmla="=-1+B16/A16"&gt;36,97%&lt;/td&gt;   &lt;td class="xl29" num="-1.112844032398641E-2" fmla="=-1+C16/A16"&gt;-1,11%&lt;/td&gt;   &lt;td class="xl29" num="0.51519657479178238" fmla="=-1+D16/A16"&gt;51,52%&lt;/td&gt;   &lt;td class="xl29" num="9.404312799969583E-2" fmla="=-1+E16/A16"&gt;9,40%&lt;/td&gt;   &lt;td class="xl29" num="0.19748867207096343" fmla="=-1+F16/A16"&gt;19,75%&lt;/td&gt;   &lt;td class="xl29" num="0.32540251148406329" fmla="=-1+G16/A16"&gt;32,54%&lt;/td&gt;   &lt;td class="xl29" num="7.3556624429924611E-2" fmla="=-1+H16/A16"&gt;7,36%&lt;/td&gt;   &lt;td class="xl29" num="0.35261416805621248" fmla="=-1+I16/A16"&gt;35,26%&lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Cada coluna representa os testes realizados em cada biblioteca. Foram executados e colhidos 10 valores para cada biblioteca. Abaixo, seguem respectivamente, a soma dos tempos, a média, o maior e o menor tempo. Por fim, a diferença em termos percentuais entre as bibliotecas e o PostgreSQL direto.&lt;br /&gt;&lt;br /&gt;Na ordem:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;PDO&lt;/li&gt;&lt;li&gt;PostgreSQL diretamente&lt;/li&gt;&lt;li&gt;Creole, utilizando o método SPL&lt;/li&gt;&lt;li&gt;ADOdb&lt;/li&gt;&lt;li&gt;DBX&lt;/li&gt;&lt;li&gt;Creole, utilizando o método JDBC&lt;/li&gt;&lt;li&gt;Metabase&lt;/li&gt;&lt;li&gt;PEAR::DB&lt;/li&gt;&lt;li&gt;PEAR::MDB2&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Destaque para o bom desempenho do PDO, que andou sempre abaixo dos tempos tomados como base e o mau desempenho, novamente, das bibliotecas do PEAR. Sistemas que tenham desempenham como requisito importante, talvez elas não sejam as melhores opções.&lt;br /&gt;&lt;br /&gt;Abaixo, seguem os mesmos testes no MySQL:&lt;br /&gt;&lt;table str="" style="border-collapse: collapse; width: 763pt;" border="0" cellpadding="0" cellspacing="0" width="1016"&gt;&lt;col style="width: 80pt;" width="107"&gt;  &lt;col style="width: 79pt;" width="105"&gt;  &lt;col style="width: 92pt;" width="123"&gt;  &lt;col style="width: 102pt;" width="136"&gt;  &lt;col style="width: 83pt;" width="110"&gt;  &lt;col style="width: 82pt;" width="109"&gt;  &lt;col style="width: 83pt;" width="110"&gt;  &lt;col style="width: 83pt;" width="111"&gt;  &lt;col style="width: 79pt;" width="105"&gt;  &lt;tbody&gt;&lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl25" style="height: 12.75pt; width: 80pt;" height="17" width="107"&gt;Mysql&lt;/td&gt;   &lt;td class="xl25" style="width: 79pt;" width="105"&gt;Pear DB&lt;/td&gt;   &lt;td class="xl25" style="width: 92pt;" width="123"&gt;PDO&lt;/td&gt;   &lt;td class="xl25" style="width: 102pt;" width="136"&gt;Pear MDB2&lt;/td&gt;   &lt;td class="xl25" style="width: 83pt;" width="110"&gt;DBX&lt;/td&gt;   &lt;td class="xl25" style="width: 82pt;" width="109"&gt;ADODB&lt;/td&gt;   &lt;td class="xl25" style="width: 83pt;" width="110"&gt;Creole JDBC&lt;/td&gt;   &lt;td class="xl25" style="width: 83pt;" width="111"&gt;Creole SPL&lt;/td&gt;   &lt;td class="xl25" style="width: 79pt;" width="105"&gt;Metabase&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4658858776099999" height="17"&gt;2,46589&lt;/td&gt;   &lt;td class="xl24" num="3.24190592766"&gt;3,24191&lt;/td&gt;   &lt;td class="xl24" num="2.4822878837600002"&gt;2,48229&lt;/td&gt;   &lt;td class="xl24" num="3.3525631427799998"&gt;3,35256&lt;/td&gt;   &lt;td class="xl24" num="2.64677500725"&gt;2,64678&lt;/td&gt;   &lt;td class="xl24" num="2.7741160392799999"&gt;2,77412&lt;/td&gt;   &lt;td class="xl24" num="3.1987719535800001"&gt;3,19877&lt;/td&gt;   &lt;td class="xl24" num="2.93436408043"&gt;2,93436&lt;/td&gt;   &lt;td class="xl24" num="118.360369921"&gt;118,36037&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4658241271999999" height="17"&gt;2,46582&lt;/td&gt;   &lt;td class="xl24" num="3.22849297523"&gt;3,22849&lt;/td&gt;   &lt;td class="xl24" num="2.4653050899500002"&gt;2,46531&lt;/td&gt;   &lt;td class="xl24" num="3.3322060108199998"&gt;3,33221&lt;/td&gt;   &lt;td class="xl24" num="2.6362290382400002"&gt;2,63623&lt;/td&gt;   &lt;td class="xl24" num="2.76855587959"&gt;2,76856&lt;/td&gt;   &lt;td class="xl24" num="3.1847670078300001"&gt;3,18477&lt;/td&gt;   &lt;td class="xl24" num="2.9301400184599999"&gt;2,93014&lt;/td&gt;   &lt;td class="xl24" num="118.339843988"&gt;118,33984&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4699881076799999" height="17"&gt;2,46999&lt;/td&gt;   &lt;td class="xl24" num="3.2251679897300001"&gt;3,22517&lt;/td&gt;   &lt;td class="xl24" num="2.47153041375"&gt;2,47153&lt;/td&gt;   &lt;td class="xl24" num="3.3355457782700002"&gt;3,33555&lt;/td&gt;   &lt;td class="xl24" num="2.62987709045"&gt;2,62988&lt;/td&gt;   &lt;td class="xl24" num="2.7671229839299998"&gt;2,76712&lt;/td&gt;   &lt;td class="xl24" num="3.1909379959100002"&gt;3,19094&lt;/td&gt;   &lt;td class="xl24" num="2.9371149539900001"&gt;2,93711&lt;/td&gt;   &lt;td class="xl24" num="118.787709951"&gt;118,78771&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.46977806091" height="17"&gt;2,46978&lt;/td&gt;   &lt;td class="xl24" num="3.2306051254299999"&gt;3,23061&lt;/td&gt;   &lt;td class="xl24" num="2.4748336953000001"&gt;2,47483&lt;/td&gt;   &lt;td class="xl24" num="3.33502101898"&gt;3,33502&lt;/td&gt;   &lt;td class="xl24" num="2.6326801776900002"&gt;2,63268&lt;/td&gt;   &lt;td class="xl24" num="2.7599408626600002"&gt;2,75994&lt;/td&gt;   &lt;td class="xl24" num="3.1862859725999999"&gt;3,18629&lt;/td&gt;   &lt;td class="xl24" num="2.9417450428"&gt;2,94175&lt;/td&gt;   &lt;td class="xl24" num="118.64868783999999"&gt;118,64869&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4744532108300001" height="17"&gt;2,47445&lt;/td&gt;   &lt;td class="xl24" num="3.2224340438799999"&gt;3,22243&lt;/td&gt;   &lt;td class="xl24" num="2.4674780368799998"&gt;2,46748&lt;/td&gt;   &lt;td class="xl24" num="3.3357741832699999"&gt;3,33577&lt;/td&gt;   &lt;td class="xl24" num="2.6268210411099999"&gt;2,62682&lt;/td&gt;   &lt;td class="xl24" num="2.7707626903799998"&gt;2,77076&lt;/td&gt;   &lt;td class="xl24" num="3.1898500919299999"&gt;3,18985&lt;/td&gt;   &lt;td class="xl24" num="2.93569302559"&gt;2,93569&lt;/td&gt;   &lt;td class="xl24" num="118.744022083"&gt;118,74402&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4719309806799998" height="17"&gt;2,47193&lt;/td&gt;   &lt;td class="xl26" num="3.2290620803799999"&gt;3,22906&lt;/td&gt;   &lt;td class="xl24" num="2.4634041786199998"&gt;2,46340&lt;/td&gt;   &lt;td class="xl24" num="3.3368110656700001"&gt;3,33681&lt;/td&gt;   &lt;td class="xl24" num="2.6287229061100001"&gt;2,62872&lt;/td&gt;   &lt;td class="xl24" num="2.7650458812699998"&gt;2,76505&lt;/td&gt;   &lt;td class="xl24" num="3.1984131336199999"&gt;3,19841&lt;/td&gt;   &lt;td class="xl24" num="2.9295070171400002"&gt;2,92951&lt;/td&gt;   &lt;td class="xl24" num="118.82049608200001"&gt;118,82050&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4649410247799999" height="17"&gt;2,46494&lt;/td&gt;   &lt;td class="xl26" num="3.2244760990099999"&gt;3,22448&lt;/td&gt;   &lt;td class="xl24" num="2.4628899097399999"&gt;2,46289&lt;/td&gt;   &lt;td class="xl24" num="3.3316638469700002"&gt;3,33166&lt;/td&gt;   &lt;td class="xl24" num="2.6324520111099998"&gt;2,63245&lt;/td&gt;   &lt;td class="xl24" num="2.7651629447900001"&gt;2,76516&lt;/td&gt;   &lt;td class="xl24" num="3.1869199276"&gt;3,18692&lt;/td&gt;   &lt;td class="xl24" num="2.9346139431"&gt;2,93461&lt;/td&gt;   &lt;td class="xl24" num="118.714658976"&gt;118,71466&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4656319618200002" height="17"&gt;2,46563&lt;/td&gt;   &lt;td class="xl26" num="3.2318649291999999"&gt;3,23186&lt;/td&gt;   &lt;td class="xl24" num="2.46532297134"&gt;2,46532&lt;/td&gt;   &lt;td class="xl24" num="3.3319239616399998"&gt;3,33192&lt;/td&gt;   &lt;td class="xl24" num="2.6375238895400002"&gt;2,63752&lt;/td&gt;   &lt;td class="xl24" num="2.7671718597399999"&gt;2,76717&lt;/td&gt;   &lt;td class="xl24" num="3.19743185425"&gt;3,19743&lt;/td&gt;   &lt;td class="xl24" num="2.92784714699"&gt;2,92785&lt;/td&gt;   &lt;td class="xl24" num="118.627634048"&gt;118,62763&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.4732348918899998" height="17"&gt;2,47323&lt;/td&gt;   &lt;td class="xl26" num="3.22111606598"&gt;3,22112&lt;/td&gt;   &lt;td class="xl24" num="2.4673364072799999"&gt;2,46734&lt;/td&gt;   &lt;td class="xl24" num="3.3294570445999998"&gt;3,32946&lt;/td&gt;   &lt;td class="xl24" num="2.63166999817"&gt;2,63167&lt;/td&gt;   &lt;td class="xl24" num="2.7625319957699999"&gt;2,76253&lt;/td&gt;   &lt;td class="xl24" num="3.1903820037799999"&gt;3,19038&lt;/td&gt;   &lt;td class="xl24" num="2.9309577941899998"&gt;2,93096&lt;/td&gt;   &lt;td class="xl24" num="118.66344189599999"&gt;118,66344&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl24" style="height: 12.75pt;" num="2.47618412971" height="17"&gt;2,47618&lt;/td&gt;   &lt;td class="xl26" num="3.22931599617"&gt;3,22932&lt;/td&gt;   &lt;td class="xl24" num="2.4652690887499999"&gt;2,46527&lt;/td&gt;   &lt;td class="xl24" num="3.3330779075599999"&gt;3,33308&lt;/td&gt;   &lt;td class="xl24" num="2.6365449428600001"&gt;2,63654&lt;/td&gt;   &lt;td class="xl24" num="2.7648088932000001"&gt;2,76481&lt;/td&gt;   &lt;td class="xl24" num="3.1905829906499998"&gt;3,19058&lt;/td&gt;   &lt;td class="xl24" num="2.9337918758399999"&gt;2,93379&lt;/td&gt;   &lt;td class="xl24" num="118.65429616"&gt;118,65430&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl27" style="height: 12.75pt;" height="17"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="24.697852373110003" fmla="=SUM(A2:A11)" height="17"&gt;24,697852&lt;/td&gt;   &lt;td class="xl28" num="32.284441232669998" fmla="=SUM(B2:B11)"&gt;32,284441&lt;/td&gt;   &lt;td class="xl28" num="24.685657675369999" fmla="=SUM(C2:C11)"&gt;24,685658&lt;/td&gt;   &lt;td class="xl28" num="33.354043960560006" fmla="=SUM(D2:D11)"&gt;33,354044&lt;/td&gt;   &lt;td class="xl28" num="26.33929610253" fmla="=SUM(E2:E11)"&gt;26,339296&lt;/td&gt;   &lt;td class="xl28" num="27.665220030610001" fmla="=SUM(F2:F11)"&gt;27,665220&lt;/td&gt;   &lt;td class="xl28" num="31.914342931749999" fmla="=SUM(G2:G11)"&gt;31,914343&lt;/td&gt;   &lt;td class="xl28" num="29.335774898530001" fmla="=SUM(H2:H11)"&gt;29,335775&lt;/td&gt;   &lt;td class="xl28" num="1186.3611609450002" fmla="=SUM(I2:I11)"&gt;1186,361161&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="2.4697852373110001" fmla="=AVERAGE(A2:A11)" height="17"&gt;2,469785&lt;/td&gt;   &lt;td class="xl28" num="3.2284441232669998" fmla="=AVERAGE(B2:B11)"&gt;3,228444&lt;/td&gt;   &lt;td class="xl28" num="2.4685657675370001" fmla="=AVERAGE(C2:C11)"&gt;2,468566&lt;/td&gt;   &lt;td class="xl28" num="3.3354043960560005" fmla="=AVERAGE(D2:D11)"&gt;3,335404&lt;/td&gt;   &lt;td class="xl28" num="2.6339296102529999" fmla="=AVERAGE(E2:E11)"&gt;2,633930&lt;/td&gt;   &lt;td class="xl28" num="2.766522003061" fmla="=AVERAGE(F2:F11)"&gt;2,766522&lt;/td&gt;   &lt;td class="xl28" num="3.1914342931749999" fmla="=AVERAGE(G2:G11)"&gt;3,191434&lt;/td&gt;   &lt;td class="xl28" num="2.933577489853" fmla="=AVERAGE(H2:H11)"&gt;2,933577&lt;/td&gt;   &lt;td class="xl28" num="118.63611609450001" fmla="=AVERAGE(I2:I11)"&gt;118,636116&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="2.47618412971" fmla="=LARGE(A2:A11,1)" height="17"&gt;2,476184&lt;/td&gt;   &lt;td class="xl28" num="3.24190592766" fmla="=LARGE(B2:B11,1)"&gt;3,241906&lt;/td&gt;   &lt;td class="xl28" num="2.4822878837600002" fmla="=LARGE(C2:C11,1)"&gt;2,482288&lt;/td&gt;   &lt;td class="xl28" num="3.3525631427799998" fmla="=LARGE(D2:D11,1)"&gt;3,352563&lt;/td&gt;   &lt;td class="xl28" num="2.64677500725" fmla="=LARGE(E2:E11,1)"&gt;2,646775&lt;/td&gt;   &lt;td class="xl28" num="2.7741160392799999" fmla="=LARGE(F2:F11,1)"&gt;2,774116&lt;/td&gt;   &lt;td class="xl28" num="3.1987719535800001" fmla="=LARGE(G2:G11,1)"&gt;3,198772&lt;/td&gt;   &lt;td class="xl28" num="2.9417450428" fmla="=LARGE(H2:H11,1)"&gt;2,941745&lt;/td&gt;   &lt;td class="xl28" num="118.82049608200001" fmla="=LARGE(I2:I11,1)"&gt;118,820496&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl28" style="height: 12.75pt;" num="2.4649410247799999" fmla="=SMALL(A2:A11,1)" height="17"&gt;2,464941&lt;/td&gt;   &lt;td class="xl28" num="3.22111606598" fmla="=SMALL(B2:B11,1)"&gt;3,221116&lt;/td&gt;   &lt;td class="xl28" num="2.4628899097399999" fmla="=SMALL(C2:C11,1)"&gt;2,462890&lt;/td&gt;   &lt;td class="xl28" num="3.3294570445999998" fmla="=SMALL(D2:D11,1)"&gt;3,329457&lt;/td&gt;   &lt;td class="xl28" num="2.6268210411099999" fmla="=SMALL(E2:E11,1)"&gt;2,626821&lt;/td&gt;   &lt;td class="xl28" num="2.7599408626600002" fmla="=SMALL(F2:F11,1)"&gt;2,759941&lt;/td&gt;   &lt;td class="xl28" num="3.1847670078300001" fmla="=SMALL(G2:G11,1)"&gt;3,184767&lt;/td&gt;   &lt;td class="xl28" num="2.92784714699" fmla="=SMALL(H2:H11,1)"&gt;2,927847&lt;/td&gt;   &lt;td class="xl28" num="118.339843988" fmla="=SMALL(I2:I11,1)"&gt;118,339844&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl27" style="height: 12.75pt;" height="17"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td class="xl27"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.30717605502492829" fmla="=-1+B13/A13"&gt;30,72%&lt;/td&gt;   &lt;td class="xl29" num="-4.937553903788805E-4" fmla="=-1+C13/A13"&gt;-0,05%&lt;/td&gt;   &lt;td class="xl29" num="0.35048357471253277" fmla="=-1+D13/A13"&gt;35,05%&lt;/td&gt;   &lt;td class="xl29" num="6.6460990397980257E-2" fmla="=-1+E13/A13"&gt;6,65%&lt;/td&gt;   &lt;td class="xl29" num="0.12014678898683284" fmla="=-1+F13/A13"&gt;12,01%&lt;/td&gt;   &lt;td class="xl29" num="0.29219101521948576" fmla="=-1+G13/A13"&gt;29,22%&lt;/td&gt;   &lt;td class="xl29" num="0.18778647047342378" fmla="=-1+H13/A13"&gt;18,78%&lt;/td&gt;   &lt;td class="xl29" num="47.034992801101239" fmla="=-1+I13/A13"&gt;4703,50%&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.30717605502492851" fmla="=-1+B14/A14"&gt;30,72%&lt;/td&gt;   &lt;td class="xl29" num="-4.9375539037865845E-4" fmla="=-1+C14/A14"&gt;-0,05%&lt;/td&gt;   &lt;td class="xl29" num="0.35048357471253277" fmla="=-1+D14/A14"&gt;35,05%&lt;/td&gt;   &lt;td class="xl29" num="6.6460990397980257E-2" fmla="=-1+E14/A14"&gt;6,65%&lt;/td&gt;   &lt;td class="xl29" num="0.12014678898683306" fmla="=-1+F14/A14"&gt;12,01%&lt;/td&gt;   &lt;td class="xl29" num="0.29219101521948576" fmla="=-1+G14/A14"&gt;29,22%&lt;/td&gt;   &lt;td class="xl29" num="0.18778647047342378" fmla="=-1+H14/A14"&gt;18,78%&lt;/td&gt;   &lt;td class="xl29" num="47.034992801101239" fmla="=-1+I14/A14"&gt;4703,50%&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.309234595587073" fmla="=-1+B15/A15"&gt;30,92%&lt;/td&gt;   &lt;td class="xl29" num="2.4649839148735975E-3" fmla="=-1+C15/A15"&gt;0,25%&lt;/td&gt;   &lt;td class="xl29" num="0.35392320084558393" fmla="=-1+D15/A15"&gt;35,39%&lt;/td&gt;   &lt;td class="xl29" num="6.889264634774106E-2" fmla="=-1+E15/A15"&gt;6,89%&lt;/td&gt;   &lt;td class="xl29" num="0.12031896416559795" fmla="=-1+F15/A15"&gt;12,03%&lt;/td&gt;   &lt;td class="xl29" num="0.29181506140846913" fmla="=-1+G15/A15"&gt;29,18%&lt;/td&gt;   &lt;td class="xl29" num="0.18801546601646479" fmla="=-1+H15/A15"&gt;18,80%&lt;/td&gt;   &lt;td class="xl29" num="46.985323327274436" fmla="=-1+I15/A15"&gt;4698,53%&lt;/td&gt;  &lt;/tr&gt;  &lt;tr style="height: 12.75pt;" height="17"&gt;   &lt;td class="xl29" style="height: 12.75pt;" num="0" height="17"&gt;0,00%&lt;/td&gt;   &lt;td class="xl29" num="0.30677206212975827" fmla="=-1+B16/A16"&gt;30,68%&lt;/td&gt;   &lt;td class="xl29" num="-8.3211525930237951E-4" fmla="=-1+C16/A16"&gt;-0,08%&lt;/td&gt;   &lt;td class="xl29" num="0.35072482916590642" fmla="=-1+D16/A16"&gt;35,07%&lt;/td&gt;   &lt;td class="xl29" num="6.5672977447583492E-2" fmla="=-1+E16/A16"&gt;6,57%&lt;/td&gt;   &lt;td class="xl29" num="0.1196782539275274" fmla="=-1+F16/A16"&gt;11,97%&lt;/td&gt;   &lt;td class="xl29" num="0.29202564110605689" fmla="=-1+G16/A16"&gt;29,20%&lt;/td&gt;   &lt;td class="xl29" num="0.18779602333541234" fmla="=-1+H16/A16"&gt;18,78%&lt;/td&gt;   &lt;td class="xl29" num="47.009198921325925" fmla="=-1+I16/A16"&gt;4700,92%&lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Na ordem:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;PDO&lt;/li&gt;&lt;li&gt;MySQL direto&lt;/li&gt;&lt;li&gt;DBX&lt;/li&gt;&lt;li&gt;ADOdb&lt;/li&gt;&lt;li&gt;Creole SPL&lt;/li&gt;&lt;li&gt;PEAR::DB&lt;/li&gt;&lt;li&gt;PEAR::MDB2&lt;/li&gt;&lt;li&gt;Metabase (?)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;No geral, elas andaram mais rápido, destaque para a diferença menor em termos percentuais entre elas e a execução direta no MySQL e para um resultado estranho nos número da Metabase. Tão estranho que cheguei a procurar onde estava errando e uma melhor maneira fazer. Como não descobri, fica a deixa para quem quiser desvendar esse mistério. Interessante também o resultado melhor da DBX, que dessa vez andou sempre à frete da Creole SPL e da ADOdb. A Creole SPL também perdeu espaço para a ADOdb.&lt;br /&gt;&lt;br /&gt;Bom, espero que dessa vez o estudo pareça mais autêntico. Peço que você teste também em outras plataformas e combinações de configuração. Abraço e até o próximo post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37519337-160263237422557314?l=joseberardo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/160263237422557314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/160263237422557314'/><link rel='alternate' type='text/html' href='http://joseberardo.blogspot.com/2007/05/abstrao-de-sgbds-estudo-comparativo.html' title='Abstração de SGBDs - Estudo comparativo - Parte 3 - Mais sobre desempenho'/><author><name>Jose Berardo</name><uri>http://www.blogger.com/profile/12931771695642938128</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-37519337.post-5165980881498719850</id><published>2007-02-11T20:27:00.000-08:00</published><updated>2007-02-11T20:45:33.279-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='enum'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='oop'/><title type='text'>Constantes e as limitações do PHP</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-US"&gt;Houston, we have a problem! &lt;/span&gt;Seriam limitações? Bugs? Sinceramente, ainda não sei, mas como o intuito é falar sobre PHP de maneira descompromissada, largo mão até da corriqueira mania de “evangelizar” (quem sou eu) a linguagem que trabalho há uns 7 anos e sou professor há quase outros tantos, para meter um pouco de pimenta no acarajé nosso de cada dia.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Lembro vagamente do meu professor de matemática em alguma série ginasial dizendo que uma constante é uma maneira de representar algum dado absoluto e imutável. Na verdade não lembro, odiava matemática (&lt;i style=""&gt;putz&lt;/i&gt;, por que eu fui odiar logo matemática), mas certamente ele falou quando fez a gente engolir aquele ¶ obscuro. Quando comecei a estudar PHP, logo li que constantes também só admitem valores escalares. Até aí tudo bem, estava iniciando na linguagem e pude sobreviver sem questionar nada.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;O PHP5 trouxe alguns avanços na programação orientada a objetos e blábláblá que você, se está aqui, já deve saber. Entre as dádivas da quinta geração está a instrução const. Com ela é possível declarar constantes de classe, ou seja, uma maneira de representar algum dado absoluto e imutável, como dizia meu professor (ou seria professora, ...), agora inerente a uma classe.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Via de regra, constantes de classe são sempre públicas e estáticas (estão vinculadas à própria classe e não às suas instâncias), tanto é que declarar algo como public const ou static const são erros de sintaxe por se tratar de algo redundante. Sobre elas recai a mesma restrição imposta às suas irmãs globais, oriundas de instruções define, no que diz respeito à impossibilidade de assumirem valores como objetos ou arrays.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Perdoai minha insolência, mas por que esta limitação? O que há de mal nas linhas:&lt;/p&gt;      &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;define('MEU_ARRAY', array("a" =&gt; 1));&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:10;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;echo MEU_ARRAY["a"];&lt;/span&gt;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;ou&lt;/p&gt;      &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:10;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;define('MEU_OBJETO', new Objeto());&lt;/span&gt;&lt;o:p style="font-family: courier new;"&gt;&lt;/o:p&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;echo MEU_OBJETO-&gt;getQualquerCoisa();&lt;/span&gt;&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Quando o assunto é array, concordo que pode não ser interessante ter que garantir a constância de uma estrutura complexa na memória. No entanto, ao atribuir um objeto a uma variável no PHP5, seu valor será apenas uma referência ao objeto. Em outras palavras, nenhuma variável no PHP5 possui um valor complexo, mas sim um dado escalar referente ao endereço de memória onde reside de fato o objeto. Por que então as constantes, que só admitem valores escalares, não podem agora referenciar objetos? Note que o que deve ser imutável é o valor da constante, ou seja, a referência ao objeto. Mas o objeto em si pode sofrer alterações em seus atributos sem maiores preocupações.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Só para ilustrar, suponha uma listagem de dados de clientes (dentre eles os seus endereços). A classe Cliente possui um atributo do tipo Endereço que por sua vez, possui um atributo do tipo Uf a fim de representar qual o Estado do cliente. Ao buscar os dados do banco e construir o objeto cliente, uma instrução como essa:&lt;/p&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;while ( ... ) {&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;    $cliente = ...;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    $cliente-&gt;endereco-&gt;uf = new Uf($registroDoBanco[‘uf_sigla’]);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    $lista[] = $cliente;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}    &lt;/span&gt;&lt;/span&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;              &lt;p class="MsoNormal"&gt;Criaria um objeto Uf para cada cliente, mesmo que a sigla obtida no banco de dados seja a mesma obtida numa linha anterior.&lt;/p&gt;&lt;p class="MsoNormal"&gt;Para evitar essas instâncias desnecessárias, seria possível carregar um array de Ufs obtidas e só criar uma nova quando esta for baseada numa nova sigla. Veja:&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;while (...) {&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;     &lt;/span&gt;$cliente = ...;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;     &lt;/span&gt;$uf = $registroDoBanco[‘uf_sigla’];&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;     &lt;/span&gt;if (!in_array($uf, $ufsJaObtidas)) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;         &lt;/span&gt;$ufsJaObtidas[$uf] = new Uf($uf);&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;     &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;     &lt;/span&gt;$cliente-&gt;endereco-&gt;uf = $ufsJaObtidas[$uf];&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;     &lt;/span&gt;$lista[] = $cliente;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;No entanto, gostaria de contar com uma saída mais elegante em que eu não me preocupasse em sobrecarregar meu código sempre que fosse listar algo do tipo. Pensei no padrão de projeto Typesafe Enum.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Joshua Bloch, idealizador deste padrão, em seu livro Effective Java Programming Language Guide, recomenda 57 regras para programadores Java. Dentre elas, quatro são focadas em trazer construções interessantes disponíveis na linguagem C. Uma delas (o item 21) são justamente os tipos enumerados (&lt;i style=""&gt;enum&lt;/i&gt;). Estes são comuns em diversas linguagens e bancos de dados. São úteis em momentos em que você já conhece todas as variações possíveis que determinado dado pode assumir.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;Devido à popularidade deste padrão de projeto, o JCP (&lt;i style=""&gt;Java Community Process&lt;/i&gt; – entidade que dita os caminhos dessa tecnologia) resolveu, sob a JSR 161, introduzir a declaração de tipos Enum no Java 5 (&lt;i style=""&gt;tiger&lt;/i&gt;), o que já era comum em ambientes .NET. Dizem as más línguas, esse fato foi um dos principais catalisadores desta JSR.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Pois bem, no PHP não temos o tipo Enum, no entanto o padrão Typesafe Enum poderia resolver nosso problema, veja como seria declarada a classe Uf:&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;span style="font-size:85%;"&gt;&lt;span  lang="EN-US" style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;class Uf {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const AC = new Uf("AC"); const AL = new Uf("AL");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const AM = new Uf("AM"); const AP = new Uf("AP");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const BA = new Uf("BA"); const CE = new Uf("CE");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const DF = new Uf("DF"); const ES = new Uf("ES");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const GO = new Uf("GO"); const MA = new Uf("MA");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const MG = new Uf("MG"); const MS = new Uf("MS");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const MT = new Uf("MT"); const PA = new Uf("PA");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const PB = new Uf("PB"); const PE = new Uf("PE");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const PI = new Uf("PI"); const PR = new Uf("PR");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const RJ = new Uf("RJ"); const RN = new Uf("RN");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const RO = new Uf("RO"); const RS = new Uf("RS");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const SC = new Uf("SC"); const SE = new Uf("SE");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;const SP = new Uf("SP"); const TO = new Uf("TO");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;private $sigla;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;private $nome;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;private function __construct($sigla = "") {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;$this-&gt;setSigla($sigla);&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;public function getSigla() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;return $this-&gt;sigla;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;private function setSigla($sigla) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;$this-&gt;sigla = $sigla;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;switch($this-&gt;sigla) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;      &lt;/span&gt;case "AC":&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;$this-&gt;setNome("Acre");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;break;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;      &lt;/span&gt;case "AL":&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;$this-&gt;setNome("Alagoas");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;        &lt;/span&gt;&lt;/span&gt;break;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;        &lt;/span&gt;// ... E assim por diante&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;    &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;  &lt;/span&gt;&lt;span style="" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;public function getNome() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;    &lt;/span&gt;return $this-&gt;nome;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;public function setNome($nome) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;  &lt;/p&gt;&lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;$this-&gt;nome = $nome;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;?&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Veja que a classe Uf já declarou uma constante para cada Estado do Brasil e atribuiu a ela uma instância dela mesma, ou seja, cada constante da classe Uf é um objeto Uf, cuja sigla e nome serão configurados de acordo com a string passada como parâmetro ao seu construtor. Assim como no Singleton, o construtor é privado para que ninguém tente construir um objeto Uf, todos eles já serão criados na primeira referência à classe Uf de todo o script.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Nosso script de acesso a dados ficaria assim:&lt;/p&gt;    &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;while ( ... ) {&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;            &lt;/span&gt;$cliente = ...;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="text-indent: 35.4pt;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;$cliente-&gt;endereco-&gt;uf = Uf::$registroDoBanco[‘uf_sigla’];&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="text-indent: 35.4pt;font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;$lista[] = $cliente;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;No caso da sigla obtida no banco de dados ser PE, seria o mesmo que termos:&lt;/p&gt;    &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;$cliente-&gt;endereco-&gt;uf = Uf::PE;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Simples e eficaz, no entanto é preciso ter cuidado com o uso dos tipos enumerados. Recomendo apenas em casos de objetos simples e relativamente poucos. Não considero 26 objetos compostos por dois atributos de pequenas strings como algo degradante em termos de desempenho, porém não o recomendo em casos onde os objetos sejam muitos ou possuam gráficos extensos, visto que haverá muita alocação desnecessária de memória no momento da primeira referência à classe &lt;i style=""&gt;enum&lt;/i&gt;.&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Nossa classe Uf não pôde implementar o Typesafe Enum justamente pela limitação de valores escalares para constantes. Tive uma idéia. Por que não declarar as constantes simplesmente como variáveis de classe (static). Ora, eu vou perder a garantia do valor constante (perdão professor (a)), mas posso obter o mesmo resultado:&lt;/p&gt;    &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;class Uf {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;public static $AC = new Uf("AC"); public static $AL = new Uf("AL");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;&lt;/span&gt;…&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;O código de acesso ficaria:&lt;/p&gt;    &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;$uf = ::$registroDoBanco[‘uf_sigla’];&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;$cliente-&gt;endereco-&gt;uf = Uf::$$uf;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;Entrei no ônibus, esbarrei na manivela. O PHP também não suporta chamada a qualquer procedimento no momento da declaração de atributos. O curioso é que se nossas variáveis de classe $AC e companhia fossem arrays, não haveria problemas:&lt;/p&gt;    &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;class Uf {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;public static $AC = array ("AC");&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="" lang="EN-US"&gt;&lt;span style=""&gt;  &lt;/span&gt;&lt;/span&gt;…&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;This is Houston. Say again please! Bom, minha conclusão antes que a véia que for passando me leve pro delegado é que constantes não podem referenciar objetos por um triste legado do PHP4 onde estes eram, como li em algum lugar, arrays que comeram espinafre. Procurei algo a respeito no site de bugs do PHP, mas como não encontrei nada, achei que o problema era comigo mesmo. Fessora, suas aulas de matemática eram ótimas, eu juro.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37519337-5165980881498719850?l=joseberardo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joseberardo.blogspot.com/feeds/5165980881498719850/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37519337&amp;postID=5165980881498719850' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/5165980881498719850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/5165980881498719850'/><link rel='alternate' type='text/html' href='http://joseberardo.blogspot.com/2007/02/constantes-e-as-limitaes-do-php.html' title='Constantes e as limitações do PHP'/><author><name>Jose Berardo</name><uri>http://www.blogger.com/profile/12931771695642938128</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37519337.post-116914534348722715</id><published>2007-01-18T10:33:00.000-08:00</published><updated>2007-02-01T15:05:01.470-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='gof'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Design patterns: 1 - O onipresente Singleton e o conceito de aplicação</title><content type='html'>&lt;p class="MsoNormal"&gt;Desde o lançamento da Zend Engine 2, núcleo do PHP5, há 3 anos, venho presenciando um crescente interesse da comunidade PHP na orientação a objetos. Não é pra menos, afinal, foi nesta área que ela trouxe maiores impactos. Vale frisar que seu novo modelo de objetos já era ansiosamente aguardado. Lembrar da OO no PHP4 hoje, dá vontade de rir - ou chorar se houver necessidade implementar algo nesse sentido - basta lembrar dos incontáveis &amp;'s.&lt;br /&gt;&lt;br /&gt;Como um fenômeno inexplicável em qualquer linguagem com suporte maduro à OO, a moda no PHP pós-moderno são os padrões de projeto. Por favor, não há tempo para introduções. Deixaremos o arquiteto Cristopher Alexander, Martin Fowler, Erich Gamma e seus mosqueteiros para o seu professor de faculdade.&lt;br /&gt;&lt;br /&gt;O que me chama à atenção é a quase que instantânea explanação acerca do padrão criacional&lt;span style="font-size:0;"&gt; &lt;/span&gt;GoF Singleton. Falou em design pattern (para os que não gostam de traduzir certos termos já amplamente conhecidos abaixo da linha do Equador em sua língua pátria), explicou o Singleton. Note que ele foi concebido num livro que tratou de C++, Eiffel, SmallTalk e trouxe diagramas em formatos mais livres anteriores à UML, ou seja, para a maioria dos programadores, definitivamente, não foi cunhado em linguagem cotidiana.&lt;/p&gt;&lt;p class="MsoNormal"&gt;Mas afinal, por que todo mundo fala em Singleton? Bom, se o intuito de se catalogar padrões de projeto for promover o conhecimento de uma solução consistente para determinados problemas corriqueiros e gerar um vocabulário comum de entendimento universal, talvez estejamos diante de uma verdadeira obra-prima. Seria a gangue dos quatro (GoF – Gang of Four) composta por Leonardo, Michelangelo, Donatello e Rafael?&lt;/p&gt;&lt;p class="MsoNormal"&gt;Talvez a resposta esteja exatamente no livro dos livros. Presente há mais de uma década na cabeceira de nove entre dez analistas de sistemas, a obra Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1995) não é de fácil leitura. Seus exemplos não são os mais comerciais (quem leu deve lembrar do labirinto ou do editor de textos), mas atingiu o status cult. É bonito falar dele. O Singleton então faz o papel de padrão de projeto mais trivial e acessível dos 23 catalogados.&lt;/p&gt;&lt;p class="MsoNormal"&gt;Recentemente, li quatro artigos em PHP sobre Singleton. Adler Medrado, no phpavancado.net, Diego Botelho, no phpbrasil.com, Felipe Ribeiro em seu blog, aqui mesmo no Blogger e Alexandre Altair de Melo em seu artigo sobre padrões de projeto elaborado para a primeira edição da revista eletrônica &lt;i&gt;brazuca&lt;/i&gt; PHP Magazine (não confunda com sua xará alemã). Registro aqui meus parabéns pela iniciativa. Quando crescer, quero escrever para vocês =).&lt;/p&gt;&lt;p class="MsoNormal"&gt;Numa definição breve, Singleton é uma implementação OO para situações onde é necessário que tenhamos apenas uma única instância (objeto) de determinada classe. Não sei que fixação é essa, mas o que eu mais vi em PHP sobre o assunto trouxe o exemplo de uma classe que criasse objetos para gerenciar conexões a um banco de dados. Vamos a ela então (código retirado do artigo do Alexandre Melo – nossa única ressalva é a declaração static do método getInstancia() que ele esqueceu de colocar):&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;?&lt;/o:p&gt;&lt;? &lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;/**&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Classe para se conectar com o banco de dados.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;*/&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;class ConectaBanco {&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;/**&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Propriedade flag utilizada para verificar se já&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* existe uma instância do objeto&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;*/&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;private static $instancia = null;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;/**&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Construtor.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Aqui está a grande sacada o construtor da classe é privado.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Assim só um outro método interno pode ter acesso,&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* a esse construtor.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* @return void&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;*/&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;private function __construct() {}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;/**&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Método que irá fornecer o ponto global para se&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* ter acesso a instância.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* @return ConectaBanco&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;*/&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;public static function getInstancia() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;if (is_null(ConectaBanco::$instancia)) {&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;ConectaBanco::$instancia = new ConectaBanco();&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;return ConectaBanco::$instancia;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;?&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;br /&gt;O primeiro passo para implamentação do padrão Singleton é proibir a criação de objetos da classe em questão a partir de fora dela. Isso ocorre, vedando o acesso externo ao construtor com o modificador private. Assim, new ConectaBanco(), que invoca o construtor, só pode ser feito na própria ConectaBanco. Os membros de classe (static) $instancia e do método getInstancia() independem de objeto, existem a partir do momento em que a classe existir. O método instanciou um objeto ConectaBanco e o atribuiu à variável de classe ConectaBanco::$instancia apenas se esta ainda estiver nula. A partir de chamadas sucessivas, ele apenas retornará o conteúdo já atribuído.&lt;/p&gt;&lt;p class="MsoNormal"&gt;Assim, nas linhas abaixo:&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;$conn1 = ConectaBanco::getInstancia();&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"  style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;$conn2 = ConectaBanco::getInstancia();&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;As variáveis $conn1 e $conn2 referenciam o mesmo objeto.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="FONT-WEIGHT: bold"&gt;Críticas construtivas&lt;/p&gt;&lt;p class="MsoNormal"&gt;Perdão ao Diego, mas sua classe misturou demais o HTML ao PHP.&lt;/p&gt;&lt;p class="MsoNormal"&gt;Perdão ao Adler, mas seu código fugiu um pouco do conceito de Singleton. O método getInstancia()&lt;span style="font-size:0;"&gt; &lt;/span&gt;(no seu caso, singleton()) retorna uma instância de mysqli e não da própria classe, como reza a norma GoFiana forjada em ambientes mais fortemente tipados.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;Perdão ao Alexandre, mas se eu me deparasse com esse exemplo como argumento para utilização do Singleton há alguns anos, provavelmente continuaria trabalhando com meus códigos procedurais onde toda página incluía um simples arquivo conexao.php que atribuísse o almejado recurso de conexão com o banco de dados numa simples variável global.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="FONT-WEIGHT: bold"&gt;O conceito de aplicação&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;o:p&gt;&lt;/o:p&gt;Conforme bem lembra Felipe Ribeiro (aliás, o povo agradece por sair do lugar comum e elaborar um exemplo diferente da conexão com o banco):&lt;/p&gt;&lt;p class="MsoNormal"&gt;“Em PHP não existe o conceito de Aplicação, ou seja, cada vez que alguém acessa sua página, o que acontece é apenas a execução de um script numa thread do seu webserver, e mesmo que várias pessoas acessam simultaneamente o *mesmo* script, essas execuções são independentes, não há relação nenhuma entre elas.”&lt;/p&gt;&lt;p class="MsoNormal"&gt;Cada nova requisição inicia um novo processo no servidor que é encerrado no momento que não houver mais nada a devolver ao browser.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="FONT-WEIGHT: bold"&gt;Estaria o PHP fadado a não suportar o Singleton?&lt;/p&gt;&lt;p class="MsoNormal"&gt;Permita-me concordar não por completo com Felipe. O conceito de aplicação pode sim ser definido pelo desenvolvedor. Recentemente, ao elaborar um sistema e-commerce orientado a objetos pensei da seguinte maneira: Considerei que a aplicação deveria estar disponível para cada cliente, enquanto ele navegar. Começando na sua chegada à página inicial e encerrando no fechamento do browser ou conclusão da compra. Nesse último caso, ela reinicia automaticamente.&lt;/p&gt;&lt;p class="MsoNormal"&gt;Se você pensou em sessões, pensou o mesmo que eu. Observe a definição da classe Carrinho que elaborei (obviamente, não trouxe seus demais atributos e métodos de negócio para não acarretar num código demasiadamente extenso):&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;?&lt;? &lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;class Carrinho {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;/**&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Instância única do Carrinho&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* @var Carrinho&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;*/&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;private static $instancia;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;/**&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Método estático de acesso ao objeto Carrinho.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Antes de construir um novo Carrinho, ele verifica&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* se há algum já salvo na sessão do cliente.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Se houver, retorna ela. Só em último caso, retorna uma nova.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* @return Carrinho objeto único &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;*/&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;public static function getCarrinhoAtual() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;if (!isset(Carrinho::$instancia)) {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;Carrinho::$instancia = (isset($_SESSION['carrinho'])) ?&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;$_SESSION['carrinho'] :&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;new Carrinho();&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;return Carrinho::$instancia;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;/**&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Construtor privado&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;*/&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;private function __construct() {}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;/**&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Apenas aproveitei o destrutor para lançar o&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* Carrinho na sessão.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;* É necessário que o script execute um sesssion_start()&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;&lt;span lang="EN-US"&gt;*/&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;public function __destruct() {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;$_SESSION['carrinho'] = Carrinho::$instancia;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span lang="EN-US"&gt;&lt;span style="font-size:0;"&gt;&lt;/span&gt;&lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;?&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p class="MsoNormal"&gt;Dessa forma, consegui criar um objeto Carrinho que será único até o usuário fechar o browser ou encerrar a sessão de alguma forma. O que vai depender de como o sistema deve gerenciar suas sessões. Para um Singleton único por toda a aplicação, provavelmente seria necessário elaborar algum mecanismo de serialização e acesso concorrente, mas não foi o que precisei neste caso.&lt;/p&gt;&lt;p class="MsoNormal"&gt;O argumento para utilizar o Singleton agora, diferentemente da simples conexão com o banco é que nosso objeto pode ser inserido num contexto OO completo, possuindo associações com outras classes, como o Carrinho possuir uma coleção de objetos Item, constituírem um atributo de outro objeto Compra e assim por diante.&lt;/p&gt;&lt;p class="MsoNormal"&gt;Enfim, a idéia desse artigo não foi exatamente explicar o que é o Singleton, mas mostrar que o propósito dos padrões de projeto é atender às necessidades do desenvolvedor mostrando-o uma saída a um problema que ele já deve ter, e não forçá-lo a programar de uma maneira rígida. Não acho legal ver as pessoas querendo apenas adotar os padrões simplesmente como eles são, estejam eles adequados ou não à sua realidade.&lt;/p&gt;&lt;br /&gt;&lt;/o:p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37519337-116914534348722715?l=joseberardo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joseberardo.blogspot.com/feeds/116914534348722715/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37519337&amp;postID=116914534348722715' title='6 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/116914534348722715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/116914534348722715'/><link rel='alternate' type='text/html' href='http://joseberardo.blogspot.com/2007/01/o-cansado-singleton.html' title='Design patterns: 1 - O onipresente Singleton e o conceito de aplicação'/><author><name>Jose Berardo</name><uri>http://www.blogger.com/profile/12931771695642938128</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37519337.post-116330761352696032</id><published>2006-11-11T20:50:00.000-08:00</published><updated>2006-12-06T13:51:43.443-08:00</updated><title type='text'>Abstração de SGBDs - Estudo comparativo - Parte 2 Desempenho</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;em&gt;Esse post é uma continuação do anterior &lt;/em&gt;&lt;/span&gt;&lt;a href="http://www.especializa.com.br/berardo/2006/11/abstrao-de-sgbds-estudo-comparativo.html"&gt;&lt;span style="font-size:85%;"&gt;&lt;em&gt;http://www.especializa.com.br/berardo/2006/11/abstrao-de-sgbds-estudo-comparativo.html&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;em&gt;. Para saber mais sobre as bibliotecas, visite o link acima.&lt;br /&gt;&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;a name="_Toc151038470"&gt;&lt;strong&gt;Estudo comparativo&lt;/strong&gt;&lt;/a&gt;&lt;br /&gt;&lt;a name="_Toc151038470"&gt;&lt;br /&gt;&lt;/a&gt;A partir de agora, apresentaremos um estudo comparativo entre as sete bibliotecas citadas. Não é nosso intuito procurar uma resposta definitiva sobre qual é a melhor, você vai perceber que nos três quesitos que avaliaremos (desempenho, facilidade e portabilidade) nenhuma conseguiu se sobressair completamente. Vale ressaltar aqui que este é um estudo bem inicial, servindo apenas para fomentar a pesquisa antes de tecer qualquer julgamento sobre alguma delas. Sem contar que muitos outros fatores importantes não estão sendo avaliados.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Desempenho&lt;br /&gt;&lt;/em&gt;Este certamente é um fator da mais alta importância. Inspirado no blog de Joseph Scott (&lt;a href="http://joseph.randomnetworks.com/"&gt;http://joseph.randomnetworks.com/&lt;/a&gt;), que trouxe um comparativo preliminar apenas com três destas bibliotecas, nosso estudo também é inicial.&lt;br /&gt;Avaliaremos o tempo de processamento do PHP para consultar uma &lt;a href="http://www.especializa.com.br/berardo/atores.sql"&gt;base de dados &lt;/a&gt;PostgreSQL de cadastro de atores de cinema. Nela, há 542 atores cadastrados e faremos uma consulta para listar seus nomes em ordem alfabética. Primeiramente, não exibiremos seus nomes e colhemos o resultado, depois exibiremos e também coletaremos o resultado. Uma consulta com essa quantidade de registros não é grande o suficiente, portanto, a repetiremos num laço 250 vezes.&lt;br /&gt;Tomaremos como base um simples script procedural com acesso diretamente através das funções nativas do PostgreSQL. Confira no código abaixo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Código 1 – Benchmark – PostgreSQL direto&lt;br /&gt;1.          &lt;?php&lt;br /&gt;2.          $time_start = microtime(true);&lt;br /&gt;3.          $db = pg_connect("host=localhost dbname=locadora " .&lt;br /&gt;4.                           "user=postgres password=postgres");&lt;br /&gt;5.          &lt;br /&gt;6.          $runs = 250;&lt;br /&gt;7.          for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;8.              $sql = "select nome from atores order by nome";&lt;br /&gt;9.              $rs = pg_query($db, $sql);&lt;br /&gt;10.          while($row = pg_fetch_row($rs)) {&lt;br /&gt;11.            echo $row[0];&lt;br /&gt;12.          }&lt;br /&gt;13.      }&lt;br /&gt;14.      &lt;br /&gt;15.      $time_end = microtime(true);&lt;br /&gt;16.      $time = $time_end - $time_start;&lt;br /&gt;17.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;18.      ?&gt;&lt;?php 2.          $time_start = microtime(true); 3.          $db = pg_connect("host=localhost dbname=locadora " . 4.                           "user=postgres password=postgres"); 5.           6.          $runs = 250; 7.          for($i = 0; $i &lt; $runs; $i++) { 8.              $sql = "select nome from atores order by nome"; 9.              $rs = pg_query($db, $sql); 10.          while($row = pg_fetch_row($rs)) { 11.            echo $row[0]; 12.          } 13.      } 14.       15.      $time_end = microtime(true); 16.      $time = $time_end - $time_start; 17.      print("\n\nTEMPO: {$time}\n"); 18.      ?&gt;&lt;?php 2.          $time_start = microtime(true); 3.          $db = pg_connect("host=localhost dbname=locadora " . 4.                           "user=postgres password=postgres"); 5.           6.          $runs = 250; 7.          for($i = 0; $i &lt; $runs; $i++) { 8.              $sql = "select nome from atores order by nome"; 9.              $rs = pg_query($db, $sql); 10.          while($row = pg_fetch_row($rs)) { 11.            echo $row[0]; 12.          } 13.      } 14.       15.      $time_end = microtime(true); 16.      $time = $time_end - $time_start; 17.      print("\n\nTEMPO: {$time}\n"); 18.      ?&gt;&lt;?php 2.          $time_start = microtime(true); 3.          $db = pg_connect("host=localhost dbname=locadora " . 4.                           "user=postgres password=postgres"); 5.           6.          $runs = 250; 7.          for($i = 0; $i &lt; $runs; $i++) { 8.              $sql = "select nome from atores order by nome"; 9.              $rs = pg_query($db, $sql); 10.          while($row = pg_fetch_row($rs)) { 11.            echo $row[0]; 12.          } 13.      } 14.       15.      $time_end = microtime(true); 16.      $time = $time_end - $time_start; 17.      print("\n\nTEMPO: {$time}\n"); 18.      ?&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;O primeiro passo foi recuperar o timestamp atual (em $time_start). Depois conectamos ao banco PostgreSQL. A linha que nos interessa é a 11. Nela, exibiremos o resultado carregado em $row. Ao final das 250 consultas idênticas, recuperaremos o timestamp final e exibiremos a diferença.&lt;br /&gt;Os testes foram realizados primeiramente numa máquina modesta. Foram feitas chamadas ao script diretamente da linha de comando (# php teste1.php), ou seja, sem requerer processamento do Apache e envio da resposta ao browser. Invocamos a execução do script omitindo a linha 11, que imprime os nomes. Apesar de não percebermos variações significativas de resultado, colhemos o valor do tempo mais baixo. Depois executamos mais cinco vezes com a linha omitida anteriormente e também colhemos o resultado mais baixo. Para tornar o teste mais real, efetuamos o mesmo procedimento em outra máquina um pouco mais potente. Confira suas configurações:&lt;br /&gt;Máquina 1: Intel Pentium III, 256Mb RAM, SO Linux Slackware 10.2. PHP 5.1.6&lt;br /&gt;Máquina 2: AMD Sempron 64 2800, 512Mb RAM, SO Linux Slackware 10.2. PHP 5.1.6. Confira os resultados na tabela abaixo (valores arredondados em segundos):&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Tabela 1 – Benchmark – Resultados PostgreSQL direto&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;table style="FONT-SIZE: 80%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Agora veja como faríamos na primeira biblioteca citada, Metabase:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Código 2 – Benchmark – Metabase &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;1.          &lt;?php&lt;br /&gt;2.          require("metabase/metabase_interface.php");&lt;br /&gt;3.          require("metabase/metabase_database.php");&lt;br /&gt;4.          ini_set('include_path',&lt;br /&gt;5.                   ini_get('include_path').':'.&lt;br /&gt;6.                   dirname(__FILE__).'/metabase');&lt;br /&gt;7.          $time_start = microtime(true);&lt;br /&gt;8.          &lt;br /&gt;9.          MetabaseSetupDatabaseObject(array(&lt;br /&gt;10.        "Type"     =&gt; "pgsql",&lt;br /&gt;11.        "User"     =&gt; "postgres",&lt;br /&gt;12.        "Password" =&gt; "postgres"),&lt;br /&gt;13.        $conn);&lt;br /&gt;14.      MetabaseSetDatabase($conn-&gt;database, "locadora");&lt;br /&gt;15.      &lt;br /&gt;16.      $runs = 250;&lt;br /&gt;17.      for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;18.          $sql = "select nome from atores order by nome";&lt;br /&gt;19.          $rs = $conn-&gt;Query($sql);&lt;br /&gt;20.          $rows = $conn-&gt;NumberOfRows($rs);&lt;br /&gt;21.          for ($x=0; $x&lt;$rows; $x++) {&lt;br /&gt;22.            echo $conn-&gt;FetchResult($rs, $x, 0);&lt;br /&gt;23.          }&lt;br /&gt;24.      }&lt;br /&gt;25.      &lt;br /&gt;26.      $time_end = microtime(true);&lt;br /&gt;27.      $time = $time_end - $time_start;&lt;br /&gt;28.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;29.      ?&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;Aproveitando para explicar o código, inicialmente, incluímos os arquivos necessários e adicionamos o diretório da biblioteca Metabase extraída (sob o próprio diretório dos testes) na include_path. Só a partir daí o script começou a contar o tempo. A função MetabaseSetupDatabaseObject estabeleceu a conexão com o servidor passado como parâmetro e MetabaseSetDatabase definiu a base de dados . Objeto $conn efetuou a consulta ($conn-&gt;Query()) e um recuperou o total de linhas ($conn-&gt;NumberOfRows()). Dentro do laço, cada linha foi recuperada através de $conn-&gt;FetchResult(). No primeiro teste, a linha 22 não foi totalmente omitida. Se fosse, nenhum dado seria carregado na memória, visto que o laço é um simples &lt;em&gt;for&lt;/em&gt; de zero até o total de linhas consultadas. O que fizemos foi testar a linha 22 da seguinte forma:&lt;br /&gt;&lt;br /&gt;$resultado = $conn-&gt;FetchResult($rs, $x, 0);&lt;br /&gt;&lt;br /&gt;Trouxemos o resultado para uma variável em vez de imprimir direto. No segundo teste, a linha 22 ficou como está lá. Veja o resultado. Mantivemos os valores do PostgreSQL direto para efeito comparativo. A última linha mostra quanto em valores percentuais os novos tempos excederam os primeiros (valores arredondados):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:85%;"&gt;Tabela 2 – Benchmark – Resultados Metabase &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;5,0331959&lt;/td&gt;&lt;td align="right"&gt;9,8323698&lt;/td&gt;&lt;td align="right"&gt;2,3078690&lt;/td&gt;&lt;td align="right"&gt;5,6365590&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;150,07%&lt;/td&gt;&lt;td align="right"&gt;131,92%&lt;/td&gt;&lt;td align="right"&gt;150,89%&lt;/td&gt;&lt;td align="right"&gt;137,53%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Percebe-se que o PHP passou a sofrer um pouco para recuperar os mesmos dados. Se antes ele precisava de pouco mais de quatro segundos para efetuar uma operação, agora serão necessários mais do dobro. Dando seqüência aos testes, apresentaremos a ADOdb. Confira:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:100%;"&gt;Código 3 – Benchmark ADOdb&lt;br /&gt;1.          &lt;?php&lt;br /&gt;2.          require_once("adodb/adodb.inc.php");&lt;br /&gt;3.          $time_start = microtime(true);&lt;br /&gt;4.          &lt;br /&gt;5.          $conn = NewADOConnection(&lt;br /&gt;6.                    "pgsql://postgres:postgres@localhost/locadora");&lt;br /&gt;7.          $ADODB_FETCH_MODE = ADODB_FETCH_NUM;&lt;br /&gt;8.          $runs = 250;&lt;br /&gt;9.          for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;10.          $sql = "select nome from atores order by nome";&lt;br /&gt;11.          $rs = $conn-&gt;Execute($sql);&lt;br /&gt;12.          while(!$rs-&gt;EOF) {&lt;br /&gt;13.            echo $rs-&gt;fields[0];&lt;br /&gt;14.            $rs-&gt;MoveNext();&lt;br /&gt;15.          }&lt;br /&gt;16.      }&lt;br /&gt;17.      &lt;br /&gt;18.      $time_end = microtime(true);&lt;br /&gt;19.      $time = $time_end - $time_start;&lt;br /&gt;20.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;21.      ?&gt;&lt;br /&gt;&lt;br /&gt;Assim como na Metabase, fizemos o download da ADOdb e extraímos num diretório abaixo do nosso teste. Agora, apenas o arquivo adodb.inc.php foi necessário. Não precisamos adicionar este subdiretório da biblioteca na include_path.&lt;br /&gt;A função NewADOConnection() entregou a $conn o objeto que utilizaremos para efetuar a consulta. Neste momento, também foi mais fácil passar os parâmetros necessário para ela saber qual banco conectar. Parâmetros na forma de uma única URL, no lugar de uma array de parâmetros e um método adicional para escolher a base, simplifica bem as coisas.&lt;br /&gt;A variável definida na linha 8 foi necessária para informar à biblioteca que traga apenas arrays indexados, já que o padrão é trazer arrays com valores indexados e associativos (algo como MYSQL_BOTH que você já conhece).&lt;br /&gt;Na linha 12, a instrução $conn-&gt;Execute() efetuou a consulta e devolveu o identificador do resultado para $rs. O atributo $rs-&gt;EOF (end of file) será verdadeiro quando o ponteiro de leitura do resultado alcançar o final do resultado. Já o atributo $rs-&gt;fields é um array (apenas indexado devido à variável $ADODB_FETCH_MODE ser ADODB_FETCH_NUM) com os campos da consulta.&lt;br /&gt;A linha 14 foi comentada no primeiro teste e recolocada no segundo. O método $rs-&gt;MoveNext() foi o responsável para avançar ao próximo registro. Sem ele, entraríamos em loop infinito.&lt;br /&gt;Da mesma maneira que fizemos com a Metabase, confira os resultados:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Tabela 3 – Benchmark – Resultados ADOdb&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;5,1899459&lt;/td&gt;&lt;td align="right"&gt;10,7471740&lt;/td&gt;&lt;td align="right"&gt;2,2355139&lt;/td&gt;&lt;td align="right"&gt;6,1193878&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;157,86%&lt;/td&gt;&lt;td align="right"&gt;153,50%&lt;/td&gt;&lt;td align="right"&gt;143,03%&lt;/td&gt;&lt;td align="right"&gt;157,88%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note que o resultado final foi ligeiramente mais lento do que a Metabase, chegando ser mais rápida apenas no terceiro teste. Podemos concluir que elas tiveram tecnicamente o mesmo desempenho, com vitória da Metabase no critério de desempate =D.&lt;br /&gt;A próxima a ser testada será a extensão DBX. Confira seu código:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Código 4 – Benchmark DBX&lt;br /&gt;1.          &lt;?php&lt;br /&gt;2.          $time_start = microtime(true);&lt;br /&gt;3.          &lt;br /&gt;4.          $conn = dbx_connect("pgsql", "localhost",&lt;br /&gt;5.                              "locadora", "postgres", "postgres");&lt;br /&gt;6.          $runs = 250;&lt;br /&gt;7.          for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;8.              $sql = "select nome from atores order by nome";&lt;br /&gt;9.              $rs = dbx_query($conn, $sql, DBX_RESULT_INDEX);&lt;br /&gt;10.          for ($x = 0; $x &lt; $rs-&gt;rows; $x++) {&lt;br /&gt;11.            echo $rs-&gt;data[$x][0];&lt;br /&gt;12.          }&lt;br /&gt;13.      }&lt;br /&gt;14.      $time_end = microtime(true);&lt;br /&gt;15.      $time = $time_end - $time_start;&lt;br /&gt;16.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;17.      ?&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Por se tratar de uma extensão, não foi necessário incluir arquivo algum ao script. A função dbx_connect(), conectou ao nosso banco recebendo as informações cada uma como um parâmetro (banco, host, base, usuário e senha). A consulta ficou a cargo da função dbx_query(), que assim como a pg_query(), recebeu no primeiro argumento, a variável que representa a conexão e no segundo a instrução SQL. O terceiro, DBX_RESULT_INDEX, foi para informar que o resultado será recuperado num array apenas indexado. O mesmo que fizemos com a ADOdb.&lt;br /&gt;Após a consulta, a variável $rs recebeu um objeto de stdClass com alguns atributos populados. $rs-&gt;rows corresponde ao total de linhas da consulta. Em $rs-&gt;data todo o conteúdo foi lançado como uma matriz. O que fizemos foi varrer essa matriz da maneira mais eficiente (através de um laço for - utilizar um foreach nesse caso degradaria o desempenho desnecessariamente). A linha 11 foi simplesmente comentada no primeiro teste e refeita no segundo. Confira o resultado:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Tabela 4 – Benchmark – Resultados DBX&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;4,7955241&lt;/td&gt;&lt;td align="right"&gt;9,3504899&lt;/td&gt;&lt;td align="right"&gt;1,9520251&lt;/td&gt;&lt;td align="right"&gt;4,8769801&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;138,26%&lt;/td&gt;&lt;td align="right"&gt;120,26%&lt;/td&gt;&lt;td align="right"&gt;112,21%&lt;/td&gt;&lt;td align="right"&gt;105,52%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Houve um pequeno ganho de desempenho. Uma coisa interessante de se notar é a queda considerável de percentual nos testes com impressão do resultado. A explicação é bem simples. A DBX carregou os dados numa matriz, num processo semelhante à pg_fetch_row() que recuperou o resultado num array a cada iteração do laço. O ato de leitura em ambas foi apenas imprimir a posição de um array indexado. Assim a ação de exibição dos dados na tela levou o mesmo tempo em ambas. Em suma, a diferença está exclusivamente no momento de envio da consulta ao SGBD e recuperação do resultado em variável.&lt;br /&gt;&lt;br /&gt;A próxima da lista é a PEAR::DB. Acompanhe:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Código 5 – Benchmark PEAR::DB&lt;br /&gt;1.          &lt;?php&lt;br /&gt;2.          require_once("PEAR.php");&lt;br /&gt;3.          require_once("DB.php");&lt;br /&gt;4.          $time_start = microtime(true);&lt;br /&gt;5.          &lt;br /&gt;6.          $conn = DB::Connect(&lt;br /&gt;7.                  "pgsql://postgres:postgres@localhost/locadora");&lt;br /&gt;8.          $runs = 250;&lt;br /&gt;9.          for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;10.        $sql = "select nome from atores order by nome";&lt;br /&gt;11.        $rs = $conn-&gt;query($sql);&lt;br /&gt;12.        while($row = $rs-&gt;fetchRow()) {&lt;br /&gt;13.          echo $row[0];&lt;br /&gt;14.        }&lt;br /&gt;15.      }&lt;br /&gt;16.      &lt;br /&gt;17.      $time_end = microtime(true);&lt;br /&gt;18.      $time = $time_end - $time_start;&lt;br /&gt;19.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;20.      ?&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;Incluímos, no início, os arquivos necessários. PEAR.php para todo e qualquer biblioteca do PEAR (ela seria incluída indiretamente se não fizéssemos, como nosso foco é o desempenho apenas da consulta, a incluímos logo de cara, antes de zerar os cronômetros) e DB.php específico para a PEAR::DB.&lt;br /&gt;A conexão foi efetuada pela instrução DB::Connect(). DB é uma classe utilitária, seu método estático Connect() retorna um objeto do tipo DB_common. Esta última é uma classe extendida pelas classes particulares de cada SGBD suportado. Assim, no nosso caso, a variável $conn recebeu uma instância de DB_ pgsql (que herda de DB_common) devido à informação do protocolo (pgsql://) na URL de conexão.&lt;br /&gt;A consulta se deu através do método $conn-&gt;query(), declarado em DB_common e redefinido em cada uma de suas subclasses. Num processo semelhante ao do PostgreSQL direto, fizemos um while onde uma variável $row recebeu o resultado do método $rs-&gt;fetchRow(), que por padrão já retorna um array indexado.&lt;br /&gt;Comentando e descomentando a linha 13, obtivemos os seguintes resultados:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Tabela 5 – Benchmark – Resultados PEAR::DB&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;7,6816080&lt;/td&gt;&lt;td align="right"&gt;16,5098081&lt;/td&gt;&lt;td align="right"&gt;3,4886191&lt;/td&gt;&lt;td align="right"&gt;9,4957421&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;281,66%&lt;/td&gt;&lt;td align="right"&gt;289,43%&lt;/td&gt;&lt;td align="right"&gt;279,25%&lt;/td&gt;&lt;td align="right"&gt;300,17%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Repetimos esses testes exaustivamente por simplesmente não acreditarmos que o resultado pudesse ter sido tão ruim. O mais estranho foi o aumento percentual nos testes com impressão do resultado. É como se houvesse uma alocação excessiva de memória, suficiente até para que uma simples exibição de dados nas variáveis também se tornasse uma operação mais custosa do que no diretamente nas funções de acesso ao PostgreSQL.&lt;br /&gt;Com a sua sucessora PEAR::MDB2 o resultado curiosamente só piorou. Veja:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Código 6 – Benchmark PEAR::MDB2&lt;br /&gt;1.          &lt;?php&lt;br /&gt;2.          require_once("PEAR.php");&lt;br /&gt;3.          require_once("MDB2.php");&lt;br /&gt;4.          $time_start = microtime(true);&lt;br /&gt;5.          &lt;br /&gt;6.          $conn = MDB2::Connect(&lt;br /&gt;7.                 "pgsql://postgres:postgres@localhost/locadora");&lt;br /&gt;8.          $runs = 250;&lt;br /&gt;9.          for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;10.          $sql = "select nome from atores order by nome";&lt;br /&gt;11.          $rs = $conn-&gt;query($sql);&lt;br /&gt;12.          while($row = $rs-&gt;fetchRow()) {&lt;br /&gt;13.            echo $row[0];&lt;br /&gt;14.          }&lt;br /&gt;15.      }&lt;br /&gt;16.      &lt;br /&gt;17.      $time_end = microtime(true);&lt;br /&gt;18.      $time = $time_end - $time_start;&lt;br /&gt;19.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;20.      ?&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:100%;"&gt;Note que o script foi praticamente o mesmo. Os métodos de $conn e $rs não mudaram. Confira o resultado:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;Tabela 6 – Benchmark – Resultados PEAR::MDB2 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;9,3536999&lt;/td&gt;&lt;td align="right"&gt;20,7585239&lt;/td&gt;&lt;td align="right"&gt;4,2592630&lt;/td&gt;&lt;td align="right"&gt;11,3491249&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;364,74%&lt;/td&gt;&lt;td align="right"&gt;389,64%&lt;/td&gt;&lt;td align="right"&gt;363,03%&lt;/td&gt;&lt;td align="right"&gt;378,27%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Tornamos a falar que nosso teste não é conclusivo. Haveria uma série de outras coisas a se avaliar. No entanto, numa operação bastante corriqueira em qualquer sistema (simples listagem de dados de uma base), a diferença entre as demais soluções e as do PEAR foram expressivas.&lt;br /&gt;A próxima biblioteca analisada foi a Creole, veja como foi:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Código 7 – Benchmark Creole&lt;br /&gt;1.          &lt;?php&lt;br /&gt;2.          require_once("creole/Creole.php");&lt;br /&gt;3.          $time_start = microtime(true);&lt;br /&gt;4.          &lt;br /&gt;5.          $conn = Creole::getConnection(&lt;br /&gt;6.                  "pgsql://postgres:postgres@localhost/locadora");&lt;br /&gt;7.          $stmt = $conn-&gt;createStatement();&lt;br /&gt;8.          $runs = 250;&lt;br /&gt;9.          for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;10.          $sql = "select nome from atores order by nome";&lt;br /&gt;11.          $rs = $stmt-&gt;executeQuery($sql, ResultSet::FETCHMODE_NUM);&lt;br /&gt;12.          while ($rs-&gt;next()) {&lt;br /&gt;13.            echo $rs-&gt;getString(1);&lt;br /&gt;14.          }&lt;br /&gt;15.      }&lt;br /&gt;16.      &lt;br /&gt;17.      $time_end = microtime(true);&lt;br /&gt;18.      $time = $time_end - $time_start;&lt;br /&gt;19.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;20.      ?&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;Assim como em Java, $conn é uma instância de uma classe que implementa a interface Connection (no JDBC seria java.sql.Connection), no caso, PgSQLConnection. A partir de $conn, obtivemos um objeto Statement (PgSQLStatement) que armazenamos em $stmt. Objetos são os responsável por efetuar as consultas.&lt;br /&gt;O método $stmt-&gt;executeQuery() recuperou um objeto ResultSet, de onde iremos colher as informações. Seu método $rs-&gt;next() avança o ponteiro e retorna verdadeiro se houver próximo registro, falso caso contrário.&lt;br /&gt;Seguir à risca a sintaxe do JDBC não rendeu tão bem, se você trocar o laço while das linhas 12 a 14 pelo laço abaixo, terá um resultado mais eficiente:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;foreach ($rs as $row) {&lt;br /&gt;echo $row[0];&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:100%;"&gt;A variável $rs é do tipo PgSQLResultSet, que por sua vez, implementa a interface ResultSet, como seria em Java. O que a Creole fez de interessante foi declarar que ResultSet herda da interface SPL IteratorAggregate. Assim, PgSQLResultSet implementou os métodos homônimos ao ResultSet do JDBC, mais o método getIterator(). No caso da PgSQLResult, o método retorna uma instância de PgSQLResultSetIterator. Assim, foi possível passar $rs no foreach, o PHP já vai saber que deve chamar os métodos de PgSQLResultSetIterator para recuperar cada valor colocado em $row. Finalmente, $row será apenas um array indexado, devido ao parâmetro ResultSet::FETCHMODE_NUM passado na consulta.&lt;br /&gt;A tabela abaixo mostra os resultados das duas metodologias:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Tabela 7 – Benchmark – Resultados Creole &lt;/span&gt;&lt;/p&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th colspan="4"&gt;Método JDBC&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;3,9955730&lt;/td&gt;&lt;td align="right"&gt;11,8272559&lt;/td&gt;&lt;td align="right"&gt;1,7274060&lt;/td&gt;&lt;td align="right"&gt;7,6208939&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;98,52%&lt;/td&gt;&lt;td align="right"&gt;178,98%&lt;/td&gt;&lt;td align="right"&gt;87,79%&lt;/td&gt;&lt;td align="right"&gt;221,16%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th colspan="4"&gt;Método SPL&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;3,6212871&lt;/td&gt;&lt;td align="right"&gt;7,4538250&lt;/td&gt;&lt;td align="right"&gt;1,5732012&lt;/td&gt;&lt;td align="right"&gt;4,2920520&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;79,92%&lt;/td&gt;&lt;td align="right"&gt;75,85%&lt;/td&gt;&lt;td align="right"&gt;71,03%&lt;/td&gt;&lt;td align="right"&gt;80,87%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;O formato SPL garantiu um melhor desempenho em todos os testes, com destaque para o momento em que exibimos o resultado (Com impressão) que, no método JDBC foi bem mais lento em termos percentuais e no SPL chegou a ser mais rápido na máquina 1 e pouco mais lento na máquina 2. Afinal exibir o valor de um array é mais rápido do que chamar um método que pesquisará por esse valor no resultado da consulta.&lt;br /&gt;&lt;br /&gt;A última biblioteca testada foi a PDO, confira:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Código 8 – Benchmark PDO&lt;br /&gt;1.          &lt;?php&lt;br /&gt;2.          $conn = new PDO("pgsql:host=localhost dbname=locadora " .&lt;br /&gt;3.                        "user=postgres password=postgres");&lt;br /&gt;4.          $runs = 250;&lt;br /&gt;5.          for($i = 0; $i &lt; $runs; $i++) {&lt;br /&gt;6.              $sql = "select nome from atores order by nome";&lt;br /&gt;7.              foreach($conn-&gt;query($sql, PDO::FETCH_NUM) as $row) {&lt;br /&gt;8.                echo $row[0];&lt;br /&gt;9.              }&lt;br /&gt;10.      }&lt;br /&gt;11.      &lt;br /&gt;12.      $time_end = microtime(true);&lt;br /&gt;13.      $time = $time_end - $time_start;&lt;br /&gt;14.      print("\n\nTEMPO: {$time}\n");&lt;br /&gt;15.      ?&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:100%;"&gt;A conexão com o SGBD se dá através da instância de um objeto da classe PDO. Passamos como parâmetro, a mesma string que havíamos passado no pg_connect(), adicionando apenas o rótulo pgsql:. Num exemplo de desatenção à portabilidade, a conexão PDO com o MySQL, não seria desta forma, mas de acordo com a sintaxe da função mysql_connect(), ou seja, receberia três parâmetros, como abaixo:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;$conn = new PDO("mysql:host=localhost;dbname=locadora", "root", "");&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Nesse caso, as diferenças para a mysql_connect() são apenas o rótulo mysql: e a informação da base de dados, no lugar da chamada à infame mysql_select_db().&lt;br /&gt;Como você deve saber que conexões com o banco devem ser declaradas em um único local para serem incluídas quando necessárias (afinal, trocar de banco só em casos especiais, mas a troca de servidor, usuário ou senha é um procedimento bem comum), a diferença nessa declaração de um SGBD para outro não lhe traria maiores problemas.&lt;br /&gt;A consulta foi feita através da instrução $conn-&gt;query() que recebeu a intrução SQL como parâmetro e retornou um objeto do tipo PDOStatement, uma classe da API da PDO que implementa a interface SPL IteratorAggregate, por isso, é transpassável por um foreach como fosse um array. Devido ao segundo parâmetro PDO::FETCH_NUM, o resultado de cada iteração do laço será um array indexado.&lt;br /&gt;O resultado final foi surpreendente. Apesar de já esperarmos que um bom desempenho do PDO por ser uma extensão escrita em C, a boa implementação da SPL proporcionou o melhor resultado, longe dos demais. Observe:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Tabela 8 – Benchmark – Resultados PDO &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Máquina 1 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 1 - Com impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Sem impressão&lt;/th&gt;&lt;th&gt;Máquina 2 - Com impressão&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,01268792&lt;/td&gt;&lt;td align="right"&gt;4,2395219&lt;/td&gt;&lt;td align="right"&gt;0,9198659&lt;/td&gt;&lt;td align="right"&gt;2,3729560&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;2,1494179&lt;/td&gt;&lt;td align="right"&gt;4,4430050&lt;/td&gt;&lt;td align="right"&gt;0,9116380&lt;/td&gt;&lt;td align="right"&gt;1,9495799&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align="right"&gt;6,79%&lt;/td&gt;&lt;td align="right"&gt;4,80%&lt;/td&gt;&lt;td align="right"&gt;-0,89%&lt;/td&gt;&lt;td align="right"&gt;-17,84%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Em todos os testes, ela andou bastante próxima das chamadas nativas. E por mais estranho que possa parecer, chegou a superá-las na segunda máquina. Não pense que foi um resultado isolado, durante os testes nesta máquina, a PDO andou regularmente abaixo do PostgreSQL direto.&lt;br /&gt;&lt;br /&gt;As grades abaixo mostram o acumulado de resultados catalogados aqui, com as bibliotecas na ordem da média do percentual de tempo:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Tabela 9 – Benchmark – Grade Máquina 1 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;table style="FONT-SIZE: 80%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th widh="20%"&gt;Acesso&lt;/th&gt;&lt;th widh="20%"&gt;Sem impressão (s)&lt;/th&gt;&lt;th widh="20%"&gt;Com impressão (s)&lt;/th&gt;&lt;th widh="20%"&gt;Sem impressão %&lt;/th&gt;&lt;th widh="20%"&gt;Com impressão %&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PostgreSQL&lt;/td&gt;&lt;td align="right"&gt;2,01268792152&lt;/td&gt;&lt;td align="right"&gt;4,23952198029&lt;/td&gt;&lt;td align="right"&gt;0,00%&lt;/td&gt;&lt;td align="right"&gt;0,00%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PDO&lt;/td&gt;&lt;td align="right"&gt;2,1494178772&lt;/td&gt;&lt;td align="right"&gt;4,44300508499&lt;/td&gt;&lt;td align="right"&gt;6,79%&lt;/td&gt;&lt;td align="right"&gt;4,80%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Creole SPL&lt;/td&gt;&lt;td align="right"&gt;3,62128710747&lt;/td&gt;&lt;td align="right"&gt;7,45382499695&lt;/td&gt;&lt;td align="right"&gt;79,92%&lt;/td&gt;&lt;td align="right"&gt;75,82%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DBX&lt;/td&gt;&lt;td align="right"&gt;4,79552412033&lt;/td&gt;&lt;td align="right"&gt;9,35048985481&lt;/td&gt;&lt;td align="right"&gt;138,26%&lt;/td&gt;&lt;td align="right"&gt;120,56%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Creole JDBC&lt;/td&gt;&lt;td align="right"&gt;3,99557304382&lt;/td&gt;&lt;td align="right"&gt;11,8272559643&lt;/td&gt;&lt;td align="right"&gt;98,52%&lt;/td&gt;&lt;td align="right"&gt;178,98%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Metabase&lt;/td&gt;&lt;td align="right"&gt;5,03319597244&lt;/td&gt;&lt;td align="right"&gt;9,83236980438&lt;/td&gt;&lt;td align="right"&gt;150,07%&lt;/td&gt;&lt;td align="right"&gt;131,92%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ADOdb&lt;/td&gt;&lt;td align="right"&gt;5,1899459362&lt;/td&gt;&lt;td align="right"&gt;10,7471740246&lt;/td&gt;&lt;td align="right"&gt;157,86%&lt;/td&gt;&lt;td align="right"&gt;153,50%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DB&lt;/td&gt;&lt;td align="right"&gt;7,68160796165&lt;/td&gt;&lt;td align="right"&gt;16,5098080635&lt;/td&gt;&lt;td align="right"&gt;281,66%&lt;/td&gt;&lt;td align="right"&gt;289,43%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;MDB2&lt;/td&gt;&lt;td align="right"&gt;9,35369992256&lt;/td&gt;&lt;td align="right"&gt;20,758523941&lt;/td&gt;&lt;td align="right"&gt;364,74%&lt;/td&gt;&lt;td align="right"&gt;389,64%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Tabela 10 – Benchmark – Grade Máquina 2 &lt;/span&gt;&lt;br /&gt;&lt;table style="FONT-SIZE: 80%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th widh="20%"&gt;Acesso&lt;/th&gt;&lt;th widh="20%"&gt;Sem impressão (s)&lt;/th&gt;&lt;th widh="20%"&gt;Com impressão (s)&lt;/th&gt;&lt;th widh="20%"&gt;Sem impressão %&lt;/th&gt;&lt;th widh="20%"&gt;Com impressão %&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PDO&lt;/td&gt;&lt;td align="right"&gt;0,911638021469&lt;/td&gt;&lt;td align="right"&gt;1,94957995415&lt;/td&gt;&lt;td align="right"&gt;-0,89%&lt;/td&gt;&lt;td align="right"&gt;-17,84%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PostgreSQL&lt;/td&gt;&lt;td align="right"&gt;0,919865846634&lt;/td&gt;&lt;td align="right"&gt;2,37295603752&lt;/td&gt;&lt;td align="right"&gt;0,00%&lt;/td&gt;&lt;td align="right"&gt;0,00%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Creole SPL&lt;/td&gt;&lt;td align="right"&gt;1,5732011795&lt;/td&gt;&lt;td align="right"&gt;4,29205203056&lt;/td&gt;&lt;td align="right"&gt;71,03%&lt;/td&gt;&lt;td align="right"&gt;80,07%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DBX&lt;/td&gt;&lt;td align="right"&gt;1,95202517509&lt;/td&gt;&lt;td align="right"&gt;4,8769800663&lt;/td&gt;&lt;td align="right"&gt;112,21%&lt;/td&gt;&lt;td align="right"&gt;105,52%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Metabase&lt;/td&gt;&lt;td align="right"&gt;2,30786895752&lt;/td&gt;&lt;td align="right"&gt;5,63655900955&lt;/td&gt;&lt;td align="right"&gt;150,89%&lt;/td&gt;&lt;td align="right"&gt;137,53%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ADOdb&lt;/td&gt;&lt;td align="right"&gt;2,23551392555&lt;/td&gt;&lt;td align="right"&gt;6,11938786507&lt;/td&gt;&lt;td align="right"&gt;143,03%&lt;/td&gt;&lt;td align="right"&gt;157,88%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Creole JDBC&lt;/td&gt;&lt;td align="right"&gt;1,72740602493&lt;/td&gt;&lt;td align="right"&gt;7,62089395523&lt;/td&gt;&lt;td align="right"&gt;87,79%&lt;/td&gt;&lt;td align="right"&gt;221,16%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DB&lt;/td&gt;&lt;td align="right"&gt;3,48861908913&lt;/td&gt;&lt;td align="right"&gt;9,4957420826&lt;/td&gt;&lt;td align="right"&gt;279,25%&lt;/td&gt;&lt;td align="right"&gt;300,17%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;MDB2&lt;/td&gt;&lt;td align="right"&gt;4,25926303864&lt;/td&gt;&lt;td align="right"&gt;11,3491249084&lt;/td&gt;&lt;td align="right"&gt;363,03%&lt;/td&gt;&lt;td align="right"&gt;378,27%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Na média geral dos percentuais de tempo, o resultado foi:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Tabela 11 – Grade final – Média percentual dos quatro tempos &lt;/span&gt;&lt;br /&gt;&lt;table style="FONT-SIZE: 85%" border="1" celspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th widh="50%"&gt;Acesso&lt;/th&gt;&lt;th widh="50%"&gt;Média percentual&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PDO&lt;/td&gt;&lt;td align="right"&gt;-1,79%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PostgreSQL&lt;/td&gt;&lt;td align="right"&gt;0,00%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Creole SPL&lt;/td&gt;&lt;td align="right"&gt;76,91%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DBX&lt;/td&gt;&lt;td align="right"&gt;119,14%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Metabase&lt;/td&gt;&lt;td align="right"&gt;142,61%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Creole JDBC&lt;/td&gt;&lt;td align="right"&gt;146,61%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ADOdb&lt;/td&gt;&lt;td align="right"&gt;153,07%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PEAR::DB&lt;/td&gt;&lt;td align="right"&gt;287,63%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PEAR::MDB2&lt;/td&gt;&lt;td align="right"&gt;373,92%&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;No próximo post, entraremos nos próximos quesitos do estudo: facilidade e portabilidade.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37519337-116330761352696032?l=joseberardo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joseberardo.blogspot.com/feeds/116330761352696032/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37519337&amp;postID=116330761352696032' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/116330761352696032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/116330761352696032'/><link rel='alternate' type='text/html' href='http://joseberardo.blogspot.com/2006/11/abstrao-de-sgbds-estudo-comparativo_11.html' title='Abstração de SGBDs - Estudo comparativo - Parte 2 Desempenho'/><author><name>Jose Berardo</name><uri>http://www.blogger.com/profile/12931771695642938128</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37519337.post-116330353515009176</id><published>2006-11-11T19:46:00.000-08:00</published><updated>2007-01-18T04:55:37.710-08:00</updated><title type='text'>Abstração de SGBDs - Estudo comparativo - Parte 1 Bibliotecas</title><content type='html'>&lt;strong&gt;Abstração de bancos de dados&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Talvez você ache fácil comunicar-se com SGBDs no PHP através de funções específicas (mysql_connect(), mysql_query(), etc.). No entanto, talvez tenha percebido que um sistema recheado de “mysql_queries” perde muito em flexibilidade. Imagine o trabalho que o programador teria no momento em que precisasse passar a trabalhar com outro SGBD. E mais, imagine o grau de “retrabalho” no desenvolvimento de algum software com suporte a cinco ou dez SGBDs diferentes.&lt;br /&gt;Mesmo que haja uma tendência a certa degradação de desempenho (degradação inclusive questionável, mas, a rigor, há esta tendência), seria interessante construirmos alguma camada de código capaz de intermediar as requisições particulares do sistema ao banco de dados que de fato foi utilizado. Apesar de nosso objetivo ser aprender o “como fazer”, nesse momento, não reinventaremos a roda. Existe uma série de bibliotecas a esse respeito.&lt;br /&gt;Não seria bicho de sete cabeças desenvolver algo nesse sentido, entretanto, construir uma biblioteca de abstração de SGBDs realmente portável, isto é, capaz de trabalhar com pelo menos uns dez bancos diferentes, de maneira homogênea, suportando questões avançadas como prepared statements e transações e sabendo aplicar as particularidades de cada banco quando estas acarretarem ganhos de desempenho e segurança, pode sim ser uma tarefa complicada e trabalhosa.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Abstração de SGBD é uma necessidade absoluta?&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;Na verdade, a resposta é não. Como já dissemos, a tendência natural do uso dessa camada é a degradação de desempenho.&lt;br /&gt;Diversas soluções nessa direção já foram desenvolvidas. Se você já trabalhou ou pelo menos ouviu falar na solução da Microsoft ODBC (Open Database Connectivity, baseada na Call Level Interface, CLI, da SQL Access Group), sabe que se trata de uma camada intermediária entre os processos da aplicação e do SGBD a fim de proporcionar essa portabilidade, uma vez que o programa só precisará acessar o driver ODBC que este último se encarrega da comunicação com o banco adjacente.&lt;br /&gt;Acessar determinado banco através de um driver ODBC, no PHP (e porque não estender essa observação às demais linguagens), é normalmente mais lento e custoso para o servidor do que nativamente.&lt;br /&gt;A própria Microsoft desenvolveu uma API para acesso a servidores de bancos de dados chamada ADO (ActiveX Data Objects), popular desde versões mais antigas do seu Visual Basic, que pode trabalhar via ODBC ou nativamente com alguns SGBDs. A sintaxe desta API inspirou diversas bibliotecas com o mesmo propósito no PHP, mesmo sob o olhar crítico de alguns que não gostam da ADO ou simplesmente levantam questões de incompatibilidade entre os dois ambientes.&lt;br /&gt;Nossa opinião é a seguinte, se o desempenho for o requisito mais importante do seu sistema, acesse diretamente e se preocupe com os mínimos detalhes da API nativa do SGBD. No entanto, se a portabilidade e o conhecimento único aplicável a um grande leque de SGBDs forem questões relevantes no desenvolvimento de software, definitivamente, vale a pena investir na abstração.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Bibliotecas de abstração&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Nessa seção, apresentaremos algumas das mais populares bibliotecas de abstração de SGBDs do mercado. Praticamente 100% dos programadores experientes em PHP utilizam ou já utilizaram alguma(s) delas em seus projetos, e isso certamente, lhes rendeu algumas horas de sono a mais.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Metabase&lt;/em&gt;&lt;br /&gt;Uma das mais antigas ainda atualizadas e ativas no mercado. Criada por Manuel Lemos, desde quando o PHP ainda estava sua terceira versão. Mas muito bem adequada ao PHP4, ainda podendo ser utilizada em projetos PHP5 sem maiores problemas. No endereço &lt;a href="http://www.phpclasses.org/browse/package/20.html"&gt;http://www.phpclasses.org/browse/package/20.html&lt;/a&gt;, você encontrará sua mais nova versão, além de uma boa documentação em português.&lt;br /&gt;Há três formas de interagir com suas funcionalidades. A primeira, mais antiga, é através de um punhado de funções que iniciam com a palavra Metabase, a segunda, através dos métodos de um objeto gerado pela função MetabaseSetupDatabaseObject, a terceira seria uma mistura das outras duas.&lt;br /&gt;A tabela abaixo mostra a lista de SGBDs suportados pela Metabase e suas respectivas siglas utilizadas na biblioteca:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Tabela 1 – SGBDs suportados pela Metabase&lt;/span&gt;&lt;br /&gt;&lt;table class="MsoTableGrid" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN-LEFT: 41.4pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing="0" cellpadding="0" border="1"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Sigla&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;SGBD&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 1"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;ibase&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 0.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;Interbase&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 2"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;ifx&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;Informix&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 3"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;msql&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;Msql&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 4"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;mysql&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;MySQL&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 5"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;oci&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;Oracle&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 6"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;odbc&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;ODBC&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 7"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;odbc_msaccess&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;ODBC (particularmente ao Microsoft Access)&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 8"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;pgsql&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;PostgreSQL&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="mso-yfti-irow: 9; mso-yfti-lastrow: yes"&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 131.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="175"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 0.15pt 0pt 0cm"&gt;sqlite&lt;/p&gt;&lt;/td&gt;&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: medium none; WIDTH: 291.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign="top" width="389"&gt;&lt;p class="CodigoFonte" style="MARGIN: 3pt 9.15pt 0pt 0cm"&gt;SQLite&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;É uma das bibliotecas mais preocupadas com a portabilidade. Com ela é possível modelar uma base de dados num arquivo XML e criar um script PHP para processá-lo e gerar o esquema no banco. Para isso, é necessário baixar um outro pacote, o Generic XML Parser, disponível no endereço &lt;a href="http://www.phpclasses.org/browse/package/4.html"&gt;http://www.phpclasses.org/browse/package/4.html&lt;/a&gt;.&lt;br /&gt;Possui tratamento homogêneo a campos auto incrementados (que cada SGBD faz à sua maneira), funções de conversão de dados que possam sofrer mudanças de representação de um banco para outro como strings, datas, horas, pontos flutuantes e boleanos. Suporta consultas preparadas (prepared statements) e interage com tipos textuais grandes (CLOBs) e grandes binários (BLOBs) de maneira fácil e eficiente.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;ADOdb&lt;/em&gt;&lt;br /&gt;Disponível também para a linguagem Phyton, além de ser uma das mais antigas, é, sem dúvida, uma das mais populares do mercado. Nasceu da iniciativa de portar a sintaxe da Microsoft ADO ao mundo PHP. Suporta uma gama ainda maior de SGBDs como: MySQL, Interbase, Firebird, Oracle, MS SQL Server, Foxpro, MS Access, ADO, IBM DB2, SAP DB, SQLite, ODBC e, graças à sua imensa comunidade, PostgreSQL, Informix, Sybase, FrontBase, Netezza, ODBTP e ainda é capaz de acessar dados de um servidor de domínios LDAP.&lt;br /&gt;Seu site oficial &lt;a href="http://adodb.sourceforge.net/"&gt;http://adodb.sourceforge.net/&lt;/a&gt; cita diversos softwares populares que a utilizam, como os gerenciadores de conteúdo PostNuke, Xaraya e Mambo e a ótima solução de groupware eGroupWare.&lt;br /&gt;Preocupa-se bastante com a portabilidade, como por exemplo, quando disponibiliza em seu objeto fruto da conexão métodos como SelectLimit(), para que você não escreva uma instrução SQL SELECT que contenha a maneira como o seu SGBD escolhido trabalha com consultas limitadas (LIMIT x OFFSET y, PostgreSQL, LIMIT y, x no MySQL ou SELECT TOP x *, no MS SQL Server, por exemplo), leftOuter(), rightOuter() e ansiOuter() para variações de JOINs entre tabelas e mais uma série de outros que você pode consultar no endereço &lt;a href="http://phplens.com/lens/adodb/tips_portable_sql.htm"&gt;http://phplens.com/lens/adodb/tips_portable_sql.htm&lt;/a&gt;.&lt;br /&gt;Suporta ainda transações, prepared statements e, hoje, ainda é possível trabalhar semelhantemente à sintaxa da biblioteca PEAR::DB, que se popularizou bastante nos últimos anos. É possível utilizar recursos específicos do PHP5, como levantamento de exceções quando houver problemas na conexão com o banco, por exemplo. Apesar da pouca documentação nesse ponto, ainda há uma versão que você pode instalar como extensão do PHP, escrita em C, o que deve aumentar bastante o desempenho final.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;DBX&lt;br /&gt;&lt;/em&gt;Esta é a primeira iniciativa do PHP em criar uma extensão nativa e não um conjunto de arquivos PHP que devem ser incluídos no seu script. Totalmente procedural, apresenta algumas simples funções que fazem todo o trabalho. Suporta os SGBDs FrontBase, Microsoft SQL Server, MySQL, ODBC, PostgreSQL, Sybase-CT, Oracle (oci8), e, mais recentemente o SQLite.&lt;br /&gt;É fornecida nas próprias fontes do PHP. Para habilitá-la, basta informar a diretiva --enable-dbx no momento de compilação. Com a recente extensão PDO, a DBX perdeu espaço, já que seu maior argumento, o fato de ser uma extensão do PHP, gerando uma API nativa (sem precisa dar include em arquivo algum), também se enquadra nesta última.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;PEAR::DB&lt;br /&gt;&lt;/em&gt;Até meados de 2006, foi um dos pacotes mais importantes do PEAR, visto que compunha a lista de pacotes básica inserida em qualquer distribuição do PHP. Rapidamente angariou inúmeros adeptos. Apesar de não ser a mais portável, nem tão pouco a mais eficiente (veremos um benchmark adiante), foi considerada a “oficial” do PHP por muito tempo, visto que mesmo sem ser uma extensão nativa, estava lá disponível em qualquer servidor Web que suportasse PHP.&lt;br /&gt;Hoje, em seu endereço, &lt;a href="http://pear.php.net/package/DB"&gt;http://pear.php.net/package/DB&lt;/a&gt;, há uma mensagem sugerindo que o programador opte por baixar o pacote PEAR::MDB2, já que sua última versão 1.7.6 será atualizada apenas para correção de bugs e ajustes de segurança. Provavelmente não passará de 1.7.X.&lt;br /&gt;Trouxe para o PHP algumas técnicas bastante interessantes, como os métodos simplificados de recuperação de dados getAll(), getAssoc(), getRow() e getOne(). Suporta campos auto incrementados (sequences), prepared statements e transações. No entanto, alguns recursos como manipulação de BLOBs ficaram de fora. O endereço &lt;a href="http://phplens.com/phpeverywhere/node/view/39"&gt;http://phplens.com/phpeverywhere/node/view/39&lt;/a&gt; faz um comparativo entre a DB e a ADOdb. Apesar de tendencioso, dá para você fazer uma análise de que falta a essa biblioteca.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;PEAR::MDB2&lt;br /&gt;&lt;/em&gt;Sucessora de fato da PEAR::DB, a MDB2 é a segunda versão do pacote PEAR::MDB, uma iniciativa de portar a Metabase ao formato padrão do PEAR e aproximar da sintaxe da PEAR::DB. Apesar de (ainda) não ser distribuída na lista básica de pacotes PEAR, esta disponível através do comando pear install ou no endereço &lt;a href="http://pear.php.net/manual/en/package.database.mdb2.php"&gt;http://pear.php.net/manual/en/package.database.mdb2.php&lt;/a&gt;.&lt;br /&gt;Por se tratar de uma adaptação da Metabase, a MDB2 vai bem mais além, em questões de portabilidade. Está certamente entre as que mais garante a pretendida abstração de SGBDs. Suporta, por exemplo, a manipulação de BLOBs e alguns outros recursos ausentes em sua antecessora.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Creole&lt;br /&gt;&lt;/em&gt;Biblioteca interessantíssima não só pelo que faz, mas por como faz. No lugar de tentar se aproximar da sintaxe da Microsoft ADO ou da PEAR::DB, a Creole se aproxima bastante da sintaxe da API JDBC (Java Database Connectivity).&lt;br /&gt;Surgiu como um subprojeto do Propel, um framework de mapeamento objeto x relacional. Devido à bagagem Java de seus desenvolvedores (o Propel possui algumas características do Hibernate, como mapeamento em arquivos XML), e à necessidade de uma API mais bem estruturada no mundo OO, em seu site oficial &lt;a href="http://creole.phpdb.org/"&gt;http://creole.phpdb.org/&lt;/a&gt; consta a informação de que eles tentaram utilizar as bibliotecas PEAR::DB, PEAR::MDB e ADOdb, mas não ficaram satisfeitos com o resultado. Por isso criaram a Creole.&lt;br /&gt;Possui ainda um outro subprojeto chamado Jargon, uma extensão que adiciona alguns métodos de atalho para leitura e escrita de dados.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;PDO&lt;br /&gt;&lt;/em&gt;Ex-pacote PECL (no PHP 5.0), a PDO é um dos recursos mais aclamados do PHP 5.1. Alguns acreditam que não passa de euforia passageira, afinal, ela não inventou nada realmente novo. O fato é que se trata de uma biblioteca, que por ser posterior, pôde ser arquitetada sobre os erros e acertos das demais. Alie isso ao fato da biblioteca vir na forma de extensão distribuída em conjunto com o PHP, o que sugere maior desempenho (acompanhe o benchmark adiante). Por outro lado, ela ainda precisa evoluir em portabilidade, nesse quesito ainda está bem aquém da Metabase, ADOdb, MDB2 ou Creole.&lt;br /&gt;Suporta os SGBDs MySQL, PostgreSQL, MS SQL Server, Sybase, Informix, SQLite, Oracle, Firebird e MSSQL, além do ODBC, no entanto requer uma diretiva para suportar cada banco no ato de compilação. A linha abaixo configuraria o PHP para ser instalado como módulo do Apache2, com suporte aos SGBDs MySQL, PostgreSQL e SQLite, adicionando o acesso via PDO:&lt;br /&gt;&lt;br /&gt;# ./configure --with-apxs2=/usr/local/apache/bin/apxs --with-pgsql=/usr/local/pgsql --with-mysql=/usr/local/mysql --with-sqlite --enable-pdo --with-pdo-pgsql=/usr/local/pgsql --with-pdo-mysql=/usr/local/mysql --with-pdo-sqlite&lt;br /&gt;&lt;br /&gt;As barras invertidas acima servem apenas para poder continuarmos o comando na linha de baixo. Perceba que além de adicionar o suporte aos três SGBDs&lt;span style="font-size:85%;"&gt;[1]&lt;/span&gt;, habilitamos o PDO e inserimos uma diretiva para que ela seja capaz de acessar cada banco especificamente.&lt;br /&gt;O site oficial &lt;a href="http://www.php.net/pdo"&gt;http://www.php.net/pdo&lt;/a&gt; recomenda que você instale o PDO como um módulo compartilhado (shared), adicionando a diretiva da seguinte forma:&lt;br /&gt;&lt;br /&gt;--enable-pdo=shared&lt;br /&gt;Assim, um arquivo pdo.so será gerado no diretório da diretiva extension_dir do php.ini. Para habilitar o PDO, será necessário adicionar ao php.ini a linha:&lt;br /&gt;&lt;br /&gt;extension=pdo.so&lt;br /&gt;Como você faria no Windows para habilitar o pdo.dll que já vem fornecido na distribuição binária do PHP. O mesmo deve ser feito para cada SGBD (--with-pdo-mysql=shared e extension=pdo_mysql.so, por exemplo).&lt;br /&gt;Num PHP já instalado, é possível adicionar o suporte ao PDO através do instalador do PECL. As linhas:&lt;br /&gt;&lt;br /&gt;# pecl install pdo&lt;br /&gt;# pecl install pdo_mysql&lt;br /&gt;# pecl install pdo_pgsql&lt;br /&gt;# pecl install pdo_sqlite&lt;br /&gt;Irão disparar os mesmos passos do instalador pear. O único pré-requisito para esse procedimento é que o PHP tenha sido instalado com suporte à biblioteca Zlib (--with-zlib) para permitir que o pecl possa baixar e descompactar os pacotes do PDO. A instalação via pecl irá gerar o módulo compartilhado pdo.so (e os demais para cada SGBD adicionado) e você deve habilitá-los no php.ini da mesma forma da instalação shared. Nesses últimos dois processos é possível atualizar o pdo também através do pecl:&lt;br /&gt;&lt;br /&gt;# pecl upgrade pdo&lt;br /&gt;Instrução idêntica à que você faria para atualizar algum pacote PEAR.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;1 SQLite não é um SGBD, mas um punhado de código C capaz de ler e escrever e um arquivo sob a semântica de acesso SQL. Assim como a PDO, já vem fornecido nas fontes do PHP.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37519337-116330353515009176?l=joseberardo.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://joseberardo.blogspot.com/feeds/116330353515009176/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=37519337&amp;postID=116330353515009176' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/116330353515009176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37519337/posts/default/116330353515009176'/><link rel='alternate' type='text/html' href='http://joseberardo.blogspot.com/2006/11/abstrao-de-sgbds-estudo-comparativo.html' title='Abstração de SGBDs - Estudo comparativo - Parte 1 Bibliotecas'/><author><name>Jose Berardo</name><uri>http://www.blogger.com/profile/12931771695642938128</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>
