Design de banco de dados não relacional [fechado]

114

Estou interessado em ouvir sobre as estratégias de design que você usou com bancos de dados "nosql" não relacionais - ou seja, a classe (principalmente nova) de armazenamentos de dados que não usam design relacional tradicional ou SQL (como Hypertable, CouchDB, SimpleDB, armazenamento de dados do Google App Engine, Voldemort, Cassandra, SQL Data Services, etc.). Eles também são frequentemente chamados de "armazenamentos de chave / valor" e, na base, agem como gigantescas tabelas hash persistentes distribuídas.

Especificamente, quero aprender sobre as diferenças no design conceitual de dados com esses novos bancos de dados. O que é mais fácil, o que é mais difícil, o que não pode ser feito de jeito nenhum?

  • Você criou designs alternativos que funcionam muito melhor no mundo não relacional?

  • Você bateu com a cabeça em algo que parece impossível?

  • Você preencheu a lacuna com algum padrão de projeto, por exemplo, para traduzir de um para o outro?

  • Você ao menos faz modelos de dados explícitos agora (por exemplo, em UML) ou os rejeitou inteiramente em favor de blobs de dados orientados a documentos / semiestruturados?

  • Você sente falta de algum dos principais serviços extras que os RDBMSs fornecem, como integridade relacional, suporte a transações arbitrariamente complexas, acionadores, etc?

Eu venho de um background de banco de dados relacional SQL, então a normalização está no meu sangue. Dito isso, obtenho as vantagens dos bancos de dados não relacionais para simplicidade e escalonamento, e meu instinto me diz que deve haver uma sobreposição mais rica de recursos de design. O que é que você fez?

Para sua informação, houve discussões StackOverflow sobre tópicos semelhantes aqui:

Ian Varley
fonte
2
banco de dados de chave / valor a velha coisa nova.
Christopher
1
Para todos os interessados, há uma longa discussão em andamento no grupo NoSQL do google, aqui: groups.google.com/group/nosql-discussion/browse_thread/thread/…
Ian Varley
4
Para sua informação, escrevi um relatório extenso sobre este tópico, aqui: google.com/url?sa=D&q=http://ianvarley.com/UT/MR/… Obrigado a todos por sua contribuição útil!
Ian Varley

Respostas:

55

Acho que você deve considerar que o SGBD não relacional difere muito em relação ao seu modelo de dados e, portanto, o design de dados conceituais também difere muito. No thread Data Design in Non-Relational Databases do grupo NOSQL Google os diferentes paradigmas são categorizados assim:

  1. Sistemas semelhantes a Bigtable (HBase, Hypertable, etc)
  2. Lojas de valor-chave (Tóquio, Voldemort, etc)
  3. Bancos de dados de documentos (CouchDB, MongoDB, etc)
  4. Bancos de dados de gráficos (AllegroGraph, Neo4j, Sesame, etc)

Eu gosto principalmente de bancos de dados gráficos , e a elegância do design de dados usando esse paradigma foi o que me trouxe até lá, cansado das deficiências do RDBMS . Eu coloquei alguns exemplos de design de dados usando um banco de dados gráfico nesta página wiki e há um exemplo de como modelar os dados básicos do filme / ator / papel IMDB também.

Os slides da apresentação (slideshare) Graph Databases eo Futuro da Large Scale-Gestão do Conhecimento por Marko Rodriguez contém uma muito boa introdução ao design de dados usando um banco de dados gráfico também.

Respondendo a perguntas específicas do ponto de vista do graphdb:

Design alternativo: adicionar relacionamentos entre muitos tipos diferentes de entidades sem nenhuma preocupação ou necessidade de predefinir quais entidades podem se conectar.

Preenchendo a lacuna: eu tendo a fazer isso diferente para cada caso, com base no próprio domínio, pois não quero um "gráfico orientado a tabela" e coisas do gênero. No entanto, aqui estão algumas informações sobre a tradução automática de RDBMS para graphdb.

Modelos de dados explícitos: eu faço isso o tempo todo (estilo quadro branco) e uso o modelo como está no banco de dados também.

Saudades do mundo RDBMS: maneiras fáceis de criar relatórios. Update: talvez não seja que duro para criar relatórios a partir de um banco de dados de gráfico, consulte Criando um relatório para um banco de dados Neo4J Amostra .

