Schema Design 
Latinoware 2014 
Christiano Anderson 
anderson@propus.com.br 
Twitter: @dump 
Blog: http://christiano.me
Agenda 
● Apresentação 
● Modelo de documento MongoDB 
● Tipos de dados 
● Arquitetura 
● Boas práticas
Quem sou? 
● Especialista em Big Data e NoSQL na Propus; 
● Desenvolvedor Python; 
● Trabalha desde o início da internet comercial 
do Brasil; 
● Fundador do MUG-SP;
MongoDB 
● Orientação a documentos; 
● Índices simples e compostos; 
● Suporte a índices: 
– Full Text Search; 
– Geográfico;
Alguns conceitos 
● Base de dados; 
● Coleção; 
● Documento;
Alguns conceitos 
● Uma base de dados possui várias coleções; 
● Uma coleção possui vários documentos; 
– Comparando com banco de dados relacional, 
podemos dizer que: 
● Coleção = Tabela; 
● Documento = Registro;
Exemplo de documento 1 
{ 
"_id" : ObjectId("541f30d992a2ee25fedaa652"), 
"nome" : "Christiano", 
"twitter" : "dump" 
} 
Chave Valor
Exemplo de documento 2 
{ 
"_id" : ObjectId("541f30d992a2ee25fedaa652"), 
"nome" : "Christiano", 
"twitter" : "dump", 
"linguagens" : [ 
"Python", 
"C", 
"JavaScript", 
"C++" 
] 
} 
Uma lista ou array
Exemplo de documento 3 
{ 
"_id" : ObjectId("541f361892a2ee25fedaa653"), 
"nome" : "Christiano", 
"redes_sociais" : { 
"Twitter" : "dump", 
"Facebook" : "christiano.anderson", 
"LinkedIn" : "christiano.anderson", 
"Instagram" : "canderson9" 
} 
} 
Uma lista de valores ou 
Um documento embarcado
Desnormalização
Exemplo de dado 
Nome: Christiano Anderson 
Twitter: dump 
Cidade: São Paulo 
Estado: SP
Banco Relacional
select * from cadastro; 
Informação 
Normalizada, relaciona 
Com a tabela de cidade 
Que relaciona com a 
tabela de UF
E no MongoDB? 
{ 
"_id" : ObjectId("541f64d092a2ee25fedaa654"), 
"nome" : "Christiano", 
"twitter" : "dump", 
"cidade" : "São Paulo", 
"uf" : "SP" 
} 
Os dados são desnormalizados
E coleções de referência? 
Não há necessidade de criar uma coleção de 
referência para Estados e outra para Cidades
Pode ser inconsistente? 
● Sim, pode ocorrer inconsistências; 
● O controle deve ser feito via código;
Schema Design 
O grande segredo da modelagem 
Está no “schema design”
Schema Design 
● O arquiteto precisa entender como as 
informações serão inseridas e consultadas no 
sistema; 
● O sucesso está em extrair o maior número de 
informações em uma única consulta
Uma aplicação de Blog 
Você já viu a quantidade de tabelas existentes no 
WordPress?
Schema do Wordpress 
Fonte: http://codex.wordpress.org/Database_Description/3.3
Posts e Comentários 
Vamos pegar a parte principal 
de uma aplicação de blog: 
Posts 
Comentários
Posts e Comentários
Posts e comentários 
Exemplo clássico de 
“Um para muitos” 
Um post = Vários comentários
Pensando no Relacional 
● Tabela de Post possui a FK de cada post 
● Tabela de Comentário possui FK ligando a 
cada post 
● A cada acesso no Post, é necessário fazer uma 
consulta na tabela de Comentários para buscar 
todos
E no MongoDB?
No MongoDB 
Uma das técnicas é deixar posts 
e comentários na mesma coleção
{ 
"_id" : ObjectId("541f6a9092a2ee25fedaa655"), 
"titulo" : "Aqui é o título", 
"tags" : [ 
"teste", 
"exemplo", 
"mongodb" 
], 
"conteudo" : "Aqui vem o Lorem Ipsum básico", 
"comentarios" : [ 
{ 
"usuario" : "Usuario Troll", 
"email" : "troll@troland.com", 
"comentario" : "Vim aqui só trollar" 
}, 
{ 
"usuario" : "Usuario Sério", 
"email" : "serio@serioland.com", 
"comentario" : "Parabéns pelo post" 
} 
] 
} 
Post 
Os comentários ficam 
embarcados no 
mesmo documento 
que o post
Uma única query retorna o post 
E todos seus comentários
Outro exemplo de schema design: 
Coleção: livraria 
Coleção: alunos 
Os alunos podem retirar um ou 
mais livros da livraria. 
Como melhor fazer esse 
Controle com MongoDB?
Coleção de alunos 
> db.alunos.find() 
{ "_id" : 1, "nome" : "Pedrinho", "sala" : "200" } 
{ "_id" : 2, "nome" : "Zezinho", "sala" : "404" } 
{ "_id" : 3, "nome" : "Luizinho", "sala" : "500" }
Coleção de Livros 
> db.livros.find().pretty() 
{ "_id" : 1, "titulo" : "A Ilha Perdida", "autor" : "Maria José Dupré" } 
{ "_id" : 2, "titulo" : "Éramos Seis", "autor" : "Maria José Dupré" } 
{ "_id" : 3, "titulo" : "Sozinha no Mundo", "autor" : "Marcos Rey" }
Primeiro cenário 
Luizinho quer alugar o livro “A Ilha Perdida” 
Criar uma chave “aluguel” 
na coleção de livros
Alteração no documento do livro 
{ 
"_id" : 1, 
"titulo" : "A Ilha Perdida", 
"autor" : "Maria José Dupré", 
"aluguel" : { 
"aluno_id" : 3, 
"data" : ISODate("2014-09-21T00:00:00Z") 
} 
} 
Ligação com o id do 
aluno, Luizinho
Query de atualização 
db.livros.update({'_id': 1}, 
{$set:{'aluguel':{'aluno_id':3,'data':ISODate('2014-09- 
21')}}})
Ver todos os livros alugados 
> db.livros.find({'aluguel': 
{$exists:true}}).pretty() 
{'aluguel': 
"_id" : 1, 
"titulo" : "A Ilha Perdida", 
"autor" : "Maria José Dupré", 
"aluguel" : { 
"aluno_id" : 3, 
"data" : ISODate("2014-09- 
21T00:00:00Z") 
} 
}
Série temporal 
timestamp memoria_usada 
2013-10-10T23:06:37.000Z 1000000 
2013-10-10T23:06:38.000Z 2000000 
2013-10-10T23:06:39.000Z 2332200
A principal pergunta: 
Como você vai buscar esses dados? 
Vai agregar por horas?
Documentos únicos 
{ 
timestamp: ISODate("2013-10-10T23:06:37.000Z"), 
type: ”memory_used”, 
value: 1000000 
}, 
{ 
timestamp: ISODate("2013-10-10T23:06:38.000Z"), 
type: ”memory_used”, 
value: 2000000 
}, 
{ 
timestamp: ISODate("2013-10-10T23:06:39.000Z"), 
type: ”memory_used”, 
value: 2322000 
}
Agregado por minuto 
{ 
timestamp_minute: ISODate("2013-10- 
10T23:06:00.000Z"), 
type: “memory_used”, 
values: { 
0: 999999, 
… 
37: 1000000, 
38: 1500000, 
… 
59: 2000000 
} 
}
Agregado por hora 
{ 
timestamp_hour: ISODate("2013-10- 
10T23:00:00.000Z"), 
type: “memory_used”, 
values: { 
0: 999999, 
1: 1000000, 
…, 
3598: 1500000, 
3599: 2000000 
} 
}
Melhor schema 
A pergunta é a mesma: buscar o maior número 
de informações com uma ou poucas queries
Melhor schema 
● Eficiência na gravação 
● Eficiência na leitura 
● Não existe mágica, é necessário entender o 
funcionamento da aplicação 
● Bom schema, bom código = sucesso garantido 
● Índices e agregadores podem ser necessários.
Obrigado! 
Christiano Anderson 
Twitter: dump

MongoDB Schema Design - Latinoware 2014

  • 1.
    Schema Design Latinoware2014 Christiano Anderson anderson@propus.com.br Twitter: @dump Blog: http://christiano.me
  • 2.
    Agenda ● Apresentação ● Modelo de documento MongoDB ● Tipos de dados ● Arquitetura ● Boas práticas
  • 3.
    Quem sou? ●Especialista em Big Data e NoSQL na Propus; ● Desenvolvedor Python; ● Trabalha desde o início da internet comercial do Brasil; ● Fundador do MUG-SP;
  • 4.
    MongoDB ● Orientaçãoa documentos; ● Índices simples e compostos; ● Suporte a índices: – Full Text Search; – Geográfico;
  • 5.
    Alguns conceitos ●Base de dados; ● Coleção; ● Documento;
  • 6.
    Alguns conceitos ●Uma base de dados possui várias coleções; ● Uma coleção possui vários documentos; – Comparando com banco de dados relacional, podemos dizer que: ● Coleção = Tabela; ● Documento = Registro;
  • 7.
    Exemplo de documento1 { "_id" : ObjectId("541f30d992a2ee25fedaa652"), "nome" : "Christiano", "twitter" : "dump" } Chave Valor
  • 8.
    Exemplo de documento2 { "_id" : ObjectId("541f30d992a2ee25fedaa652"), "nome" : "Christiano", "twitter" : "dump", "linguagens" : [ "Python", "C", "JavaScript", "C++" ] } Uma lista ou array
  • 9.
    Exemplo de documento3 { "_id" : ObjectId("541f361892a2ee25fedaa653"), "nome" : "Christiano", "redes_sociais" : { "Twitter" : "dump", "Facebook" : "christiano.anderson", "LinkedIn" : "christiano.anderson", "Instagram" : "canderson9" } } Uma lista de valores ou Um documento embarcado
  • 10.
  • 11.
    Exemplo de dado Nome: Christiano Anderson Twitter: dump Cidade: São Paulo Estado: SP
  • 12.
  • 13.
    select * fromcadastro; Informação Normalizada, relaciona Com a tabela de cidade Que relaciona com a tabela de UF
  • 14.
    E no MongoDB? { "_id" : ObjectId("541f64d092a2ee25fedaa654"), "nome" : "Christiano", "twitter" : "dump", "cidade" : "São Paulo", "uf" : "SP" } Os dados são desnormalizados
  • 15.
    E coleções dereferência? Não há necessidade de criar uma coleção de referência para Estados e outra para Cidades
  • 16.
    Pode ser inconsistente? ● Sim, pode ocorrer inconsistências; ● O controle deve ser feito via código;
  • 17.
    Schema Design Ogrande segredo da modelagem Está no “schema design”
  • 18.
    Schema Design ●O arquiteto precisa entender como as informações serão inseridas e consultadas no sistema; ● O sucesso está em extrair o maior número de informações em uma única consulta
  • 19.
    Uma aplicação deBlog Você já viu a quantidade de tabelas existentes no WordPress?
  • 20.
    Schema do Wordpress Fonte: http://codex.wordpress.org/Database_Description/3.3
  • 21.
    Posts e Comentários Vamos pegar a parte principal de uma aplicação de blog: Posts Comentários
  • 22.
  • 23.
    Posts e comentários Exemplo clássico de “Um para muitos” Um post = Vários comentários
  • 24.
    Pensando no Relacional ● Tabela de Post possui a FK de cada post ● Tabela de Comentário possui FK ligando a cada post ● A cada acesso no Post, é necessário fazer uma consulta na tabela de Comentários para buscar todos
  • 25.
  • 26.
    No MongoDB Umadas técnicas é deixar posts e comentários na mesma coleção
  • 27.
    { "_id" :ObjectId("541f6a9092a2ee25fedaa655"), "titulo" : "Aqui é o título", "tags" : [ "teste", "exemplo", "mongodb" ], "conteudo" : "Aqui vem o Lorem Ipsum básico", "comentarios" : [ { "usuario" : "Usuario Troll", "email" : "troll@troland.com", "comentario" : "Vim aqui só trollar" }, { "usuario" : "Usuario Sério", "email" : "serio@serioland.com", "comentario" : "Parabéns pelo post" } ] } Post Os comentários ficam embarcados no mesmo documento que o post
  • 28.
    Uma única queryretorna o post E todos seus comentários
  • 29.
    Outro exemplo deschema design: Coleção: livraria Coleção: alunos Os alunos podem retirar um ou mais livros da livraria. Como melhor fazer esse Controle com MongoDB?
  • 30.
    Coleção de alunos > db.alunos.find() { "_id" : 1, "nome" : "Pedrinho", "sala" : "200" } { "_id" : 2, "nome" : "Zezinho", "sala" : "404" } { "_id" : 3, "nome" : "Luizinho", "sala" : "500" }
  • 31.
    Coleção de Livros > db.livros.find().pretty() { "_id" : 1, "titulo" : "A Ilha Perdida", "autor" : "Maria José Dupré" } { "_id" : 2, "titulo" : "Éramos Seis", "autor" : "Maria José Dupré" } { "_id" : 3, "titulo" : "Sozinha no Mundo", "autor" : "Marcos Rey" }
  • 32.
    Primeiro cenário Luizinhoquer alugar o livro “A Ilha Perdida” Criar uma chave “aluguel” na coleção de livros
  • 33.
    Alteração no documentodo livro { "_id" : 1, "titulo" : "A Ilha Perdida", "autor" : "Maria José Dupré", "aluguel" : { "aluno_id" : 3, "data" : ISODate("2014-09-21T00:00:00Z") } } Ligação com o id do aluno, Luizinho
  • 34.
    Query de atualização db.livros.update({'_id': 1}, {$set:{'aluguel':{'aluno_id':3,'data':ISODate('2014-09- 21')}}})
  • 35.
    Ver todos oslivros alugados > db.livros.find({'aluguel': {$exists:true}}).pretty() {'aluguel': "_id" : 1, "titulo" : "A Ilha Perdida", "autor" : "Maria José Dupré", "aluguel" : { "aluno_id" : 3, "data" : ISODate("2014-09- 21T00:00:00Z") } }
  • 36.
    Série temporal timestampmemoria_usada 2013-10-10T23:06:37.000Z 1000000 2013-10-10T23:06:38.000Z 2000000 2013-10-10T23:06:39.000Z 2332200
  • 37.
    A principal pergunta: Como você vai buscar esses dados? Vai agregar por horas?
  • 38.
    Documentos únicos { timestamp: ISODate("2013-10-10T23:06:37.000Z"), type: ”memory_used”, value: 1000000 }, { timestamp: ISODate("2013-10-10T23:06:38.000Z"), type: ”memory_used”, value: 2000000 }, { timestamp: ISODate("2013-10-10T23:06:39.000Z"), type: ”memory_used”, value: 2322000 }
  • 39.
    Agregado por minuto { timestamp_minute: ISODate("2013-10- 10T23:06:00.000Z"), type: “memory_used”, values: { 0: 999999, … 37: 1000000, 38: 1500000, … 59: 2000000 } }
  • 40.
    Agregado por hora { timestamp_hour: ISODate("2013-10- 10T23:00:00.000Z"), type: “memory_used”, values: { 0: 999999, 1: 1000000, …, 3598: 1500000, 3599: 2000000 } }
  • 41.
    Melhor schema Apergunta é a mesma: buscar o maior número de informações com uma ou poucas queries
  • 42.
    Melhor schema ●Eficiência na gravação ● Eficiência na leitura ● Não existe mágica, é necessário entender o funcionamento da aplicação ● Bom schema, bom código = sucesso garantido ● Índices e agregadores podem ser necessários.
  • 43.