Ich habe eine Datenbank, die von mehreren Clients verwendet wird. Ich möchte nicht, dass inkrementelle Schlüsselwerte zwischen den Clients bluten. Ich möchte, dass die Nummerierung bei 1 beginnt und kundenspezifisch ist.
Ich verwende einen zweiteiligen zusammengesetzten Schlüssel von tenant_id
sowie eine inkrementelle ID.
Was ist der beste Weg, um einen inkrementellen Schlüssel pro Mandant zu erstellen?
Ich verwende SQL Server Azure. Ich bin besorgt über das Sperren von Tabellen, doppelte Schlüssel usw. Ich würde normalerweise den Primärschlüssel für IDENTITY setzen und weitermachen.
Danke
Planen Sie in Zukunft SQL Azure Federations zu verwenden? Wenn dies der Fall ist, unterstützt die aktuelle Version von SQL Azure Federations die Verwendung von IDENTITY als Teil eines gruppierten Index nicht. Siehe hierzu Welche Alternativen? existiert für die Verwendung von GUID als Clustered-Index für Tabellen in SQL Azure (Federations) für weitere Details.
Wenn Sie Föderationen noch nicht angesehen haben, sollten Sie sie überprüfen, da dies eine interessante Möglichkeit bietet, die Datenbank und die Mandantenisolation in der Datenbank zu sharden.
Abhängig von Ihrem Endziel können Sie mithilfe von Föderationen eine GUID als primären gruppierten Index für die Tabelle verwenden und auch ein inkrementelles Feld INT IDENTITY für die Tabelle verwenden. Dieses Feld INT IDENTITY könnte Endbenutzern angezeigt werden. Wenn Sie auf der TenantID föderieren, wird jede "Tenant-Tabelle" effektiv zu einem Silo (wie ich es zumindest verstehe), so dass die Verwendung von IDENTITY auf einem Feld innerhalb dieser Tabelle effektiv ein immer größer werdender automatisch generierter Wert wäre, der innerhalb eines gegebenen Tenants inkrementiert .
Wenn Daten zusammengeführt werden (indem Daten von mehreren Mandanten kombiniert werden), würden Sie mit Kollisionen auf diesem INT IDENTITY-Feld enden (weshalb IDENTITY nicht als Primärschlüssel in Föderationen unterstützt wird), aber solange Sie nicht Wenn Sie dieses Feld als eindeutigen Bezeichner innerhalb des Systems verwenden, sollten Sie in Ordnung sein.
Wenn Sie den Komfort eines automatisch zugewiesenen eindeutigen INT-Schlüssels beim Einfügen kopieren möchten, können Sie einen INSTEAD OF INSERT
-Trigger hinzufügen, der MAX der vorhandenen Spalte +1 verwendet, um den nächsten Wert zu bestimmen.
Wenn die Spalte mit dem Identity-Wert der erste Schlüssel in einem Index ist, ist die MAX-Abfrage eine einfache Indexsuche, sehr effizient.
Transaktionen stellen sicher, dass eindeutige Werte zugewiesen werden, aber dieser Ansatz hat eine andere Sperrsemantik als die Standardidentitätsspalte. IIRC, SQL Server kann für jede Transaktion, die es parallel anfordert, einen anderen Identitätswert zuweisen, und wenn eine Transaktion zurückgesetzt wird, werden die ihr zugewiesenen Werte verworfen. Der MAX-Ansatz würde nur einer Transaktion erlauben, Zeilen gleichzeitig in die Tabelle einzufügen.
Ein verwandter Ansatz könnte eine dedizierte Schlüsselwerttabelle sein, die durch den Tabellennamen, die Mandanten-ID und den aktuellen Identitätswert verschlüsselt wird. Es würde den gleichen INSTEAD OF INSERT
Trigger und mehr Boilerplate erfordern, um diese Schlüsseltabelle abzufragen und zu behalten. Es würde jedoch parallele Operationen nicht verbessern; das Schloss wäre nur auf einer anderen Tabelle gespeichert.
Eine Möglichkeit, den Locking-Engpass zu beheben, wäre, die aktuelle SPID in den Wert des Schlüssels einzuschließen (jetzt ist der Identitätsschlüssel eine Kombination aus sequenziellem int und jedem SPID, der zugewiesen wurde und nicht einfach sequenziell), den dedizierten Identitätswert verwenden Tabelle und Einfügen von Datensätzen dort je SPID nach Bedarf; Die Identitätstabelle PK wäre (Tabellenname, Mandant, SPID) und hätte eine Nicht-Schlüsselspalte mit dem aktuellen sequentiellen Wert. Auf diese Weise hätte jede SPID ihren eigenen dynamisch zugewiesenen Identitätspool und würde immer nur ihre eigenen SPID-spezifischen Einträge haben.
Ein weiterer Nachteil ist die Beibehaltung von Triggern, die aktualisiert werden müssen, wenn Sie die Spalten in einer der speziellen Identitätstabellen ändern.
Tags und Links sql primary-key multi-tenant