Explorando o CouchDB

Um banco de dados orientado a documentos para aplicativos da Web

Bancos de dados relacionais definem uma rígida estrutura e fornecem uma maneira de manter dados para um aplicativo de software. O CouchDB de software livre da Apache oferece um novo método para armazenar dados, o que é referido como um modelo de banco de dados orientado a documentos livre de esquema. Em vez de o armazenamento de dados altamente estruturado de um modelo relacional, o CouchDB armazena dados de maneira semiestruturada, usando um modelo de visualização baseado em JavaScript para gerar agregação estruturada e resultados de relatórios a partir desses documentos semiestruturados. O CouchDB foi desenvolvido a partir da base com aplicativos da Web como o principal foco e tem como meta tornar-se o banco de dados de fato para desenvolvimento de aplicativos da Web.

Joe Lennon, Software developer, Core International

Joe Lennon photoJoe Lennon, 24 anos, é desenvolvedor de software em Cork, Irlanda. Autor do livro Beginning CouchDB da Apress (ainda não publicado), tem colaborado com o IBM developerWorks com diversos artigos técnicos e tutoriais. Em seu tempo livre, Joe gosta de jogar futebol, mexer em pequenos mecanismos e bater seus recordes em seu Xbox 360.


nível de autor Contribuidor do
        developerWorks

31/Mar/2009

O que é o CouchDB?

CouchDB é um sistema de software livre de gerenciamento de banco de dados orientado a documentos que pode ser acessado através da API de JavaScript Object Notation (JSON) RESTful. O termo "Couch" é um acrônimo para "Cluster Of Unreliable Commodity Hardware", que reflete a meta do CouchDB de ser extremamente escalável, oferecendo alta disponibilidade e confiabilidade, mesmo ao executar em hardware que está geralmente sujeito à falhar. O CouchDB foi gravado originalmente em C++, mas em abril de 2008, o projeto foi movido para a plataforma Erlang OTP devido à sua ênfase em tolerância a falhas.

O CouchDB pode ser instalado na maioria dos sistemas POSIX, incluindo Linux® e Mac OS X. Apesar de o Windows® não ser atualmente suportado oficialmente, está sendo realizado um trabalho em um instalador binário não oficial para a plataforma Windows. O CouchDB pode ser instalado a partir da origem ou, quando disponível, pode ser instalado usando um gerenciador de pacote (por exemplo, MacPorts no Mac OS X).

O CouchDB é um projeto de software livre de alto nível da Apache Software Foundation, liberado sob a V2.0 da licença Apache. Essa licença de software livre permite que o código de origem seja usado e modificado para ser usado em outro software, desde que o aviso de copyright e a renúncia de responsabilidade sejam preservados. Como a maioria das licenças de software livre, permite que o software seja usado, modificado e distribuído por usuários conforme necessário. Quaisquer modificações não precisam ser disponibilizadas sob a mesma licença, desde que um aviso de uso do código licenciado da Apache seja mantido.


Diferenças entre um Banco de Dados Orientado a Documentos e um Relacional

Para muitos, o conceito de um sistema de gerenciamento de banco de dados orientado a documentos é difícil de entender no início, principalmente, se estiverem trabalhando com sistemas de gerenciamento de banco de dados relacional há muito tempo. A razão por trás disso é que as semelhanças entre os dois modelos são raras.

Um banco de dados orientado a documentos é, não surpreendentemente, formado por uma série de documentos autocontidos. Isso significa que todos os dados para o documento em questão estão armazenados no próprio documento — não em uma tabela relacionada como seria em um banco de dados relacional. Na verdade, não há nenhuma tabela, linha, coluna ou relacionamento em um banco de dados orientado a documentos. Isso significa que são livres de esquema; não é necessário definir nenhum esquema rígido antes de realmente usar o banco de dados. Se um documento precisar incluir um novo campo, pode simplesmente incluir esse campo, sem afetar de forma adversa outros documentos do banco de dados. Além disso, os documentos não precisam armazenar valores de dados vazios para campos para os quais não possuem um valor.

O manual a ser lançado CouchDB: The Definitive Guide (consulte Recursos) usa o exemplo de um cartão de visita como um "documento do mundo real" e descreve como isso seria descrito em um banco de dados orientado a documentos em comparação a um relacional. No banco de dados relacional, é possível ter quatro ou mais tabelas para armazenar esses dados: uma para "Pessoa", uma para "Empresa", uma para "Detalhes do Contato" e uma para o próprio cartão de visita. Elas todas teriam colunas e chaves rigidamente definidas e os dados seriam montados usando uma série de junções.

