Seite 1 von 3

Getrennte Datenbank für jeden Mandanten

Verfasst: Mo 12. Jan 2009, 20:24
von rethus
Gibt es wieder was neues in Bezug auf die Datenbank-Struktur in Verbindung mit den Mandanten?

Momentan besteht ja das Problem, das bei einem Multi-Mandanten-Betrieb eine Datenbanksicherung immer alle Mandanten sichert... somit ein Datenbackup - insbesondere das zurückspielen des Backups,,, nicht Mandantenunabhängig geht...

Das stellt vor allem Probleme dar, wenn es sich bei den Mandanten um unabhängige Kunden handelt.

Beispiel:
Kunde 1 hat bei der Datenpflege einen Fehler gemacht und möchte den Datenstand von "vor 3 Wochen" herstellen. Alle anderen 20 Mandanten wollen aber nicht auf diesen Stand zurück.
Da die Daten alle in einer DB liegen, und nicht Kundenspezifisch sind, ist dies derzeit unmöglich.

Gibt es auf diesem Gebiet schon was neues... bzw, sind definitive Pläne gefasst worden?

Verfasst: Di 13. Jan 2009, 11:42
von Oldperl
Hallo rethus,

ich denke mal eher "nein", da dazu der komplette Core umgebaut werden müsste. Im Moment werden die Mandanten-Daten für alle Mandanten in den gleichen DB-Tabellen verwaltet.
Um eine backupfähige Trennung der Mandanten zu erreichen, müßten diese immer in eigenen DB-Tabellen gepflegt werden.

Da du selbst seit einiger Zeit an einem Plugin arbeitest und wohl inzwischen auch ein wenig mehr den Aufbau der DB kennengelernt hast, kannst du dir sicher vorstellen, wie viel Aufwand das ist.

Gruß aus Franken

Ortwin

Verfasst: Di 13. Jan 2009, 16:56
von rethus
Ja, das kann ich mir vorstellen.
Schön wäre, wenn sich hier ggf. ein Arbeitskreis bilden könnte, der sich dieser Sache mal annimmt.

Also erstmal Konzept machen, dann Schritt für Schritt umsetzen. Vorausgehen muss natürlich die Zusage, dass dies ins nächste Release aufgenommen wird.

Also wer wäre dabei?

Re: Getrennte Datenbank für jeden Mandanten

Verfasst: Mi 14. Jan 2009, 00:15
von xmurrix
Hallo rethus,

was haltest du von der Idee, die Datenbankzugangsdaten konfigurierbar zu machen, so dass anhand der Clientid oder des Hosts eine andere DB-Connection aufgebaut wird.

Eine Quich'n Dirty Lösung wäre z. B. in der conlib/local.php den Constructor von DB_Contenido zu erweitern, z. B.

