Welche Probleme bekomme ich beim Erstellen einer Datenbank pro Kunde?

49

Ich erinnere mich an die Stackoverflow-Podcasts, dass Fog Creek eine Datenbank pro Kunde für Fogbugz verwendet . Ich gehe davon aus, dass die Fogbugz On Demand-Server Zehntausende von Datenbanken haben.

Wir fangen gerade an, eine Web-App zu entwickeln und haben ein ähnliches Problem zu lösen (viele Kunden mit ihren eigenen isolierten Daten).

Mit welchen Problemen sollte ich bei der Verwendung einer Datenbank pro Kunde rechnen? Wie kann ich sie lösen?

Meine ersten Gedanken

Vorteile einer Datenbank pro Kunde

  • Einfacheres Datenbankschema
  • Einfachere Backups - Sie können jeden Kunden einzeln sichern, ohne dass dies Auswirkungen auf andere Kunden hat.
  • Erleichtert den Export von Kundendaten.
  • Bessere Cache-Leistung - Ein Schreibvorgang in eine der aktiveren Tabellen wirkt sich nur auf den einzelnen Kunden aus, der den Schreibvorgang ausgeführt hat.
  • Einfachere Hardware-Skalierung. Wenn wir beispielsweise von 1 auf 2 Server wechseln müssen, verschieben wir nur die Hälfte unserer Kunden auf den neuen Server.

Nachteile

  • Kann MySQL mit 5.000 Datenbanken umgehen? Würde Leistung scheiße sein?
  • Es kann schwierig sein, Änderungen am Schema in allen Datenbanken zu replizieren. Wir müssten dafür wirklich einen automatisierten Plan haben, wie zum Beispiel die Versionierung des Schemas und ein Skript, das versteht, wie eine Datenbank von einer Version in eine andere übertragen wird.
  • Etwas zu tun, was allen unseren Kunden gemeinsam ist, kann umständlich oder unmöglich sein
  • Ähnlich wie oben, aber Analysen, die wir für alle unsere Kunden durchführen möchten, sind möglicherweise unmöglich. Wie sollten wir zum Beispiel die Nutzung für alle Kunden verfolgen?
Rik Heywood
quelle
2
Denken Sie daran, dass "Datenbank" für verschiedene Personen unterschiedliche Bedeutungen hat. In der Oracle-Welt wäre eine Datenbank pro Benutzer ein gewaltiger Overkill. Aber in MySQL ist "Datenbank" synonym mit "Schema".
Gaius
Ich meine es im MySQL-Sinne. USE CompanyData;
Rik Heywood
1
Microsoft hat einen ausführlichen Artikel zur mandantenfähigen Datenarchitektur .
Nick Chammas
Ich würde nicht sagen, dass die Versionierung des Schemas ein Nachteil ist ... mehr Arbeit, aber insgesamt besser
Neil McGuigan

Antworten:

41

Diese Lösung wird als mandantenfähiges Design bezeichnet, bei dem jeder Mandant (Kunde) eine eigene Datenbank hat. In Anbetracht dessen gibt es einige andere Überlegungen zu dem alternativen Ansatz, bei dem es sich um eine einzelne Datenbank handelt:

  1. Mit einer einzigen Datenbank muss jeder auf der gleichen Version sein, egal was passiert. Einige Kunden können nicht aktualisiert werden, andere nicht. Dies kann problematisch sein, wenn ein Kunde einen Hotfix für eine Anwendung wünscht, die nicht für die Weiterveröffentlichung bereit ist.
  2. Wenn Sie ein Upgrade für eine einzelne Datenbank durchführen, ist jeder Client inaktiv. Wenn etwas schief geht, wird jeder Kunde geschraubt.
  3. Mit einer einzigen Datenbank ist es viel schwieriger, Ressourcen zu drosseln. Dh, wenn ein Client die Datenbank hämmert, ist es schwieriger, ihm mehr Ressourcen zur Verfügung zu stellen, die von allen anderen getrennt sind.
  4. Es ist viel schwieriger, Benutzern das Hosten eigener Versionen Ihrer Anwendung zu ermöglichen. Wenn Sie eine Lösung entwickeln, die von großen Unternehmen verwendet wird, ist dies häufig kein Einstieg. Ihre IT-Abteilung möchte die vollständige Kontrolle über den Zugriff auf das System haben.
  5. Es ist wahrscheinlich billiger, Datenbanken zu skalieren, als sie zu skalieren. Das heißt, in schnellere Hardware zu investieren, um eine Datenbank zu hosten, um sie alle zu beherrschen, ist wahrscheinlich teurer als die Möglichkeit, Kunden auf kleinere, kostengünstigere Datenbankserver zu skalieren. Ich kann dies nicht definitiv sagen, da es stark von der Serversoftware abhängt. Wenn Sie sich an MySQL halten, ist dies wahrscheinlich so, weil die Lizenzkosten vernachlässigbar sind. Wenn Sie jedoch zum Beispiel auf SQL Server umsteigen, wird das Skalieren viel teurer, es sei denn, Sie verwenden eine VPS-Umgebung und das Kosten-Nutzen-Verhältnis des Skalierens im Vergleich zum Skalieren von Änderungen. Ich kann jedoch sagen, dass das Management eines einmal sehr großen Datenbestands immer mehr Fachwissen erfordert. Bei sehr großen Datenbanken müssen Sie mit mehreren Dateigruppen herumspielen und bestimmte Indizes auf verschiedene Spindeln verschieben, um eine bessere Leistung zu erzielen. Kurz gesagt, sie können sehr schnell kompliziert werden.