Apesar de isso fornecer a vantagem de ter uma única entrada para cada dado sem possibilidade de repetição, se houver necessidade de modificação posteriormente, será uma tarefa rígida e difícil. Isso também significa que o registro não pode ser adaptado para diferentes circunstâncias. Por exemplo, uma pessoa pode ter um número de fax, enquanto outra pode não ter. Em um cartão de visita, não apareceria "Fax: Nenhum", simplesmente, não seria mostrado nenhum detalhe de fax.

Em um banco de dados orientado a documentos, cada cartão de visita seria mantido em seu próprio documento, cada um dos quais podendo definir os campos que deseja usar. Portanto, a pessoa sem um número de fax não precisa definir um valor de fax, enquanto que a pessoa com um número de fax está livre para defini-lo se quiser.

Outra diferença entre esses tipos de bancos de dados está no armazenamento de identificadores exclusivos. É comum que os bancos de dados relacionais usem o conceito de chaves primárias, gerados por um recurso de incremento automático ou por um gerador de sequência. É claro que esses identificados são exclusivos somente para a tabela ou o banco de dados no qual são usados — podem ser reutilizados por outras tabelas e bancos de dados. Se uma operação de atualização for feita ao mesmo tempo em dois bancos de dados em redes separadas, ambos não podem recuperar precisamente o próximo identificador exclusivo. O CouchDB não é fornecido com um recurso de incremento automático ou de sequência. Em vez disso, designa um Universally Unique Identifier (UUID) para todo e qualquer documento, tornando praticamente impossível que outro banco de dados selecione acidentalmente o mesmo identificador exclusivo.

Outra diferença chave entre os bancos de dados orientados a documentos e os relacionais é que os bancos de dados orientados a documentos não suportam junções. Isso é uma consequência de não haver nenhuma chave primária nem estrangeira no CouchDB. Não há chaves parabasear as junções. Isso não significa que não seja possível recuperar um conjunto de dados relacionados a partir de um banco de dados CouchDB. Um recurso chamado de visualização permite criar uma relação arbitrária entre documentos que não está realmente definida no próprio banco de dados. Isso significa que é possível obter todos os benefícios de consultas de junções SQL típicas sem o peso de predefinir seus relacionamentos na camada do banco de dados.

É importante observar que, apesar de bancos de dados orientados a documentos operarem de maneira diferente dos bancos de dados relacionais, não parecem ser uma substituição viável. O CouchDB não tenta oferecer uma substituição para os bancos de dados relacionais, mas, em vez disso, oferece uma alternativa para os projetos em que um modelo orientado a documentos é mais adequado do que um banco de dados relacional tradicional, como wikis, blogs e sistemas de gerenciamento de documentos.


Como o CouchDB Funciona

O CouchDB é construído em um poderoso mecanismo de armazenamento B-tree, que é responsável por manter os dados do CouchDB classificados e fornece um mecanismo para procurar, inserir e excluir em tempo amortizado de forma logarítmica. O CouchDB usa esse mecanismo para todos os dados internos, documentos e visualizações.

Devido à maneira livre de esquema na qual o banco de dados está estruturado, o CouchDB depende do uso de visualizações para criar relacionamentos arbitrários entre documentos e para fornecer recursos de agregação e relatório. Os resultados dessas visualizações são computados usando Mapear/Reduzir, um modelo para processar e gerar grandes conjuntos de dados usando computação distribuída. O modelo Mapear/Reduzir foi introduzido pela Google e pode ser dividido na etapa Mapear e na etapa Reduzir. Na etapa mapear, o documento é captado pelo nó principal e o problema é dividido em subproblemas. Esses subproblemas são, então, distribuídos por nós trabalhadores, que solucionam o problema e retornam os resultados ao nó principal. Na etapa reduzir, o nó principal capta os resultados recebidos dos nós trabalhadores e combina os mesmos para obter um resultado geral e resposta para o problema original.

As funções Mapear/Reduzir no CouchDB produzem pares de chave/valor, permitindo que o CouchDB insira-os no mecanismo B-tree, classificados por chaves. Isso permite consultas ultraeficientes por chave e aprimora o desempenho de operações no B-tree. Além disso, isso também significa que os dados podem ser particionados por muitos nós sem interferir com a capacidade de consultar cada nó individualmente.

