Mitos sobre NoSQL

maio 29th, 2010 | by alex | escalabilidade, mysql, nosql, sql

mai
29

Com essa onda de NoSQL pra cá, NoSQL pra lá, muitos ainda tem muitas duvidas em relação ao NoSQL, de quando usar, como usar e etc. E como não podia deixar de ser, vários mitos estão rodeando esse novo conceito de banco de dados.

Afinal o que é NoSQL?

NoSQL é uma nova forma de bancos de dados, que não usam apenas os comandos SQL que você está acostumado, SELECT, UPDATE, DELETE e todas as váriaveis dele. Normalmente essas instruções foram trocadas por funções e muitas vezes já em oop.

Não é só porque ele não usa instruções SQL que ele é melhor que o banco de dados que você usa. Os bancos de dados atuais, são muito antigos,  o MySQL por exemplo começou em 1994, utilizando o modelo relacional de tabelas, isso é um conceito tão antigo quanto esses bancos de dados. Os bancos de dados NoSQL aproveitam e corrigem erros como a dificuldade de escalar esses bancos de dados.

Pra que serve?

Um dos mitos do NoSQL é que só 10% dos sites de hoje em dia, devem usar o NoSQL. Isso na verdade é uma interpretação errada, a idéia na afirmação é que 90% dos sites não sentiriam uma melhora consideravel de performance. Isso é verdade imagine um blog com 10 visitas diárias, qualquer banco de dados atual serve pra essa aplicação, até mesmo se você tiver 10mil visitas diárias.

Mas isso não siguinifica que você não possa usar um banco de dados NoSQL para a sua aplicação. Se você quiser usar um banco de dadso NoSQL no seu blog de 10 visitas diárias, isso não te impede de nada.

Se não preciso porque usar?

Você pode ter um site, que é bastante visitado o seu banco de dados estar aguentando bem, mas você quer gerar alguns logs, seja para estatisticas ou para qualquer outra coisa. Seria bastante viavel usar um banco de dados desses, porque você vai ter muitos dados, você vai precisar consultar de forma rápida e fácil, um NoSQL seria ótimo para isso.

Onde usar?

Muito se tem visto sobre usar o NoSQL em aplicações web de grande porte, porem ela pode ser usada em qualquer tipo de aplicação, você pode usar na web ou no desktop, não tem limites para isso.

Não posso usar NoSQL com um banco de dados relacional

Você pode e deve usar um NoSQL com algum banco de dados relacional que você use. Você pode até usar vários tipos de NoSQL e um MySQL por exemplo. Pode usar um NoSQL para cache dos dados, outro para os registros de logs e assim por diante, claro que você não precisa disso, mas você pode fazer.

Qual posso usar?

Você pode usar qualquer NoSQL, porem se você quer começar no mundo NoSQL eu aconselharia um banco de dados orientado a documentos, eu creio que seja o mais próximo de um banco de dados relacional, e são extremamente faceis de se usar. Apesar de serem bastante parecidos, eles tem conceitos diferentes, por exemplo, você não precisa de uma tabela para comentarios e uma para posts, você coloca tudo no mesmo documento(como se fosse uma tabela).

Considerações finais

Como vocês puderam ver, um NoSQL pode ser usado para qualquer tipo de aplicação, seja web como desktop, pequena, média ou grande. Porem as vezes você pode sentir mais diferença estruturando corretamente o seu banco de dados atual do que mudando completamente para um NoSQL.

A vatagem de um NoSQL é a alta escalabilidade a velocidade de inserção e de consulta desses bancos são absurdos. Eles vieram para arrumar problemas que os bancos de dados relacionais tem e que não foram projetados nem imaginados na época que o sistema relacional foi criado.

8 Comments »

Converter MySQL para MongoDB

maio 20th, 2010 | by suissa | converter, mongodb, mysql, nosql, sql

mai
20

Notando que a maioria dos programadores PHP utilizam MySQL e para você começar a usar o MongoDB ncessita de uma base de dados para começar a programar sua funções, tive a idéia de criar um conversor simples de MySQL para MongoDB. Aqui vou explicar o seu código e como é simples utilizar o MongoDB com PHP.

Criei uma interface bem simples para que possamos enviar os dados sem precisar ficar mudando no código.

Interface do meu conversor

Interface do meu conversor

Essa interface enviará, via POST, as variáveis de conexão com o banco de dados MySQL.

$host = isset($_REQUEST['host_mysql']) ? $_REQUEST['host_mysql'] : “localhost”;

$user = isset($_REQUEST['user_mysql']) ? $_REQUEST['user_mysql'] : “usuario”;