Wenn Sie getrennte Datenbanken haben, müssen Sie einen Aktualisierungsmechanismus erstellen, der die Datenbankversion mit der Anwendungs- / Site-Version vergleicht. Separate Datenbanken bieten jedoch eine hervorragende Datenisolierung und IMO hat geringere Hosting-Kosten. Es ist nicht für alle Szenarien eine Lösung. Wenn Ihr System niemals außerhalb Ihres Hostings gehostet werden sollte und eine schnelle Skalierung der Kunden erforderlich war und es wünschenswert war, alle Benutzer auf derselben Version des Anwendungs- und Datenbankschemas zu haben, ist eine einzige Datenbank sicherlich der bessere Ansatz.

Thomas
quelle
2
Ich führe Webdienste sowohl mit der gemeinsam genutzten Datenbank als auch mit separaten Datenbank-Setups für mehrere Mandanten aus. Es gibt Zeiten, in denen beide die richtige Wahl sind. In der App, in der ich eine separate Datenbank pro Kunde habe, habe ich genau dieselben 5 Gründe, warum es die richtige Wahl für diese App war.
Dan Grossman
Die aktuelle serverlose Cloud-Datenbank Aurora von Amazon stellt angeblich automatisch mehr Ressourcen zur Verfügung, wenn sie für eine höhere Auslastung benötigt wird, und sie scheint das Design einer einzelnen Datenbank zu fördern. Aber ich verstehe es nicht ganz. Ich denke, ich werde mit einem einzelnen DB gehen, mit separaten Tabellen für jeden Benutzer. Dies könnte es einfacher machen, sie in separate DBs aufzuteilen, wenn dies erforderlich ist, und es wird einfacher, aggregierte Abfragen für alle Benutzerdaten durchzuführen.
Buttle Butkus
Beachten Sie Folgendes: Ich habe alle meine Kunden in einer Datenbank und verwende eine Datenbank-Code-Ebene, die sicherstellt, dass jede Abfrage kundenspezifische Kriterien enthält. Das Gefährliche ist, wenn Sie sich aus der Datenbankebene entfernen müssen, um etwas sehr Spezifisches zu tun - wie eine schrecklich große, komplizierte Abfrage, bei der Daten von einem unerwarteten Ort eindringen können.
Enigma Plus
14

Nach meiner Erfahrung sollten Sie nicht eine Datenbank pro Kunde erstellen. Lassen Sie mich Ihnen ein Beispiel geben:

Letztes Jahr habe ich mit 70 Datenbanken gearbeitet (viel weniger als 5000), jede mit demselben Schema und allen. Theoretisch würde alles wie geplant verlaufen (wie Sie im Abschnitt über die Vorteile erwähnt haben), aber in Wirklichkeit nicht so sehr. Wir hatten viele Probleme mit der Aktualisierung von Schemas, der Benutzerunterstützung und der Softwareaktualisierung. Es war furchtbar.

