Je travaille sur une application PHP qui vise à faciliter le workflow de l'entreprise et la gestion de projet, disons quelque chose comme Basecamp et GoPlan .
Je ne sais pas quelle est la meilleure approche, au niveau de la base de données. Dois-je utiliser une seule base de données et ajouter des colonnes spécifiques au client à chacune des tables, ou dois-je créer une base de données pour chaque nouveau client? L'automatisation est un facteur important: je veux que ce soit simple de créer un nouveau client (et peut-être d'ouvrir la possibilité de s'inscrire pour vous-même).
Contre possible je peux penser à utiliser une base de données:
Que pensez-vous de ceci? Avez-vous une idée de la solution que les entreprises ci-dessus sont les plus susceptibles d'avoir choisies?
J'ajoute généralement ClientID à toutes les tables et j'utilise une seule base de données. Mais comme la base de données est généralement difficile à mettre à l'échelle, je pourrai également exécuter plusieurs 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 gros sur des serveurs séparés.
Cependant, un facteur clé pour la maintenabilité est que vous gardez le schéma identique dans toutes les bases de données. Il y aura suffisamment de maux de tête pour gérer le contrôle de version sans introduire de schémas spécifiques au client.
Écoutez le podcast Stackoverflow où Joel et Jeff parlent de la même question. Joel parle de son expérience en offrant une version hébergée de son logiciel. Il souligne que l'ajout d'ID client sur toute votre base de données complique la conception et le code (êtes-vous sûr de ne pas avoir accidentellement oublié 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 vous retrouver dans une situation où les concurrents d'Arch utilisent tous les deux votre système, vous feriez mieux de disposer de bases de données distinctes. 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 possède une copie distincte de l'infrastructure, cela suggère une seule base de données (ou un changement de SGBD). Si plusieurs bases de données peuvent être desservies par une seule copie de l'infrastructure, je choisirais des bases de données distinctes.
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 distincte que si une seule base de données est partagée. Pensez à retirer un client; encore une fois, beaucoup plus facile avec des bases de données distinctes.
(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" par rapport à une "instance de serveur", par exemple. Ajouter: La question est étiquetée "mysql ', alors peut-être que ces pensées ne sont pas complètement pertinentes.)
Ajouter: Encore un problème - avec plusieurs clients dans une seule base de données, chaque requête SQL devra s'assurer que les données pour le client correct sont choisies. Cela signifie que le SQL sera plus difficile à écrire et à lire, et le SGBD devra travailler plus dur sur le traitement des données, et les index seront plus gros, et ... j'irais vraiment avec une base de données distincte par client à de nombreuses fins.
De toute évidence, StackOverflow (à titre d'exemple) n'a pas de base de données distincte par utilisateur; nous utilisons tous la même base de données. Mais si vous dirigiez 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. Imaginez à quel point il sera facile de sauvegarder, restaurer ou supprimer les données d'un client. Ou pour mesurer/surveiller/facturer l'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.
PERFORMANCE Pour les performances, utilisez une base de données pour tous. Pensez au pool de connexions, à la mémoire partagée, à la mise en cache, etc.
BUSINESS Si votre plan d'affaires est d'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 des données, etc. entièrement automatisées et exposées 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 disposer de scripts d'administration système qui peuvent être exploités par votre personnel de support client.
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, vous devriez donc vous pencher sur cela. J'irais avec leur approche.
Il y a un autre grand article à ce sujet sur MSDN. Il explique en détail quand vous devez utiliser une approche partagée ou isolée. N'oubliez pas que le fait d'avoir une base de données partagée pour tous vos locataires a des implications de sécurité importantes et si tous partagent les mêmes objets de base de données, vous voudrez peut-être utiliser [la sécurité au niveau de la ligne] - selon le SGBD que vous utilisez (je suis sûr que c'est possible dans MS SQL Server et Oracle, probablement dans IBM DB2 également). Vous pouvez utiliser des astuces comme sécurité au niveau des lignes dans mySQL pour obtenir des résultats similaires (vues + déclencheurs).
Pour la mutualisation, les performances augmentent généralement à mesure que vous gérez plus de ressources à partager entre les locataires, voir
http://en.wikipedia.org/wiki/Multitenancy
Donc, si vous le pouvez, optez pour la base de données unique. Je suis d'accord que les problèmes de sécurité ne se produiraient qu'en raison de bogues, 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 (afin que chaque utilisateur authentifié obtienne une vue différente).
Il existe également des moyens de fournir une extensibilité. Par exemple, vous pouvez créer une table unique avec des attributs d'extension (saisis par locataire, enregistrement de base et identifiant d'attribut d'extension). Ou vous pouvez créer des tables d'extension par locataire, afin que chaque locataire ait son propre schéma d'extension.
Lorsque vous concevez une base de données multi-locataire, vous avez généralement trois options:
L'option que vous choisissez a des implications sur l'évolutivité, l'extensibilité et l'isolement. Ces implications ont été largement discutées dans différents questions StackOverflow et articles de base de données.
En pratique, chacune des trois options de conception - avec suffisamment d'effort - peut répondre aux questions d'échelle, de données qui varient selon les locataires et d'isolement. La décision dépend de la dimension principale pour laquelle vous construisez. Le résumé:
Par exemple, Google et Salesforce suivent le premier modèle et demandent à leurs locataires de partager 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 industries réglementées, comme 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 la mise à l'échelle 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 séparer les données d'une entreprise des autres.
Avoir une base de données par client n'est généralement pas très évolutif. 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 seule instance, ce qui se produirait dans une situation de mutualisation à 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 pertinent.
De plus, le "sharding" d'une application multi-locataire sera probablement la bonne chose à faire à mesure que votre application s'agrandit.
Le partage ne signifie cependant pas une base de données (ou instance) par locataire, mais une par fragment ou ensemble de fragments, qui peut avoir plusieurs locataires chacun. Vous devrez découvrir les bons paramètres de réglage par vous-même, probablement en production (il doit donc probablement être assez réglable dès le départ)
€ Je ne peux pas le garantir.
Vous pouvez commencer avec une seule base de données et la partitionner à mesure que l'application grandit. 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 vont partager 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 vers cet autre serveur et conserver vos données intactes.