Os sistemas de gerenciamento de banco de dados relacional tradicionais às vezes usam bloqueio para gerenciar simultaneidade, impedindo que clientes acessem dados enquanto outro cliente está atualizando esses dados. Isso impede que diversos clientes façam mudanças no mesmo conjunto de dados ao mesmo tempo, mas em situações que há muitos clientes usando o sistema simultaneamente, é bem comum que o banco de dados trave ao determinar qual cliente deve receber o bloqueio e manter a ordem da fila de bloqueio. No CouchDB, não há nenhum mecanismo de bloqueio, em vez disso, usa-se um método referido como Multiversion concurrency control (MVCC) — onde cada cliente recebe uma captura instantânea da versão mais recente do banco de dados. Isso significa que nenhuma mudança é vista pelos outros usuários até a transação ter sido consolidada. A maioria dos bancos de dados modernos começaram a mudar de mecanismos de bloqueio para MVCC, incluindo o Oracle (desde a V7), o MySQL (quando usado com InnoDB) e o Microsoft® SQL Server 2005 e posterior.


Documentos: Os Blocos de Construção de um Banco de Dados CouchDB

Os bancos de dados CouchDB armazenam documentos denominados exclusivamente e fornecem uma API de JSON RESTful que permitem que aplicativos leiam e modifiquem esses documentos. Todos os dados de um banco de dados CouchDB são armazenados em um documento e cada documento pode ser formado por um número indefinido de campos. Isso significa que cada documento pode ter campos que não são definidos em outros documentos. Ou seja, os documentos não estão ligados a um esquema rígido de banco de dados.

Cada documento pode conter metadados (dados sobre os dados), como um ID de documento exclusivo e números de revisão. Os campos do documento podem conter diversos tipos de dados, como cadeias de texto, números, valores booleanos (true/false), etc. Os campos não são ligados a um limite de tamanho. Cada campo deve receber um nome exclusivo (os documentos não podem ter dois campos com o mesmo nome).

Quando são feitas mudanças em um documento do CouchDB, as mudanças não são realmente anexadas ao documento existente, mas, em vez disso, uma nova versão de todo o documento, chamada revisão, é criada. Isso significa que um histórico completo de modificações de documentos é mantido automaticamente pelo banco de dados. O sistema de revisão de documento funciona de forma semelhante a como um wiki ou o sistema de gerenciamento de documento baseado na Web gerencia o controle de revisão, exceto por tudo ser tratado automaticamente no nível do banco de dados.

O CouchDB não possui mecanismos de bloqueio; dois clientes podem carregar e editar o mesmo documento ao mesmo tempo. No entanto, se um cliente salvar suas mudanças, o outro cliente receberá um conflito de edição ao tentar salvar suas mudanças. Esse conflito pode ser resolvido carregando a versão mais nova do documento, aplicando novamente as edições e tentando salvar novamente. O CouchDB mantém consistência de dados assegurando que as atualizações de documento sejam tudo ou nada — funcionam ou falham. Nunca haverá um documento parcialmente salvo no banco de dados.


Visualizações: Obtendo Informações Úteis do CouchDB

O CouchDB é de natureza desestruturada e, embora sua falta de um esquema rígido forneça benefícios em termos de flexibilidade e escalabilidade, pode ser bem difícil de realmente usar em aplicativos no mundo real. Quando se pensa em um banco de dados relacional, é possível ver que, para aplicativos do dia-a-dia, o relacionamento entre tabelas definidas rigidamente é importante para dar sentido aos dados. No entanto, quando alto desempenho é necessário, visualizações materializadas são criadas para desnormalizar os dados. Muitas vezes, o banco de dados orientado a documentos faz as coisas ao contrário. Armazena seus dado em um espaço de endereço simples, bem semelhante a um armazém de dados completamente desnormalizado. Fornece um modelo de visualização para incluir estrutura nos dados de forma que possa ser agregada para fornecer significado útil.

Visualizações no CouchDB são criadas on demand e podem ser usadas para agregar, juntar e relatar sobre documentos do banco de dados. Elas são construídas dinamicamente e não têm nenhum efeito nos documentos do banco de dados. As visualizações são definidas em documentos de design e podem ser replicadas em instâncias. Esses documentos de design contêm funções JavaScript que executam consultas usando o conceito MapReduce. A função mapear da visualização usa o documento como um argumento e executa uma série de computações para determinar quais dados devem estar disponíveis através da visualização. Se uma visualização tiver uma função reduzir, é usada para agregar os resultados. Recebe um conjunto de chaves e valores e combina os mesmos em um único valor.