Wir haben Firebird verwendet und ich wurde so eingestellt, nachdem das Produkt versandt wurde, aber dies gab mir das Wissen, niemals mit getrennten Datenbanken zu arbeiten.

Ich sage nicht, dass Sie es nicht schaffen können, ich sage, dass Dinge sehr schief gehen können, und um ehrlich zu sein, Ihre Vorteilsliste klang nicht ansprechend genug, um das Risiko einzugehen. Die meisten von ihnen können mit einer einzigen Datenbank durchgeführt werden.

Eiefai
quelle
Wir haben eine Multiple Listings-Datenbank implementiert, die mehrere Kunden bedient. Wir sind in einer Situation gelandet, in der Kunden anfingen, benutzerdefinierte Ergebnisse zu wollen. Um dieses Problem zu lösen, haben wir die gespeicherten Prozesse geklont, ihnen eindeutige Kundennamen-Präfixe gegeben und sie dann aus der Anwendung heraus aufgerufen. Auf der anderen Seite haben wir 150 Webstores mit jeweils eigener Datenbank verkauft (97% gleich). Beides ist also situationsabhängig.
Michael Riley - AKA Gunny
Nett. Ich sage nicht, dass es nicht geht, nur, dass es nicht so einfach ist, wie es sich anhört, gut für dich, Gunny.
Eiefai
1
Wäre nett, wenn Sie Beispiele geben könnten, was genau schief gelaufen ist. Sicher ist es schwieriger, alle Datenbanken auf dem neuesten Stand zu halten, aber um zu entscheiden, müssen wir in der Lage sein, die Vor- und Nachteile zu messen.
Boris Callens
9

Sie möchten wahrscheinlich eine andere Datenbank führen, um zu verfolgen, auf welcher Version sich jeder Kunde befindet, damit Sie nachverfolgen können, welche die letzte Runde der Änderungen durchlaufen haben oder nicht.

Das Scripting der Upgrades wäre nicht so schwierig ... Sie könnten etwas schreiben, das den Katalog der Datenbanken betrachtet und die notwendigen Änderungen anwendet, um jede Datenbank auf die neueste Version zu bringen, und möglicherweise diejenigen überspringen, die aus irgendeinem Grund nicht aktualisiert werden sollten.

Da mysql-Datenbanken nur Schemata sind, können Sie, wie Gaius betonte, den Namen der Tabellen, die Sie ändern möchten, einfach qualifizieren oder Informationen aus folgenden Quellen abrufen:

alter schema.table ...
select ... from schema.table

...

Wenn Sie anfangen, Dinge auf mehreren Servern aufzuteilen, können Sie dennoch ein Skript erstellen, das Verbindungen zu mehreren Servern herstellt, damit Sie alle Änderungen anwenden können. Für die Analyse könnten Sie wiederum eine Reihe von Datenbankverknüpfungen mithilfe von Verbundtabellen in Ihrer master-Datenbank festlegen, um von einer Stelle aus auf die Daten zuzugreifen, da Sie nur aus den Tabellen lesen würden.

...

Beachten Sie auch, dass sie nicht mySQL für den Stapelaustausch verwenden, sondern SQL Server.

Und ich habe keine Ahnung, wie hoch der Performance-Aufwand in dieser Größenordnung in MySQL sein würde. Ich glaube nicht, dass ich jemals über 30 'Datenbanken' in MySQL hinausgekommen bin.

Joe
quelle
Warum nicht eine Versionsinformationstabelle in Ihrer Datenbank selbst aufbewahren?
Boris Callens
@Boris: Weil es viel ärgerlicher ist, sich mit jeder Datenbank zu verbinden und sie nach ihrer Version zu fragen, wenn Sie Dutzende oder Hunderte von Datenbanken haben. Es ist keine schlechte Idee für jeden, sich selbst zu verfolgen, aber es lohnt sich auch, eine Masterliste für den DBA zu haben
Joe,
7

Ich habe einen Web- / DB-Hosting-Client, der über 750 Kundendatenbanken mit der gleichen Anzahl von Tabellen (162) und den gleichen Tabellenstrukturen verfügt. Zusammen ergeben alle Kundendaten meines Kunden 524 GB (95% InnoDB).

