2.1 Surgimento do termo NoSQL

Recentemente, o termo "NoSQL" tornou-se muito popular e popular, todos os tipos de soluções de software estão sendo ativamente desenvolvidos e promovidos sob este signo. NoSQL tornou-se sinônimo de grandes quantidades de dados, escalabilidade linear, clusters, tolerância a falhas, não relacionalidade. No entanto, poucas pessoas têm uma compreensão clara do que é armazenamento NoSQL, como surgiu o termo e quais características comuns eles possuem. Vamos tentar preencher esta lacuna.

O mais interessante sobre o termo é que, apesar de ter sido usado pela primeira vez no final dos anos 90, só adquiriu real significado na forma como é usado agora em meados de 2009. Inicialmente, esse era o nome de um aberto - banco de dados de origem criado por Carlo Strozzi, que armazenava todos os dados como arquivos ASCII e usava scripts de shell em vez de SQL para acessar os dados. Não tinha nada a ver com "NoSQL" em sua forma atual.

Em junho de 2009, Johan Oskarsson organizou uma reunião em São Francisco para discutir as novas tendências no mercado de armazenamento e processamento de TI. O principal impulso para a reunião foram os novos produtos de código aberto, como BigTable e Dynamo. Para um sinal brilhante para uma reunião, foi necessário encontrar um termo amplo e conciso que se encaixasse perfeitamente na hashtag do Twitter. Um desses termos foi proposto por Eric Evans da RackSpace - "NoSQL". O termo foi planejado para apenas uma reunião e não tinha uma carga semântica profunda, mas aconteceu que se espalhou pela rede global como um anúncio viral e se tornou o nome de fato de toda uma tendência na indústria de TI. A propósito, Voldemort (clone do Amazon Dynamo), Cassandra, Hbase (análogos do Google BigTable), Hypertable, CouchDB, MongoDB falaram na conferência.

Vale ressaltar mais uma vez que o termo "NoSQL" é de origem totalmente espontânea e não possui uma definição geralmente aceita ou instituição científica por trás dele. Esse nome caracteriza o vetor de desenvolvimento de TI longe dos bancos de dados relacionais. Significa Not Only SQL, embora existam defensores da definição direta de No SQL. Pramod Sadalaj e Martin Fowler tentaram agrupar e sistematizar o conhecimento sobre o mundo NoSQL em seu recente livro "NoSQL Distilled".

2.2 Características básicas dos bancos de dados NoSQL

