Ich verwende in der Regel Auto-Inkrement-IDs als Primärschlüssel in Datenbanken. Ich versuche, die Vorteile der Verwendung von GUIDs zu lernen. Ich habe diesen Artikel gelesen: https://betterexplained.com/articles/the-quick-guide-to-guids/
Mir ist klar, dass diese GUIDs verwendet werden, um Objekte auf Anwendungsebene zu identifizieren. Werden sie auch als Primärschlüssel auf Datenbankebene gespeichert? Angenommen, ich hatte die folgende Klasse:
public class Person
{
public GUID ID;
public string Name;
..
//Person Methods follow
}
Angenommen, ich wollte eine neue Person im Speicher erstellen und dann die Person in eine Datenbank einfügen. Kann ich das einfach machen:
Person p1 = new Person();
p1.ID=GUID.NewGUID();
PersonRepository.Insert(p1);
Angenommen, ich hatte eine Datenbank mit Millionen und Abermillionen von Zeilen mit einer GUID als Primärschlüssel. Wird das immer einzigartig sein? Verstehe ich überhaupt GUIDs richtig?
Ich habe diesen Artikel früher gelesen: http://enterprisecraftsmanship.com/2014/11/15/cqs-with-database-generated-ids/ . Es verwirrt mich ein wenig, da es den Anschein hat, als würde ich ein fröhliches Medium zwischen GUIDs und Ganzzahlen als Primärschlüssel empfehlen.
Edit 11/06/18
Ich bin der Überzeugung, dass Guids für meine Anforderungen besser geeignet sind als Ints. Ich verwende CQRS heutzutage häufiger und GUIDs passen besser dazu.
Ich habe festgestellt, dass einige Entwickler die GUIDs als Zeichenfolgen im Domänenmodell modellieren, z. B. hier: https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/ Buyer.cs - in diesem Fall: IdentityGuid ist eine GUID, die als Zeichenfolge modelliert wird. Gibt es einen anderen Grund als den hier angegebenen: Verwenden Sie ein benutzerdefiniertes Wertobjekt oder eine Guid als Entitätskennung in einem verteilten System? . Ist es "normal", die GUID als Zeichenfolge zu modellieren, oder sollte ich sie als GUID in Modell und Datenbank modellieren?
quelle
Antworten:
GUIDs sind per Definition "Globally Unique IDentifiers". In Java gibt es ein ähnliches, aber leicht unterschiedliches Konzept mit der Bezeichnung UUIDs "Universally Unique IDentifiers". Die Namen sind für den praktischen Gebrauch austauschbar.
GUIDs sind von zentraler Bedeutung für die Funktionsweise von Microsoft-Datenbankclustern. Wenn Sie Daten aus manchmal verbundenen Quellen einbinden müssen, tragen sie wirklich dazu bei, Datenkollisionen zu vermeiden.
Einige Pro-GUID-Fakten:
Etwas hässlich mit GUIDs
Durch GUIDs werden Ihre Indizes größer, sodass die Speicherplatzkosten für die Indizierung einer Spalte höher sind. Zufällige GUIDs fragmentieren Ihre Indizes.
Wenn Sie nicht wissen, dass Sie Daten aus verschiedenen Netzwerken synchronisieren, können GUIDs mehr Aufwand verursachen, als sie wert sind.
Wenn Sie Daten von manchmal verbundenen Clients erfassen müssen, sind diese möglicherweise wesentlich robuster, um Schlüsselkollisionen zu verhindern, als wenn Sie Sequenzbereiche für diese Clients festlegen.
quelle
Immer? Nein nicht immer; Es ist eine endliche Folge von Bits.
Millionen und Abermillionen, Sie sind wahrscheinlich in Sicherheit. Eine Million Millionen, und die Wahrscheinlichkeit einer Kollision wird erheblich. Es gibt jedoch gute Nachrichten: Bis dahin ist der Speicherplatz bereits erschöpft.
Sie können; Es ist keine ganz gute Idee. Ihr Domain-Modell sollte normalerweise keine Zufallszahlen generieren. Sie sollten Eingaben für Ihr Modell sein.
Darüber hinaus schützt Sie eine deterministisch generierte UUID in einem unzuverlässigen Netzwerk, in dem möglicherweise doppelte Nachrichten angezeigt werden, vor doppelten Entitäten. Wenn Sie jedoch jedem eine neue Zufallszahl zuweisen, müssen Sie mehr tun, um die Duplizierung zu identifizieren.
Siehe die Beschreibung der namensbasierten UUID in RFC 4122
Ich denke nicht, dass es sehr wichtig ist. Bei den meisten Domain-Modellen handelt es sich um eine Kennung . Die einzige Frage, die Sie danach stellen, ist, ob sie mit einer anderen Kennung identisch ist oder nicht. In Ihrem Domain-Modell wird normalerweise nicht die speicherinterne Darstellung eines Bezeichners überprüft.
Wenn GUID in Ihrer Domain-Agnostic-Einstellung als "primitiver Typ" verfügbar ist, würde ich es verwenden. es ermöglicht dem unterstützenden Kontext, geeignete Optimierungen auszuwählen, die verfügbar sein können.
Was Sie jedoch erkennen sollten, ist, dass die Darstellung des Bezeichners sowohl im Speicher als auch im Speicher eine Entscheidung ist, die Sie in Ihrer Implementierung treffen, und daher sollten Sie Schritte unternehmen, um sicherzustellen, dass der Footprint des Codes damit gekoppelt ist Entscheidung ist klein - siehe Parnas 1972 .
quelle
Die GUID oder UUID ist aufgrund ihrer Generierung sehr wahrscheinlich eindeutig und bietet eine sichere Möglichkeit, die Eindeutigkeit zu gewährleisten, ohne mit einer zentralen Behörde kommunizieren zu müssen.
Vorteile von GUIDs als Primärschlüssel:
In dem von Ihnen angegebenen Beispiel:
Wenn Sie die GUID vor dem Einfügen angeben, kann beim Einfügen aufeinanderfolgender untergeordneter Datensätze ein Roundtrip in die Datenbank gespeichert werden, und Sie können sie in derselben Transaktion festschreiben.
Nachteile für GUIDs als Primärschlüssel:
Wenn Ihre Anwendung kein Sharding oder Clustering benötigt, sollten Sie sich an kleinere, einfachere Datentypen wie int oder bigint halten.
Viele Datenbanken haben ihre eigenen internen Implementierungen, die versuchen, die durch GUIDs verursachten Speicherprobleme abzumildern. SQL Server verfügt sogar über eine neue sequentielle ID , um die Reihenfolge der UUIDs zu vereinfachen und eine bessere Verwendung der Indizes zu ermöglichen, und sie weisen im Allgemeinen bessere Leistungseigenschaften auf.
Aus der Sicht eines Testers, Benutzers oder Entwicklers, der mit der Anwendung arbeitet, verbessert die Verwendung einer ID über eine GUID die Kommunikation erheblich. Stellen Sie sich vor, Sie müssen eine GUID über ein Telefon lesen.
Letztendlich ist es pragmatischer, sich an automatisch inkrementierende IDs zu halten, es sei denn, es sind umfangreiche Clustering- oder Verschleierungs-URLs erforderlich.
quelle
Ich würde nein sagen, keine GUIDs als Primärschlüssel verwenden. Ich habe gerade mit einer solchen Datenbank zu tun, und sie sind eine der Hauptursachen für Leistungsprobleme.
Die zusätzlichen 12 Bytes summieren sich schnell. Denken Sie daran, die meisten PKs sind FKs in anderen Tabellen, und nur drei FKs in einer Tabelle haben Sie jetzt 48 Byte mehr für jede Zeile. Das summiert sich in der Tabelle und in den Indizes. Es summiert sich auch in Festplatten-E / A. Diese zusätzlichen 12 Bytes müssen gelesen und geschrieben werden.
Und wenn Sie keine sequenziellen Guids verwenden und die PKs geclustert sind (was standardmäßig der Fall ist), muss SQL von Zeit zu Zeit ganze Seiten mit Daten verschieben, um sie an die richtige Stelle zu bringen. Bei einer hochgradig transaktionsbezogenen Datenbank mit vielen Einfügungen, Aktualisierungen und Löschvorgängen geht es schnell bergab.
Wenn Sie eine eindeutige Kennung für die Synchronisierung benötigen, fügen Sie eine Guid-Spalte hinzu. Mach es einfach nicht zum PK.
quelle
Dies ist mit Abstand der wichtigste Grund für die Verwendung von GUIDs.
Die Tatsache, dass Sie eine eindeutige ID erstellen können, ohne dass Ihr Code Ihre Persistenzschicht kennt oder mit dieser kommuniziert, ist ein großer Vorteil.
Sie können sicher sein, dass das soeben erstellte Personenobjekt auf Ihrem Server, PC-Telefon, Laptop, Offline-Gerät oder was auch immer auf all Ihren Servern auf der ganzen Welt einzigartig ist, jedoch verteilt.
Sie können es in jede Art von Datenbank rdb oder no-sql speichern, ablegen, an einen beliebigen Webservice senden oder es sofort als nicht benötigt wegwerfen
Nein, Sie werden niemals eine Kollision bekommen.
Ja, Einfügungen können etwas langsamer sein, da der Index möglicherweise geändert werden muss.
Ja, es ist größer als ein Int.
Ich weiß, dass viele Menschen Auto-Inc-Ints sehr ernst nehmen, und dies ist ein umstrittenes Thema bei DBAs
Aber ich kann wirklich nicht stark genug sagen, wie überlegen Guids sind. Sie sollten in jeder Anwendung standardmäßig Guids verwenden .
Auto Inc Ints haben viele, viele Mängel
Sie verwenden eine verteilte No-Sql-Datenbank. Sie können einfach nicht mit allen anderen Instanzen sprechen, um herauszufinden, was die nächste Nummer ist.
Sie verwenden ein Message Queue-System. Dinge brauchen Ausweise, bevor sie die Datenbank erreichen
Sie erstellen mehrere Elemente und bearbeiten sie vor dem Speichern. Jeder braucht eine ID, bevor Sie die DB getroffen haben
Sie möchten Zeilen löschen und erneut einfügen. Stellen Sie sicher, dass Sie Ihre Auto-Inc-IDs nicht hochzählen und leer sind!
Sie möchten nicht jedem Benutzer mitteilen, wie viele Bestellungen Sie in diesem Jahr entgegengenommen haben
Sie möchten anonymisierte Daten aus der Produktion verschieben, um die Beziehungen zu testen und aufrechtzuerhalten. Löschen Sie jedoch nicht alle vorhandenen Testdaten.
Sie möchten Ihr Produkt mit einem Mandanten in einer Datenbank mit mehreren Mandanten zusammenführen, aber jeder hat eine Bestellung 56.
Sie erstellen Objekte, die dauerhaft, aber kurzlebig sind. (unvollständige Bestellungen) Verbrauchen Sie nicht alle Ihre Bestellungen mit Dingen, die nicht mehr existieren.
Die Liste ist endlos und es handelt sich um echte Probleme, die den Menschen ständig passieren. im gegensatz zu nicht genügend speicherplatz wegen etwas größerer fk cols
Schließlich ist die massive Ausgabe mit ints, dass Sie aus ihnen heraus laufen !!! ok in der Theorie gibt es keine Lasten. Aber in der Praxis tun Sie das, weil die Leute sie nicht wie bedeutungslose Zufallszahlen behandeln. Sie machen Dinge wie
Oh, ich möchte nicht, dass Kunden glauben, wir seien neu. Beginnen Sie bei 10.000
Ich musste eine Menge Daten importieren, also habe ich den Startwert auf 1 m erhöht, damit wir wissen, was importiert wird
Wir brauchen Kategorien von Daten. Jede Periode beginnt bei der nächsten Million, sodass wir die ersten Ziffern als magische Zahl verwenden können
Ich habe alle Daten gelöscht und erneut mit neuen IDs importiert. Ja, sogar die Audit-Protokolle.
Verwenden Sie diese Nummer, bei der es sich um einen zusammengesetzten Schlüssel handelt, als ID für diese andere Sache
quelle
Hier sollten Sie genau anhalten und umdenken.
Der Primärschlüssel Ihrer Datenbank sollte NIEMALS geschäftliche Bedeutung haben. Es sollte per Definition bedeutungslos sein.
Fügen Sie daher die GUID als Geschäftsschlüssel und einen normalen Primärschlüssel (normalerweise einen langen int) als Datenbankprimärschlüssel hinzu. Sie können der GUID jederzeit einen eindeutigen Index zuweisen, um die Eindeutigkeit zu gewährleisten.
Das ist natürlich eine Diskussion über die Datenbanktheorie, aber es ist auch eine gute Praxis. Ich habe mich mit Datenbanken befasst, bei denen die Primärschlüssel geschäftliche Bedeutung hatten (ein Kunde hatte gedacht, einige Datenbankressourcen zu sparen, indem er sie beispielsweise als Mitarbeiternummern, Kundennummern usw. usw. verwendete), und dies führt immer zu Problemen.
quelle
Verwenden Sie immer datenbankgenerierte, automatisch inkrementierende Primärschlüssel (PKs).
Warum Auto-Inkrementierung anstelle von GUID / UUID verwenden?
Aber wie soll man dann mit Scherben, Clustern usw. umgehen?
Ein 3-Spalten-PK für eine gruppierte Tabelle könnte sein ...
Aber was ist mit...?
Mehrere Fahrten in die Datenbank - Die meisten Anwendungen müssen einen Datensatz, der erstellt wird, erst eindeutig identifizieren, wenn er in die Datenbank eingefügt wurde, da dieser Thread / diese Sitzung / alles, was gerade bearbeitet wird, immer nur jeweils einzeln ausgeführt wird. Wenn die Anwendung diese Funktion wirklich benötigt, verwenden Sie eine von der Anwendung generierte temporäre PK , die nicht an die Datenbank gesendet wird . Lassen Sie die Datenbank ihre eigene PK mit automatischer Inkrementierung in die Zeile einfügen, wenn sie eingefügt wird. Einfügungen verwenden die temporäre PK, während Aktualisierungen und Löschungen die von der Datenbank zugewiesene permanente PK verwenden.
Leistung - Computer können einfache Ganzzahlen weitaus schneller verarbeiten als alles andere, da die Domäne nach Möglichkeit sehr viel größer ist und die Werte pro Element in einer GUID (37) im Vergleich zu einer Ganzzahl (10) stehen. Denken Sie auch daran, dass jedes Zeichen in einer GUID zuerst in eine Zahl umgewandelt werden muss, damit die CPU sie manipulieren kann.
Häufiger Missbrauch von Primärschlüsseln PKs haben nur einen Zweck ... eine Zeile in einer Tabelle absolut eindeutig zu identifizieren. Alles andere ist ein allzu häufiger Missbrauch.
Fehlende Datensätze erkennen
Sortierung
quelle
Wie alles andere hat dies Vor- und Nachteile:
Das gute:
Ihre Schlüssel sind immer gleich lang (sehr große Datenbanken können sehr große Schlüssel haben)
Die Eindeutigkeit ist so gut wie garantiert - selbst wenn Sie sie aus einem separaten System generieren und / oder die letzte ID nicht aus der Datenbank gelesen haben
Das Schlechte:
Wie oben schon viel erwähnt - größere Indizes und Datenspeicher.
Sie können nicht nach Ausweis bestellen, sondern müssen nach etwas anderem bestellen. Mehr Indizes, wahrscheinlich weniger effizient.
Sie sind weniger lesbar. Ganzzahlen sind im Allgemeinen einfacher zu analysieren, zu merken und für Menschen einzugeben. Die Verwendung von GUIDs als IDs in WHERE-Klauseln über mehrere verknüpfte Tabellen hinweg kann Ihren Kopf zum Schmelzen bringen.
Verwenden Sie sie, wie alles andere auch, und seien Sie nicht dogmatisch. In vielen Situationen sind automatisch inkrementierende Ganzzahlen besser, gelegentlich sind GUIDs großartig.
quelle
Ja, Sie können GUID als Primärschlüssel verwenden. Der Nachteil ist die Größe und schnelle Fragmentierung des Index.
Sofern Sie keine datenbankübergreifende Eindeutigkeit benötigen (z. B. ein Cluster), wird eine Ganzzahl bevorzugt.
quelle
Hier ist meine Sicht auf dieses Problem - die Lösung ist ein Mittelweg zwischen GUID- und int-Werten, wobei das Beste aus beiden Werten herausgearbeitet wird.
Die Klasse generiert einen Pseudozufalls-ID-Wert (der sich jedoch mit der Zeit erhöht), der einer Comb-GUID ähnelt .
Der Hauptvorteil besteht darin, dass ID-Werte auf dem Client generiert werden können, anstatt auf dem Server generierte Auto-Inkrement-Werte (für die ein Roundtrip erforderlich ist) zu verwenden, bei denen das Risiko doppelter Werte nahezu null ist.
Die generierten Werte verwenden nur 8 Bytes anstelle von 16 für eine GUID und sind nicht von einer bestimmten Sortierreihenfolge der Datenbank abhängig (z. B. SQL Server für GUIDs ). Die Werte könnten erweitert werden, um den gesamten vorzeichenlosen langen Bereich zu verwenden. Dies würde jedoch Probleme mit Datenbanken oder anderen Datenrepositorys verursachen, die nur ganzzahlige Typen mit Vorzeichen aufweisen.
quelle