A Lista 1 é um exemplo das funções mapear e reduzir de uma visualização do CouchDB que conta o número de documentos que têm um anexo.

Lista 1. Uma Visualização Típica do CouchDB
map: function(doc) {
  if (doc._attachments) {
    emit("with attachment", 1);
  }
  else {
    emit("without attachment", 1);
  }
}
reduce: function(keys, values) {
   return sum(values);
}

As visualizações do CouchDB podem ser visualizações permanentes armazenadas dentro do documento de design ou visualizações temporárias executadas on demand. As visualizações temporárias exigem muitos recursos e se tornam mais lentas à medida que a quantidade de dados armazenados no banco de dados aumenta. Por essa razão, as visualizações do CouchDB devem, em grande parte, ser criadas em documentos de design.


A API de JSON RESTful

O CouchDB oferece uma API como um meio para recuperar dados do banco de dados. Essa API pode ser acessada através de pedidos HTTP GET e POST e retorna dados no formato de objetos JavaScript usando JSON. Isso facilita a execução de operações do banco de dados, independentemente da linguagem na qual seu aplicativo é desenvolvido. É possível simplesmente usar uma estrutura JavaScript com objetos de pedido Ajax, como Prototype, JQuery ou ExtJS — não há necessidade para uma linguagem do lado do servidor para seus aplicativos da Web.

Por questão de simplicidade e para ilustrar as respostas JSON brutas emitidas pela API, vamos usar a ferramenta de linha de comando curl neste artigo. Isso permite emitir os pedidos GET, POST, PUT e DELETE e exibe a resposta HTTP bruta recebida do servidor da Web (neste caso, um servidor CouchDB instalado localmente).

O pedido curl http://127.0.0.1:5984/ retorna a seguinte resposta: {"couchdb":"Welcome","version":"0.8.1-incubating"}. Essa chamada de API simples é um pedido GET simples, com a resposta informando a versão instalada do CouchDB. Para definir explicitamente o tipo de pedido que está sendo feito, vamos usar o parâmetro -X de curl, como no pedido a seguir: curl -X GET http://127.0.0.1:5984/_all_dbs. Isso retorna o seguinte resultado: [].

Neste exemplo, solicitamos um URI de uma visualização especial do CouchDB que retorna uma lista de todos os bancos de dados no servidor do CouchDB. Se tivéssemos realmente criado bancos de dados, isso teria retornado uma array de nomes de bancos de dados. Nesta instância, retornou uma array JavaScript vazia. Agora, vamos criar dois bancos de dados e da próxima vez que executarmos esse pedido, deveremos ver um resultado diferente: curl -X PUT http://127.0.0.1:5984/fruit.

A resposta recebida é: {"ok":true}. Em seguida, emitimos um segundo pedido: curl -X PUT http://127.0.0.1:5984/vegetables e recebemos a mesma resposta que antes. Agora, vamos solicitar uma lista de bancos de dados novamente: curl -X GET http://127.0.0.1:5984/_all_dbs. Desta vez, obtemos um melhor resultado do que antes: ["fruit","vegetables"].

Quando criamos esses bancos de dados, eles retornaram um atributo "ok" com um valor booleano igual a true. Isso indica que a operação foi bem-sucedida. Mas o que acontece se as coisas não saírem conforme planejado? Para tentar fazer com que o servidor do CouchDB cometa um erro, vamos tentar criar um banco de dados com o mesmo nome que um dos bancos de dados existentes: curl -X PUT http://127.0.0.1:5984/fruit.

Desta vez, obtemos a seguinte resposta: {"error":"database_already_exists","reason":"Database \"fruit\" already exists."}.

Como pode ver, o CouchDB tentou criar o banco de dados, mas encontrou um erro no processo. Como resultado, retornou um atributo "error" com o valor do código de erro encontrado — neste caso, "database_already_exists". É claro que em um aplicativo no mundo real, executaríamos uma verificação da existência de um atributo error em todas as respostas do servidor do CouchDB e exibiríamos uma mensagem de erro fácil e simples sobre o código de erro localizado.

Digamos que não precisamos mais do banco de dados vegetables e queremos removê-lo. Para excluir um banco de dados do CouchDB, simplesmente emitimos o pedido HTTP DELETE com o nome do banco de dados anexado a nosso URI base, como no exemplo a seguir: curl -X DELETE http://127.0.0.1:5984/vegetables. Isso fornece a mesma resposta bem-sucedida que os pedidos PUT executados anteriormente. Agora, vamos recuperar uma lista de bancos de dados usando: curl -X GET http://127.0.0.1:5984/_all_dbs. Isso fornece a seguinte resposta: ["fruit"].