nawroth
fonte
79

Acabei de começar com bancos de dados não relacionais e ainda estou tentando entender isso e descobrir qual seria o melhor modelo. E só posso falar pelo CouchDB.

Ainda assim, tenho algumas conclusões preliminares:

Você criou designs alternativos que funcionam muito melhor no mundo não relacional?

O foco do design muda: O design do modelo de documento (correspondendo às tabelas do banco de dados) torna-se quase irrelevante, enquanto tudo depende do design das visualizações (correspondentes às consultas).

O tipo de banco de dados de documentos troca as complexidades: o SQL tem dados inflexíveis e consultas flexíveis, os bancos de dados de documentos são o contrário.

O modelo CouchDB é uma coleção de "documentos JSON" (basicamente tabelas hash aninhadas). Cada documento possui um ID exclusivo e pode ser facilmente recuperado por ID. Para qualquer outra consulta, você escreve "visualizações", que são conjuntos nomeados de funções mapear / reduzir. As visualizações retornam um conjunto de resultados como uma lista de pares chave / valor.

O truque é não consultar o banco de dados no sentido de consultar um banco de dados SQL: os resultados da execução das funções de exibição são armazenados em um índice e apenas o índice pode ser consultado. (Como "obter tudo", "obter chave" ou "obter intervalo de chaves".)

A analogia mais próxima no mundo SQL seria se você pudesse apenas consultar o banco de dados usando procedimentos armazenados - toda consulta que você deseja oferecer suporte deve ser predefinida.

O design dos documentos é extremamente flexível. Encontrei apenas duas restrições:

  • Mantenha os dados relacionados juntos no mesmo documento, pois não há nada que corresponda a uma junção.
  • Não torne os documentos tão grandes a ponto de serem atualizados com muita frequência (como colocar todas as vendas da empresa para o ano no mesmo documento), pois cada atualização de documento aciona uma reindexação.

Mas tudo depende do design das vistas.

Os designs alternativos que descobri que funcionam melhor com o CouchDB do que com qualquer banco de dados SQL em ordens de magnitude, e não no nível de armazenamento, mas sim no nível do sistema. Se você possui alguns dados e deseja veiculá-los em uma página da web, a complexidade do sistema total é reduzida em pelo menos 50%:

  • sem criação de tabelas de banco de dados (pequeno problema)
  • nenhuma camada intermediária ODBC / JDBC, todas as consultas e transações via http (problema moderado)
  • mapeamento simples de banco de dados para objeto de JSON, que é quase trivial em comparação com o mesmo em SQL (importante!)
  • você pode potencialmente ignorar todo o servidor de aplicativos, pois pode projetar seus documentos para serem recuperados diretamente pelo navegador usando AJAX e adicionar um pouco de polimento de JavaScript antes de serem exibidos como HTML. (IMENSO!!)

Para webapps normais, bancos de dados baseados em documento / JSON são uma grande vitória, e as desvantagens de consultas menos flexíveis e alguns códigos extras para validação de dados parecem um preço pequeno a pagar.

Você bateu com a cabeça em algo que parece impossível?

Ainda não. Mapear / reduzir como meio de consultar um banco de dados não é familiar e requer muito mais raciocínio do que escrever SQL. Há um número relativamente pequeno de primitivas, portanto, obter os resultados de que você precisa é principalmente uma questão de ser criativo ao especificar as chaves.

Há uma limitação em que as consultas não podem olhar para dois ou mais documentos ao mesmo tempo - nenhuma junção ou outros tipos de relacionamentos de vários documentos, mas nada até agora foi intransponível.

Como limitação de exemplo, contagens e somas são fáceis, mas as médias não podem ser calculadas por uma visualização / consulta CouchDB. Correção: Retorne a soma e conte separadamente e calcule a média no cliente.

Você preencheu a lacuna com algum padrão de projeto, por exemplo, para traduzir de um para o outro?

Não tenho certeza se isso é viável. É mais um redesenho completo, como traduzir um programa de estilo funcional para um estilo orientado a objetos. Em geral, existem muito menos tipos de documentos do que tabelas SQL e mais dados em cada documento.

