Esses dias, após o Rails Summit, resolvi testar uma tecnologia que eu vi por lá e achei extremamente interessante: CouchDB.

O CouchDB, projeto hospedado no incubador do Apache, é um banco de dados não-relacional, com algumas características interessantes: ao invés de ordenar os dados por tabela, você ordena por documentos, define um “Tipo” no documento, e todos ficam por lá. Depois, para buscar os documentos que você quer, usa-se um conceito chamado de View – basicamente, uma sequencia de duas funções Javascript que criam um índice para seus documentos, e expoem eles. Seu formato nativo é JSON – ou seja, atributos multivalorados, hashes, dinamicamente tipado e tudo o mais. Um exemplo típico de registro:

{
  tipo: "Pessoa",
  nome: "Maurício Szabo"
  idade: 21
}

Para listar apenas as pessoas (indexando-as por nome, por exemplo), usa-se uma função Javascript semelhante com a seguinte:

function(doc) {
  if(doc.tipo && doc.tipo == "Pessoa") {
    emit(doc.nome, doc)
  }
}

Pensei com meus botões: “Puxa, que maravilha! Eu posso formatar no banco de dados os dados da forma que eu quero! E ele ainda indexa isso para mim!”. Aí, resolvi fazer uma experiência – portar o sistema de matrículas que desenvolvemos para CouchDB (afinal, eu não teria que me preocupar com validações, telas, HTML, etc, porque tudo isso já está pronto).

O primeiro problema foi na hora de modelar os dados – o CouchDB permite que um documento seja relativamente grande, mas no sistema que montamos era possível cadastrar horários das disciplinas em simultâneo! Eu não podia colocar tudo isso num documento Disciplina, porque poderia haver conflitos (duas pessoas editando a mesma disciplina, porém editando horários diferentes). Acabei modelando meio “relacional”, mas vi que essa era uma falha da forma como eu tinha pensado no sistema inicialmente.

O segundo problema foi na hora de buscar um período de matrícula – o CouchDB simplesmente não permite que eu busque usando dois campos! Logo, eu não poderia, por exemplo, buscar um periodo.inicio < Date.today && periodo.fim > Date.today. Perguntei para diversas pessoas uma solução, e todas me mandaram a mesma resposta: “Use Views!”. Como? Até que, finalmente, na lista de mensagens do CouchDB eu consegui uma resposta: “Use o Lucene (uma extensão do Couch) ou use Views, emitindo um registro para cada dia que for ser executado o período de matrícula”. Ou seja, se eu tivesse um período de matrícula que fosse do dia 10/01 até o 15/01, eu precisaria emitir, para cada período disponível no banco de dados, 5 índices. Bom, nem tentei o Lucene – se um banco de dados não faz essa coisa tão básica sozinho, eu realmente nem quero ver o restante dele.

Ah, sim, até tinha pensado em fazer um aplicativo (tipo Wiki) usando CouchDB – para ver se quando você usar algo mais com cara de “Documento” ele se sai melhor. Acabou que, se um artigo tem várias Tags, eu não consigo buscar todos os posts que possuem as tags “Ruby” e “Rails”, por exemplo – eu só consigo buscar uma por vez. Acabei desistindo do CouchDB, e agora estou estudando o MongoDB.

Sim, o MongoDB permite eu fazer essas coisas. O problema dele são os Mapeadores Objeto-Relacionais (que tentam, digamos, deixar o MongoDB com cara de banco de dados relacional). Estou inclusive montando meu próprio ORM para Ruby – MongoParadigm. Novidades em breve.


2 Comments

Lucas Renan · 2010-06-23 at 17:03

Maurício,

sinto lhe dizer que está um pouco equivocado com relação ao CouchDB.
Com relação ao seu primeiro “problema”, o CouchDB assim como outros bancos NoSQL tem a chamada consistência eventual, dessa forma certa responsabilidade é atribuída ao programador, ou seja, é responsabilidade do programador tratar os conflitos nos documentos.
Já no segundo problema, não é necessário utilizar Lucene para buscar as datas por um período, apenas (como te disseram) as views.
Você pode dar uma olhada em algo relacionado a views aqui: http://www.p3m.com.br/blog/order-by-no-couchdb/
Se você gerar chaves compostas como por exemplo [dia, mes, ano], fica extremamente fácil buscar utilizando os parâmetros startkey e endkey.
E eu acho que para utilizar o CouchDB é necessário uma quebra de paradigma, estamos muito acostumados ao modelo relacional e temos grande tendência a querer fazer as coisas como estamos acostumados, talvez seja por isso que muitas pessoas preferem utilizar o MongoDB, afinal o mongo tem certas características que lembram muito os bancos relacionais.

    Maurício Szabo · 2010-07-06 at 10:22

    Desculpe, mas todo mundo me disse “use views”, e quando eu tentei usá-las simplesmente não havia como compor uma query como citei: usando um CAMPO como startkey, e OUTRO como endkey. A informação para usar Lucene foi dada pelos próprios desenvolvedores do CouchDB, quando entrei em contato com eles.

Comments are closed.