Stellen Sie sich all diese Datenbanken vor, die auf neun DB-Servern über eine zirkuläre Replikation um 13 GB Innodb-Pufferpool konkurrieren. Mit dieser Hardwarekonfiguration zu skalieren war nicht genug. Wir haben dem Kunden sofort empfohlen, zu skalieren.

Wir haben diesen Client kürzlich auf 3 DB-Server mit weitaus mehr Leistung migriert. Wir haben sie von MySQL 5.0.90 auf MySQL 5.5.9 aktualisiert. Dramatische Unterschiede waren fast augenblicklich zu sehen.

Das Skalieren muss ebenfalls berücksichtigt werden, da bei Hunderten von Clients, die dieselben Speicher- und Datenträgerressourcen verwenden, die Auslastung durch das Skalieren linear verringert wird (O (n)), wobei n auf der Anzahl der DB-Server in einer Multimaster-Umgebung basiert.

Bei meinem Kunden reduziert meine Firma ihn von 9 DB-Servern (Quad Code, 32 GB RAM, 824 G RAID10) auf schnellere DB-Server (Dual HexaCore [das sind 12 CPUs], 192 GB RAM, 1,7 TB RAID10) von MySQL 5.5 .9 (um die Vorteile mehrerer CPUs zu nutzen). Stellen Sie sich außerdem einen 150-GB-Innodb-Pufferpool in 50 Partitionen mit jeweils 3 GB vor (Mehrere InnoDB-Pufferpools sind eine neue Funktion in MySQL 5.5). Ein kleineres, aber massives Scale-out hatte für die einzigartige Infrastruktur meines Kunden funktioniert.

MORAL DER GESCHICHTE : Skalieren oder Verkleinern ist nicht immer die Lösung, wenn Sie schlecht gestaltete Tische haben. Was ich damit meine, ist Folgendes: Wenn Indexseiten ein schiefes Schlüsselaufkommen für mehrspaltige Indizes aufweisen, führt das Abfragen von Schlüsseln aus den schief liegenden Teilen von Indizes zu einem Tabellenscan nach dem anderen, oder zumindest zu Indizes, die aufgrund des Ausschlusses durch die MySQL-Abfrage nie verwendet werden Optimierer. Es gibt einfach keinen Ersatz für die richtige Gestaltung.

RolandoMySQLDBA
quelle
2
Ich weiß, dass dies wirklich alt ist, aber ich frage mich, was die Begründung für Ihren Kommentar zu SSDs in Umgebungen mit hohem Schreibaufwand ist. Kannst du mich aufklären?
Elixenide
4
@EdCottrell Ich vermute, dies war eine Warnung vor eingeschränkten Schreibzugriffen auf SSDs. Irgendwann nutzt dies das Laufwerk bis zu dem Punkt, an dem es nicht mehr verwendet werden kann. Ich glaube, dass in den letzten Jahren das TRIM und andere Technologien in die SSD-Controller-Chips eingebaut wurden, um diese Probleme größtenteils zu lindern, so dass die SSD schreiben kann ist nicht so ein Problem, obwohl ich sicher bin, dass es immer noch ein Problem sein kann.
Shaunhusain
2

MySQL erstellt Datenbanken in separaten Verzeichnissen, so dass vieles vom zugrunde liegenden Betriebssystem und der Anzahl der Ordner / Datei-Handles abhängt, die es verarbeiten kann. Sollte bei modernen Betriebssystemen kein Problem sein, aber von dort wird ein Großteil des Engpasses ausgehen.

David Hall
quelle
1

Es gibt nichts, was besagt, dass Sie verschiedene Versionen der Datenbank oder App hosten müssen. Was ist falsch daran, die Daten einfach zu isolieren, indem man eine Datenbank pro Kunde erstellt und eine Version der Datenbank und der App besitzt? Natürlich müsste jede Kunden-Datenbank von einer Vorlage der aktuellen Arbeitsversion geklont werden. Unter dem Gesichtspunkt der Sicherheit und Datenisolierung halte ich dies für ideal.

Der einzige Nachteil, den ich sehen kann, ist, dass Sie jede Datenbank manuell aktualisieren müssen, wenn Sie eine neue Version erstellen. Dies könnte jedoch leicht automatisiert werden.

Sean Siegel
quelle