Pessoal,
Meus 2 cents:
É bem mais fácil rodar numa base só, separando na estrutura das tabelas (Ex.: Tabela "Empresa") de qual empresa pertence o dado. É mais fácil manter a gestão de uma infra só, um procedimento de deploy só, mas obviamente nem tudo são rosas. Jà trabalhei num ambiente desta forma com algumas centenas de clientes corporativos, algumas milhões de usuários e algumas dezenas de milhares e registros. E pasmem, em SQL Server. Foi a primeira vez que eu vi um SQL Server chegando ao limite, principalmente no que tange a vazão de I/O. Com a melhoria do hardware, isso melhorou.
O grande trade off a ser feito aqui, é que vale a pena fazer isso desde que seja um código para todos os clientes. Você pode através de parâmetros, factories, etc, fazer partes diferentes da aplicação reagirem de forma diferente. Ex.: Um cliente tem uma data de entrega por pedido. Outro tem uma data de entrega por item de pedido. Você pode tratar isso com parâmetros.
O grande problema disso é que a complexidade da aplicação começa a ficar exponencial com o decorrer do tempo. Fica difícil de testar, de manter e são tantas variações de "sabores" da aplicação dada a criatividade de cada cliente que a aplicação fica gigante.
Com o tempo, você começa a ter problema com evolução de tecnologia. Por exemplo, você fez agora tudo em
ASP.NET MVC 3, com SQL Server e .NET 4.0 usando um framework arquitetural. Daqui a 5-10 anos surgem novas tecnologias e tecnicas de desenvolvimento. Você não tem opção. Como tudo está numa base de código só, você só consegue subir de tecnologia, se portar tudo.
Sempre vai ter aquele cliente que paga uma merreca por mês, que está usando um treco que só serve pra ele e a tua empresa vai ter que pagar do bolso dela pra você subir isso de tecnologia.
Se eu fosse começar um negócio desse tamanho hoje, eu utilizaria a seguinte linha de raciocínio:
- Usar e abusar de polimorfismo/strategy/inversão de dependência fazendo com que cada especificidade de cada cliente seja implementada numa classe específica dele de forma que o core da aplicação conheça somente uma abstração.
- Particionar o domínio de negócio, de forma que no exemplo acima eu possa ter dois módulos de pedido, cada um com sua estrutura completamente distinta de forma que cada cliente possa combinar os módulos para formar o seu "sabor" da aplicação
- Usar um conceito de SOA/ESB para fazer esses diferentes domínios se conversarem com o restante do sistema.
O principal motivador dessa quebra de domínio de negócio (que ainda não pude aplicar na prática) é justamente a questão da evolução tecnológica que eu comentei. Coisas novas ficam novas e coisas velhas ficam velhas. Você não é obrigado a portar todo o passado para uma tecnologia nova. Pode somente construir um pedaço de um domínio de negócio novo em tecnologia nova, manter o velho velho. Na experiência que vivi pessoalmente foi aqui que a coisa emperrou. Tudo começou a uma década e meia atrás em classic ASP e Delphi, que até hoje estão rodando firme e fortes, pq ninguém quer bancar o upgrade disso. Quando entram clientes novos sai sempre mais barato meter mais uma flag e um desvio na estrutura antiga, do que criar toda uma estrutura nova. As coisas novas nascem velhas e cada vez mais a estrutura fica mais paquiderme e difícil de evoluir.
Tem que ver se é o momento certo pra investir nisso. Se neste momento os clientes não tem tantas coisas específicas talvez não seja o momento, mas quando as customizações começam a torcer o sistema de uma forma que ele não foi feito pra atender (o exemplo da data de entrega é um exemplo). Multitenancy é legal, mas tem um limite. Quando você tenta fazer uma estrutura que acomode coisas muito heterogêneas o negócio fica impossível de gerenciar.
O velho trade-off. Pagar mais caro agora e pensar num futuro sustentável ou comprar uma dívida técnica.
Abraço,
Eric