Je me souviens des podcasts stackoverflow que Fog Creek utilise une base de données par client pour Fogbugz . Je suppose que cela signifie que les serveurs Fogbugz On Demand ont des dizaines de milliers de bases de données.
Nous commençons tout juste à développer une application web et avons un problème similaire à résoudre (beaucoup de clients avec leurs propres données isolées).
À quels problèmes dois-je m'attendre avec l'utilisation d'une base de données par client? Comment puis-je les résoudre?
Avantages d'une base de données par client
Inconvénients
Cette solution est appelée une conception multi-locataire où chaque locataire (client) a sa propre base de données. Compte tenu de cela, il existe d'autres considérations à l'approche alternative qui est une base de données unique:
Avoir des bases de données distinctes signifie que vous devez créer un mécanisme de mise à jour qui correspond à la version de la base de données avec la version de l'application/du site. Cependant, des bases de données distinctes offrent une meilleure isolation des données et l'OMI a un coût d'hébergement inférieur. Ce n'est pas une solution pour tous les scénarios. Si votre système ne devait jamais être hébergé en dehors de votre hébergement et devait évoluer rapidement chez les clients et que tous les utilisateurs sur la même version de l'application et du schéma de base de données étaient souhaitables, alors avoir une seule base de données est certainement une meilleure approche.
D'après mon expérience, vous ne devez pas créer une base de données par client. Laisse moi te donner un exemple:
L'année dernière, j'ai travaillé avec 70 bases de données (beaucoup moins de 5000), chacune avec le même schéma et tout. En théorie, les choses se passeraient comme prévu (comme vous le mentionnez dans la section avantages), mais en réalité pas tellement. Nous avons eu de nombreux problèmes avec la mise à jour des schémas, le support utilisateur, la mise à jour logicielle, vous l'appelez. C'était horrible.
Nous avons utilisé Firebird et j'ai été embauché bien après l'expédition du produit, mais cela m'a permis de ne jamais travailler avec des bases de données séparées.
Je ne dis pas que vous ne pouvez pas le faire, je dis les choses peuvent aller très mal et pour être honnête, votre liste d'avantages n'était pas assez attrayante pour prendre le risque. La plupart d'entre eux peuvent être réalisés avec une seule base de données.
Vous voudrez probablement conserver une autre base de données pour suivre la version de chaque client, afin de pouvoir garder une trace de celles qui ont ou n'ont pas subi la dernière série de modifications.
L'écriture des mises à niveau ne serait pas si difficile ... vous pourriez écrire quelque chose qui regarde le catalogue des bases de données et appliquer les modifications nécessaires pour obtenir chaque base de données à la dernière version, en sautant éventuellement celles qui ne devraient pas être mises à niveau pour une raison quelconque.
Comme les `` bases de données '' mysql ne sont que des schémas, comme l'a souligné Gaius, si tout fonctionne à partir de la même instance de serveur, vous pouvez simplement qualifier le nom des tables que vous essayez de modifier, ou obtenir des informations:
alter schema.table ...
select ... from schema.table
...
Si vous commencez à répartir les choses sur plusieurs serveurs, vous pouvez toujours créer un script qui établit des connexions avec plusieurs serveurs afin que vous puissiez appliquer toutes les modifications; pour l'analytique, encore une fois, vous pouvez définir un ensemble de liens de base de données en utilisant tables fédérées dans votre base de données master pour accéder aux données à partir d'un seul endroit, comme vous le feriez simplement dans les tables.
...
Sachez également qu'ils n'utilisent pas mySQL pour l'échange de pile, ils utilisent SQL Server.
Et je n'ai aucune idée du type de surcharge de performance qu'il y aurait dans mysql à cette échelle, je ne pense pas avoir dépassé les 30 "bases de données" dans mysql.
J'ai un client d'hébergement Web/DB qui a plus de 750 bases de données client avec le même nombre de tables (162) et les mêmes structures de table. Ensemble, toutes les données client de mon client totalisent 524 Go (95% InnoDB)
Imaginez toutes ces bases de données en concurrence pour 13 G de pool de mémoire tampon innodb sur neuf serveurs DB via la réplication circulaire. La mise à l'échelle avec cette configuration matérielle n'était pas suffisante. Immédiatement, nous avons recommandé au client de se développer.
Nous avons récemment migré ce client vers 3 serveurs DB avec beaucoup plus de puissance (à tout prix, restez loin des SSD dans des environnements à écriture élevée, TOUJOURS !!!). Nous les avons mis à niveau de MySQL 5.0.90 vers MySQL 5.5.9. Des différences dramatiques ont été observées presque instantanément.
La mise à l'échelle doit également être prise en compte car si des centaines de clients utilisent les mêmes ressources de mémoire et de disque, la mise à l'échelle réduit leur utilisation de manière linéaire (O (n)), où n est basé sur le nombre de serveurs de base de données dans un environnement multimaître.
Dans le cas de mon client, mon entreprise le réduit de 9 serveurs DB (Quad Code, 32 Go de RAM, 824G RAID10) à des serveurs DB plus rapides (Dual HexaCore [c'est vrai 12 processeurs], 192 Go de RAM, 1,7 To RAID10) de MySQL 5.5 .9 (pour tirer parti des multiples processeurs). De plus, imaginez un pool de tampons innodb de 150 Go dans 50 partitions de 3 Go chacune (plusieurs pools de tampons InnoDB est une nouvelle fonctionnalité de MySQL 5.5). Une plus petite échelle, mais une augmentation massive, avait fonctionné pour l'infrastructure unique de mon client.
MORAL OF THE STORY: La montée en puissance ou l'extrapolation n'est pas toujours la solution si vous avez des tableaux mal conçus. Ce que je veux dire est le suivant: si les pages d'index ont une population de clés déséquilibrée pour les index multicolonnes, l'interrogation des clés à partir des parties déséquilibrées des index conduit à l'analyse de table après analyse de table, ou au moins aux index qui ne sont jamais utilisés en raison de leur exclusion par la requête MySQL. Optimiseur. Il n'y a tout simplement pas de substitut à une conception appropriée.
MySQL crée des bases de données dans des répertoires séparés, donc cela dépend beaucoup du système d'exploitation sous-jacent et du nombre de dossiers/fichiers qu'il peut gérer. Cela ne devrait pas être un problème avec les systèmes d'exploitation modernes, mais c'est de là que viendra une grande partie du goulot d'étranglement.
Rien ne dit que vous devez héberger différentes versions de la base de données ou de l'application. Qu'y a-t-il de mal à simplement isoler les données en effectuant une base de données par client et en ayant une version de la base de données et de l'application? Bien sûr, chaque base de données client devrait être clonée à partir d'un modèle de la version de travail actuelle. Du point de vue de la sécurité et de l'isolement des données, je pense que c'est idéal.
Le seul inconvénient que je peux voir est que vous devrez mettre à jour manuellement chaque base de données lors de la création d'une nouvelle version. Cela pourrait cependant être facilement automatisé.