Uma maneira de pensar nisso é examinar seu SQL em busca de inserções e consultas comuns: quais tabelas e colunas são atualizadas quando um cliente faz um pedido, por exemplo? E quais para relatórios de vendas mensais? Essa informação provavelmente deve ir no mesmo documento.

Ou seja: Um documento para Pedido, contendo ID de cliente e ID de produto, com campos replicados conforme necessário para simplificar as consultas. Qualquer coisa dentro de um documento pode ser consultada facilmente, qualquer coisa que requeira referência cruzada entre, digamos, o Pedido e o Cliente, deve ser feito pelo cliente. Portanto, se você deseja um relatório de vendas por região, provavelmente deve inserir um código de região no pedido.

Você pelo menos faz modelos de dados explícitos agora (por exemplo, em UML)?

Desculpe, nunca fiz muito UML antes de documentar bancos de dados :)

Mas você precisa de algum tipo de modelo que diga quais campos pertencem a quais documentos e quais tipos de valores eles contêm. Para sua própria referência posterior e para se certificar de que todos os usuários do banco de dados conheçam as convenções. Uma vez que você não receberá mais um erro se armazenar uma data em um campo de texto, por exemplo, e qualquer pessoa puder adicionar ou remover qualquer campo que desejar, você precisa do código de validação e das convenções para compensar. Principalmente se você trabalhar com recursos externos.

Você sente falta de algum dos principais serviços extras que os RDBMSs fornecem?

Não. Mas minha formação é desenvolvedor de aplicativos web, lidamos com bancos de dados apenas na medida em que devemos :)

Uma empresa para a qual trabalhei fez um produto (um webapp) que foi projetado para rodar em bancos de dados SQL de vários fornecedores, e os "serviços extras" são tão diferentes de um banco de dados para outro que tiveram que ser implementados separadamente para cada banco de dados. Portanto, foi menos trabalhoso remover a funcionalidade do RDBMS. Isso se estendeu até mesmo à pesquisa de texto completo.

Então, seja o que for que estou desistindo, é algo que nunca realmente tive. Obviamente, sua experiência pode ser diferente.


Uma advertência: estou trabalhando agora em um webapp para dados financeiros, cotações de ações e outros. Esta é uma combinação muito boa para um banco de dados de documentos, do meu ponto de vista eu obtenho todos os benefícios de um banco de dados (persistência e consultas) sem nenhum incômodo.

Mas esses dados são bastante independentes uns dos outros, não há consultas relacionais complexas. Obtenha as últimas cotações por ticker, obtenha cotações por ticker e intervalo de datas, obtenha meta-informações da empresa, isso é praticamente tudo. Outro exemplo que vi foi um aplicativo de blog, e os blogs também não são caracterizados por esquemas de banco de dados extremamente complicados.

O que estou tentando dizer é que todas as aplicações bem-sucedidas de bancos de dados de documentos que conheço foram com dados que não tinham muitas inter-relações em primeiro lugar: documentos (como na pesquisa do Google), postagens de blog, artigos de notícias, dados financeiros .

Espero que existam conjuntos de dados que mapeiam melhor para SQL do que para o modelo de documento, então imagino que o SQL sobreviverá.

Mas para aqueles de nós que querem apenas uma maneira simples de armazenar e recuperar dados - e eu suspeito que existam muitos de nós - bancos de dados de documentos (como no CouchDB) são uma dádiva de Deus.

jg-faustus
fonte
9
Muito útil. Especialmente "SQL tem dados inflexíveis e consultas flexíveis, bancos de dados de documentos são o contrário" e a ausência de junções.
j_random_hacker
2
1, isso foi muito esclarecedor.
Mas
2
Verdade, eu votaria a favor mais de uma vez, se possível.
Octavian A. Damiean
Isso ainda era extremamente útil em 2014, seria ótimo se você pudesse adicionar o que aprendeu desde 2010 ou criar um link para informações que possa ter em outro lugar.
Maggie
11

Estou respondendo a isso com o CouchDB no fundo da minha mente, mas presumo que a maioria também seja verdadeira para outros bancos de dados. Analisamos o uso do CouchDB, mas finalmente decidimos não fazê-lo, já que nosso acesso aos dados não é conhecido de antemão e a escalabilidade não é o problema.