Existem poucas características comuns para todos os NoSQL, já que muitos sistemas heterogêneos agora estão ocultos sob o rótulo NoSQL (talvez a lista mais completa possa ser encontrada em http://nosql-database.org/). Muitas características são peculiares apenas a determinados bancos de dados NoSQL, com certeza vou mencionar isso ao listar.

1. Nenhum SQL é usado

Quero dizer ANSI SQL DML, já que muitos bancos de dados tentam usar linguagens de consulta semelhantes à conhecida sintaxe favorita, mas ninguém conseguiu implementá-la totalmente e é improvável que tenha sucesso. Embora existam rumores de startups que estão tentando implementar o SQL, por exemplo, em hadup ( http://www.drawntoscalehq.com/ e http://www.hadapt.com/ ).

2. Não estruturado (sem esquema)

O significado é que em bancos de dados NoSQL, ao contrário dos bancos de dados relacionais, a estrutura de dados não é regulada (ou fracamente digitada, se fizermos analogias com linguagens de programação) - você pode adicionar um campo arbitrário em uma linha ou documento separado sem primeiro alterar declarativamente a estrutura de toda a mesa. Assim, se houver necessidade de alterar o modelo de dados, a única ação suficiente é refletir a alteração no código do aplicativo.

Por exemplo, ao renomear um campo no MongoDB:

BasicDBObject order = new BasicDBObject();
order.put("date", orderDate); // this field was a long time ago
order.put("totalSum", total); // before we just used "sum"

Se alterarmos a lógica do aplicativo, esperamos um novo campo também durante a leitura. Mas devido à falta de um esquema de dados, o campo totalSum está ausente de outros objetos Order já existentes. Nesta situação, existem duas opções para ação adicional.

A primeira é rastrear todos os documentos e atualizar este campo em todos os documentos existentes. Devido ao volume de dados, este processo ocorre sem bloqueios (comparável ao comando alter table rename column), portanto, durante a atualização, os dados já existentes podem ser lidos por outros processos. Portanto, a segunda opção - verificar o código do aplicativo - é inevitável:

BasicDBObject order = new BasicDBObject();
Double totalSum = order.getDouble("sum"); // This is the old model
if (totalSum  == null)
totalSum = order.getDouble("totalSum"); // This is the updated model

E já quando regravamos, vamos gravar este campo no banco de dados em um novo formato.

Uma consequência agradável da ausência de um esquema é a eficiência de trabalhar com dados esparsos. Se um documento tiver um campo date_published e o segundo não, nenhum campo date_published vazio será criado para o segundo. Isso, em princípio, é lógico, mas um exemplo menos óbvio são os bancos de dados NoSQL de família de colunas, que usam os conceitos familiares de tabelas/colunas. No entanto, devido à falta de um esquema, as colunas não são declaradas declarativamente e podem ser alteradas/adicionadas durante uma sessão de banco de dados do usuário. Isso permite, em particular, o uso de colunas dinâmicas para a implementação de listas.

O esquema não estruturado tem suas desvantagens - além da sobrecarga mencionada acima no código do aplicativo ao alterar o modelo de dados - a ausência de todos os tipos de restrições da base (não nulo, exclusivo, restrição de verificação etc.), além de haver existem dificuldades adicionais em entender e controlar os dados da estrutura ao trabalhar com o banco de dados de diferentes projetos em paralelo (não há dicionários ao lado do banco de dados). No entanto, em um mundo moderno em rápida mudança, essa flexibilidade ainda é uma vantagem. Um exemplo é o Twitter, que há cinco anos, junto com o tweet, armazenava apenas um pouco de informação adicional (hora, identificador do Twitter e mais alguns bytes de metainformação), mas agora, além da própria mensagem, mais alguns kilobytes de metadados são armazenados no banco de dados.

(Daqui em diante, estamos falando principalmente de valores-chave, documentos e bancos de dados de família de colunas, bancos de dados gráficos podem não ter essas propriedades)

2.3. Representação de dados na forma de agregados (agregados)

Ao contrário do modelo relacional, que armazena a entidade de negócios lógica do aplicativo em várias tabelas físicas para fins de normalização, os armazenamentos NoSQL operam nessas entidades como objetos holísticos:

Este exemplo demonstra agregações para um modelo relacional conceitual de comércio eletrônico padrão "Pedido - Itens do pedido - Pagamentos - Produto". Em ambos os casos, o pedido é combinado com posições em um único objeto lógico, enquanto cada posição armazena um link para o produto e alguns de seus atributos, por exemplo, o nome (essa desnormalização é necessária para não solicitar um objeto produto ao recuperar uma ordem - a regra principal dos sistemas distribuídos é "junções" entre objetos). Em um agregado, os pagamentos são combinados com o pedido e são parte integrante do objeto, no outro eles são colocados em um objeto separado. Isso demonstra a principal regra para projetar uma estrutura de dados em bancos de dados NoSQL - ela deve obedecer aos requisitos da aplicação e ser otimizada o máximo possível para as requisições mais frequentes.

Muitos objetarão, observando que trabalhar com objetos grandes, muitas vezes desnormalizados, é repleto de inúmeros problemas ao tentar consultas arbitrárias em dados quando as consultas não se encaixam na estrutura de agregados. E se usarmos pedidos junto com itens de linha de pedidos e pagamentos (é assim que o aplicativo funciona), mas a empresa nos pede para contar quantas unidades de um determinado produto foram vendidas no mês passado? Neste caso, ao invés de escanear a tabela OrderItem (no caso de um modelo relacional), teremos que recuperar todos os pedidos no armazenamento NoSQL, embora não precisemos de muitas dessas informações. Infelizmente, este é um compromisso que deve ser feito em um sistema distribuído: não podemos normalizar os dados como em um sistema convencional de servidor único,

Tentei agrupar os prós e contras de ambas as abordagens em uma tabela: