Sem esquema / flexível + Banco de dados ACID?

15

Estou olhando para reescrever um aplicativo baseado no local do VB (instalado localmente) (faturamento + inventário) como um aplicativo Clojure baseado na Web para clientes de pequenas empresas. Pretendo que isso seja oferecido como um aplicativo SaaS para clientes de comércio semelhante.

Eu estava olhando para as opções de banco de dados: Minha escolha foi um RDBMS: Postgresql / MySQL. Posso escalar até 400 usuários no primeiro ano, normalmente com 20 a 40 visualizações de página / por dia por usuário - principalmente para transações que não são estáticas. Cada visualização envolve buscar dados e atualizar dados. A conformidade com o ACID é necessária (ou assim eu acho). Portanto, o volume de transações não é enorme.

Teria sido um acéfalo escolher um destes com base na minha preferência, mas para este requisito, que acredito ser típico de um aplicativo SaaS: o esquema mudará à medida que adiciono mais clientes / usuários e para cada cliente. alteração dos requisitos de negócios (oferecerei flexibilidade limitada apenas para começar). Como não sou especialista em DB, com base no que posso pensar e ter lido, posso lidar com isso de várias maneiras:

  1. Tenha um design de esquema RDBMS tradicional no MySQl / Postgresql com um único banco de dados hospedando vários inquilinos. E adicione colunas "flutuantes" suficientes em cada tabela para permitir alterações futuras à medida que adiciono mais clientes ou alterações a um cliente existente. Isso pode ter uma desvantagem em propagar as alterações no banco de dados toda vez que uma pequena alteração é feita no esquema. Lembro-me de ler que no Postgresql as atualizações de esquema podem ser feitas em tempo real sem travar. Mas não tenho certeza, quão doloroso ou prático é neste caso de uso. E também, conforme as mudanças no esquema também podem introduzir novas / pequenas alterações no SQL.
  2. Tenha um RDBMS, mas projete o esquema do banco de dados de maneira flexível: com um valor próximo ao atributo da entidade ou apenas como um armazenamento de valor-chave. (Dia útil, FriendFeed por exemplo)
  3. Tenha tudo na memória como objetos e armazene-os em arquivos de log periodicamente (por exemplo, edval, lmax)
  4. Escolha um banco de dados NoSQL como MongoDB ou Redis. Mas, com base no que posso reunir, eles não são adequados para este caso de uso e não são totalmente compatíveis com ACID.
  5. Escolha alguns Dbs NewSQL como o VoltDb ou o JustoneDb (baseado em nuvem) que mantêm o comportamento compatível com SQL e ACID e são RDBMS de "nova geração".
  6. Eu olhei para neo4j (graphdb), mas não tenho certeza se isso se encaixará nesse caso de uso

No meu caso de uso, mais do que escalabilidade ou computação distribuída, estou procurando uma maneira melhor de obter "Flexibilidade no esquema + ACID + desempenho razoável". A maioria dos artigos que pude encontrar na rede fala da flexibilidade no esquema como causa que leva ao desempenho (no caso dos bancos de dados NoSQL) e à escalabilidade, deixando de fora o lado ACID / Transações.

Esse é um caso "de uma ou" operação de 'Flexibilidade do esquema versus ACID' ou Existe uma saída melhor?

tmbsundar
fonte
2
Confira o módulo hstore no PostgreSQL. Isso é "NoSQL" dentro de um banco de dados SQL: postgresql.org/docs/current/static/hstore.html
a_horse_with_no_name
@ cavalo: Obrigado ... É um bom ponteiro. Eu ouvi plugins NoSQL para MySQL. Eu estava procurando semelhante para o Postgres.
tmbsundar

Respostas:

11

Opção 1

Existem várias razões para isso, que explicarei abaixo. Primeiro, veja como fazê-lo.

  • Use sua opção de plataforma RDBMS padrão.

  • Configure seu esquema com vários campos configuráveis ​​pelo usuário e facilite seu aplicativo por configuração de inquilino.

  • A partir dos metadados per-tenant, você pode criar uma visão per-tenant de seu dados, que tem os filtros embutidos, e as colunas nomeadas de seus metadados. Quaisquer relatórios fornecidos também podem herdar os metadados. Se eles quiserem tirar o MI dos dados, forneça a eles uma extração dos dados transacionais, ou talvez algum aplicativo MIS adicional em um servidor diferente, se eles pagarem por isso.

  • Não tente fornecer mais personalização do que isso (ou seja, nenhuma alteração radical no esquema), a menos que o cliente esteja preparado para pagar por sua própria instância privada e manter uma compilação personalizada.

