Identitätsspalten oder UDF, die explizit eine eindeutige ID generieren?

11

Ich bin mitten in einer Debatte darüber, ob es besser ist, eine zu machen PRIMARY KEY aus einer Identitätsspalte eine aus einer UDF zu machen, die explizit eine eindeutige ID generiert.

  • Ich argumentiere für die Identitätsspalte.
  • Mein Partner plädiert dafür, die Werte manuell zu generieren, behauptet er
    • indem wir die UDF auf einen anderen Tisch legen, an dem wir eine UDF haben können
      • Sperren Sie die Ressource
      • Inkrementieren Sie eine ID-Tabelle mit einem aufgerufenen Feld ID_Value von wird1
      • Verwenden Sie dies als globale eindeutige Kennung
    • Oder lassen Sie den Tisch eine machen id+1 beim Einfügen ausführen
    • Dass es einfacher ist, Daten zwischen Servern und / oder Umgebungen zu verschieben, für die keine Identifizierungsbeschränkung besteht. Verschieben von einer Datenbank, in der Daten vorhanden sind, in eine andere ähnliche Datenbank mit beispielsweise Staging- oder Dummy-Daten. Für Tests in der Nichtproduktion möchten wir möglicherweise alle Datensätze von gestern bis zum Staging zum Testen herunterziehen.

Welche Implementierung ist sinnvoller?

Kakalapy
quelle

Antworten:

21

Ihr Kollege ist ein Idiot.

Die Lösung ist nicht skalierbar, die UDF ist nicht gleichzeitig (aus demselben Grund ). Und wie gehen Sie mit mehrzeiligen Einfügungen um: Dies würde einen UDF-Aufruf pro Zeile erfordern

Und die Migration auf ein anderes RDBMS kommt im wirklichen Leben nicht oft vor ... Sie können SQL Server jetzt genauso gut nicht verwenden und Sequenzen unter Oracle verwenden und hoffen, dass Sie nicht weg migrieren.

Bearbeiten:

Ihr Update besagt, dass das Verschieben von Daten zum Aktualisieren von Nichtproduktionsdatenbanken dient.

In diesem Fall ignorieren Sie die Identitätsspalten beim Aktualisieren. Sie gehen bei Ihrer Implementierung keine Kompromisse ein, um das Laden ohne Produkte zu vereinfachen. Oder verwenden Sie temporäre Tabellen, um die Änderungen des Identitätswerts zu verfolgen.

Oder verwenden Sie Prozesse: Wir aktualisieren unser Testsystem jede Nacht aus der Produktion, wodurch das Problem vollständig vermieden wird. (Und stellt sicher, dass unser Produkt-Backup auch wiederhergestellt werden kann)

gbn
quelle
11

Verwenden Sie einen Identitätswert. Das Generieren einer eigenen Sequenztabelle und von Sequenzwerten erfordert viel Aufwand und verursacht viel Sperren und Blockieren beim Versuch, Zahlen zu generieren.

Identität existiert aus einem Grund, benutze sie.

Wenn SQL Denali herauskommt, werden Sequenzen unterstützt, die effizienter als die Identität sind, aber Sie können selbst nichts Effizienteres erstellen.

Wenn Sie Datensätze von einer Umgebung in eine andere verschieben möchten, aktivieren Sie entweder IDENTITY_INSERT beim Einfügen oder aktivieren Sie das Kontrollkästchen in SSIS.

mrdenny
quelle
Wenn Sie von "Produktion" zu "Test" wechseln und über ein Identitätsfeld verfügen, besteht die Gefahr, dass Daten überschrieben werden oder kollidieren. Das ist alles, was ich sage. Ja, es sollte kein Problem in diese Richtung sein, aber ich sage nur, dass es passieren könnte.
Jcolebrand
Richtig, Sie haben dieselbe Nummer für verschiedene Zeilenwerte in dev, test, qa, uat und Production. Na und? Wenn diese Werte wichtig sind (wie bei einer Nachschlagetabelle), codieren Sie sie manuell fest, was kein Problem sein sollte, da Sie nicht sehr oft Werte in diese Tabellen einfügen sollten. Wenn Sie die Identitätswerte zwischen den Umgebungen steuern müssen, um Kollisionen zu vermeiden, setzen Sie die Identitätswerte zwischen den Umgebungen zurück, wenn Sie aus der Produktion wiederherstellen.
Mrdenny
5

Die Identitätsspalte klingt für mich gut. Ich bin nicht sicher, ob ich der Logik folge, warum es schwierig ist, Daten zwischen Servern zu verschieben.

Wenn Sie möchten, dass jede Zeile eine global eindeutige Identität hat, können Sie eine UUID verwenden, aber ich würde dies nicht tun, es sei denn, Sie sind sicher, dass die globale Eindeutigkeit erforderlich ist - normalerweise nicht. Die Verwendung von UUIDs als IDs verringert die Leistung, erhöht den Speicherplatzbedarf und erschwert das Debuggen. Aufgrund der Länge ist es schwierig, sich eine UUID zu merken, sie jemandem über das Telefon mitzuteilen oder sie fehlerfrei auf Papier zu schreiben.

