Viele Tabellen für viele Benutzer?

Ich habe eine Webanwendung, die in vielerlei Hinsicht als Multi-Tenant-Umgebung betrachtet werden kann. Damit meine ich, dass jeder Benutzer der Anwendung seine eigene "benutzerdefinierte" Umgebung erhält, mit keinerlei Interaktion zwischen diesen Benutzern.

Bisher habe ich die Web-Anwendung als "Single-User" -Umgebung erstellt. Mit anderen Worten, ich habe eigentlich nichts unternommen, um Multi-User zu unterstützen, sondern habe nur an der functionalität gearbeitet, die ich von der App haben möchte. Hier ist mein Problem … Was ist der beste path, um eine Multi-User-Umgebung zu erstellen:

  1. Alle Benutzer verweisen auf dasselbe "core" -Backend. Mit anderen Worten, ich erstelle die Logik, um Benutzer über geeignete SQL-Abfragen zu trennen (z. B. * aus der Tabelle auswählen, wobei Benutzer = '123' und Attribut = '456').
  2. Jeder Benutzer zeigt auf einen eindeutigen Tablespace, der separat erstellt wird, wenn sie dem System join. In diesem Fall würde ich einfach ALLE relevanten SQL-Tabellen pro Benutzer erzeugen, mit einer Art Suffix für den Benutzer. (zB würde jetzt eine Abfrage wie 'Select * from table_ where attribute =' 456 'aussehen).

Kurz gesagt, es ist ein Unterschied zwischen "Wählen * aus der Tabelle, wo USER =" und "Wählen * aus Table_USER".

Solutions Collecting From Web of "Viele Tabellen für viele Benutzer?"

Das dynamische Erstellen von Tabellen ist ziemlich dreckig und verwirrend. Außerdem, wenn Sie viele Benutzer haben, wird es ein totales Chaos sein, wenn Sie Tonnen von Tabellen haben – besonders wenn Sie etwas in n Tabellen statt einer einzelnen Tabelle ändern müssen.

-> Verwenden Sie eine Tabelle und fügen Sie eine Spalte user_id hinzu . Bei geeigneten Indizes ist dies genauso schnell oder sogar schneller als bei einzelnen Tabellen.

Die erste Option ist besser.

Im Allgemeinen sollten Tabellen normalisierte data enthalten, Sie sollten nicht dieselbe Tabelle duplizieren.

Auch die erste Option ist sicherer, da Sie nicht die Möglichkeit haben müssen, echte Tabellen für das Programm zu erstellen oder zu löschen

Ich würde sagen, dass deine Wahl abhängt. Sie haben wirklich drei Möglichkeiten:

Eine database, um alle zu regeln … (Deine Wahl 1)

Das Hinzufügen einer TenantId Spalte erleichtert das Hinzufügen neuer Mandanten (Benutzer). Es gibt jedoch einige Nachteile:

  1. Sie müssen darauf achten, dass jede Abfrage nach TenantId gefiltert wird. Es wird sehr leicht sein, die TenantId versehentlich an der richtigen Stelle zu vergessen und die data des anderen Mieters zurückzugeben.
  2. Alle übergeordneten Tabellen der obersten Ebene müssen eine TenantId enthalten. Es sind nicht nur Ihre Hauptdaten, sondern alle mandantenspezifischen Stammdaten.
  3. Mieter können nicht zu unterschiedlichen timeen unterschiedliche Schemaversionen haben. Angenommen, Sie nehmen in der Version 1.1 Ihrer Anwendung einige dataschemaänderungen vor. Wenn sich alle Mandanten in derselben database befinden, müssen alle gleichzeitig aktualisiert werden, unabhängig davon, ob Sie sie haben möchten oder nicht. Wenn Sie eine einzelne database verwenden, sind Sie außerdem fast gezwungen, eine einzelne Site zu verwenden, um sicherzustellen, dass die Site und das Schema synchron bleiben. Wenn Sie dies tun, können Sie beispielsweise keine Person für ein Upgrade aufladen, um eine neue function zu erhalten. Die Features müssen als Plug-ins im Gegensatz zu versionsspezifischen Updates erstellt werden, was zwar keine schlechte Sache ist, aber von Anfang an eine bewusste Entscheidung sein muss.
  4. Es kann mühsam sein, die data des Mieters zu trennen, wenn sie eine Kopie ihrer data haben möchten oder ihre eigenen data hosten möchten oder wenn Sie sie auf einen anderen databaseserver verschieben möchten. Da alle Ressourcen gemeinsam genutzt werden, kann es vorkommen, dass ein Mandant Ressourcen über Berichte oder dataverkehr auffrisst, sodass Sie sie auf ihren eigenen databaseserver verschieben und diesen Vorteil aufstocken können. Außerdem bin ich auf Situationen gestoßen, in denen Mieter eine Kopie ihrer data wünschen, die sie selbst herunterladen können. Wenn sich alle data in einer einzigen database befinden, kann dies mühsam sein.

Wenn Sie an Firmenkunden verkaufen, würde ich diesen path nicht gehen. Wenn Sie jedoch Tausende von Endbenutzern als Mandanten hinzufügen möchten, für die Sie keine data bereitstellen müssen, ist die Verwendung einer einzigen database wahrscheinlich der richtige Ansatz.

Segment Tenants nach Schema (zB Tenant1.Table1, Tenant1.Table2 … Tenant2.Table1, Tenant2.Table2 …) (Ich glaube, Ihre Wahl 2)

IMO, das ist eine schwierigere Version der Verwendung von separaten databaseen. Es hat den Vorteil, dass die Wartung der einen database ein wenig einfacher ist, aber darüber hinaus die gleichen Probleme wie die Verwendung separater databaseen hat.

Segmentmandant pro database

Für Firmenkunden habe ich herausgefunden, dass dies am Ende am einfachsten ist. Es beseitigt die Möglichkeit, dass der Mieter die falschen data sieht (außer die Verbindungszeichenfolge ist falsch). Es ermöglicht Unternehmen, ihr eigenes System zu hosten. Es ermöglicht Mandanten, unterschiedliche Versionen zu verwenden, wenn Sie unterschiedliche virtuelle Anwendungen pro Mandant haben. Es erleichtert die Ressourcenzuweisung, Sicherungen und Wiederherstellungen. Es ist nur (aber nicht unbedeutend) Nachteil ist die time Kosten der Einrichtung (und damit finanzielle Kosten). Es kann ein Problem sein, databaseen hinzuzufügen, wenn Sie einen neuen Client erhalten. Technisch könnte es automatisiert werden, aber es ist immer noch ein Schmerz.

Am Ende kommt es auf Ihren Zielkunden an. Wenn sie Standardbenutzer sind, würde ich mit dem Ansatz "Eine database, um alle zu regeln" gehen und sicherstellen, dass Sie viele Codeüberprüfungen und automatisierte Tests durchführen. Wenn es sich um Firmenkunden, insbesondere große Firmenkunden handelt, würde ich separate databaseen pro Mandant in Betracht ziehen.

Die einzige Möglichkeit, separate Tabellen für jeden Mandanten zu erstellen, ist, wenn Sie für jeden Mandanten eine separate database haben. In diesem Fall haben die Tabellen immer noch dieselben Namen.

Andernfalls verwenden Sie für jede Entität eine einzelne Tabelle und filtern sie nach Mandanten-ID.

Wenn Sie SQL server verwenden, empfehle ich, einzelne Tabellen für alle Mandanten zu verwenden, keinen Zugriff auf die Basistabellen für die von der Anwendung verwendete Anmeldung zu gewähren und den Zugriff auf inline-Tabellenwerte zu beschränken. Diese sind wie parametrisierte viewen und bedeuten, dass niemand mit Zugriff auf diese eine Gruppe für mehr als einen Mandanten in einem einzigen Aufruf abrufen kann (also keine versehentliche Verknüpfung mit dem Produktkatalog einer anderen Person):

 CREATE TABLE [dbo].[mt]( [ID] [int] IDENTITY(1,1) NOT NULL, [TenantID] [int] NOT NULL, [BusinessKey] [varchar](50) NOT NULL, CONSTRAINT [PK_mt] PRIMARY KEY CLUSTERED ( [ID] ASC ), CONSTRAINT [IX_mt] UNIQUE NONCLUSTERED ( [TenantID] ASC, [BusinessKey] ASC )) CREATE FUNCTION f_mt ( @TenantID AS INT ) RETURNS TABLE AS RETURN ( SELECT * FROM mt WHERE TenantID = @TenantID ) 

Wenn Sie die TenantID irgendwo in der Verbindung gespeichert haben (unter Verwendung von CONTEXT_INFO ()), ist es auch möglich, einfache viewen zu haben, die diese umbrechen:

 CREATE VIEW vw_mt AS SELECT * FROM f_mt(CONTEXT_INFO()) 

Es hängt alles davon ab, wie viel Abstraktion du damit umgehen willst.