$pass = isset($_REQUEST['pass_mysql']) ? $_REQUEST['pass_mysql'] : “senha”;

$db   = isset($_REQUEST['db_mysql']) ? $_REQUEST['db_mysql'] : “teste_latin”;

Agora é hora de criar a conexão com o MongoDB utilizando uma extensão instalada no php: http://github.com/downloads/mongodb/mongo-php-driver/mongo-1.0.6-r1-php5.3vc6ts.zip

try{

$conexao = new Mongo(); //abre conexão com o MongoDB

$db_mongo = $conexao->$db; //cria a database com o mesmo nome do MySQL

}

catch(MongoConnectionException $e){

die(“<h1 class=’erro’>Erro do banco de dados MONGODB – Inicie o servidor do MongoDD!</h1><span class=’dica’>Dica: Entre no prompt do windows<br />

cd \ <br />

cd mongodb<br />

cd bin<br />

mongod </span>”);

}
Caso o seu MongoDB não esteja rodando o script indicará o erro e mostrará a forma como iniciar seu MongoDB no Windows.

Para conseguirmos pegar o nome de todas as tabelas da nossa database no MySQL utilizamos a seguinte query:

$query_pega_tabelas = “SHOW TABLES”;

O nome do nosso campo contendo as tabelas será:

$index_tabelas = “Tables_in_”.$db; //nome do array com o valor do nome das tabelas via SHOW TABLES
Onde a variável $db será o nome da nossa database no MySQL. Após pegarmos os nomes das nossas tabelas é hora de irmos tabela por tabela pegando seus dados e inserindo-os, não será necessário pegar os metadados(tipo, tamanho) dos campos pois o MongoDB não necessita dessas informações.

if($result_pega_tabelas=mysql_query($query_pega_tabelas)){

while($arr_pega_tabelas[] = mysql_fetch_assoc($result_pega_tabelas)){

}

$rs_charset=mysql_query($query_charset);

foreach($arr_pega_tabelas as $c=>$v){

if(is_array($v)){

foreach($v as $a => $b){

echo “<h3>Tabela: “.$b.”</h3>”;

$nome_tabela = $b;

$query_pega_dados = “EXPLAIN “.$nome_tabela;

if($result_pega_dados=mysql_query($query_pega_dados)){

$arr_pega_dados = array();

while($arr_pega_dados = mysql_fetch_assoc($result_pega_dados)){

$arr_totalis[$nome_tabela][] = $arr_pega_dados;

}//fim while

}//fim if query pega dados

}//fim foreach

}//fim if array

}//fim foreeach

Geramos uma collection para cada tabela existente no MySQL.

foreach($arr_totalis as $c => $v){

$query = ‘select * from ‘.$c;

$collection = $db_mongo->$c;

$rs_select = mysql_query($query);

echo “Inserindo em “.$c.”<br />”;

echo “<pre>”;

while($arr_dados = mysql_fetch_assoc($rs_select)){

Precisamos codificar nossos valores, assim como os campos, em utf8. Porém caso nosso banco já esteja em utf8 não será necessária a conversão. Para isso criei um pequena função utilizando iconv.

foreach($arr_dados as $c => $v){

$obj[utf8_encode_suissa($c)] = utf8_encode_suissa($v);

}//fim foreach

$arr[] = $obj;

}//fim while

$erro = 0;

No caso meu banco que será convertido está codificado em latin1, correspondente ao charset iso-8859-1. Essa função vai ao final do script.

function utf8_encode_suissa($s) {

return iconv(‘iso-8859-1′, ‘utf-8′, $s);

}

Após a conversão para utf8 inserimos o objeto codificado, com a função insert(), na nossa collection que terá o mesmo nome que a tabela correspondente no MySQL.

foreach($arr as $cc => $vv){

if(!$collection->insert($vv)){

echo “Não inseriu”.print_r($c) ;

$erro++;

$var_erro[] = var_dump($vv);

}//fim if

}//fim foreach

Caso tenha ocorrido algum erro mostrará-o com var_dump, só para ter uma noção de como os dados estão estruturados.

if($erro > 0){

echo “<h3>Aconteceram os seguintes erros:</h3>”;

foreach($var_erro as $f => $g){

var_dump($g);

}//fim foreach

}//fim if

echo “</pre>”;

}//fim foreach

}//fim if

Ao término do script você poderá entrar no phpMoAdmin, ferramenta para manipular as bases e as collections do MongoDB, e ver na lista das databases sua nova base criada.

phpMoAdmin

phpMoAdmin

O scrip completo com a interface para inserir os dados se encontra em: http://www.nosqlbr.com.br/conversor_mysql_mongodb.zip

