Pesquisar este blog

sábado, 10 de setembro de 2016

Exemplo prático de banco de dados NOSql MongoDb no Java

Há alguns anos vem ganhando força, no mundo dos sistemas distribuídos, bancos de dados alternativos ao SQL, com isso surgiu o movimento de NoSQL( Not only SQL, ou não apenas SQL) que, ao contrário do que parece, não é um movimento de abolição do SQL, mas sim um movimento de utilização de alternativas, no armazenamento de dados. Os bancos de dados relacionais SQL são muito bons para armazenar alguns tipos de informação, como dados de estoque, cadastro de usuários, transações bancárias, porém com outros tipos de dados ele não performa muito bem, como armazenamento de imagens, páginas html e sistemas que possuem um fluxo de entrada de dados muito grande.

Classificação

Os bancos NoSQL podem ser classificados em:

Colunar

Estes tipos de bancos armazenam os dados de cada coluna separadamente, diferente do tipo de armazenamento padrão, onde cada linha é armazenada em um mesmo arquivo. Assim ao se fazer uma query selecionando algumas das colunas da sua tabela, o banco vai ter que ler somente aqueles arquivos que contém os dados das colunas e não precisará aplicar nenhum filtro.
Já em um banco comum ele deverá ler o arquivo com os dados de todas as colunas e depois aplicar um filtro para excluir os dados das colunas que não estão na query.
Performa muito bem em casos de queries que selecionam poucas colunas de tabelas grandes ou com muitas colunas e eles geralmente são usados em sistemas de BI.

Documental

Bancos de dados documentais são aqueles que armazenam documentos, ao invés de linhas em tabelas.
Estes bancos geralmente são schemaless, ou seja, não possuem esquema. Assim é possível inserir diversos tipos de dados diferentes, por exemplo, usuários, endereços, etc, em um mesmo local, ou com uma mesma definição de dados. Podemos ter um local de armazenamento chamado usuario, que recebe valores dos usuários, assim como valores do endereço.
Neste tipo de banco os dados armazenados pordem ser javascripts, JSONs, XML, etc e eles possuem diversas apis para se conectar com eles, REST, HTTP, Java, PHP, Python, C, etc.

Chave Valor ou Tuplas

Chave Valor é um tipo de armazenamento que funciona de maneira parecida com os mapas das linguagens de programação. Cada valor armazenado sempre terá uma chave, que será utilizada para recuperar aquele valor, e os dados.
Existem uma série de exemplos destes tipos de bancos, inclusive alguns que armazenam os dados apenas na memória das máquinas servindo como caches das aplicações.

Bancos de Grafos

Bancos de dados de grafos, armazenam os dados na forma de grafos e são muito úteis para armazenar a ligação entre os dados.
Este tipo de banco é muito utilizado para armazenar dados de redes sociais, por exemplo, um usuário X tem amizade com Y, Z e K, em um banco de dados de grafo, os dados dos usuários ficam armazenados, assim como a ligação entre eles e percorrer a distância entre um usuário e outro pode ser feita de uma maneira bem fácil.

Exemplo de NoSQL

Este post traz um exemplo de como usar um banco de dados NOSql em um sistema distribuído, usando como exemplo o MongoDb em um projeto Java.
O MongoDb é um banco de dados opensource que está classificado como um banco de documentos, já que ele armazena JSONs.

Databases

Neste banco temos databases, que são os container físicos dos dados. Cada database contém seus próprios arquivos no sistema der arquivos. Cada servidor pode possuir uma ou mais databases.

Collections

Uma collection é uma coleção de documentos do MongoDb, é o equivalente a uma tabela de um banco de dados SQL. Cada collection existe dentro de uma database e elas não possuem um esquema definido. Os documentos dentro de uma collection podem ter campos diferentes, mas cada um destes elementos geralmente são relativos a um mesmo propósito ou algo similar.

Documentos

Um documento é um par de chave valor, os quais não possuem um esquema, conforme explicado anteriormente, o que significa que documentos diferentes dentro de uma mesma collection podem ter campos diferentes e mesmo os campos iguais podem ser de tipos diferentes de dados.
Um exemplo de objeto armazenado no mongodb é mostrado abaixo:
{
   _id: ObjectId(57d0849edab45f72a3994895)
   titulo: 'Exemplo de MongoDB', 
   descricao: 'MongoDB é uma base NoSQL',
   por: 'Professor Dirceu Semighini Filho',
   site: 'http://www.dirceu.professor.blogspot.com.br',
   tags: ['mongodb', 'banco de dados', 'NoSQL'],
   likes: 100, 
   comentarios: [ 
      {
         usuario:'aluno1',
         mensagem: 'Comentário de exemplo',
         dataCriacao: new Date(2016,8,20,2,15),
         likes: 0 
      },
      {
         usuario:'aluno2',
         mensagem: 'Outro comentário de exemplo',
         dataCriacao: new Date(2016,8,25,7,45),
         likes: 5
      }
   ]
}
_id é um campo hexadecimal de 12 bytes, que deve ser único para cada documento, ele atua como se fosse uma chave primária destes objetos. Caso você não forneça um id o Mongo irá providenciar um, sendo que nesca caso os 4 primeiros bytes serão o timestamp atual, os 3 próximos bytes serão um id da máquina, os próximos 2 bytes serão o id do processo servidor do mongodb e os últimos 3 bytes é um número incremental.

Instalando o MongoDb no Linux

Para instalar o MongoDb no Linux, que seja derivado do Debian, digite no terminal:
 sudo apt-get install mongodb

Depois de instalado, para inicializar o serviço do mongo execute:
 sudo service mongodb start