Code: Alles auswählen

  function DB_Contenido($Host = "", $Database = "", $User = "", $Password = "")
  {
      global $cachemeta, $contenido_host, $contenido_database, $contenido_user, $contenido_password;
      
      global $client;
      
      if ($client == 'foo') {
        $contenido_host = 'localhost';
        $contenido_database = 'foo_db'
        $contenido_user = 'root';
        $contenido_password = 'top_secret';
      } elseif ($client == 'bar') {
        $contenido_host = 'localhost';
        $contenido_database = 'bar_db'
        $contenido_user = 'root';
        $contenido_password = 'top_secret';
      }
Ob die Variable $client immer korrekt zur Verfügung steht, kann ich schwer abschätzen, aber Versuchen kann man es trotzdem.

Einen neuen Client müsste man vermutlich über den Contenido-Setup anlegen, und die neuen Zugangsdaten inder conlib/local.php manuell nachziehen.

Einen Nachteil hat die ganze Sache natürlich, Clientunabhängige Datensätze (Contenido Konfiguration, BackendUser, usw...) sind dann Redundant zu pflegen.

Gruß
xmurrix

Verfasst: Mi 14. Jan 2009, 10:11
von MichFress
Mhm, nur so ein Gedanke, aber wie weit kommt man eigentlich, wenn man anhand der $client-Variabe die mandantenspezifischen Tabellen lädt?

Code: Alles auswählen

switch($client){
    case 1:
        $cfg['tab']['art'] = "db1.con_art";
        $cfg['tab']['cat'] = "db1.con_cat";
    case 2:
        $cfg['tab']['art'] = "db2.con_art";
        $cfg['tab']['cat'] = "db2.con_cat";
}
// mandantenübergreifend:
$cfg['tab']['irgnwas'] = "con_irngwas";
Durch den Verzicht auf auto_increment und der Nutzung der con_sequence-Tabelle dürften irgendwelche IDs da wohl kein Problem darstellen.

Verfasst: Mi 14. Jan 2009, 11:04
von xmurrix
MichFress hat geschrieben:... aber wie weit kommt man eigentlich, wenn man anhand der $client-Variabe die mandantenspezifischen Tabellen lädt?...
Das setzen der Mandantentabellen anhand der $clientid wäre auch eine einfache Möglichkeit.

Aber da fällt mir noch folgendes ein. Ich weiß nicht, wo überall Abfragen auf Tabellen gehen, um irgendwelche Datensätze über alle Clients hinweg auszulesen.

Kurz zusammengefasst:
- Pro Client eine DB wäre strikt getrennt, dafür sind manche Daten redundant zu pflegen.
- Eine DB mit mandantenspezifischen Tabellen löst das Problem von oben, ein DB Backup würde aber die Tabellen aller Clients enthalten.

Die beiden Ansätze sollten wir weiter verfolgen, bin mir sicher, dass es mit beiden gehen sollte. Aber an ein paar Stellen (z. B. Mandantenverwaltung) wird es wohl mit beiden Lösungen Probleme geben.

Grüße
xmurrix

Verfasst: Mi 14. Jan 2009, 11:30
von MichFress
Ähm, achso... Mein Vorschlag bezog sich eigentlich auch auf verschiedene Datenbanken:
$cfg['tab']['art'] = "db1.con_art"; << bezieht sich auf die Tabelle "con_art" in der Datenbank "db1"

Eigentlich drängt es mich danach, das mal auszuprobieren - da fehlt mir leider nur die Zeit zu...

Verfasst: Mi 14. Jan 2009, 21:09
von langwebdesign
Hallo,

ich finde xmurrix Ansatz mit den verschiedenen Datenbank Konfigurationen nicht schlecht.

Die zu verwendende Datenbank sollte man gleich beim anmelden auswählen müssen. So könnte man mehrere DBs mit wiederum mehreren Mandanten haben.

Wer nur eine DB haben will kann weiter wie gewohnt arbeiten.

Die zusätzlichen DB Einstellungen müssten dann nach dem Setup in der config.php gepflegt und irgendwie abgefragt werden.

was haltet ihr davon?

mfg stephan

Verfasst: Mi 14. Jan 2009, 23:30
von JeromeW
Hallo,

ich glaube der Ansatz mit den verschiedenen Datenbanken, wobei jede Datenbank mehrere Mandanten haben kann, dürfte am schnellsten zu realisieren sein. Es sollte damit auch möglich sein bisherige Installationen zu aktualisieren.

Viele Grüße
JeromeW

Verfasst: Mi 14. Jan 2009, 23:59
von Ab7zCh3kR
Wir verwenden ein ähnliches Set-up und gingen dazu wie folgt vor: Wir nutzen eine Contenido-Installation für 2 Mandanten. Abhängig vom Servernamen setzen wir in der DB-Konfiguration den sqlprefix. Das einzig unschöne daran ist dass User, Templates, Module usw. doppelt (also für beide Mandanten) gepflegt werden müssen.

Ciao, Ab7zCh3kR

Verfasst: Do 15. Jan 2009, 08:52
von JeromeW
Vorschlag:

Die zusätzlichen DB Einstellungen in der config.php speichern (siehe Vorschlag langwebdesign), im Backend ein Auwahlmenü bzgl. der Datenbank einbauen und den Construktor mit der ausgewählten Datenbank füllen. Somit braucht der Construktor nicht verändert werden.

Ich weiss nicht wo überall die config.php gelesen wird, ich nehme aber an nur beim Start des Backends.

Viele Grüße
JeromeW

Verfasst: Fr 16. Jan 2009, 13:09
von rethus
Naja, ich hatte da damals auch in die DB geschaut. Und das größte Problem ist, dass Datensätze die mandantenspezifisch sind, mit Contenido-Core-Datensätzen wild durcheinadner gewürfelt sind (soweit ich mich erinner).

Den Ansatz, einfach ne andere DB anzugeben hatte ich auch schonmal durchdacht, führt aber zu rudimentären Daten und wird der Overkill bei einem Update.

Als saubere lösung müsste wirklich ein weiteres Aufdröseln der db-struktur her, welches es erlaubt über hilfstabellen den CORE von den Mandanten-Datensätzen zu trennen.

Man kennt es ja bei normalen Anwendungen auch...

Kategorie (id,kat_name)
Eintrag (id,eintrag)

wird verknüpfft über
eint_kat (id, eintrag_id, kat_id)

und schon sind beide Tabellen unabhängig über die hilfstabelle verknüpfbar. So... halt nur im größeren Stil müsste die DB aufgebort werden.
Wenns ein größeres Unterfangen ist würde sich ggf ein aufbohren auf eine Client-Server-Struktur lohnen. Damit wäre Contenido den anderen CMS-Systemen eine ganze länge voraus.

Verfasst: Fr 16. Jan 2009, 13:31
von Oldperl
Ich denke mal das sowas nur Schritt für Schritt umzusetzen ist.
Persönlich bevorzuge ich eine Lösung, die erst mal in derselben DB Tabellen mit einem suffix anlegt bei der Neuanlage eines Mandanten (z.B. _client1, _client2, _clientx).

Eine spätere zusätzliche Erweiterung für verschiedene Datenbanken/Mandant stellt dann IMO das kleinere Problem da.

Im Vorfeld ist dazu abzuklären, welche DB-Tabellen nur für den Core und welche für den Mandanten benötigt werden. Tabellen und deren Contenidofunktionen die für beides notwendig sind, müßten dann natürlich zuerst aufgespalten werden.
Benötigte Mandantentabellen beim Erstellen eines neuen Mandanten anzulegen stellt wohl das geringste Problem dar. Auch einen suffix in der $cfg['tab'] anzuhängen für benötigte Tabellen ist schnell gemacht.

Daher der 1. Schritt: Welche Tabellen werden rein für den Mandanten (Client), welche für den Core und welche gemischt verwendet?

Gruß aus Franken

Ortwin

Verfasst: Fr 16. Jan 2009, 14:12
von xmurrix
Hallo zusammen,

ich hatte mal damit angefangen, die DB-Struktur (vor allem die Beziehungen) von Contenido in DBDesigner zu definieren - leider konnte ich esaus zeitlichen Gründen nicht weiter verfolgen.

Mittlerweile gibt es ja die MySQL Workbench, mit der man die DB-Struktur importieren kann, das Ergebnis ist ein DB-Model, mit der man grob einen Überblick hat.

Dazu braucht man die Tabellen (inkl. Create Steatements) z. B. über phpMyAdmin exportieren, und in MySQL Workbench über "File -> Import -> Reverse Engineer MySQL Create Script" importieren.
Die Beziehungen zwischen den Tabellen sind halt nicht vorhanden.

Grüße
xmurrix

Verfasst: Fr 16. Jan 2009, 14:51
von JeromeW
Hallo,
Oldperl:
Persönlich bevorzuge ich eine Lösung, die erst mal in derselben DB Tabellen mit einem suffix anlegt bei der Neuanlage eines Mandanten (z.B. _client1, _client2, _clientx).
Klar, das ist auf jeden Fall die bessere Lösung, alles in einer DB und ein Contenido internes Backup/Restore System bei dem man die Mandanten auswählen kann. Dazu dann ein Konvertierungsprogramm, dass die alte DB Struktur in die neue Struktur umwandelt.

Kennt einer ein brauchbares UML Tool, in das man php Sourcen importieren kann?

Viele Grüße
JeromeW