1 Comment »

MongoDB vs CouchDB – Porque escolhi o MongoDB

maio 14th, 2010 | by alex | cassandra, couchdb, escalabilidade, mongodb, mysql, nosql

mai
14

Aposto todas as minhas fichinhas que todos que quiseram estudar NoSQL ficaram na duvida de qual dos dois usar, MongoDB ou CouchDB, mesmo que tenha ido para um cassandra ou qualquer outro NoSQL.

A duvida fica muito maior, porque são dois banco de dados muito semelhantes(orientado a documentos) e bastante usados. Vou colocar aqui o meu relato sobre o MongoDB e o CouchDB.

CouchDB

Quando vi as possibilidades do NoSQL, o primeiro banco de dados que vi foi o CouchDB, fiquei louco para começar a aprender ele, fazer alguns projetos e tudo mais, porem, dei uma olhada muito rápida no site deles, e não vi uma versão pra Windows. Falem o que quiserem, mas muita, muita gente e todo mundo sabe disso, faz tudo no Windows e se não tiver uma versão pra ele, não vão usar, vão continuar com o MySQL.

Demorei meses para voltar para o NoSQL, mas sempre com aquela vontade de realmente aprender um desses novos bancos de dados. Voltando aquele tesão inicial em aprender o NoSQL, vi muitos códigos usando o CouchDB, muita gente usando, muitas coisas pela internet sobre ele. Isso foi um ponto forte pra mim em relação a outros, quando vi que o CouchDB era incubado pela Apache, a balança pesou mais um pouquinho.

Já que o NoSQL é uma técnologia extremamente nova, eu queria pensar a longo prazo, várias vezes fiquei me perguntando as vantagens entre esses bancos de dados. Confesso que quando vi uma pesquisa falando sobre os bancos de dados que as pessoas mais tinham vontade de aprender, apontando o CouchDB como segundo, ele ganhou mais um ponto, em primeiro vinha o cassandra, porem ele ainda não tinha instalação pra windows. O PHP é muito forte, e um dos fatores principais é a grande comunidade e excelente documentação que eles possuem, levei isso em consideração na hora da escolha do NoSQL.

O CouchDB vinha cada vez mais ganhando pontos comigo, mas na mesma pesquisa, o terceiro colocado era o MongoDB, resolvi olhar ele mais de perto, uma vez que queria dar o ponta pé inicial.

MongoDB

Cheguei para olhar o MongoDB só por olhar mesmo, só para ir pro CouchDB com a consciencia limpa. Lia alguma coisa sobre ele, já pensava, mas o CouchDB faz isso também. Mas uma coisa começou a me chamar a atenção, o MongoDB para instalar era só baixar no site e extrair em algum diretório. Isso me chamou a atenção, pois o CouchDB precisava de algumas dependencias para rodar. Logo baixei e instalei, naquele momento comecei a pensar mais sobre ele, um coraçãozinho cresceu.

Rodei uma linha de comando, e está lá, um NoSQL funcioando direitinho. Isso foi tão empolgante, que não achava que pudesse melhorar, olhei no site do MongoDB, e para rodar com o PHP bastava instalar uma DLL. Fui lá e instalei a dll.

A facilidade me encantou, porem ainda pesava a incubadora do CouchDB e todas os outros pontos. Analizando mais um pouco o CouchDB vi que era preciso vários includes para fazer ele funcionar com PHP, menos pontos pra ele, uma vez que o MongoDB se saiu muito bem nessa. Agora fui colocar lado a lado a documentação.

Não precisei olhar muito para saber o escolhido, na imensa documentação do php.net esta uma documentação para o MongoDB.  Foi ali que parei de ler o CouchDB e ler sobre o MongoDB. MongoDB funcioando na minha maquina, documentação no php.net, documentação no próprio site do MongoDB era incrivel, não tive mais tempo para o CouchDB.

Benchmark

