{"id":3051,"date":"2017-09-22T11:30:44","date_gmt":"2017-09-22T14:30:44","guid":{"rendered":"https:\/\/blog.umbler.com\/?p=3051"},"modified":"2018-12-05T10:43:05","modified_gmt":"2018-12-05T12:43:05","slug":"boas-praticas-com-mongodb","status":"publish","type":"post","link":"https:\/\/blog.umbler.com\/br\/boas-praticas-com-mongodb\/","title":{"rendered":"Boas pr\u00e1ticas com MongoDB"},"content":{"rendered":"<p>O <strong>MongoDB<\/strong> \u00e9 um banco de dados de c\u00f3digo aberto, gratuito, de alta performance, sem esquemas e orientado a documentos lan\u00e7ado em fevereiro de 2009 pela empresa 10gen. Foi escrito na linguagem de programa\u00e7\u00e3o C++ (o que o torna port\u00e1vel para diferentes sistemas operacionais) e seu desenvolvimento durou quase dois anos, tendo iniciado em 2007.<\/p>\n<p>\u00c9 utilizado por organiza\u00e7\u00f5es de todos os tamanhos para a cria\u00e7\u00e3o de aplica\u00e7\u00f5es online onde baixa lat\u00eancia, alta vaz\u00e3o e alta disponibilidade sejam requisitos cr\u00edticos do sistema. Nele, as informa\u00e7\u00f5es s\u00e3o armazenadas em documentos BSON, semelhante aos objetos JSON usados largamente na web, ao inv\u00e9s de tabelas e colunas.<\/p>\n<p>No entanto, armazenar dados em documentos \u00e9 uma forma de persist\u00eancia relativamente comum entre os banco n\u00e3o-relacionais, sendo o MongoDB o mais popular de todos eles, como mostra o gr\u00e1fico abaixo da pesquisa mais recente de bancos de dados utilizados pela <a href=\"https:\/\/insights.stackoverflow.com\/survey\/2017#technology\" target=\"_blank\" rel=\"noopener\">audi\u00eancia do StackOverflow em 2017<\/a>.<br \/>\n<img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter wp-image-3052 size-full\" src=\"https:\/\/blog.umbler.com\/wp-content\/uploads\/2017\/09\/mongodb.png\" alt=\"MongoDB bem posicionado no StackOverflow\" width=\"696\" height=\"410\" \/><br \/>\nDentre todos os bancos n\u00e3o relacionais o MongoDB \u00e9 o mais utilizado &#8211; quase \u2155 dos respondentes alegam utiliz\u00e1-lo em seus projetos, o que \u00e9 mais at\u00e9 mesmo do que o Oracle, um banco muito mais tradicional.<\/p>\n<p>At\u00e9 aqui talvez voc\u00ea n\u00e3o tenha lido nenhuma novidade, mas como tirar o maior proveito poss\u00edvel do MongoDB? Como n\u00e3o cair nas armadilhas que se escondem por tr\u00e1s de sua simplicidade? Por que MongoDB e n\u00e3o outro banco de dados?<br \/>\n<img decoding=\"async\" class=\"aligncenter wp-image-3053 size-full\" src=\"https:\/\/blog.umbler.com\/wp-content\/uploads\/2017\/09\/what.gif\" alt=\"Gif WHAT?\" width=\"500\" height=\"281\" \/><br \/>\nEssas e outras perguntas ser\u00e3o o tema desse artigo, onde abordarei quest\u00f5es t\u00e9cnicas fundamentadas em cima da documenta\u00e7\u00e3o oficial do MongoDB e experi\u00eancias pessoais de dois anos usando esta plataforma de banco de dados.<\/p>\n<p>Esse artigo est\u00e1 organizado em tr\u00eas t\u00f3picos:<\/p>\n<ul>\n<li><a href=\"#hardware\">Hardware<\/a><\/li>\n<li><a href=\"#aplica\u00e7\u00e3o\">Aplica\u00e7\u00e3o<\/a><\/li>\n<li><a href=\"#modelagem\">Modelagem<\/a><\/li>\n<\/ul>\n<p>Voc\u00ea pode ler o post por completo ou apenas estudar o item que mais interessa, clicando sobre ele. Voc\u00ea que manda! ?<br \/>\n<a name=\"hardware\"><\/a><\/p>\n<h2>#1 Boas pr\u00e1ticas de Hardware<\/h2>\n<p>Para os desenvolvedores, hardware \u00e9 algo que n\u00e3o recebe tanta import\u00e2ncia (at\u00e9 apresentar problemas!). N\u00e3o colocar o seu banco MongoDB em um servidor apropriado pode causar muitas dores de cabe\u00e7a com a <a href=\"https:\/\/blog.umbler.com\/br\/avancos-em-ia-generativa\/\">tecnologia<\/a>. \u00c9 como diz o ditado: o barato sai caro!<\/p>\n<p>Ao contratar servi\u00e7os em nuvem, como os da Umbler e outros players, procure se informar do tipo de hardware utilizado, como tecnologias de disco e mem\u00f3ria, al\u00e9m de dimensionar corretamente a inst\u00e2ncia de servidor onde estar\u00e1 o MongoDB, \u00e9 claro. Sobre este \u00faltimo, mais dicas ser\u00e3o apresentadas adiante.<\/p>\n<p>Ah, e n\u00e3o use ambientes compartilhados de MongoDB para aplica\u00e7\u00f5es em produ\u00e7\u00e3o. Nunca! Prefira sempre inst\u00e2ncias e containers dedicados para este servi\u00e7o ficar executando.<\/p>\n<h3>#1.1 Tenha mem\u00f3ria RAM suficiente<\/h3>\n<p>Como a maioria dos bancos de dados, o MongoDB funciona melhor quando as suas cole\u00e7\u00f5es e \u00edndices mais utilizados cabem completamente na mem\u00f3ria RAM do seu servidor. E, para saber o quanto de RAM cada componente ocupa, use a fun\u00e7\u00e3o stats(). No exemplo abaixo, mostro os stats da cole\u00e7\u00e3o &#8216;customers&#8217;:<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-javascript\">&gt; db.customers.stats()\r\n{\r\n    \"size\" : 715578011834,  \/\/ total size (bytes)\r\n    \"avgObjSize\" : 2862,    \/\/ average size (bytes)\r\n}\r\n<\/code><\/pre>\n<p>Para ter uma no\u00e7\u00e3o mais geral, use o comando db.serverStatus() para ver uma estimativa do tamanho do working set atual (dados mais utilizados).<\/p>\n<p>A quantidade de mem\u00f3ria RAM \u00e9 o fator mais importante quando o assunto \u00e9 hardware. O resultado de outras otimiza\u00e7\u00f5es nem se compara com a melhoria de performance que ter RAM suficiente proporciona ao seu sistema. Se o seu working set excede a capacidade de mem\u00f3ria de um \u00fanico servidor uma dica \u00e9 fazer sharding dele em v\u00e1rios servers.<\/p>\n<h3>#1.2 Use discos adequados<\/h3>\n<p>A maioria dos acessos a dados em bases MongoDB n\u00e3o s\u00e3o sequenciais e, como resultado, s\u00e3o muito mais velozes em discos de acesso aleat\u00f3rio como SSDs, tanto SATA, PCIe e NVMe. Mesmo unidades flash dom\u00e9sticas possuem uma performance superior quando utilizados em uma m\u00e1quina com boa quantidade de mem\u00f3ria RAM (vide dica 1.1) frente aos discos r\u00edgidos de alta performance de servidores como SAS e SCSI.<\/p>\n<p>No entanto, enquanto os arquivos de dados beneficiam-se dos SSDs, os arquivos de log do MongoDB s\u00e3o bons candidatos para serem armazenados em discos tradicionais devido ao seu perfil de escrita sequencial, sendo que, quando necess\u00e1rio, o uso de RAID-10 \u00e9 o mais indicado para a maioria das aplica\u00e7\u00f5es.<\/p>\n<h3>#1.3 Use m\u00faltiplos cores<\/h3>\n<p>Pode soar um tanto \u00f3bvio, mas o MongoDB realmente opera melhor em ambientes com CPUs r\u00e1pidas e, especialmente, com a storage engine WiredTiger (a mais recente e recomendada na data que escrevo este artigo), pode-se tirar enorme proveito de multi-cores. Storage engines mais antigas como MMAPv1 n\u00e3o possuem esse mesmo benef\u00edcio com m\u00faltiplos processadores, possuindo aumento de desempenho insignificante em ambientes mais modernos.<\/p>\n<p>O uso de m\u00faltiplos cores, aliado ao modelo de concorr\u00eancia da WiredTiger, fazem com que m\u00faltiplas opera\u00e7\u00f5es concorrentes no seu banco de dados se tornem extremamente mais velozes do que em ambientes single core, na propor\u00e7\u00e3o de uma opera\u00e7\u00e3o concorrente por core.<br \/>\n<a name=\"aplica\u00e7\u00e3o\"><\/a><\/p>\n<h2>#2 Boas pr\u00e1ticas de aplica\u00e7\u00e3o<\/h2>\n<p>Ter o ambiente adequado para subir o seu banco de dados \u00e9 s\u00f3 a primeira etapa rumo a tirar o m\u00e1ximo proveito do MongoDB. Geralmente a constru\u00e7\u00e3o do ambiente adequado gera um custo direto que nos leva a crer (erroneamente) que \u00e9 o requisito mais caro de qualquer projeto &#8211; quando na verdade n\u00e3o \u00e9. A constru\u00e7\u00e3o correta da aplica\u00e7\u00e3o que consumir\u00e1 o banco de dados muitas vezes \u00e9 o que consome mais dinheiro a m\u00e9dio e longo prazo, embora seja um custo dilu\u00eddo ao longo do ciclo de vida do projeto.<\/p>\n<p>Neste t\u00f3pico, vamos ver algumas dicas de uso do MongoDB em suas aplica\u00e7\u00f5es, visando a maior performance poss\u00edvel do banco.<\/p>\n<h3>#2.1 Atualize apenas os campos alterados<\/h3>\n<p>O comando update do MongoDB recebe por padr\u00e3o o documento JSON, que ir\u00e1 substituir o atual com o mesmo _id usado como filtro, certo? No entanto, substitui\u00e7\u00e3o de documentos inteiros gera um overhead desnecess\u00e1rio no banco de dados e n\u00e3o \u00e9 recomendada.<\/p>\n<p>A boa pr\u00e1tica aqui \u00e9 utilizar os operadores de update para alterar somente os campos que de fato foram atualizados pela sua aplica\u00e7\u00e3o. Ou seja, se somente o nome do cliente foi editado, envie apenas essa altera\u00e7\u00e3o ao banco de dados, diminuindo com isso o tempo de update e o uso de rede.<\/p>\n<p>Relembrando os operadores de update:<\/p>\n<ul>\n<li><strong>$set:<\/strong> muda o valor de um campo;<\/li>\n<li><strong>$unset:<\/strong> remove um campo do documento;<\/li>\n<li><strong>$rename:<\/strong> muda o nome de um campo do documento;<\/li>\n<li><strong>$inc:<\/strong> quando um campo num\u00e9rico precisa ser incrementado (ou decrementado, usando um valor negativo);<\/li>\n<li><strong>$mul:<\/strong> quando um campo num\u00e9rico precisa ser multiplicado;<\/li>\n<\/ul>\n<p>Note que como o ACID do MongoDB \u00e9 garantido somente a n\u00edvel de documento, um banco com uma concorr\u00eancia grande pode ter problemas de update caso voc\u00ea opte apenas por utilizar o operador $set (que \u00e9 o mais simples). Especialmente em campos num\u00e9ricos que precisem ser alterados, d\u00ea prefer\u00eancia aos operadores $inc e $mul, que operar\u00e3o sobre o valor atual do campo, sem que voc\u00ea tenha de conhec\u00ea-lo com anteced\u00eancia o que poderia causar inconsist\u00eancias caso o update de outro usu\u00e1rio seja mais veloz no mesmo campo.<\/p>\n<h3>#2.2 Evite nega\u00e7\u00f5es em queries<\/h3>\n<p>Como a maioria das bases de dados, o MongoDB n\u00e3o indexa a aus\u00eancia de valores e condi\u00e7\u00f5es de nega\u00e7\u00e3o podem exigir que todos os documentos de uma cole\u00e7\u00e3o sejam analisados para dar um retorno \u00e0 query. Se a nega\u00e7\u00e3o \u00e9 a \u00fanica condi\u00e7\u00e3o e ela n\u00e3o \u00e9 seletiva (por exemplo, pesquisar uma cole\u00e7\u00e3o de pedidos onde 99% dos pedidos est\u00e3o finalizados para encontrar aqueles que n\u00e3o est\u00e3o), todos os registros ser\u00e3o escaneados em busca dos documentos que preencham a nega\u00e7\u00e3o.<\/p>\n<p>Embora n\u00e3o tenha como voc\u00ea fugir de algumas nega\u00e7\u00f5es de vez em quando, experimente usar mais os operadores $e, $in e $all do que o operador $ne, sendo o mais seletivo poss\u00edvel se quiser uma performance maior nas consultas. Modelar o banco j\u00e1 pensando nas consultas que ir\u00e1 fazer ajuda bastante, como ser\u00e1 discutido no t\u00f3pico 3.<\/p>\n<h3>#2.3 Analise o plano de execu\u00e7\u00e3o<\/h3>\n<p>Para cada query importante da sua aplica\u00e7\u00e3o e\/ou queries que estejam com mau desempenho, analise o plano de execu\u00e7\u00e3o da mesma usando a fun\u00e7\u00e3o explain() no final da chamada.<\/p>\n<p>Esta fun\u00e7\u00e3o exibe informa\u00e7\u00f5es sobre como a query ser\u00e1 (ou foi) executada, incluindo:<\/p>\n<ul>\n<li>N\u00famero de documentos retornados;<\/li>\n<li>N\u00famero total de documentos lidos;<\/li>\n<li>Quais \u00edndices foram utilizados;<\/li>\n<li>Se a consulta foi coberta, ou seja, se ela conseguiu retornar resultados sem ter de ler documentos;<\/li>\n<li>Se uma ordena\u00e7\u00e3o in-memory foi realizada, o que indica que a cria\u00e7\u00e3o de um \u00edndice poderia ser ben\u00e9fica;<\/li>\n<li>O n\u00famero de entradas do \u00edndice que foram escaneadas;<\/li>\n<li>Quanto tempo a consulta levou para retornar, em ms;<\/li>\n<li>Quais outros planos de execu\u00e7\u00e3o foram rejeitados pelo motor de consulta do Mongo, indicando ainda o tempo que essa decis\u00e3o levou, geralmente 0ms (o que indica menos que 1ms)<\/li>\n<\/ul>\n<p>A ferramenta <a href=\"https:\/\/www.mongodb.com\/download-center#compass\" target=\"_blank\" rel=\"noopener\">MongoDB Compass<\/a>, dispon\u00edvel nas assinaturas Enterprise e Professional do MongoDB, permite visualizar planos de execu\u00e7\u00e3o de uma maneira bem pr\u00e1tica e did\u00e1tica, sendo que cada est\u00e1gio do pipeline de execu\u00e7\u00e3o \u00e9 exibido como um n\u00f3 em uma \u00e1rvore, como mostra a figura abaixo:<br \/>\n<img decoding=\"async\" class=\"aligncenter wp-image-3057 size-full\" src=\"https:\/\/blog.umbler.com\/wp-content\/uploads\/2017\/09\/mongodb-compass.png\" alt=\"MongoDB Compass\" width=\"1442\" height=\"1000\" \/><\/p>\n<h3>#2.4 Configure a garantia de escrita apropriada<\/h3>\n<p>Muito se discute sobre a qualidade da persist\u00eancia de dados do MongoDB frente aos bancos relacionais mais maduros e l\u00edderes de mercado. No entanto, testes e mais testes comprovam que falhas de ACID geralmente s\u00e3o provocadas por m\u00e1 programa\u00e7\u00e3o, e n\u00e3o pelo banco de dados em si.<\/p>\n<p>Isso porque ao contr\u00e1rio dos bancos relacionais que possuem escrita bloqueante por natureza (e que voc\u00ea pode desabilitar manualmente com NOLOCKs), o MongoDB permite definir o n\u00edvel de garantia de persist\u00eancia com o que ele chama de \u201cwrite concerns\u201d. Essas configura\u00e7\u00f5es podem ser realizadas a n\u00edvel de banco, de cole\u00e7\u00e3o, de conex\u00e3o ou em uma granularidade extremamente fina: a cada opera\u00e7\u00e3o.<\/p>\n<p>Note que com grandes poderes vem grandes responsabilidades e definir o write concern correto cabe ao analista\/arquiteto respons\u00e1vel pela aplica\u00e7\u00e3o, sendo que a norma padr\u00e3o garante apenas performance gen\u00e9rica de escrita, mas que pode n\u00e3o atender ao seu caso espec\u00edfico, considerando a concorr\u00eancia de leitura e escrita do seu banco.<\/p>\n<p>As op\u00e7\u00f5es de write concerns s\u00e3o as seguintes:<\/p>\n<ul>\n<li><strong>Write Acknowledged:<\/strong> op\u00e7\u00e3o padr\u00e3o e mais veloz. O mongod confirma a execu\u00e7\u00e3o da opera\u00e7\u00e3o de escrita dos dados in-memory, permitindo ao cliente detectar rapidamente erros na opera\u00e7\u00e3o como chaves duplicadas, falhas de comunica\u00e7\u00e3o, etc.<\/li>\n<li><strong>Journal Acknowledged:<\/strong> o mongod confirma a opera\u00e7\u00e3o somente depois que ela foi registrada no log com sucesso, o que permite que ela sobreviva a uma queda do servi\u00e7o, garantindo maior durabilidade. Op\u00e7\u00e3o mais segura, mas mais lenta.<\/li>\n<li><strong>Replica Acknowledged:<\/strong> v\u00e1lido apenas quando se est\u00e1 trabalhando com &#8216;replica sets&#8217;. O mongod confirma que o dado n\u00e3o apenas foi escrito no log da r\u00e9plica primary como nas demais r\u00e9plicas (voc\u00ea pode configurar de quantas r\u00e9plicas quer a confirma\u00e7\u00e3o).<\/li>\n<li><strong>Majority:<\/strong> v\u00e1lido apenas para cen\u00e1rios com &#8216;replica sets&#8217;, definindo que a maioria das r\u00e9plicas tamb\u00e9m devem confirmar que realizaram a escrita dos dados e dos logs, sempre incluindo a r\u00e9plica primary.<\/li>\n<li><strong>Data Center Awareness:<\/strong> mais avan\u00e7ada de todas op\u00e7\u00f5es, permite customizar a garantia de escrita em ambientes multi-server.<\/li>\n<\/ul>\n<p>Caso n\u00e3o lembre como definir essas op\u00e7\u00f5es, consulte a documenta\u00e7\u00e3o oficial do MongoDB, mas a n\u00edvel de opera\u00e7\u00e3o. Por exemplo, pode ser feito passando um segundo par\u00e2metro para a fun\u00e7\u00e3o de escrita (insert, nesse caso). Nesse segundo par\u00e2metro voc\u00ea informa um objeto com o tipo de write concern (w:1 \u00e9 o padr\u00e3o) e se deve aguardar pela persist\u00eancia nos logs ou n\u00e3o (j:true).<\/p>\n<pre class=\"code-highlighter line-numbers theme-dark\"><code class=\"language-javascript\">&gt; db.collection.insert({data}, {w:1, j:true})\r\n<\/code><\/pre>\n<h3>#2.5 Use os drivers mais recentes<\/h3>\n<p>MongoDB possui drivers de conex\u00e3o para dezenas de linguagens de programa\u00e7\u00e3o. Estes drivers s\u00e3o criados pelos mesmos engenheiros que mant\u00e9m o kernel do banco de dados, mas tendem a ser atualizados de maneira mais constante do que o mesmo, tipicamente a cada dois meses. Sempre use a vers\u00e3o mais recente dos drivers para aproveitar ao m\u00e1ximo a estabilidade, performance e recursos implementados regularmente.<br \/>\n<a name=\"modelagem\"><\/a><\/p>\n<h2>#3 Boas pr\u00e1ticas de Modelagem e \u00edndices<\/h2>\n<p>O MongoDB usa um modelo de dados baseado em documentos bin\u00e1rios chamado BSON, que \u00e9 baseado no padr\u00e3o JSON. Ao inv\u00e9s das tabelas de uma base relacional, o modelo de dados em documentos do Mongo \u00e9 fortemente alinhado ao modelo de objetos usado nas linguagens de programa\u00e7\u00e3o modernas e na maioria dos casos n\u00e3o h\u00e1 a necessidade de transa\u00e7\u00f5es ou joins complexos devido \u00e0s vantagens de se ter os dados relacionados ao objeto dentro do pr\u00f3prio objeto (lembra-se de agrega\u00e7\u00e3o e composi\u00e7\u00e3o na disciplina de OO e Engenharia de Software?). Note como isso \u00e9 completamente diferente da divis\u00e3o em tabelas e os relacionamentos entre elas para compor um objeto na aplica\u00e7\u00e3o a partir do banco.<\/p>\n<p>No entanto, mesmo em tese sendo mais f\u00e1cil de modelar informa\u00e7\u00f5es em documentos do que em tabelas e relacionamentos, \u00e9 necess\u00e1rio conhecer algumas boas pr\u00e1ticas gerais e ter em mente que o analista\/arquiteto do banco de dados \u00e9 o \u00fanico que pode realmente dizer qual a melhor abordagem a ser tomada na modelagem e cria\u00e7\u00e3o de \u00edndices para uma aplica\u00e7\u00e3o em particular.<\/p>\n<h3>#3.1 Armazene todos os dados de uma entidade em um \u00fanico documento<\/h3>\n<p>Existem v\u00e1rios bons motivos para voc\u00ea seguir esta regra, mas vou citar os dois mais importantes: ACID e performance.<br \/>\nO MongoDB garante conformidade com ACID a n\u00edvel de documento. Se os dados da sua entidade estiverem espalhados entre diversos documentos, n\u00e3o h\u00e1 garantia alguma da consist\u00eancia e integridade entre eles. Se ele estiver espalhado entre diversas cole\u00e7\u00f5es, pior ainda: voc\u00ea corre o risco de perder a atomicidade tamb\u00e9m.<\/p>\n<p>Al\u00e9m disso, quando os dados do seu registro s\u00e3o armazenados todos dentro de um mesmo documento, voc\u00ea consegue retornar todos os dados do mesmo com uma \u00fanica consulta por _id no banco de dados, o que \u00e9 a forma mais eficiente de se retornar dados em qualquer banco. Se pegarmos um exemplo de ecommerce moderno, al\u00e9m do schema inst\u00e1vel que os grandes varejistas possuem e que complica a vida dos bancos relacionais, a tela de detalhes de um produto hoje em dia possui muitas informa\u00e7\u00f5es que podem ser armazenadas juntamente com o produto, tais como:<\/p>\n<ul>\n<li>reviews do produto;<\/li>\n<li>vers\u00f5es do produto;<\/li>\n<li>informa\u00e7\u00f5es de entrega;<\/li>\n<li>imagens;<\/li>\n<\/ul>\n<p>Enquanto que, em um banco relacional, todas essas informa\u00e7\u00f5es que possuem cardinalidade vari\u00e1vel virariam outras tabelas e usar\u00edamos chaves estrangeiras na tabela de produto, no Mongo podemos (e devemos) colocar todas em sub-documentos e campos multi-valorados sem problema algum. E esse \u00e9 um cen\u00e1rio real e comum mesmo aqui no Brasil, entre os grandes varejistas que j\u00e1 est\u00e3o utilizando bancos n\u00e3o-relacionais.<\/p>\n<p>No entanto, em alguns casos n\u00e3o \u00e9 muito pr\u00e1tico armazenar todos os dados em um \u00fanico documento, impactando negativamente em outras opera\u00e7\u00f5es como updates por exemplo. Lidar com esses trade-offs \u00e9 responsabilidade do analista\/arquiteto da aplica\u00e7\u00e3o.<\/p>\n<h3>#3.2 Evite documentos muito grandes<\/h3>\n<p>Apesar da premissa anterior de salvar todas as informa\u00e7\u00f5es de um registro no mesmo documento, tenha em mente que o tamanho m\u00e1ximo que o MongoDB suporta para um \u00fanico documento \u00e9 16MB (na data que escrevo este artigo). Na pr\u00e1tica, a maioria dos documentos ocupam apenas alguns KB, pois a analogia \u00e9 a de que um documento seria uma linha na tabela de um relacional &#8211; n\u00e3o use documentos como se fossem tabelas inteiras.<\/p>\n<p>Geralmente essa barreira de 16MB \u00e9 um problema, caso voc\u00ea deseje armazenar bin\u00e1rios em conjunto com seus dados, como v\u00eddeos e imagens. Neste caso use GridFS, uma conven\u00e7\u00e3o implementada por todos os drivers MongoDB que distribuem os bin\u00e1rios em documentos menores indexados pelo documento principal.<\/p>\n<p>Embora n\u00e3o seja uma recomenda\u00e7\u00e3o oficial, n\u00e3o vejo (e nunca vi) muito sentido em armazenar bin\u00e1rios no banco de dados, uma vez que voc\u00ea jamais vai consult\u00e1-los. Se \u00e9 apenas para r\u00e1pido retorno, usar arquivos est\u00e1ticos na nuvem com CDN \u00e9 muito r\u00e1pido atualmente. No entanto, podem existir cen\u00e1rios onde isso \u00e9 realmente necess\u00e1rio, ent\u00e3o tome cuidado com a limita\u00e7\u00e3o.<\/p>\n<h3>#3.3 Evite nomes de campos desnecessariamente longos<\/h3>\n<p>Os documentos BSON s\u00e3o schemaless, ou seja, n\u00e3o existem meta-informa\u00e7\u00f5es dos documentos salvas em uma tabela de schemas como no caso dos bancos relacionais. Enquanto que isso te torna mais livre para criar documentos com diferen\u00e7as entre eles e sem uma grande formaliza\u00e7\u00e3o dos dados, isso te cria um grande problema que \u00e9 o armazenamento dessas meta-informa\u00e7\u00f5es no pr\u00f3prio documento.<\/p>\n<p>Todos os nomes de campos s\u00e3o armazenados em cada um dos documentos, o que faz com que o consumo de espa\u00e7o em disco em um banco MongoDB geralmente seja muito maior do que em bancos relacionais, que fazem um uso mais inteligente desse recurso, evitando repeti\u00e7\u00f5es atrav\u00e9s de schemas e relacionamentos entre tabelas. Se voc\u00ea tem um milh\u00e3o de clientes armazenados em documentos, al\u00e9m dos valores dos campos, eles possuem armazenado o nome dos campos.<\/p>\n<p>Uma forma de minimizar esse problema \u00e9 usar nomes curtos, geralmente apenas as iniciais dos campos e atrav\u00e9s de programa\u00e7\u00e3o, fornecer APIs amig\u00e1veis para acesso e a manipula\u00e7\u00e3o dessas informa\u00e7\u00f5es nos seus objetos de aplica\u00e7\u00e3o (como gets e sets do Java, por exemplo, referenciando os nomes curtos).<\/p>\n<p>Em vers\u00f5es mais recentes do MongoDB, que possuem a storage engine WiredTiger, existe uma compress\u00e3o autom\u00e1tica de nomes grandes para que eles n\u00e3o prejudiquem tanto a performance do sistema.<\/p>\n<h3>#3.4 Mantenha a manuten\u00e7\u00e3o dos \u00edndices em dia<\/h3>\n<p>O uso de \u00edndices em MongoDB segue os mesmos princ\u00edpios dos bancos relacionais: melhoram a leitura e prejudicam a escrita dos dados. Sendo assim, caso possua \u00edndices que n\u00e3o est\u00e3o sendo utilizados, remova-os, para garantir que eles n\u00e3o atrapalhem a escolha dos planos de execu\u00e7\u00e3o pelo motor de consulta do Mongo e principalmente n\u00e3o prejudique a performance de inserts, updates, etc.<\/p>\n<p>Para entender o uso e determinar se um \u00edndice merece ou n\u00e3o existir, uma agrega\u00e7\u00e3o com $indexStats permite saber com que frequ\u00eancia os \u00edndices s\u00e3o atualizados, al\u00e9m de algumas ferramentas como MongoDB Compass lhe darem essa informa\u00e7\u00e3o de maneira rica e visual.<\/p>\n<p>Outra dica \u00e9 sempre verificar se a sua cole\u00e7\u00e3o n\u00e3o deveria ter um \u00edndice composto ao inv\u00e9s de v\u00e1rios \u00edndices individuais. Caso voc\u00ea possua consultas que sempre usam os mesmos campos, como filtro, e estes campos possuem \u00edndices que n\u00e3o s\u00e3o usados individualmente, opte por condens\u00e1-los em um \u00fanico \u00edndice composto que ser\u00e1 muito mais perform\u00e1tico.<\/p>\n<h2>Outras dicas gerais<\/h2>\n<p>Mais algumas dicas r\u00e1pidas e muito \u00fateis para quem est\u00e1 come\u00e7ando com MongoDB e n\u00e3o quer cometer alguns erros bem comuns:<\/p>\n<ul>\n<li>Evite campos multivalorados com muitos elementos, pois a performance em atualiza\u00e7\u00f5es e inser\u00e7\u00f5es vai ficando cada vez mais onerosa. Prefira campos definidos na raiz do documento;<\/li>\n<li>Evite express\u00f5es regulares sem in\u00edcio e\/ou fim (\u02c6 e $, respectivamente), uma vez que os \u00edndices s\u00e3o ordenados pelos valores, o que faz com que todo o \u00edndice tenha de ser percorrido em express\u00f5es regulares ineficientes como essas;<\/li>\n<li>Scripts complexos do banco de dados devem ser salvos em arquivos .js e versionados junto ao seu projeto da aplica\u00e7\u00e3o;<\/li>\n<li>Na d\u00favida de como modelar seu banco? Fa\u00e7a-o pensando na experi\u00eancia de consulta, que \u00e9 o foco do modelo orientado \u00e0 documentos;<\/li>\n<\/ul>\n<p>Estas foram algumas dicas e boas pr\u00e1ticas de uso do MongoDB. Embora n\u00e3o existam &#8220;verdades universais&#8221; quando o assunto s\u00e3o os bancos n\u00e3o-relacionais, as recomenda\u00e7\u00f5es oficiais s\u00e3o sempre um bom &#8220;norte&#8221; para quem est\u00e1 come\u00e7ando com tecnologias que n\u00e3o conhecemos bem e \u00e9 isso que quis trazer aqui hoje, sendo que todas essas dicas (e muitas outras), podem ser encontrados nos <a href=\"https:\/\/docs.mongodb.com\/\" target=\"_blank\" rel=\"noopener\">artigos t\u00e9cnicos do MongoDB<\/a>.<\/p>\n<p>Espero que tenham gostado. Se tiver outras dicas ou d\u00favidas, compartilhe nos coment\u00e1rios!<\/p>\n<div class=\"alert alert-success\"><strong>Ah, e n\u00e3o esque\u00e7a!<\/strong> MongoDB j\u00e1 est\u00e1 dispon\u00edvel na Umbler (e harmoniza perfeitamente com <a href=\"https:\/\/www.umbler.com\/br\/hospedagem-nodejs\" target=\"_blank\" rel=\"noopener\">aplica\u00e7\u00f5es Node.js<\/a>!) \ud83d\ude09<\/div>\n","protected":false},"excerpt":{"rendered":"<p>O MongoDB \u00e9 um banco de dados de c\u00f3digo aberto, gratuito, de alta performance, sem esquemas e orientado a documentos lan\u00e7ado em fevereiro de 2009 pela empresa 10gen. Foi escrito na linguagem de programa\u00e7\u00e3o C++ (o que o torna port\u00e1vel para diferentes sistemas operacionais) e seu desenvolvimento durou quase dois anos, tendo iniciado em 2007. [&hellip;]<\/p>\n","protected":false},"author":46,"featured_media":5287,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23],"tags":[112,277,256],"class_list":["post-3051","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev","tag-banco-de-dados","tag-mongodb","tag-node-js"],"_links":{"self":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts\/3051"}],"collection":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/users\/46"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/comments?post=3051"}],"version-history":[{"count":0,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/posts\/3051\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/media\/5287"}],"wp:attachment":[{"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/media?parent=3051"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/categories?post=3051"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.umbler.com\/br\/wp-json\/wp\/v2\/tags?post=3051"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}