Mark Byers
quelle
4

Für einfache numerische IDs gehen Sie einfach mit Identität und vergessen Sie alle Probleme, sie manuell zu generieren.

Sie können jederzeit eine "Supertabelle" erstellen, die eine Identität als PK verwendet und über eine Typspalte sowie andere Informationen verfügt. Wenn Sie eine neue ID benötigen (vorausgesetzt, Sie meinen eindeutige IDS für verschiedene Tabellen), fügen Sie diese einfach in diese Tabelle ein und greifen Sie auf die zuSCOPE_IDENTITY() und fügen Sie sie dann in die tatsächliche Tabelle ein, die Sie benötigen.

Grundsätzlich erstellen Sie eine Tabelle: MasterIDs mit einer Identitäts-PK, wenn Sie eine Zeile in Ihre Tabelle1 einfügen müssen, INSERT INTO MasterIDsund erhalten die von dieser Zeile generierte Identität mithilfe von SCOPE_IDENTITY()und fügen sie dann mit diesem Wert als PK in Tabelle1 ein .

Tabelle 1 hat eine Nichtidentität int PK. Sie würden den gleichen Vorgang zum Einfügen in Tabelle 2 usw. ausführen. Lassen Sie SQL Server die Identitätswerte in der MasterIDs- Tabelle verwalten, die Sie dann in Ihren anderen Tabellen verwenden können. MasterIDs können andere Tabellen enthalten, z. B. type (damit Sie wissen, welche Tabelle, Tabelle1 oder Tabelle2 usw. diesen Identitätswert verwendet.

Paul White 9
quelle
3

Solange Sie Fremdschlüsseleinschränkungen ordnungsgemäß verwenden (Kaskadierung, Aktualisierung usw.), können Sie problemlos ein Identitätsfeld verwenden. Ich sehe in diesem Fall wirklich keinen Vorteil gegenüber der anderen Lösung.

Joe Phillips
quelle
2

Die Identität wurde passend zu Ihrem Szenario erstellt. Sie haben Tools wie die Replikation für den Datenaustausch zwischen Server und Umgebung, die alles zusammenhalten.


quelle
1

Ich habe gerade eine Arbeit beendet, bei der ich eine SQL Server- identitySpalte durch ein normales intFeld ersetzt und die ID-Zuweisung selbst gesteuert habe.

Ich habe ziemlich beeindruckende Leistungssteigerungen gesehen. Im Gegensatz zum OP habe ich keine UDF, um die ID zu generieren. Das Prinzip ist jedoch ziemlich dasselbe: Es gibt einen Teil der Software, der einen Pool von IDs verwaltet. Wenn sie leer sind, wird ein weiterer Stapel abgerufen, indem die Datenbank nach dem nächsten niedrigen Wert abgefragt und auf den nächsten hohen Wert erhöht wird .

Auf diese Weise können wir IDs generieren und alle Entitäten außerhalb einer Transaktion in unserem ORM verknüpfen, bevor wir die Stapel an die Datenbank senden. Außerdem können wir größere Stapel ohne zusätzliche Roundtrips senden, um die gerade eingefügte Identität zu erhalten (erforderlich für Identitätsspalten).

In der ID-Tabelle gibt es mehr als eine Zeile, sodass wir auf Wunsch bestimmte Bereiche verwenden können. dh zur Wiederverwendung gelöschter Blöcke und negativer IDs.

Kennzeichen
quelle
0

Ich benutze Identität seit Jahren und denke ernsthaft darüber nach, die Identitätsnummer durch UNIQUEIDENTIFIER zu ersetzen. Es ist ein Albtraum, wenn Sie den Datentyp ändern müssen, wenn jemand ihn als kompakte Datenbank konzipiert hat, und ein Albtraum, wenn Sie einer Spalte Identität hinzufügen müssen. Außerdem können Sie die Identitätsspalte nicht aktualisieren. Stellen Sie sich vor, Sie geben ein int ein und Ihre Datenbank wächst über 2 Milliarden Datensätze hinaus, was wiederum ein Albtraum ist (FKs berücksichtigen)! Etwas mit Identität zu ändern ist ein Albtraum und nicht skalierungsfreundlich, es sei denn, Sie setzen Bigint! UNIQUEIDENTIFIER vs Identity = Bequemlichkeit und Robustheit vs möglicherweise spürbare Leistungsverbesserung (hat den Benchmark nicht erreicht).

Update: Nachdem ich gesehen habe das lehne ich mich auf jeden Fall in Richtung UNIQUE. Dies zeigt keinen wirklichen Vorteil der Bigint-Identität und eine Reihe von Vorteilen für UNIQUEIDENTIFIER! Unterschiedliche Versionen von SQL Server können zu unterschiedlichen Ergebnissen führen. Es ist einfach schön, eine eindeutige ID für alle Datenbanken und Systeme zu haben (Robustheit)! Verschieben, kopieren, transformieren Sie Daten nach Belieben! https://www.mssqltips.com/sqlservertip/5105/sql-server-performance-comparison-int-versus-guid/

Hrvoje Batrnek
quelle
Ein 64-Bit-INT wird eine lange lange Zeit
dauern