As razões por trás disso são:

  • Esses sistemas de banco de dados manipularão o tipo de volumes que você descreve em hardware bastante comum. Você realmente não tem o tipo de volume de transação que merece um banco de dados NoSQL. A menos que você tenha alguma outra razão arquitetônica para querer uma, não há muito sentido em ir além.

  • São tecnologias maduras e bem compreendidas.

  • O gerenciamento do sistema, backup / restauração, replicação, relatórios e recuperação de desastres são bem classificados nas plataformas RDBMS.

  • Você pode obter bibliotecas clientes, incluindo JDBC, para todas as principais plataformas RDBMS.

  • As visualizações podem ser usadas para a personalização por usuário e geradas a partir dos metadados do aplicativo.

  • É substancialmente mais eficiente que campos XML ou estruturas EAV.

ConcernedOfTunbridgeWells
fonte
@OTW: Obrigado pela resposta detalhada. Uma coisa importante que me preocupava era a mudança "antecipada" de esquema, que acho que tenho que pensar e torná-la o mais "pré-configurável" possível, antecipadamente, e evitar mudanças drásticas de esquema posteriormente.
tmbsundar
A recuperação de desastre para um único inquilino não é simples se eles estiverem compartilhando tabelas. (Se cada linha tiver um número de identificação do inquilino.)
Mike Sherrill 'Cat Recall'
Faça isso, mas use uma coluna JSON: gist.github.com/tobyhede/2715918
mwhite
5

Com o PostgreSQL, você tem a opção de usar bancos de dados, esquemas ou visualizações separados para lidar com a multilocação.

O uso de vários bancos de dados (dentro do mesmo servidor de banco de dados) torna a administração mais complexa, pois cada banco de dados deve ser gerenciado individualmente. Portanto, isso só é aconselhável se a segurança entre os inquilinos for a maior preocupação.

Esquemas separados oferecem muita flexibilidade e segurança, mas tornam as atualizações mais complexas, porque elas devem ser aplicadas individualmente e provavelmente só são necessárias se seus inquilinos usarem estruturas de tabela completamente diferentes; o que é improvável se eles estiverem usando o mesmo aplicativo.

As visualizações permitem que os inquilinos vejam partes diferentes de uma estrutura de tabela comum e permitem controlar quais tabelas, quais colunas e quais linhas eles têm acesso. A única ressalva é que seu aplicativo deve garantir que ele use apenas essas visualizações e não as tabelas base, caso contrário, há potencial para vazamentos acidentais de dados entre os inquilinos devido a defeitos de software.

Você realmente não precisa criar colunas antes dos requisitos do aplicativo. As colunas podem ser adicionadas às tabelas dinamicamente (sem nenhum impacto perceptível nos usuários) e as visualizações também podem ser atualizadas dinamicamente. Você só precisa pensar na ordem de fazer alterações - ie. alterar tabelas e, em seguida, visualizar o código do aplicativo.

Sua única preocupação em potencial é se você precisa adicionar uma nova coluna que precise ser adicionada a um índice existente ou exija um novo índice. É quando a tabela pode ficar bloqueada de uso enquanto o índice está sendo construído - mas o PostgreSQL suporta a capacidade de criar índices simultaneamente, sem bloquear a tabela. Isso funciona bem, a menos que o novo índice precise ser exclusivo e encontre uma violação de exclusividade.

Você provavelmente não precisa de um banco de dados NoSQL, pois eles efetivamente removem o esquema do banco de dados e exigem que o aplicativo o gerencie. Não parece que seus volumes exigem esse tipo de sacrifício.

Duncan Pauly
fonte
11
Com o 9.1, você pode até substituir uma restrição exclusiva ou chave primária sem bloquear a tabela. Veja aqui: depesz.com/index.php/2011/02/19/…
a_horse_with_no_name
Acordado. Eu estava tentando dizer que surge um problema quando um índice exclusivo é criado, mas a restrição é violada - é necessário resolver o problema de exclusividade. Isso é mais um problema de adicionar colunas em vez de adicionar índices por si só.
Duncan Pauly
@DuncanPauly: Obrigado pela compreensão. Entendo pela sua resposta que o Postgresql permite 'alteração de esquema online / ao vivo'. Mas, quando eu pesquiso no Google, recebo principalmente 'alteração de esquema online do facebook' ou 'pt-online ...' etc., que pertencem ao MySQL. Você saberia de um link ou material que me ajude a entender a mudança de esquema ao vivo para o Postgresql? Agradeço sua ajuda. Obrigado.
tmbsundar
Este link descreve como você pode alterar as tabelas postgresql.org/docs/8.1/static/ddl-alter.html . O princípio importante a ser lembrado é que criar, alterar e eliminar tabelas ou visualizações é praticamente instantâneo; enquanto que criar e alterar índices é tudo menos.
Duncan Pauly