Até pouquíssimo tempo, ao definir a arquitetura de um novo sistema, a única coisa da qual tínhamos certeza é que usaríamos um banco de dados relacional para guardar o estado do nosso sistema, independente de qual linguagem ou design iríamos usar. Esta única “certeza” talvez derive um tanto por causa dos fracassos que outras abordagens para armazenamento de dados estruturados tenham tido no passado (bancos hierárquicos complicados, bancos XML com performance ruim, bancos OO que nunca deixaram de ser vaporware…), mas principalmente por causa de uma atitude mezzo conservadora, mezzo “silver-bullet-driven” por parte do “mercado”, que preferiu assumir que bancos relacionais são a única solução decente e segura para armazenar dados.
O grande problema desta “verdade universal” é quando ela não se mostra tão universal assim (pois, como todos sabem, there is no silver bullet) e, por falta de um melhor repertório tecnológico ou por basear decisões técnicas em dogmas, acabam recorrendo a alguns “jeitinhos” que, no fundo no fundo, nada mais são do que dívidas técnicas (dívidas pesadas, como aquelas que você contrai quando pede dinheiro emprestado a um mafioso) que um dia vão ter que ser pagas (imagine os capangas do mafioso batendo à sua porta).

"Si, io *SEMPRE* usarei Oracle, Don Vito."
Exemplos destas dívidas técnicas não faltam por aí, mas vou citar dois cenários nada incomuns:
- Cenário: aplicação possui algumas entidades cujas estruturas não são bem definidas ou cujos atributos podem ser definidos/removidos pelo usuário final. Jeitinho: criar uma grande tabela do tipo chave-valor para armazenar o nome dos atributos, seus respectivos valores e a chave da entidade ao qual estes atributos pertecem. Problema: como seu banco se comporta quando você precisa fazer JOINs usando estas tabelas, que possuem centenas de milhões de registros?
- Cenário: aplicação permite que entidades sejam (re)definidas em tempo de execução pelo usuário. Jeitinho: (1) criar uma tabela nova para cada entidade (re)definida e (2) as informações sobre esta entidade (metadados) ficam guardadas em um outro conjunto de tabelas e… Problema: precisa explicar?
Provavelmente você deve estar rindo porque você já se deparou com alguma destas aberrações e que lhe tiraram boas horas de sono. Horas estas que poderiam muito bem ter sido poupadas se ferramentas certas fossem usadas. E é nesta hora que ampliar um pouco os horizontes e, neste caso, conhecer um pouco sobre NoSQL iria resolver sua vida.
NoSQLACID
NoSQL é o termo usado para se referir a um conjunto de novas tecnologias de armazenamento de dados que não seguem as regras estabelecidas pela álgebra relacional e podem não conter todas as propriedades que caracterizam um banco de dados relacional como transacional.
Na verdade, embora o termo leve “SQL” no nome, seria muito mais correto se o nome fosse NoACID, uma vez que, em troca de obter coisas como escalabilidade horizontal e/ou habilidade para lidar com imensos conjuntos de dados (e considere algo como imenso a partir do momento em que você tiver que movimentar algumas dezenas de Terabytes) de maneira muito rápida, estes bancos de dados NoSQL abrem mão de coisas como consistência e o tamanho do escopo de uma transação (explicações sobre isso ficam para um próximo post). E, para o contexto em estes bancos foram criados (a maioria nasceu como solução de armazenamento de informações para redes sociais ou sites de mídia), o trade-off ACID x escalabilidade valia muito a pena. Afinal de contas, ninguém vai morrer se o Orkut perder uma ou duas atualizações de profiles. Por outro lado, este mesmo trade-off não faz o menor sentido para uma aplicação de compensação financeira, por exemplo (se fizer sentido para você, diga-me para qual banco você trabalha, por favor).
Além da questão de consistência, outra característica comum e muito interessante destes bancos é o fato de eles serem schema-free, i.e., diferentemente de um banco de dados relacional, em que entidades são mapeadas como tabelas, que possuem uma estrutura de dados bem definida usando colunas (que possuem um tamanho fixo), um banco de dados não-relacional pode guardar um vários tipos de entidades cada qual com estruturas diferentes. Por exemplo, você pode ter uma entidade Pessoa no seu sistema, mas as instâncias desta entidade podem ter estruturas diferentes entre si.
E, por fim, embora o nome (banco de dados não-relacional) sugira erradamente que estes bancos não permitem relacionamento entre entidades, a maioria deles suporta os mesmos tipos de relacionamentos que bancos relacionais suportam (1-1, 1-N, N-M,…), apesar das implementações destas poderem diferir um pouco do jeito relacional de ser. Além disso, bancos orientados a documentos permitem um tipo de relacionamento que não existe em bancos relacionais que é a incorporação, ou seja, um documento pode embutir outros documentos em sua estrutura.
E por onde começar?
Primeiro de tudo, escolha uma das várias alternativas de bancos não-relacionais disponíveis por aí. Eu sou meio suspeito, gosto muito do MongoDB e do CouchDB, dois bancos de dados orientados a documentos e que usam Javascript como linguagem para manipulação de dados. Mas existem outras alternativas muito boas, como o Apache Cassandra, Riak ou Redis (que são do tipo key-value) ou o Neo4J (banco de dados de grafos). Em segundo lugar, esqueça por alguns instantes SQL, pare de pensar em forma de tabelas, projeções, JOINs, etc etc etc. Muitas vezes o desenho que estamos acostumados a dar às nossas entidades no mundo relacional são completamente diferentes do desenho a que teremos numa abordagem orientada a documentos, por exemplo. E, por fim, não entre no hype do NoSQL e comece a tentar enfiar bancos não-relacionais em qualquer lugar porque nem sempre eles serão a melhor solução. NoSQL não é silver bullet