O documento discute as vantagens de bancos NoSQL em relação a bancos de dados relacionais tradicionais para armazenar grandes quantidades de dados. O autor apresenta exemplos de bancos NoSQL como MongoDB, orientado a documentos, e Riak, baseado em chave-valor, e discute como cada um pode ser usado para diferentes casos. O autor também fornece exemplos de código para inserir e consultar dados nesses bancos usando Python.
Utilizando NoSQL no desenvolvimento de soluções inteligentes
1. The Real-time Web
Utilizando NoSQL para
desenvolvimento de
soluções inteligentes
Christiano Anderson Nodeware
Diretor de desenvolvimento http://www.nodeware.com.br
Email: anderson@nodeware.com.br Twitter: @nodeware
Twitter: @dump
Blog: http://christiano.me
2. Sobre o autor
• Trabalha com software livre desde 1995;
• Diretor de Desenvolvimento da Nodeware;
• Ex-desenvolvedor do projeto GNU;
• Trabalha com Python desde 2000;
• Evangelista NoSQL, Django e Node.JS;
• Colabora com equipe de tradução do MongoDB;
• Fundador do MUG-SP;
@dump
3. Sobre a Nodeware
• Empresa nova mas com profissionais que
participaram do início da internet comercial do
Brasil;
• Foco em soluções emergentes, cloud, NoSQL,
Node.JS e gestão de conteúdo (CMS);
• Parceira 10gen e Amazon AWS;
• Mais em http://www.nodeware.com.br
@dump
4. NoSQL?
• O termo foi cunhado por Carlo Strozzi e
reintroduzido por Eric Evans, como referência a
um tipo de armazenamento de dados;
• O uso recomendado é Not Only SQL e nunca
deve ser usado como “Não-SQL” ou “Never SQL”;
• O movimento NoSQL é distinto do modelo
relacional, o termo NoREL também é bastante
apropriado.
@dump
6. NoSQL?
“NoSQL is a movement promoting a loosely defined class of
non-relational data stores that break with a long history of
relational databases.These data stores may not require fixed
table schemas, usually avoid join operations and typically
scale horizontally. Academics and papers typically refer to
these databases as structured storage.”
Wikipedia
@dump
7. Por que NoSQL?
• É uma questão de escolha, novos
paradigmas (nem tão novos assim);
• É uma questão de funcionalidades;
• Performance e Escalabilidade;
• Não é questão de “ódio ao modelo SQL”;
@dump
8. Por que NoSQL?
• Para trabalhar com uma massa enorme de dados
que...
• ... crescem exponencialmente;
• ... agregam muitos outros valores
dinamicamente;
• ... exigem um formato diferenciado de dados;
• ... não exigem um banco relacional, mas podem
trabalhar em conjunto com um.
@dump
9. Por que NoSQL?
• Para trabalhar com uma massa enorme de dados
que...
• ... crescem exponencialmente; Enorme é bastante
relativo
• ... agregam muitos outros valores
dinamicamente;
• ... exigem um formato diferenciado de dados;
• ... não exigem um banco relacional, mas podem
trabalhar em conjunto com um.
@dump
11. Orientação a documentos
• Dados estruturados de forma encadeada, podendo
ser coleções, tags, metadatas, hierarquias de
informações, etc.
• Exemplo de documento:
nome:”Christiano”,empresa:”Nodeware”,contatos:
[{twitter:”@dump”},{email:”anderson@nodeware.com.br”}]
• Bom para aplicações de conteúdo, blogs, análise
estatísticas, etc.
@dump
13. Grafos?
• Estrutura de nós, bordas e propriedades
para representar dados;
• Todo elemento possui um apontamento
direto para outro elemento adjacente;
• Bom para mídias sociais,
determinar relacionamento
entre dados e B.I.;
@dump
14. Chave/Valor (k/v)
Amazon SimpleDB MemcacheDB
Segue um modelo baseado em
colunas, mas que não deixa de
ser conceito chave/valor.
@dump
15. Chave/Valor (k/v)
• Quase todos os bancos NoSQL possuem o
conceito de chave/valor;
• Conceito para armazenar dados sem
precisar de uma modelagem pré-definida;
• Os dados podem estar em colunas;
• A persistência dos dados pode ser em
memória ou em disco;
@dump
17. Resposta
Depende do que você vai fazer!
As vezes pode precisar de mais de
uma ferramenta
@dump
18. Motivos para adotar NoSQL
• Grande quantidade de dados;
• Ótima performance de escrita;
• Rápido acesso chave-valor;
• Modelagem flexível;
• Migração fácil de dados;
• Fácil para manter e administrar;
• Sem pontos únicos de falha;
• Facilidade no desenvolvimento;
@dump
19. Por onde começar?
• Primeiro passo é saber o que você precisa;
• MongoDB possui uma baixa curva de
aprendizado, ótimo para conhecer os
conceitos NoSQL;
• MongoDB é o canivete suíço dos bancos
NoSQL;
@dump
20. MongoDB?
• Dois motivos para começar com
MongoDB:
• Baixa curva de aprendizado;
• Agilidade no desenvolvimento;
@dump
21. Você deve considerar o uso de MongoDB se...
• Você está usando muito cache em sua aplicação;
• Você está armazenando muitos dados em arquivos
estáticos;
• Você precisa de processamento em tempo real;
• Você gosta de desenvolvimento ágil (SCRUM);
• Você tem dificuldades para modelar sua estrutura
de dados no conceito relacional;
• Seu projeto faz muita gravação e leitura em banco
de dados;
@dump
22. O MongoDB substitui o banco relacional?
• Como já foi explicado, é uma questão de
escolha;
• Uma aplicação pode usar banco relacional e
NoSQL sem problema;
@dump
23. Desenvolvimento
• O MongoDB e outros bancos NoSQL suportam
praticamente todas as linguagens de programação;
• O MongoDB possui suporte oficial para:
• C, C++, Erlang, Haskell, Java, JavaScript, Perl, PHP,
Python, .NET, Ruby, Scala, Go Language, Node.js,
Lisp, Lua, Smalltalk...
• Mais em: http://www.mongodb.org/display/DOCS/
Drivers
@dump
24. Modelo de Documento
Um modelo de documento MongoDB possui
o seguinte formato:
{‘nome’:‘Christiano’,
‘linguagem’:‘node.js’,
‘nota’: 10}
Sim, é praticamente
um JSON
@dump
25. Comparando com SQL
SQL MongoDB
INSERT INTO USERS VALUES(1,1) db.users.insert({a:1, b:1})
SELECT a,b FROM users db.users.find({}, {a: 1, b: 1})
SELECT * FROM users db.users.find()
SELECT * FROM users WHERE age=33 db.users.find({age: 33})
SELECT * FROm users WHERE name = “pedro” db.users.find({name:”pedro”})
@dump
26. Comparando com SQL
SQL MongoDB
SELECT * FROM users WHERE db.users.find({‘age’:33}).sort({name:
age=33 ORDER BY name 1})
SELECT * FROM users WHERE age
db.users.find({‘age’:{$lt:33}})})
< 33
CREATE INDEX myindexname ON
db.users.ensureIndex({name:1})
user(name)
SELECT * FROM users WHERE a = 1 AND b =
‘q’ db.users.find({a:1, b:’q’})
SELECT * FROM users LIMIT 10 SKIP 20 db.users.find().limit(10).skip(20)
@dump
27. Índices
• Possui suporte a índices para ganho de
performance;
• O conceito é similar a bancos relacionais, como
MySQL;
• Exemplo:
• db.colecao.ensureIndex({nome:1})
• Mais: http://www.mongodb.org/display/DOCS/
Indexes
@dump
28. Replica Sets
• Possível dividir a carga em vários servidores, replicando seu conteúdo via
Replica Sets;
• Possível crescer o ambiente de forma bastante orgânica;
• Replica Set consiste em um ou mais node que replicam seus valores entre si.
Server 1 Server 2
Somente leitura
Leitura, Escrita
Primário
Cliente
@dump
29. Sharding
• MongoDB escala horizontalmente via auto-
sharding, particionando pedaço de dados entre
servidores;
• Pode adicionar novos nodes facilmente sem
interromper o sistema;
• Possível escalar centenas e milhares de servidores;
• Não tem ponto único de falha;
• Failover automático;
@dump
30. Python e MongoDB
• Pymongo é o módulo que permite a conexão de
qualquer aplicativo em Python ao MongoDB;
• Instalado facilmente via pip ou easy_install:
• pip install pymongo
@dump
31. Código de exemplo
>>> from pymongo import Connection
>>> con = Connection(“localhost”)
>>> db = con[‘blog’]
@dump
32. Inserindo um documento
>>> post = {'title':'My first post',
…'author': 'Christiano Anderson',
…'content': 'This is my first
paragraph', … 'tags':
['mongodb','blog','example']}
>>> posts = db['posts']
>>> posts.insert(post)
ObjectId('4cb662f508bf532b1b000000')
@dump
33. Inserindo vários documentos
>>> other_posts = [{'title':'Second Post', 'author': 'Christiano
Anderson','tags':['test'], 'content': 'Hey, my second Post'},
{'title':'Third Post', 'author':'Luke Skywalker','tags':
['naboo'],'content':'Hey princess Leya'}]
>>> posts.insert(other_posts) [ObjectId('4cb6651b08bf532b97000000'),
ObjectId('4cb6651b08bf532b97000001')]
@dump
34. Realizando pesquisas
>>> my_post = db.posts.find_one({})
{u'content': u'This is my first post at
MongoDB', u'title': u'My first post', u'_id':
ObjectId('4cb662f508bf532b1b000000'), u'tags':
[u'mongodb', u'blog', u'example'], u'author':
u'Christiano Anderson'}
>>> my_post = db.posts.find_one({ 'author':
'Christiano Anderson'})
@dump
35. Operadores
• Também é possível utilizar operadores como $ne,
$lte, $gte,entre outros...
• Mais: http://www.mongodb.org/display/DOCS/
Advanced+Queries
@dump
36. Consultas à base
>>> all_posts = db.posts.find({})
>>> for p in all_posts:
... print p['title']
My first post Second Post Third Post
@dump
38. Map/Reduce
• Utilizado para criar funções de pesquisa e
agregadores no MongoDB;
• Utiliza-se JavaScript;
• Pode ser comparado a um Stored Procedure;
@dump
39. Exemplo de Map/Reduce
function() {
this.tags.forEach(function(z)) {
emit(z, 1);
});}
function(key, value) {
var total = 0;
for(var i = 0; i < values.length;
i++) {
total += values[i]; }
return total;
}
@dump
41. Riak
• Implementado a partir de papers do
Amazon DynamoDB;
• Escrito em Erlang;
• Seu modelo é baseado em chave/valor (kv);
• Muito, mas muito fácil para escalar;
• Riak-search oferece busca estilo Solr/
Lucene;
@dump
42. Buckets
• Buckets são utilizadas para definir um
espaço virtual de dados;
• Podem ser comparadas a pastas ou tabelas,
em sistemas operacionais ou banco de
dados relacionais respectivamente;
• Essa é a única maneira de armazenar dados
no Riak;
@dump
43. Riak - Exemplos em Python
import riak
client = riak.RiakClient()
bucket = client.bucket('nodeware')
p = bucket.new('anderson', data = {
'nome': 'Christiano Anderson',
'empresa': 'Nodeware',
'email': ‘anderson@nodeware.com.br’,
})
p.store()
@dump
44. Riak - Exemplos em Python
import riak Definição de Bucket
client = riak.RiakClient()
bucket = client.bucket('nodeware')
p = bucket.new('anderson', data = {
'nome': 'Christiano Anderson',
'empresa': 'Nodeware',
'email': ‘anderson@nodeware.com.br’,
})
p.store()
@dump
45. Riak - Exemplos em Python
import riak Definição de Bucket
client = riak.RiakClient()
bucket = client.bucket('nodeware')
p = bucket.new('anderson', data = {
'nome': 'Christiano Anderson', Dados
'empresa': 'Nodeware',
'email': ‘anderson@nodeware.com.br’,
})
p.store()
@dump