<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MySQL &#8211; Turbosite &#8211; Blog</title>
	<atom:link href="https://www.turbosite.com.br/blog/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.turbosite.com.br/blog</link>
	<description></description>
	<lastBuildDate>Tue, 09 Dec 2014 13:54:17 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://www.turbosite.com.br/blog/wp-content/uploads/2026/09/cropped-logo_turbo_vermelha-32x32.png</url>
	<title>MySQL &#8211; Turbosite &#8211; Blog</title>
	<link>https://www.turbosite.com.br/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>SQL do lado do Cliente? Web SQL Database com HTML5</title>
		<link>https://www.turbosite.com.br/blog/sql-do-lado-do-cliente-web-sql-database-com-html5/</link>
		
		<dc:creator><![CDATA[turboajuda]]></dc:creator>
		<pubDate>Tue, 09 Dec 2014 13:54:17 +0000</pubDate>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[html 5 SQL]]></category>
		<category><![CDATA[novidade HTML 5]]></category>
		<category><![CDATA[SQL do lado do cliente]]></category>
		<category><![CDATA[Web SQL Database]]></category>
		<guid isPermaLink="false">http://blog.turbosite.com.br/?p=3903</guid>

					<description><![CDATA[Como trabalhar com o recurso Web SQL Database HTML 5. Vamos explicar, exemplificar e testar a funcionalidade para demonstrar sua utilização e seus benefícios.]]></description>
										<content:encoded><![CDATA[<p>Já pensou em utilizar SQL do lado do Cliente? Bom, agora isso é possível, com o HTML 5 podemos utilizar o Web SQL Database.</p>
<p>Ele traz uma API de banco de dados SQL Web, por enquanto ainda é uma especificação separada do HTML 5, mas já introduz um conjunto de APIs para manipular base de dados do lado do cliente utilizando SQL.</p>
<p>Estamos supondo que você já conheça e trabalhe com o SQL, mas caso não saiba o que é, recomendamos um <a href="https://www.youtube.com/watch?v=EjE57WqB7xg&amp;list=PLyH68Dr1pa5ym3xKGelKhDkjfe-MfBWCJ" target="_blank">mini curso de MySQL</a>.</p>
<p>Por enquanto, Web SQL Database está suportado nas últimas versões do Chorme, Safari e Opera.</p>
<p>Esta postagem é baseada no artigo em inglês:<a href="http://www.tutorialspoint.com/html5/html5_web_sql.htm" target="_blank"> Web SQL Database</a></p>
<p>&nbsp;</p>
<h2>Os métodos principais:</h2>
<p>Há três seguintes métodos fundamentais definidos na especificação de que vamos mostrar nesta postagem:</p>
<ol>
<li><b>openDataBase:</b> Este método cria o objeto de banco de dados, depois utiliza um banco de dados existente ou criar um novo.</li>
<li><b>transaction:</b> Este método controlar a transação e  nos retorna uma confirmação ou anulação com base no que foi executado.</li>
<li><b>executeSql:</b> Este método é usado para executar um consulta SQL.</li>
</ol>
<p>&nbsp;</p>
<h2>Abrindo Base de dados:</h2>
<p>O o<i>penDataBase</i> método cuida da abertura de um banco de dados se ele já existe, este método irá criá-lo se ele não existe.</p>
<p>Para criar e abrir um banco de dados, use o seguinte código:</p>
<pre class="top-margin:20 bottom-margin:20 left-set:true left-margin:20 right-set:true right-margin:20 whitespace-before:2 whitespace-after:2 lang:js decode:true">var db = openDatabase ('Teste', '1.0', 'Teste Web SQL Database', 2 * 1024 * 1024);
</pre>
<p>&nbsp;</p>
<p>Acima método tem quatro parâmetros:</p>
<ol>
<li>Nome do banco</li>
<li>Número da versão</li>
<li>Descrição de texto</li>
<li>Tamanho da base de dados</li>
</ol>
<p>&nbsp;</p>
<h2>Execução de consultas:</h2>
<p>Para executar uma consulta, deve ser utilizado a função database.transaction (). Esta função precisa de um único argumento, mas pode ser passado o 2º e 3º parametro para verificar se foi completado com sucesso o comando, segue exemplo de duas consultas, uma simples e outra debugando:</p>
<pre class="top-margin:20 bottom-margin:20 left-set:true left-margin:20 right-set:true right-margin:20 whitespace-before:2 whitespace-after:2 lang:js decode:true">var db = openDatabase ('Teste', '1.0', 'Teste Web SQL Database', 2 * 1024 * 1024);

// Simples
db.transaction (function (tx) {  
   tx.executeSql ("CREATE TABLE IF NOT EXISTS LOGS (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, log)");
});

// Debugando
db.transaction (function (tx) {  
   tx.executeSql ("CREATE TABLE IF NOT EXISTS LOGS (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, log)",
       function(tx){
           /*Sucesso*/
       },
       function(erro){
           /*Error*/
       });
});</pre>
<p>&nbsp;</p>
<p>As consultas acima irão criar uma tabela chamada LOGS na base de dados &#8220;Teste&#8217;.</p>
<p>&nbsp;</p>
<h2>Inserir dados:</h2>
<p>Para inserir dados  na tabela, utilizamos a função transaction() também, só que, desta vez com o INSERT para popular a tabela, veja o exemplo:</p>
<pre class="top-margin:20 bottom-margin:20 left-set:true left-margin:20 right-set:true right-margin:20 whitespace-before:2 whitespace-after:2 lang:js decode:true">var db = openDatabase ('Teste', '1.0', 'Teste Web SQL Database', 2 * 1024 * 1024);

db.transaction (function (tx) {
   tx.executeSql ("CREATE TABLE IF NOT EXISTS LOGS (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, log)");

   // Os 3 null represetam
   // 1º - Um array contendo dados
   // 2º - Função para sucesso
   // 3º - Função para Erro
   // Vamos explicá-los mais abaixo
   tx.executeSql ("INSERT INTO LOGS (log) VALUES ('Resultado do Log de Teste 01') ", null, null, null);
   tx.executeSql ("INSERT INTO LOGS (log) VALUES ('Resultado do Log de Teste 02') ", null, null, null);
});</pre>
<p>&nbsp;</p>
<p>Também podemos passar valores dinâmicos, utilizamos a seguinte sintaxe:</p>
<pre class="top-margin:20 bottom-margin:20 left-set:true left-margin:20 right-set:true right-margin:20 whitespace-before:2 whitespace-after:2 lang:js decode:true">var db = openDatabase ('Teste', '1.0', 'Teste Web SQL Database', 2 * 1024 * 1024);

db.transaction (function (tx) {

  var novo_log = 'Resultado do Log de Teste 01';

   // Os 3 null estão sendo mostrados aqui
   // 1º - Um array contendo dados, estamos passando apenas um valor com o novo_log
   // 2º - Função para sucesso
   // 3º - Função para Erro
   // Vamos explicá-los mais abaixo
  tx.executeSql ("CREATE TABLE IF NOT EXISTS LOGS (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, log)");
  tx.executeSql ("INSERT INTO REGISTROS (log) VALUES (?)",[novo_log],null,null);						
});</pre>
<p>&nbsp;</p>
<p>Aqui novo_log é uma variável e executeSql mapeia cada item no argumento de matriz para o &#8220;?&#8221;, isto é, poderíamos ter vários &#8220;?&#8221; e no final teríamos [var_1,var_2,var_3], sendo que, ele utilizará a ordem exata das variáveis para popular a query.</p>
<p>&nbsp;</p>
<h2>Lendo os dados:</h2>
<p>Para ler os registros já existentes usamos um callback para capturar os resultados da seguinte forma:</p>
<pre class="top-margin:20 bottom-margin:20 left-set:true left-margin:20 right-set:true right-margin:20 whitespace-before:2 whitespace-after:2 lang:js decode:true">var db = openDatabase ('Teste', '1.0', 'Teste Web SQL Database', 2 * 1024 * 1024);

db.transaction (function (tx) {
    tx.executeSql ("CREATE TABLE IF NOT EXISTS LOGS (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, log TEXT)",null,null);
    tx.executeSql ("INSERT INTO LOGS (log) VALUES (?)",['Resultado do Log de Teste 01'],null,null);
    tx.executeSql ("INSERT INTO LOGS (log) VALUES (?)",['Resultado do Log de Teste 02'],null,null);
});

db.transaction (function (tx) {
   tx.executeSql ('SELECT * FROM LOGS', [], function (tx, results) {
   var len = results.rows.length, i;
   msg = "&lt;p&gt; Registros encontrados:" + len + "&lt;/ p&gt;";
   for (i = 0; i &lt;len; i ++) {
      console.log(results.rows.item(i) .log);
   }
 }, null);
});</pre>
<p>&nbsp;</p>
<h2>Exemplo final:</h2>
<p>Então, finalmente, vamos  criar um exemplo em HTML 5,  este exemplo está funcional e testado no Chrome versão Versão 39.0.2171.71 m.</p>
<pre class="top-margin:20 bottom-margin:20 left-set:true left-margin:20 right-set:true right-margin:20 whitespace-before:2 whitespace-after:2 lang:js decode:true">var db = openDatabase ('Teste', '1.0', 'Teste Web SQL Database', 2 * 1024 * 1024);

db.transaction (function (tx) {
    tx.executeSql ("CREATE TABLE IF NOT EXISTS LOGS (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, log TEXT)",null,null);
    tx.executeSql ("INSERT INTO LOGS (log) VALUES (?)",['Resultado do Log de Teste 01'],null,null);
    tx.executeSql ("INSERT INTO LOGS (log) VALUES (?)",['Resultado do Log de Teste 02'],null,null);
   console.log('Log mensagem criada e linha inserida');
});

db.transaction(function(tx){
    tx.executeSql(       
        "SELECT * FROM LOGS",
        [],
        function(tx, result){
            console.log('Deu certo!');
            var len = result.rows.length, i;
            for(i=0;i&lt;len;i++){
                console.log( result.rows.item(i) );
            }
        },
        function(tx, error){
            console.log('Deu errado!');
            console.log(error);
        }
    );
});</pre>
<p>&nbsp;</p>
<p>Isso produziria o seguinte resultado:</p>
<pre class="top-margin:20 bottom-margin:20 left-set:true left-margin:20 right-set:true right-margin:20 whitespace-before:2 whitespace-after:2 lang:js decode:true">Log mensagem criada e linha inserida
Deu certo!
Object {id: 1, log: "Resultado do Log de Teste 01"}
Object {id: 2, log: "Resultado do Log de Teste 02"}
</pre>
<p>&nbsp;</p>
<h2>Conclusão:</h2>
<p>É bem simples utilizar e depende apenas de um pouco de treino, nos testes detectamos que a sua persistência é como uma sessão, ao fechar o browser perde-se o objeto, mas ao trocar de página dentro do mesmo domínio o mesmo permanece.</p>
<p>Já pensou em utilizar esta nova funcionalidade com o evento <a href="https://www.turbosite.com.br/blog/aviso-de-alteracoes-na-pagina-para-nao-perder-dados-javascript/" target="_blank">onBeforeUnload </a>para rastrear todo o caminho que um usuário caminhou dentro do seu site? A utilização ficará por conta da imaginação de vocês.</p>
<p>&nbsp;</p>
<p>Um exemplo que encontramos no GitHub e que vale a pena ver:<br />
<a href="https://gist.github.com/andyj/1599544" target="_blank">Link original do código aqui.</a></p>
<p>https://gist.github.com/andyj/1599544</p>
<p>Link de uma aplicação feita com Web Sql.<br />
<a href="https://github.com/abeauseigle/webSqlApp" target="_blank">HTML5 webSQL app synching with a php MySQL server</a></p>
<p>Se gostaram, compartilhem e façam comentários, sugestões, correções e correções sempre são bem vindas. A Turbosite tem o comprometimento em divulgar conhecimento!</p>
<hr />
<p>&nbsp;</p>
<p><strong>Quer servidores Seguros, Estáveis, com uptime de 99,9%, no Brasil e de baixo Custo? A <span style="color: #ff0000;">Turbosite</span> é sua resposta.</strong></p>
<p><strong><a href="https://www.turbosite.com.br/hospedagem-de-sites" target="_blank">Hospedagem de Sites</a>, <a href="https://www.turbosite.com.br/datacenter" target="_blank">Data Center</a> e <a href="https://www.turbosite.com.br/registro-dominio" target="_blank">Registro de Domínio Grátis</a> só aqui!</strong></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Mysql &#8211; NATURAL JOIN – Joins mais fáceis</title>
		<link>https://www.turbosite.com.br/blog/mysql-natural-join-joins-mais-faceis/</link>
		
		<dc:creator><![CDATA[turboajuda]]></dc:creator>
		<pubDate>Thu, 27 Nov 2014 13:34:54 +0000</pubDate>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Destaque]]></category>
		<category><![CDATA[dica]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[natural join]]></category>
		<guid isPermaLink="false">http://blog.turbosite.com.br/?p=3834</guid>

					<description><![CDATA[Esta dica é para facilitar algumas consultas no banco de dados. O Mysql tem suporte ao NATURAL Join o que facilita muito as querys.]]></description>
										<content:encoded><![CDATA[<p>Esta dica é para facilitar algumas consultas no banco de dados. O Mysql tem suporte ao NATURAL Join o que facilita muito as querys.</p>
<p>Vamos supor que temos 2 tabelas relacionadas, clientes e telefones. O cliente tem a seguinte estrutura:</p>
<pre class="lang:mysql decode:true">CREATE TABLE `clients` (
  `idClients` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(150) DEFAULT NULL,
  PRIMARY KEY (`idClients`)
)
insert  into `clients`(`name`) values ('Turbosite');</pre>
<p>&nbsp;</p>
<p>Note que no final inserimos um usuário para nosso teste.</p>
<p>A tabela de telefones ficaria desta forma:</p>
<pre class="lang:php decode:true">CREATE TABLE `phones` (
  `idPhones` int(11) NOT NULL AUTO_INCREMENT,
  `number` char(20) NOT NULL,
  `idClients` int(11) NOT NULL,
  PRIMARY KEY (`idPhones`,`idClients`),
  KEY `idClients` (`idClients`),
  CONSTRAINT `phones_ibfk_1` FOREIGN KEY (`idClients`) REFERENCES `clients` (`idClients`)
)
insert  into `phones`(`number`,`idClients`) values ('(31) 4003-2322',1);
insert  into `phones`(`number`,`idClients`) values ('(31) 3261-2168',1);</pre>
<p>&nbsp;</p>
<p>Sem utilizar o NATURAL Join, a consulta para pegar os telefones de um cliente seria da seguinte forma:</p>
<pre class="lang:php decode:true">SELECT C.`name`,P.`number` FROM clients C
INNER JOIN phones P
ON C.`idClients` = P.`idClients`
WHERE C.`idClients` = 1</pre>
<p>&nbsp;</p>
<p>Resultado seria:</p>
<table border="1">
<tbody>
<tr>
<td class="medium" bgcolor="silver">name</td>
<td class="medium" bgcolor="silver">number</td>
</tr>
<tr>
<td class="normal" valign="top">Turbosite</td>
<td class="normal" valign="top">(31) 4003-2322</td>
</tr>
<tr>
<td class="normal" valign="top">Turbosite</td>
<td class="normal" valign="top">(31) 3261-2168</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Agora com o Natural JOIN, a consulta seria:</p>
<pre class="lang:mysql decode:true">SELECT * FROM clients
NATURAL JOIN phones
WHERE idClients = 1</pre>
<p>O resultado da pesquisa:</p>
<table border="1">
<tbody>
<tr>
<td class="medium" bgcolor="silver">idClients</td>
<td class="medium" bgcolor="silver">name</td>
<td class="medium" bgcolor="silver">idPhones</td>
<td class="medium" bgcolor="silver">number</td>
</tr>
<tr>
<td class="normal" valign="top">1</td>
<td class="normal" valign="top">Turbosite</td>
<td class="normal" valign="top">5</td>
<td class="normal" valign="top">(31) 4003-2322</td>
</tr>
<tr>
<td class="normal" valign="top">1</td>
<td class="normal" valign="top">Turbosite</td>
<td class="normal" valign="top">6</td>
<td class="normal" valign="top">(31) 3261-2168</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>O Natural JOIN é inteligente o suficiente para não acusar erro por ambiguidade de coluna, como uma faz referência a outra, ele não lista em duplicidade as colunas de referência.<br />
A consulta fica mais limpa, mais fácil de entender e de dar manutenção, caso esta tabela fizesse referência a uma 3ª tabela, era só adicionar uma linha ficando desta forma:</p>
<pre class="lang:php decode:true">SELECT * FROM clients
NATURAL JOIN phones
NATURAL JOIN tabela3
WHERE idClients = 1</pre>
<p>&nbsp;</p>
<p>Vamos deixar aqui um link com uma apresentação de JOINS do MYSQL. É interessante ver e aprender para tomar a melhor decisão no desenvolvimento de seus projetos.</p>
<p><a href="http://w3resource.com/gallery/mysql-joins-slides-presentation">http://w3resource.com/gallery/mysql-joins-slides-presentation</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PDO ou MySQLi, qual usar?</title>
		<link>https://www.turbosite.com.br/blog/pdo-ou-mysqli-qual-usar/</link>
		
		<dc:creator><![CDATA[turboajuda]]></dc:creator>
		<pubDate>Tue, 25 Nov 2014 12:34:07 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Dicas]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[MySQLi]]></category>
		<category><![CDATA[PDO]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">http://blog.turbosite.com.br/?p=3818</guid>

					<description><![CDATA[A extensão original MySQL do PHP está obsoleta, deixando como escolha o MySQLi e PDO MySQL. Porém, qual das duas é a melhor escolha? Explicaremos nesse artigo.]]></description>
										<content:encoded><![CDATA[<p>A <strong>PHP</strong> já anunciou o descontinuamento da extensão original do <strong>MySQL</strong>, nomeando-a como <a href="http://php.net/manual/en/migration55.deprecated.php">obsoleta</a> e já com planos para desligá-la completamente em versões futuras. A partir da versão <strong>PHP 5.5</strong>, tentativas de conexão e execução de querys com a antiga ferramenta irá gerar mensagens de alerta, denunciando que o método está obsoleto. A antiga forma de conexão com o MySQL  já está a caminho de deixar de existir.</p>
<p style="padding-left: 30px;"><span style="color: #ff0000;"><em>Deprecated: The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead</em></span></p>
<p>Querendo ou não, o desligamento da antiga ferramenta MySQL é inevitável. Sem dúvida, o trabalho para conseguir migrar todas as funções de conexão com o MySQL para uma outra ferramenta, em provavelmente grande parte de seus projetos, vai ser custosa e demorada. Porém, é muito provável que seus esforços serão recompensados. Em seu site, a PHP nos indica duas ferramentas de conexão com o MySQL: a MySQLi (Improved) e o PDO.</p>
<p style="padding-left: 30px;"><em>A <a href="http://php.net/manual/en/book.mysql.php">extensão original MySQL</a> está agora obsoleta e irá gerar erros <strong>E_DEPRECATED</strong> quando conectar à um banco de dados. Em seu lugar, use a extensão <a href="http://php.net/manual/en/book.mysqli.php">MySQLi</a> ou <a href="http://php.net/manual/en/ref.pdo-mysql.php">PDO MySQL</a>.</em></p>
<p>A equipe da <a href="https://www.turbosite.com.br/">Turbosite</a> retirou do blog <a href="http://code.tutsplus.com/pt/tutorials/pdo-vs-mysqli-which-should-you-use--net-24059">Code</a> um artigo que explica em detalhes o funcionamento e as diferenças de cada ferramenta. Detalhando código para conexão, querys, detalhes de segurança e desempenho. Abaixo você confere as diferenças entre essas duas ferramentas.</p>
<p>&nbsp;</p>
<h2>Comparativo</h2>
<table>
<thead>
<tr>
<th></th>
<th>PDO</th>
<th>MySQLi</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Suporte a Bancos de Dados</strong></td>
<td>12 drivers diferentes</td>
<td>Somente MySQL</td>
</tr>
<tr>
<td><strong>API</strong></td>
<td>Orientada a Objetos</td>
<td>Orientada a Objetos + Procedural</td>
</tr>
<tr>
<td><strong>Conexão</strong></td>
<td>Fácil</td>
<td>Fácil</td>
</tr>
<tr>
<td><strong>Parâmetros Nomeados</strong></td>
<td>Sim</td>
<td>Não</td>
</tr>
<tr>
<td><strong>Mapeamento de Objetos</strong></td>
<td>Sim</td>
<td>Sim</td>
</tr>
<tr>
<td><strong>Sentenças Preparadas (lado do cliente)</strong></td>
<td>Sim</td>
<td>Não</td>
</tr>
<tr>
<td><strong>Performance</strong></td>
<td>Rápido</td>
<td>Rápido</td>
</tr>
<tr>
<td><strong>Procedimentos Armazenados</strong></td>
<td>Sim</td>
<td>Sim</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h2 class="nolinks">Conexão</h2>
<p>Criar uma conexão com uma base de dados é fácil em ambas as ferramentas:</p>
<pre class="lang:php decode:true ">// PDO
$pdo = new PDO("mysql:host=servidor;dbname=banco_de_dados", 'usuario', 'senha');
  
// MySQLi, forma procedural
$mysqli = mysqli_connect('servidor', 'usuario', 'senha', 'banco_de_dados');
  
// MySQLi, forma via orientação a objetos
$mysqli = new mysqli('servidor', 'usuario', 'senha', 'banco_de_dados');
</pre>
<p>&nbsp;</p>
<h2 class="nolinks">Suporte de API</h2>
<p>Tanto PDO quanto MySQli oferecem um API orientada a objetos, mas o MySQLi também oferece uma API procedural &#8211; facilitando o entendimento por parte dos novatos. Se você já é familiarizado com o driver nativo do MySQL para PHP, migrar para a interface procedural do MySQLi será extremamente simples. Por outro lado, uma vez que você compreender a PDO, você poderá usá-la com qualquer banco de dados que desejar!</p>
<p>&nbsp;</p>
<h2 class="nolinks">Suporte a Bancos de Dados</h2>
<p><img fetchpriority="high" decoding="async" class="size-full wp-image-3819 alignnone" src="https://www.turbosite.com.br/blog/wp-content/uploads/2014/11/tutorial_3.png" alt="tutorial_3" width="640" height="320" srcset="https://www.turbosite.com.br/blog/wp-content/uploads/2014/11/tutorial_3.png 640w, https://www.turbosite.com.br/blog/wp-content/uploads/2014/11/tutorial_3-300x150.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>&nbsp;</p>
<p>A principal vantagem do PDO sobre o MySQLi é seu suporte aos drivers de diversos bancos de dados. No momento em que traduzimos esse artigo, o <strong>PDO dá suporte a 12 tipos diferentes de drivers</strong>, enquanto o MySQLi só dá <strong>suporte ao MySQL</strong>.</p>
<p>Caso queira saber quais os drivers que o PDO dá suporte no momento, use o código a seguir:</p>
<pre class="lang:php decode:true ">var_dump(PDO::getAvailableDrivers());</pre>
<p>O que isso significa? Bem, em situações que você precisar usar outro banco de dados, a PDO torna esse processo transparente. Então, <em>a única coisa que você precisará fazer</em> é mudar os parâmetros de conexão e algumas consultas, isso se elas usarem algum método que não seja suportado por outra base de dados. Já com o MySQLi, você precisará <em>reescrever todo o código que lida com banco de dados, </em> inclusive as consultas.</p>
<p>&nbsp;</p>
<h2 class="nolinks">Parâmetros Nomeados</h2>
<p>Essa é outra característica importante que o PDO tem. Vincular parâmetros com PDO é muito mais fácil usando a vinculação nomeada:</p>
<pre class="lang:php decode:true ">$params = [':usuario' =&gt; 'teste', ':email' =&gt; $email =&gt; ':ultimo_login' =&gt; time() - 3600];
  
$pdo-&gt;prepare('SELECT * FROM users WHERE username = :usuario AND email = :email AND las_login = :ultimo_login');
  
$pdo-&gt;execute($params);</pre>
<p>Ao contrário da maneira do MySQLi:</p>
<pre class="lang:php decode:true">$query = $mysqli-&gt;prepare('SELECT * FROM users WHERE username = ? AND email = ? AND lasT_login = ?');
  
$query-&gt;bind_param('teste', $mail, time() - 3600);
$query-&gt;execute();</pre>
<p>A vinculação dos parâmetros na forma de interrogação pode parecer menor, mas, nem de longe, é tão flexível quanto aos parâmetros nomeados, devido ao fato do desenvolvedor ser obrigado a saber a ordem dos parâmetros. Ela parece um <em>hack</em> feito para permitir vinculação de parâmetros em algumas circunstâncias.</p>
<p>Infelizmente, <strong>MySQLi não dá suporte a parâmetros nomeados</strong>.</p>
<p>&nbsp;</p>
<h2 class="nolinks">Mapeamento de Objetos</h2>
<p>Tanto PDO quanto MySQLi podem mapear resultados em objetos. Isso vem bem a calhar se você não quer usar uma camada de abstração de banco de dados customizada, mas ainda quer um comportamento semelhante ao de um <em>ORM</em>. Vamos imaginar que nós temos uma classe <code>User</code> com algumas propriedades nomeadas de forma idêntica aos campos da tabela do Banco de Dados:</p>
<pre class="lang:php decode:true  ">class User {
public $id;
public $first_name;
public $last_name;
  
public function info()
{
return "#" . $this-&gt;id . ": " . $this-&gt;first_name . " " . $this-&gt;last_name;
}
}</pre>
<p>Sem o mapeamento de objetos, nós precisaríamos preencher cada um dos campos (fosse manualmente ou através de um método construtor), anes de podermos usar o método <code>info()</code> corretamente.</p>
<p>Isso permite que nós predefinamos as propriedades antes mesmo do objeto ser construído! Por exemplo</p>
<pre class="lang:php decode:true">$query = "SELECT id, first_name, last_name FROM users";
  
// PDO
$result = $pdo-&gt;query($query);
$result-&gt;setFetchMode(PDO::FETCH_CLASS, 'User');
  
while ($user = $result-&gt;fetch()) {
echo $user-&gt;info() . "\n";
}
  
// MySQLi, forma procedural
if ($result = mysqli_query($mysqli, $query)) {
while ($user = mysqli_fetch_object($result, 'User')) {
echo $user-&gt;info() . "\n";
}
}
  
// MySQLi, forma orientada a objetos
if ($result = $mysqli-&gt;query($query)) {
while ($user = $result-&gt;fetch_object('User')) {
echo $user-&gt;info() . "\n";
}
}</pre>
<p>&nbsp;</p>
<h2 class="nolinks">Segurança</h2>
<p><img decoding="async" class="size-full wp-image-3820 alignnone" src="https://www.turbosite.com.br/blog/wp-content/uploads/2014/11/tutorial_1.png" alt="tutorial_1" width="640" height="320" srcset="https://www.turbosite.com.br/blog/wp-content/uploads/2014/11/tutorial_1.png 640w, https://www.turbosite.com.br/blog/wp-content/uploads/2014/11/tutorial_1-300x150.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<p>&nbsp;</p>
<p>Ambas as bibliotecas proveem <strong>segurança contra injeção de SQL, desde que o desenvolvedor as use da maneira que elas foram planejadas para usar. </strong>Digamos que um <em>hacker</em> esteja tentando injetar algum código malicioso através de um parâmetro &#8216;username&#8217; de uma requisição HTTP GET:</p>
<pre class="lang:php decode:true">$_GET['username'] = "'; DELETE FROM users; /*"</pre>
<p>&nbsp;</p>
<p>Se nós falharmos em limpá-lo, ele será incluído na consulta exatamente como está  e deletará todas linhas da tabela <code>users</code> (tanto PDO quanto MySQLi suporta múltiplas consultas).</p>
<pre class="lang:php decode:true ">// PDO, limpeza manual
$username = PDO::quote($_GET['username']);
  
$pdo-&gt;query("SELECT * FROM users WHERE username = $username");
  
// MySQLi, limpeza manual
$username = mysqli_real_escape_string($_GET['username']);
  
$mysqli-&gt;query("SELECT * FROM users WHERE username = '$username'");</pre>
<p>&nbsp;</p>
<p>Como podem ver, <code>PDO::quote()</code> <strong>não só valida, mas fixa as aspas</strong>. Por outro lado, <code>mysqli_real_escape_string()</code> só limpará, forçando você a fixar as aspas manualmente.</p>
<pre class="lang:php decode:true">// PDO com sentenças preparadas
$pdo-&gt;prepare('SELECT * FROM users WHERE username = :username');
$pdo-&gt;execute([':username' =&gt; $_GET['username']]);
  
// MySQLi, sentenças preparadas
$query = $mysqli-&gt;prepare('SELECT * FROM users WHERE username = ?');
$query-&gt;bind_param('s', $_GET['username']);
$query-&gt;execute();</pre>
<p>&nbsp;</p>
<p>Recomendamos que você sempre use sentenças preparadas com consultas vinculadas ao invés da <code>PDO::quote()</code> e da <code>mysqli_real_scape_string()</code>.</p>
<p>&nbsp;</p>
<h2 class="nolinks">Performance</h2>
<p>Tanto PDO quanto MySQLi são bem rápidas, porém, MySQLi se sai mais rápida nos comparativos; ~2,5% para sentenças não preparadas e ~6,5% para as sentenças preparadas. Porém, a extensão nativa do MySQL é ainda mais rápida que ambas. Mas, como afirmei no começo, ela não é mais uma opção.</p>
<p>&nbsp;</p>
<h2 class="nolinks">Conclusão</h2>
<p>PDO possuí suporte a 12 drivers de bases de dados diferentes e parâmetros nomeados. MySQLi ganha em desempenho, comparado com o PDO  e possui uma sintaxe mais simples, facilitando a migração a partir do antigo MySQL. Com relação à segurança, ambas são seguras, desde que o desenvolvedor saiba usá-las da forma correta.</p>
<p>Em especial, deixaremos a conclusão desse artigo para o leitor. Caso você esteja procurando desempenho em suas querys e não quer esquentar a cabeça para aprender uma nova ferramenta de conexão com o banco de dados, talvez o <a href="http://php.net/manual/pt_BR/book.mysqli.php">MySQLi </a>seja sua melhor escolha. Caso você esteja procurando uma ferramenta mais completa e robusta, o <a href="http://php.net/manual/pt_BR/ref.pdo-mysql.php">PDO MySQL</a> seria a melhor escolha.</p>
<p>Deixe-nos sua resposta, faça um comentário abaixo falando qual ferramenta você escolheu o por quê.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dicas para otimizar seu MySQL</title>
		<link>https://www.turbosite.com.br/blog/dicas-para-otimizar-seu-mysql/</link>
		
		<dc:creator><![CDATA[turboajuda]]></dc:creator>
		<pubDate>Mon, 03 Nov 2014 13:51:19 +0000</pubDate>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">http://blog.turbosite.com.br/?p=3648</guid>

					<description><![CDATA[A equipe da Turbosite compartilha nesse artigo algumas dicas para otimização de seu Banco de Dados por meio de algumas funções MySQL.]]></description>
										<content:encoded><![CDATA[<p>Suas consultas estáo demorando muito tempo? Está gerando filas de conexões? Todas as operações de banco estão sofrendo lentidão? Se respondeu sim para qualquer uma das perguntas, então está na hora de otimizar seu Banco de Dados.  A equipe da <a title="Turbosite" href="https://www.turbosite.com.br/" target="_blank">Turbosite</a> compartilha nesse artigo algumas dicas para otimização de seu Banco de Dados. Utilizando poucas funções <strong>MySQL</strong>, o resultado no desempenho de seu sistema pode ser surpreendente.</p>
<p>Dos três modos de otimização (configuração de hardware do servidor, configuração de rede do servidor e otimização de código), apresentamos aqui métodos para otimização por código MySQL.</p>
<p>&nbsp;</p>
<h2>MYSQLREPORT</h2>
<p>Como primeiro passo, você pode usar o comando <strong>MYSQLREPORT</strong> para gerar relatórios sobre bancos de dados que estão atingindo o limite de sua capacidade de uso  e estabelecer um patamar para operações e usos adicionais. Talvez também você se veja obrigado a modificar arquivo de configuração (my.cnf) para registrar o log de consultas lentas. Identifique as consultas que estão processando muito devagar e as possíveis causas.</p>
<p>Para acessar a documentação completa do MYSQLREPORT, recomendamos esse link: <a title="mysqlreport" href="http://man.he.net/man1/mysqlreport" target="_blank">man.he.net/man1/mysqlreport</a>.</p>
<p>&nbsp;</p>
<h2>EXPLAIN</h2>
<p>Aplique o comando <strong>EXPLAIN</strong> antes do script <em>SELECT</em> para o MySQL retornar um registro contendo a análise do script para aquela tabela consultada. Esse método retorna algumas informações, como <em>ID</em>, <em>SELECT_TYPE</em>, <em>TABLE</em>, <em>TYPE</em>, <em>KEY_LEN</em>, <em>REF</em>, sendo que as informações que você vai querer para avaliar o desempenho do código são:</p>
<ul>
<li><strong><em>POSSIBLE_KEYS</em>: </strong>mostra os índices disponíveis para serem utilizados naquela consulta;</li>
<li><strong><em>KEY</em>:</strong> mostra o índice escolhido pelo MySQL para realizar a consulta;</li>
<li><strong><em>ROW</em>:</strong> número estimado de linhas percorridas para encontrar o resultado do <em>SELECT;</em></li>
<li><strong><em>EXTRA</em>: </strong>sugestões de otimização em índices da consultas, como usar <em>DISTINCT</em>, <em>NOT</em> <em>EXIST</em>, <em>USING</em> <em>INDEX</em>, entre outras.</li>
</ul>
<pre class="lang:mysql decode:true">EXPLAIN SELECT * FROM funcionarios;</pre>
<p>&nbsp;</p>
<h2><strong>ANALYZE</strong></h2>
<p>Use o comando <strong>ANALYZE</strong> para gerar uma distribuição de chaves, para a tabela a ser utilizada pelo otimizador de consultas do MySQL, para decidir quais índices serão melhores se utilizados em uma consulta.</p>
<pre class="lang:mysql decode:true">ANALYZE TABLE funcionarios;</pre>
<p>&nbsp;</p>
<h2><strong>OPTIMIZE </strong></h2>
<p>Se há grandes quantidades de inserções/exclusões em uma tabela, principalmente se a tabela conter muitos campos do tipo <em>varchar</em>, <em>text</em> e <em>blob</em>, o disco será comprometido à várias fragmentações. O comando <strong>OPTIMIZE</strong> deve ser usado com freqüência para esse tipo de situação. O comando ira otimizar a movimentação da cabeça de leitura e gravação do disco durante a recuperação de dados, implementando a desfragmentação do disco causada por campos de comprimento variável.</p>
<p>&nbsp;</p>
<pre class="lang:mysql decode:true">OPTIMIZE TABLE funcionarios;</pre>
<p>&nbsp;</p>
<h2><strong>LOAD DATA INFILE</strong></h2>
<p>Para a importação de dados para uma tabela, o comando <strong>LOAD DATA INFILE</strong>, no lugar do comando <em>SELECT</em>, irá apresentar um desempenho até 20 vezes melhor.</p>
<pre class="lang:mysql decode:true">LOAD DATA INFILE 'filedata.dat' INTO TABLE funcioanrios (col1,col2,...,colM) 
     FIELDS TERMINATED BY '|'");</pre>
<p>&nbsp;</p>
<h2><strong>TRUNCATE</strong></h2>
<p>O comando <em>DELETE</em> deleta linha por linha, enquanto <strong>TRUNCATE</strong> deleta todas as linhas de uma só vez. Portanto, se você não estiver interessado no número de linhas suprimidas de uma tabela, como resultado do comando <em>DELETE</em>, utilize o comando <em>TRUNCATE</em> com a seguinte sintaxe:</p>
<pre class="lang:php decode:true ">TRUNCATE TABLE funcionarios;</pre>
<p>&nbsp;</p>
<h2><strong>Prioridade dos comandos</strong></h2>
<p>Se há mais consultas do que inserções de dados, você pode ter uma <strong>prioridade</strong> mais baixa do comando <em>INSERT</em> utilizando</p>
<pre class="lang:mysql decode:true ">INSERT LOW_PRIORITY</pre>
<p>ou</p>
<pre class="lang:mysql decode:true">SELECT HIGH_PRIORITY</pre>
<p>Se o cliente não está interessado nos resultados do comando <em>INSERT</em>, então esta operação já pode imediatamente utilizar menos os recursos do sistema, utilizando-se o seguinte comando:</p>
<pre class="lang:mysql decode:true ">INSERT DELAYED</pre>
<p>Isso torna o sistema mais rápido porque acumula as inserções em lotes.</p>
<p>&nbsp;</p>
<h2>Permissões no MySQL</h2>
<p>Além de incrementar na segurança da conexão, criar usuários com permissões específicas reduzem o <em>overhead</em> das verificações das permissões em todos os comandos realizados no MySQL, melhorando assim no desempenho do sistema. Como exemplo, um leitor do blog apenas tem interesse na leitura de postagem, leitura e inserção de comentários. Criar um usuário de nome &#8220;leitor&#8221;, com acesso apenas a leitura da tabelas &#8216;postagens&#8217;, e acesso a leitura e escrita à tabela &#8216;comentarios&#8217;, será de fato uma boa prática. A segurança será incrementada, já que aquele usuário não terá permissão de acessar, modificar ou deletar outros registros que não são de seu respeito, como também o desempenho, já que o <em>overhead</em> do usuário constará suas propriedades de acessos de antemão.</p>
<pre class="lang:mysql decode:true">GRANT Oper1,...,OperN ON db_name.tb_name TO user_name@computer_name IDENTIFIED BY password;</pre>
<p>&nbsp;</p>
<h2><strong>BENCHMARK</strong></h2>
<p>Por fim, para saber quanto tempo uma determinada função ou expressão MySQL está demorando, use a função MySQL embutida:</p>
<pre class="lang:mysql decode:true ">SELECT BENCHMARK ( 10000, ( SELECT col1 FROM funcionarios LIMIT 1 ) );</pre>
<p>Lembrando que, para passar consultas na função <em>BENCHMARK</em>, obrigatoriamente a <em>query</em> deve retornar 1 linha com 1 coluna.</p>
<p>&nbsp;</p>
<h2> Outras dicas corriqueiras</h2>
<ul>
<li>Utilize <strong>ORDER BY </strong>sempre na primeira tabelas, de preferência em índices, quando estiver realizando uma consulta em várias tabelas interligadas;</li>
<li>Utilize <strong>LIMIT</strong>, o MySQL irá primeiro avaliar o comando <em>LIMIT</em> para depois executar funções como <em>ORDER BY</em> e <em>GROUP BY</em>;</li>
<li>Realize <strong>UPDATE </strong>e<strong> INSERT </strong>em um lote inteiro de registros, de uma só vez, além de realizar uma ação por cada registro;</li>
<li>Remova parênteses desnecessários na cláusula WHERE.</li>
</ul>
<p>&nbsp;</p>
<p>Referências: <a href="http://www.comofazertudo.com.br/computadores-e-internet/como-otimizar-consultas-mysql">Como otimizar consultas MySQL</a>, <a href="http://www.sitepoint.com/using-explain-to-write-better-mysql-queries/">Using EXPLAIN to Write Better MySQL Queries</a>, <a href="http://www.webgoal.com.br/como-otimizar-consultas-no-mysql/">Como otimizar consultas no MySQL-Análise das queries</a>. </p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