Mais difíceis:

  • É preciso repensar no nível conceitual para que seja 'mais difícil', pois é apenas diferente. Como você deve conhecer seus padrões de acesso a dados com antecedência, nenhuma tradução automática pode ser aplicada. Você precisaria adicionar pelo menos o padrão de acesso.
  • A consistência não é tratada pelo banco de dados, mas deve ser tratada no aplicativo. Menos garantias significa migração mais fácil, failover e melhor escalabilidade ao custo de um aplicativo mais complicado. Um aplicativo precisa lidar com conflitos e inconsistências.
  • Links que cruzam documentos (ou chave / valor) também devem ser tratados no nível do aplicativo.
  • Os bancos de dados do tipo SQL possuem IDEs muito mais maduros. Você obtém muitas bibliotecas de suporte (embora as camadas dessas bibliotecas tornem as coisas muito mais complexas do que o necessário para SQL).

Mais fácil:

  • Mais rápido se você conhecer seus padrões de acesso aos dados.
  • A migração / failover é mais fácil para o banco de dados, pois nenhuma promessa é feita a você como programador de aplicativos. Embora você obtenha consistência eventual. Provavelmente. Finalmente. Às vezes.
  • Uma chave / valor é muito mais fácil de entender do que uma linha de uma tabela. Todas as relações (árvore) já estão presentes e objetos completos podem ser reconhecidos.

A modelagem deve ser quase a mesma, mas você deve ter cuidado com o que colocar em um documento: UML também pode ser usada para modelagem OO e modelagem de banco de dados, que já são duas feras diferentes.

Eu teria gostado de ver um bom banco de dados OO aberto bem integrado com C # / Silverlight. Só para tornar a escolha ainda mais difícil. :)

Rutger Nijlunsing
fonte
1

Arquivos simples há muito são considerados misteriosos e impraticáveis ​​para um conjunto de dados de qualquer tamanho. No entanto, computadores mais rápidos com mais memória possibilitam carregar um arquivo na memória e classificá-lo em tempo real, pelo menos para aplicativos de usuário único e locais razoavelmente pequenos.

Por exemplo, normalmente você pode ler um arquivo de 10.000 registros E classificá-lo em um campo em menos de meio segundo, um tempo de resposta aceitável.

Claro, há razões para usar um banco de dados em vez de um arquivo simples - operações relacionais, integridade de dados, capacidade multiusuário, acesso remoto, maior capacidade, padronização, etc., mas o aumento da velocidade do computador e da capacidade de memória fizeram a manipulação na memória de dados mais práticos em alguns casos.

xpda
fonte
1

Os bancos de dados relacionais que vejo na vida real tendem a não ser muito bem normalizados, ao contrário do que você afirma. Quando questionados, os designers me dizem que isso se deve principalmente ao desempenho. RDBMs não são bons em unir, portanto, as tabelas tendem a ser muito largas do ponto de vista da normalização. Bancos de dados orientados a objetos tendem a ser muito melhores nisso.

Outro ponto em que os RDBMs têm problemas é a manipulação de chaves dependentes de histórico / tempo.

Stephan Eggermont
fonte
3
Stephan - você está certo de que os sistemas do mundo real geralmente carecem do departamento de normalização. Mas não é preciso dizer que os RDBMs "não são bons em ingressar"; a maioria dos produtos comerciais (como Oracle, MS SQL Server, etc) tem otimizadores de consulta extremamente avançados e podem executar uma ampla variedade de algoritmos de junção física, muito mais rápido do que as mesmas operações poderiam ser feitas no código do aplicativo. (MySQL é uma exceção a isso, pelo que entendi). Na minha experiência, a desnormalização prematura é, como outras otimizações prematuras, geralmente um sinal de mau desenvolvedor.
Ian Varley
2
Continuando com este pensamento: junções ruins são o resultado de indexação e estatísticas ruins. Se o otimizador não tiver nada com que trabalhar, ou as informações sobre o que ele tem estiverem desatualizadas, ele fará escolhas erradas. Muitos confundem isso com "adesão ruim". Os sistemas RDBMs modernos têm auto-ajuste, o que mascara a necessidade de usar o cérebro ao configurar a indexação e as estatísticas. Além disso, as pessoas confundem o esquema lógico (quinta forma normal) e o esquema físico (frequentemente desnormalizado para a terceira forma normal). Só porque o banco de dados que você é "amplo" não significa que foi mal projetado logicamente.
Godeke