Felix Geisendörfer fez uma referência em PHP, que foi super-fácil para portar para MongoDB. Seu benchmark diz a respeito da inserção dos dados e não sobre consultas e atualizações. Agora comparando seus resultados para CouchDB com o meu para MongoDB (tempo em ms):
Como você pode ver o MongoDB é um pouco melhor. Aqui estão os números:
N º de inserções
Couch Tempo Total (seg)
Couch / Doc (ms)
Mongo Tempo Total (seg)
Mongo / Doc (ms)
1 0,0015
1,46
0,0005
0,5
2 0,0015
0,75
0,0004
0,2096
3 0,0017
0,56
0,0005
0,1604
4 0,0017
0,44
0,0005
0,1190
5 0,0018
0,36
0,0005
0,1060
6 0,0019
0,32
0,0006
0,0931
7 0,0021
0,3
0,0006
0,0847
8 0,0022
0,27
0,0007
0,0789
9 0,0023
0,25
0,0007
0,0734
10 0,0025
0,25
0,0007
0,0721
50 0,007
0,14
0,0024
0,0476
100 0,0136
0,14
0,0044
0,0442
500 0,0687
0,14
0,0253
0,0505
1000 0,1361
0,14
0,0372
0,0372
2500 0,4686
0,19
0,0278
0,0372
5000 0,9165
0,18
0,0488
0,0371
7500 1,5116
0,2
0,0835
0,0098
10000 2,3111
0,23
0,1065
0,0111
25000 6,8684
0,27
0,2711
0,0107
50000 15,8227
0,32
0,5430
0,0109
100000 35,3071
0,35
1,7697 0,0177
250000 104.0009
0,42
6,4533
0,0258
500000 230.6021
0,46
11,7684
0,0235
750000 352.7959
0,47
17,0473
0,0227
1000000
487.3284
0,49
18,4376
0,0184

Analisando os dados do gráfico e da tabela podemos perceber que o tempo real do MongoDB quase sempre esta uma casa(decimal) abaixo do CouchDB, ou seja, enquanto o CouchDB demora 0,0025 o Mongo DB, para o mesmo conjunto de instruções, demora 0,0007 segundos. E por conseguinte notamos que no final da inserção de 1 milhão de registros o CouchDB demora 487.3284 e o MongoDB 18,4376 segundos ao total. É um tempo considerável a se levar em conta

Conclusão

Posso ter puxado o saco do MongoDB, mas a facilidade de instalação, sem dependencias nem nada, só instalar uma dll no meu php e rodar, foi fator decisivo. No meio do caminho da comparação, o processo foi tão simples que parei por ali. Ao ver a documentação do php.net vi que ali o MongoDB tinha o apoio que eu esperava. Apesar de muitas pessoas estarem entrando no NoSQL indo direto pro CouchDB o MongoDB tem uma comunidade bastante forte, a facilidade dele como um todo é incrivel, isso conta muitos pontos.

Eu escolhi o MongoDB, mas vou estudar o CouchDB e o Cassandra. Eles são tão faceis, que quero aprender nem que seja um pouco de cada um deles, mas estou estudando a fundo o MongoDB.

6 Comments »

Páginação PHP com MongoDB

maio 11th, 2010 | by alex | mongodb, mysql, nosql, uncategorized

mai
11

Um post rápido sobre a fácilidade de páginação com o MongoDB e PHP e todas as outras linguagens.

Com esse simples código, você pode começar a fazer a sua páginação em PHP e MongoDB:

[php]
$cursor->limit(400)->skip(0);
[/php]

Esse é o “substituto” do LIMIT 0,400
Essa fácilidade ainda vem com um forte aliado, o count:

[php]
$cursor->count(true);
$cursor->count();
[/php]

O primeiro count vai retornar a quantidade TOTAL de todos os registros que foram retornados na consulta sem o limit. No nosso exemplo aqui, estamos limitando a 400 registros, mas a quantidade de registros total era de 5 milhões. No segundo count retornamos só o que esta sendo exibido, no caso 400 registros.

A partir dai você já sabe, só da um for na quantidade total dos registros, e montar as páginas.
Mas tome cuidado com esse exemplo que te dei, pois ele pode retornar muitas, muitas páginas mesmo, dependendo da quantidade de registros que você tenha, por isso, faça uma páginação mais detalhada #ficadica.

Como vocês podem ver, a páginação é algo muito simples em relação ao MySQL por exemplo, pois não precisamos consultar novamente o banco de dados para saber a quantidade total de registros.

1 Comment »

Lighttpd + MongoDB + PHP + MySQL + Servidor direto do pendrive(USB)

maio 7th, 2010 | by alex | escalabilidade, mongodb, mysql, nosql

mai
07

Quem já não teve vontade de testar o mundo nosql, mas ou não conseguiu instalar, ou teve preguiça ou não queria mudar para o linux? Aposto que mais de 90%.

Vendo essa necessidade, aproveitei o programa Lighty2Go que já vem com Lighttpd, php e MySQL, aproveitei e fiz algumas modificações e coloquei o MongoDB e PHP juntos, e de bonus o phpmoadmin, que serve para administrar o MongoDB.

Ele funciona de forma extremamente simples, depois de você baixar os arquivos extraia no pendrive ou em qualquer lugar do seu computador. Depois é só iniciar o servidor