O que há de bom em um banco de dados se não possui nenhum dado? A resposta na Lista 2 cria um documento chamado "apple".

Lista 2. Criando um Documento Chamado Apple
curl -X PUT http://127.0.0.1:5984/fruit/apple \
-H "Content-Type: application/json" -d {}

O servidor responde o seguinte: {"ok":true,"id":"apple","rev":"1801185866"}.

Agora que criamos um documento, vamos recuperá-lo do banco de dados: curl -X GET http://127.0.0.1:5984/fruit/apple. O CouchDB responde o seguinte: {"_id":"apple","_rev":"1801185866"}.

A chamada final da API que faremos é uma que recupera informações sobre um banco de dados específico — nesta instância, o banco de dados fruit: curl -X GET http://127.0.0.1:5984/fruit. A resposta recebida do servidor informa algumas informações interessante sobre o banco de dados.

Lista 3. Resposta do Servidor
{"db_name":"fruit","doc_count":1,"doc_del_count":0,"update_seq":1,
"compact_running":false,"disk_size":14263}

Nesta seção, exploramos diversos métodos de API disponíveis através da interface da API de JSON RESTful fornecida pelo CouchDB. No mundo real, não estaríamos codificando esses pedidos HTTP manualmente, mas nossa linguagem de programação ou de script de opção faria isso.

O CouchDB também inclui um aplicativo da Web chamado Futon, que pode ser usado como uma ferramenta de administração do CouchDB, permitindo manter os bancos de dados, os documentos e as revisões dos documentos para sua plena satisfação. Caso tenha instalado o CouchDB em sua máquina local na porta padrão 5984, é possível acessar o Futon apontando seu navegador para: http://127.0.0.1:5984/_utils/. A Figura 1 ilustra o Futon em ação.

Figura 1. O Utilitário Futon do CouchDB em Ação
O utilitário CouchDB Futon em ação

A API RESTful fornecida pelo CouchDB pode ser desanimadora inicialmente para aqueles acostumados a sistemas de gerenciamento de banco de dados relacional, mas fornece um meio exclusivo e extremamente acessível de interação com o banco de dados. Os sistemas de banco de dados tradicionais geralmente exigiam uma conexão com o banco de dados usando alguma forma de cliente SQL, que, então, aceitaria uma série de instruções SQL para recuperar dados e executar operações Create, Update, Delete (CRUD). Graças a API de JSON RESTful, os usuários podem conectar ao CouchDB usando qualquer software que suporte i protocolo HTTP. Na verdade, a maioria das linguagens de programação e script fornecem alguma forma de interface ao protocolo HTTP, o que significa que o CouchDB pode ser usado na praticamente qualquer projeto de desenvolvimento.


Resumo

O projeto Apache CouchDB ainda está no começo. O CouchDB ainda é considerado muito como um software alfa. Posto isso, o CouchDB está se tornando cada vez mais popular em aplicativos da Web, aplicativos para iPhone e aplicativos do Facebook. Até o momento, poderosos software de wiki, blog, fórum de discussão e gerenciamento de documentos conseguiram soluções alternativas para que os bancos de dados relacionais armazenem dados orientados a documentos, da forma mais eficiente possível. À medida que releases mais estáveis do CouchDB são disponibilizados, no entanto, torna-se uma proposta mais atraente como a opção de banco de dados subjacente para esses tipos de software, removendo o esforço de gerenciamento de revisão de documentos e alterando continuamente os requisitos.

De forma geral, a reação ao CouchDB até agora tem sido principalmente positiva, apesar de muitos sentirem repetidamente a necessidade de discutir em blogs e fóruns qual é melhor — relacional ou orientado a documentos. O simples fato da questão é que o CouchDB nunca alegou ser uma substituição para os bancos de dados relacionais nem que seria o novo padrão para desenvolvimento de banco de dados. É claro que em muitos cenários a pura simplicidade do CouchDB não pode corresponder ao poder oferecido pelos semelhantes ao DB2 e ao Oracle. Mas, em muito outros cenários, a simplicidade do banco de dados é exatamente o que se precisa e ofertas tradicionais de RDBMS são muito inchadas e exigem muitos recursos para a tarefa em questão.

Recursos

Aprender

Obter produtos e tecnologias

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Software livre
ArticleID=394412
ArticleTitle=Explorando o CouchDB
publish-date=03312009