Multilocação - banco de dados único vs banco de dados múltiplo

20

Temos vários clientes, cujos sistemas compartilham algumas funcionalidades, mas também possuem um grau bastante diversificado. O número de clientes está crescendo - sempre uma coisa saudável! - e a diversidade entre seus negócios também está aumentando.

Atualmente, existe um único site ASP.Net (Web Forms) (em oposição ao projeto da web), que possui subpastas para cada inquilino, com as páginas não padrão desse inquilino. Há um projeto de modelo separado, que trata do acesso ao banco de dados e da lógica de negócios.

Qual é preferível - e mais importante, por quê - entre ter (a) 1 banco de dados por cliente, apenas com os recursos associados a esse cliente; ou (b) um único banco de dados compartilhado por todos os clientes, onde apenas um subconjunto de tabelas é usado por qualquer cliente.

As principais preocupações da empresa acabaram:

  • manutenção de vários ativos - backups, controle de versão e similares
  • promover a reutilização, tanto quanto possível

Como você garantiria que essas preocupações fossem abordadas, qual solução é preferível e por quê? (Também compilei respostas para perguntas semelhantes)

RichardW1001
fonte
Existe alguma chance de isso mudar para um ambiente de nuvem PaaS como o Azure? Nesse caso, convém considerar as melhores práticas para o meio ambiente. Na última vez que procurei, a MS recomendou vários bancos de dados para software multitenant no Azure.
Harper Shelby
Obrigado por perguntar. Fiquei pensando em coisas semelhantes, mas não consegui colocar em formato de pergunta tão eloquentemente quanto você.
MathAttack
Você deve ler a série de blogs de multilocação do Ayende. Ele faz alguns pontos muito bons sobre o banco de dados multi vs único.
Sebazzz 15/04/2015

Respostas:

12

Aqui estão os destaques da pesquisa de outras fontes (originalmente da revisão 2 da pergunta ):

user40980
fonte
10

Se você estiver usando o SQL Server, use um banco de dados, mas use esquemas. Use o dbo para coisas gerais para todos os clientes e crie um esquema para cada cliente e torne esse esquema padrão para os usuários desse cliente. Agora você pode ter um objeto geral (por exemplo, um processo getBudget) no esquema dbo e um objeto personalizado para o cliente em seu esquema com o mesmo nome.

HLGEM
fonte
+1 Isso também permitirá que você para evitar ter de configurar MSDTC e assumir os associados gerais (dois commits fase)
brian
E espero que você evitar a armadilha de ter colunas como CustomField1 através CustomField30 e / ou ter tabelas como Orçamento, BudgetEx, BudgetCustom, BudgetCustomerName, BudgetAnotherCustomerName, etc.
jfrankcarr
Existe uma camada de acesso a dados existente que usa muitos procedimentos armazenados - 190 tabelas, 5 procedimentos gerados por código por tabela, além de alguns personalizados - enquanto o objetivo de médio prazo é apresentar o Entity Framework, seria necessário replicar os dados armazenados procedimentos para cada esquema?
RichardW1001
@ RichardW1001: depende. você pode fazer SQL dinâmico no sp, a fim de torná-lo genérico, mas isso obviamente depende da estrutura pelo menos um pouco semelhante. Uma possível alternativa para o sql dinâmico seria o Sinônimos , infelizmente, como eu os entendo, eles são de todo o sistema e não estão contidos em uma transação, portanto, não são adequados para uso simultâneo com valores diferentes.
jmoreno
Se usarmos vários esquemas, usando o EF Code First, será possível migrar todos os esquemas para a versão mais recente após a ativação do sistema?
Yashvit
4

Como os bancos de dados e a funcionalidade dos clientes são divergentes, significa que em um ponto eles acabarão sendo sistemas diferentes; portanto, neste caso, eu recomendaria sistemas separados, pois os custos de manutenção das personalizações para cada cliente superam os benefícios de um único sistema de banco de dados.

Os sistemas de banco de dados único são melhores para quando as alterações entre clientes diferentes são meramente configurações, mas não recursos adicionais para cada cliente.

Stephen Senkomago Musoke
fonte
Qual seria sua sugestão sobre como gerenciar a funcionalidade comum com o mínimo de dor?
RichardW1001
1
No seu sistema de controle de versão, mantenha uma cabeça para o aplicativo principal e crie uma ramificação principal para cada cliente, com sub ramificações para os novos recursos que eles precisam manter. Desenvolver características específicas dos clientes nos ramos, com opções para atualizar o tronco etc. Pode ambientes específicos do cliente, em seguida, SpinUp com facilidade sempre que você precisar deles
Stephen Senkomago Musoke
3

Você está perdendo algumas preocupações. Os problemas virão com o crescimento. Se você pode supor que um dia crescerá mais do que um servidor de banco de dados - um banco de dados complexo definitivamente causará dor de cabeça. A menos que você invista em arquitetura com antecedência. Mas também é um passo caro)

Portanto, não esqueça que é muitas vezes mais barato e muitas vezes mais fácil dimensionar alguns bancos de dados diferentes do que os enormes)

estimulação
fonte
Você tem algum dado que confirme a facilidade do dimensionamento? Nesse caso, seria um caso muito convincente. Você poderia falar sobre as outras preocupações que faltam? Estou tentando criar o argumento mais completo possível dos dois lados.
RichardW1001
1

Uma área que eu não vi abordada nas respostas são os problemas com a proteção correta de um aplicativo de banco de dados multilocatário. Os aplicativos multilocatários precisam ser projetados com muito cuidado para evitar problemas de segurança. A maioria dos bancos de dados e aplicativos fornece algum isolamento, mas não completo - geralmente existem maneiras de inferir direta ou indiretamente dados nos esquemas de banco de dados. E alguns recursos compartilhados (logs e outros arquivos, tabelas DBA, cursores ...) que podem, no mínimo, levar a ataques fáceis de Negação de Serviço a outros inquilinos e, geralmente, muito mais.

Garça
fonte