Quando você iniciar o servidor, ele vai estar na porta 81, ou seja, para acessar ele você deve entrar em http://localhost:81

Para administrar o MySQL acesse:
http://localhost:81/phpmyadmin/

Para ver o phpinfo:
http://localhost:81/phpinfo

Para ver o phpmoadmin:
http://localhost:81/moadmin.php

Os arquivos do seu site você pode colocar tudo dentro de HTDOCS.
Fica ai esse excelente pacote, com um dos melhores servidores web o lighttpd, com a melhor programação o PHP, com o melhor banco de dados MongoDB, e o antigo melhor, MySQL.

Download

http://www.megaupload.com/?d=A1MVB1YP
http://rapidshare.com/files/384566309/Lighty2Go.rar.html

3 Comments »

Alguns números do Twitter

maio 6th, 2010 | by suissa | cassandra, escalabilidade, flockdb, hadoop, mysql, twitter

mai
06

Fiquei pasmo coma quantidade de informação

-50 milhões de tweets/dia
-300 mil novas contas/dia
- O Twitter gera 7 TB/dia, 2 PB/ano.
- Solução para logs com Scribe após tentar com syslog-ng.
- Hadoo p/HDFS para armazenamento e processamento distribuído. Pig para analise.
- Projeto próprio para gerenciar grafos sociais. FlockDB.
- Estão migrando de MySQL com memcached para Cassandra. Particionar MySQL leva a muitos pontos de falha, é computacionalmente pesado e demanda mais trabalho.
- Deploy em mais de 1000 maquinas em menos de 1 minuto com BitTorrent (Murder).

Agora me pergunto seria possível sem NOSQL?

1 Comment »

Meu Benchmark – pequeno comparativo MySQL e MongoDB

maio 6th, 2010 | by suissa | benchmark, mongodb, mysql, nosql

mai
06

Inserindo/lendo
array(“title” => “Calvin and Hobbes”);
No MYSQL – Inserção
inserindo 50k
Tempo (segundos): 26.963586091995
inserindo 50k
Tempo (segundos): 35.74323797226
inserindo 50k
Tempo (segundos): 27.360780954361
inserindo 50k
Tempo (segundos): 27.239809989929
LEITURA dos 200k: Tempo (segundos): 0.16633296012878
MongoDB – Inserção
inserindo 50k
Tempo (segundos): 6.9094848632812
inserindo 50k
Tempo (segundos): 9.049604177475
inserindo 50k
Tempo (segundos): 4.2792370319366
inserindo 50k
Tempo (segundos): 10.331115007401
LEITURA dos 200k: Tempo (segundos): 0.14360809326172
As vezes a uma diferença de 100% mas provavelmente pode ser pelo sistema estar escrevendo outras coisas no HD, pq não deixei só os testes rodando.
Mas já é uma boa comparação.
Leitura Mysql:
$q = “select COUNT(*) total from teste_mysql where title=’Calvin and Hobbes’”;
getTime();
mysql_query($q);
Leitura Mongo
getTime();
$filter = array( “title” => “Calvin and Hobbes” );
$cursor = $collection->find($filter);
//$cursor->sort(array(“title” => 1))->limit(4)->skip(0);
var_dump($cursor->count(true));
//var_dump($cursor->count());
getTime();
Código mysql

[php]
<?php
$linkk = mysql_connect("localhost","root","****");
mysql_select_db("testes", $linkk);
function getTime(){ static $tempo; if( $tempo == NULL ){ $tempo = microtime(true); } else{ echo ‘Tempo (segundos): ‘.(microtime(true)-$tempo).”; } }
$q = "insert into teste_mysql VALUES(‘Calvin and Hobbes’)";
getTime();
for($i=0;$i<50000;$i++){
mysql_query($q);
}
getTime();
echo "<br />";
exit;
?>
[/php]

Código mongoDB

[php]
<?php
$conexao = new Mongo();
$db = $conexao->testes2;
$collection = $db->teste_mongo2;

function getTime(){static $tempo; if( $tempo == NULL ){ $tempo = microtime(true); } else{ echo ‘Tempo (segundos): ‘.(microtime(true)-$tempo).”; } }

getTime();

for($i=0;$i<50000;$i++){
$obj = array( "title" => "Calvin and Hobbes" );
$collection->insert($obj);
}

getTime();
$filter = array( "title" => "Calvin and Hobbes" );
$cursor = $collection->find($filter);
var_dump($cursor->count(true));
getTime();

echo "<br />";

$conexao->close();
exit;
?>
[/php]

1 Comment »