Dois-je utiliser une configuration de base de données unique ou multiple pour une application multi-client?
Je travaille sur une application PHP qui a l'intention de faciliter le flux de travail de l'entreprise et la gestion de projet, disons quelque chose comme Basecamp et GoPlan.
Je ne suis pas sûr de la meilleure approche, en ce qui concerne la base de données. Devrais-je utiliser une seule base de données et ajouter des colonnes spécifiques au client à chacune des tables, ou devrais-je créer une base de données pour chaque nouveau client? Un facteur important est l'automatisation: je veux qu'il soit très simple de créer un nouveau client (et peut-être d'ouvrir le possibilité de vous inscrire pour vous-même).
Inconvénients possibles je peux penser à utiliser une base de données:
- Manque d'extensibilité
- problèmes de sécurité (bien que les bogues ne devraient pas être là en premier lieu)
Quelles sont vos pensées sur cette question? Avez-vous des idées sur la solution que les entreprises ci-dessus sont les plus susceptibles d'avoir choisie?
10 réponses
J'ajoute habituellement ClientID à toutes les tables et je vais avec une base de données. Mais comme la base de données est généralement difficile à mettre à l'échelle, je vais également permettre de fonctionner sur différentes instances de base de données pour certains ou tous les clients.
De cette façon, vous pouvez avoir un tas de petits clients dans une base de données et les grands sur des serveurs séparés.
Un facteur clé pour la maintenabilité est que vous gardez le schéma identique dans toutes les bases de données. Il y aura assez de maux de tête pour gérer le versioning sans présentation de schémas spécifiques au client.
Écoutez le podcast Stackoverflow où Joel et Jeff parlent de la même question. Joel parle de leur expérience en offrant une version hébergée de leur logiciel. Il souligne que l'ajout d'ID client partout dans votre base de données complique la conception et le code (êtes-vous sûr de ne pas oublier accidentellement de l'ajouter à une clause WHERE?) et complique la fonctionnalité d'hébergement, comme les sauvegardes spécifiques au client.
C'était dans l'épisode # 20 ou # 21 (consultez les transcriptions pour plus de détails).
À mon avis, cela dépendra de votre clientèle probable. Si vous pouviez entrer dans une situation où les rivaux de l'Arc utilisent tous les deux votre système, alors vous seriez mieux avec des bases de données séparées. Cela dépend également de la façon dont plusieurs bases de données sont implémentées par votre SGBD. Si chaque base de données a une copie distincte de l'infrastructure, cela suggère une base de données unique (ou un changement de SGBD). Si plusieurs bases de données peuvent être servies par une seule copie de l'infrastructure, alors j'opterais pour séparé les bases de données.
Pensez à la sauvegarde de la base de données. Le client A dit "veuillez m'envoyer une copie de mes données". Beaucoup, beaucoup plus facile dans une configuration de base de données séparée que si une seule base de données est partagée. Pensez à supprimer un client; encore une fois, beaucoup plus facile avec des bases de données séparées.
(la partie 'infrastructure' est farfelue car il existe des différences majeures entre les différents SGBD sur ce qui constitue une' base de données 'et une' instance de serveur', par exemple. Ajouter: La question est balisé 'mysql', alors peut-être que ces pensées ne sont pas complètement pertinentes.)
Ajouter: Un autre problème-avec plusieurs clients dans une seule base de données, chaque requête SQL devra s'assurer que les données du bon client sont choisies. Cela signifie que le SQL va être plus difficile à écrire, et à lire, et le SGBD va devoir travailler plus dur sur le traitement des données, et les index seront plus grands, et ... J'irais vraiment avec une base de données séparée par client pour beaucoup but.
De toute évidence, StackOverflow (par exemple) n'a pas de base de données séparée par utilisateur; nous utilisons tous la même base de données. Mais si vous utilisez des systèmes comptables pour différentes entreprises, Je ne pense pas qu'il serait acceptable (pour les entreprises, et peut-être pas pour les personnes morales) de partager des bases de données.
Développement Pour un développement rapide, utilisez une base de données par client. Pensez à quel point il sera facile de sauvegarder, restaurer ou supprimer les données d'un client. Ou pour mesurer / surveiller / bill utilisation. Vous n'aurez pas besoin d'écrire du code pour le faire vous-même, utilisez simplement vos primitives de base de données.
Les PERFORMANCES Pour les performances, utilisez une base de données pour tous. Pensez à la mise en commun des connexions, à la mémoire partagée, à la mise en cache, etc.
Entreprises Si votre plan d'affaires est avoir beaucoup de petits clients (pensez hotmail), vous devriez probablement travailler sur une seule base de données. Et ont toutes les tâches administratives telles que l'enregistrement, la suppression, la migration de données, etc. entièrement automatisé et exposé dans une interface conviviale. Si vous prévoyez d'avoir des dizaines ou jusqu'à quelques centaines de gros clients, vous pouvez travailler dans une base de données par client et avoir des scripts d'administration système en place qui peuvent être exploités par votre personnel de soutien à la clientèle.
Ce qui suit screencast explique comment cela se fait sur salesforce.com. ils utilisent une base de données avec une colonne spéciale OrgId qui identifie les données de chaque locataire. Il y a beaucoup plus à cela, donc vous devriez regarder dans ce. J'irais avec leur approche.
Il y a un autre grand article à ce sujet sur MSDN. Il explique en profondeur quand vous devez utiliser une approche partagée ou isolée. Rappelez-vous que le fait d'avoir une base de données partagée pour tous vos locataires a des implications importantes en matière de sécurité et si tous partagent les mêmes objets DB, vous pouvez utiliser [row level security] - en fonction du SGBD que vous utilisez (Je suis sûr que C'est possible dans MS SQL Server et Oracle, probablement dans IBM DB2 aussi). Vous pouvez utiliser des astuces comme row level security dans mySQL pour obtenir des résultats similaires (vues + déclencheurs).
Pour la multi-location, les performances augmentent généralement plus vous parvenez à partager de ressources entre les locataires, voir
Http://en.wikipedia.org/wiki/Multitenancy
Donc, si vous le pouvez, allez avec la base de données unique. Je suis d'accord que les problèmes de sécurité ne se produiraient qu'en raison de bugs, car vous pouvez implémenter tout le contrôle d'accès dans l'application. Dans certaines bases de données, vous pouvez toujours utiliser le contrôle d'accès à la base de données en utilisant soigneusement les vues (de sorte que chaque utilisateur authentifié obtienne un vue).
Il existe également des moyens de fournir une extensibilité. Par exemple, vous pouvez créer une seule table avec des attributs d'extension (saisis par locataire, enregistrement de base et ID d'attribut d'extension). Ou vous pouvez créer des tables d'extension par locataire, de sorte que chaque locataire ait son propre schéma d'extension.
Lorsque vous concevez une base de données multi-locataires, vous avez généralement trois options:
- avoir une base de données par locataire
- avoir un schéma par locataire
- Tous les locataires partagent la(les) même (s) table (s)
L'option que vous choisissez a des implications sur l'évolutivité, l'extensibilité et l'isolement. Ces implications ont été largement discutées à travers différents questions de StackOverflow et articles de base de données.
, Dans la pratique, chacun des trois les options - avec suffisamment d'efforts - peuvent répondre à des questions concernant l'échelle, les données qui varient selon les locataires et l'isolement. La décision dépend de la dimension principale pour laquelle vous construisez. Le résumé:
- Si vous construisez pour scale: demandez à tous les locataires de partager la(les) même (s) table (s)
- Si vous construisez pour l'isolement: créez une base de données par locataire
Par exemple, Google et Salesforce suivent le premier modèle et leurs locataires partagent les mêmes tables. Stackoverflow d'autre part suit le deuxième modèle et conserve une base de données par locataire. La deuxième approche est également plus courante dans les secteurs réglementés, tels que les soins de santé.
La décision se résume à la dimension principale pour laquelle vous optimisez la conception de votre base de données. cet article sur la conception de votre base de données SaaS pour scale parle des compromis et fournit un résumé dans le contexte de PostgreSQL.
Un autre point à considérer est que vous pouvez avoir une obligation légale de garder les données d'une entreprise séparées des autres.
Avoir une base de données par client ne s'adapte généralement pas bien. MySQL (et probablement d'autres bases de données) détient des ressources ouvertes par table, cela ne se prête pas bien aux tables 10k+ sur une instance, ce qui se produirait dans une situation de multi-location à grande échelle.
Bien sûr, si vous avez un autre problème qui provoque d'autres problèmes avant d'arriver à ce niveau, cela peut ne pas être pertinente.
De plus," sharding " une application multi-locataires est probablement€ la bonne chose à faire finalement, votre application devient de plus en plus grande.
Le Sharding ne signifie cependant pas une base de données (ou une instance) par locataire, mais une par fragment ou ensemble de fragments, qui peuvent avoir plusieurs locataires chacun. Vous aurez besoin de découvrir les bons paramètres de réglage pour vous-même, probablement en production (d'où probablement besoin d'être assez accordable dès le départ)
€ Je ne peux pas le garantir.
Vous pouvez commencer avec une seule base de données et la partitionner au fur et à mesure que l'application se développe. Si vous faites cela, il y a quelques choses que je recommanderais:
1) concevez la base de données de manière à ce qu'elle puisse être facilement partitionnée. Par exemple, si les clients partagent des données, assurez-vous que les données sont facilement répliquées dans chaque base de données.
2) Lorsque vous n'avez qu'une seule base de données, assurez-vous qu'elle est sauvegardée sur un autre serveur physique. En cas de basculement vous pouvez rétablir le trafic autre serveur et ont toujours vos données intactes.