Agora para executar o mongo basta digitar:
mongo
 Se a instalação ocorreu com sucesso, você irá ver o seguinte no terminal:
MongoDB shell version: 2.6.10
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user

Comandos úteis do MongoDb

db.help()
Mostra os comandos disponíveis na versão instalada do mongo.
db.stats()
Mostra estatísticas dos dados armazenados no banco.

Considerações sobre como desenvolver um banco no Mongo

Todos objetos que forem utilizados juntos, devem ser armazenados juntos, assim serão executadas menos requisições ao mongo para extrair os dados. Tenha certeza que não serão necessários executar joins para ler objetos do banco.
Dados podem ser duplicados, já que o custo do armazenamento é bem menor do que o custo do processamento dos dados. Porém, não se deve duplicar dados que são constantemente atualizados, já que isso implicaria em múltiplas atualizações para atualizar um mesmo objeto.
Joins devem ser feitos na escrita e não na leitura.
Faça otimizações no seu esquema, para os casos de uso mais frequentes.

Usando o Mongo

Para saber quais são as bases disponíveis na sua instância do Mongo use o comando:
show dbs
Para criar uma base de dados basta usar o comando use, como mostrado a seguir:
use dsd
Repare que caso você liste novamente as bases de dados, esta base dsd ainda não estará na lista de bases, para que isto aconteça você deve ter pelo menos um documento inserido nela, para fazer isto execute:
db.professor.insert({"nome":"Dirceu"})
Com isto criamos uma collection, que é equivalente a uma tabela no mongo, e inserimos dados nesta collection.
O MongoDb suporta os seguintes tipos de dados:

  • String : Este é o tipo de dados mais comum e no Mongo ela dever ser do tipo UTF-8 .
  • Integer : Usado para armazenar números no Mongo, um Integer pode ser 32 bit ou 64 bit depende do seu servidor.
  • Boolean : Armazena valores (true/ false).
  • Double : Usado para armazenar valores decimais.
  • Min/ Max keys : Usado para comparar valores entre o maior e o menor dos elementos BSON.
  • Arrays : Valor utilizado para armazenar mais de um valor, ou uma lista, dentro de uma mesma chave.
  • Timestamp : ctimestamp. Valor muito usado para armazenar quando o dado foi inserido, ou alterado.
  • Object : Usado para armazenar documentos embutidos.
  • Null : Valor de nulidade.
  • Symbol : Semelhante a String, porem é utilizado em linguas que possuem caracteres não UTF-8.
  • Date : Usado para armazenar a data local, no formato UNIX Time. Você pode criar um objeto Date passando pra ele o dia, o mês e o ano.
  • Object ID : Usado para armazenar o ID daquele valor.
  • Binary data : Armazena dados binários.
  • Code : Usado para armazenar código Javascript.
  • Regular expression : Usado para armazenar expressões regulares no banco.
Para listar as collections da base de dados que estamos usando faça:
db.getCollectionNames()
[ "professor", "system.indexes" ]
 Para apagar a sua base de dados, digite:
db.dropDatabase()
Após este comando, se digitarmos show dbs, ele não mostrará mais a base dsd na lista de bases disponíveis naquela instância do Mongo.
Para listar os dados de uma collection use o domando find, da seguinte maneira:
 db.professor.find()
{ "_id" : ObjectId("57d0849edab45f72a3994895"), "nome" : "Dirceu" }
Para apagar uma collection execute o comando drop:
db.professor.drop()
Com isto todos os dados presentes naquela collection serão eliminados do Mongo.

Usando o Mongo com o Java

Até agora foi mostrado como manipular os dados no Mongo na unha, agora serão mostrados exemplos com o Java. Os exemplos usados neste post estão no seguinte repositório.
Existem alguns objetos que serão usados para manipular os dados do Mongo no Java, mas antes de tudo deve-se adicionar o driver do Mongo como dependência do seu projeto, para fazer isto, adicione a dependência no seu build.sbt:
"org.mongodb" % "mongo-java-driver" % "2.10.1"
Dentre as classes que utilizaremos no nosso projeto, a primeira a ser estudada é o cliente do mongo, MongoClient, para criar uma instância dela fazermos:
MongoClient mongo = new MongoClient( host , port);
Por padrão a porta utilizada pelo mongo é a 27017, e o host será o localhost, isto para instâncias do mongo que estão rodando na sua máquina, caso você esteja usando um mongo de uma outra máquina, altere o localhost para o nome da máquina onde está rodando o MongoDb.
Com a instância do cliente do Mongo é possível pegar uma instância de uma base, também chamada de DB, para isso inclua no seu código a linha abaixo:
DB mongoDB = mongo.getDB(dbName);
No DB é possível acessarmos as collections daquele banco, para fazer isto executamos:
DBCollection collection = mongoDB.getCollection(collectionName);
Para acessar as collections usamos o nome da collection.
O objeto collection possui métodos para inserir (insert), remover (remove), achar (find) e atualizar (update), objetos daquela collection. Todos estes métodos recebem um BasicDBObject como argumento. Este BasicDBObject nada mais é do que um mapa, onde vamos inserindo os atributos do nosso objeto, comoMongoClient mongo = new MongoClient( host , port); mostrado abaixo:
BasicDBObject inserir = new BasicDBObject();
inserir.put("nomeDoCampo", valorDoCampo);
Para cada atributo do objeto, iremos executar uma chamada ao método put passando o nome do campo e o seu valor. Ao final basta chamar um:
collection.insert(inserir);
que o objeto será gravado na collection do Mongo.

Nenhum comentário:

Postar um comentário