Laden...

[Diskussion] Guid vs. Seq. Guid vs Int32 als Primary Key

Erstellt von Abt vor 8 Jahren Letzter Beitrag vor 8 Jahren 3.653 Views
Thema geschlossen
Hinweis von Abt vor 8 Jahren

Abgeteilt von One-To-One Beziehung zu abgeleiter Klasse mit Key in Basis-Klasse

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren
[Diskussion] Guid vs. Seq. Guid vs Int32 als Primary Key

p.s. Guids sind für den SQL Sever alles andere als Ideal für den Primär Key.

Ich will jetzt keine Debatte Int32 vs. Guid lostreten (zur Not spalte ich es ab), aber bei dieser Aussage dürfe jedem DB-Admin und DB-Entwickler die Haare zu Berge stehen.
Manchmal muss man sich deutlich ausdrücken: diese Aussage ist vollkommener Humbug!

Zusätzlich zu den Links von Th69:
Es führt an Guids kein Weg vorbei, wenn man größere bzw. horizontal skalierte Datenbanken plant und zB. aufgrund der Anwendungslogik die IDs in der Anwendung generieren muss.
Gerade wegen der Skalierbarkeit und der verbundenen Eindeutigkeit bei diesen Szenarien ist zB. der Einsatz von Int32 Primarys bei NoSQL-Datenbanken überhaupt nicht möglich.
Man kann einfach Guids an jeder Stelle und egal wann generieren ohne ein Konflikt zu riskieren.

Dann wären wir beim Punkt Merging: Guids sind eindeutig. Über verschiedene Tabellen hinweg, über verschiedene Datenbanken hinweg.
Muss man also Tabellen oder Ergebnisse Mergen so ist das mit Hilfe von GUID ein vielfaches leichter.

Ja, die Performance von Guid ist etwas schlechter als Int32, weswegen man auch Sequentiell Guids verwenden sollte. Ja, das Debugging macht es an manchen Stellen komplizierter.
Wenn wir aber von Ein-Instanz-Anwendungen mit ein paar (hundert)tausend Einträgen sprechen dann traue ich es mir zu sagen, dass es für die Anwendungen, die wir hier im Forum meistens behandeln, absolut wurst ist. Und wenn das Entity Framework, das zum Performance-Flaschenhals par excellence zählt, dann ist es hundert mal wurst.
Viel viel wichtiger wichtiger wäre da die Optimierung von Queries als beim Thema Performance sich über Guid Gedanken zu machen...

Davon abgesehen erzwingen gewisse Replications ohnehin Guid.

@23994: ich rate Dir beim Thema EF die DataAnnotiations zu verwerfen und vollständig auf FluentApi zu setzen.
Mischen ist noch schlechter.

P
1.090 Beiträge seit 2011
vor 8 Jahren

p.s. Guids sind für den SQL Sever alles andere als Ideal für den Primär Key.

Ich will jetzt keine Debatte Int32 vs. Guid lostreten (zur Not spalte ich es ab), aber bei dieser Aussage dürfe jedem DB-Admin und DB-Entwickler die Haare zu Berge stehen.
Manchmal muss man sich deutlich ausdrücken: diese Aussage ist vollkommener Humbug!.

Ja, die Performance von Guid ist etwas schlechter als Int32, weswegen man auch Sequentiell Guids verwenden sollte. .

[Ironie] Danke, das du meine Aussage als vollkommen Humbig bezeichnest. Und dann ein paar Sätze weiter behauptest. Das man besser Sequentielle Guids benutzen sollte. [/Ironie]

Und das Argument wie so ich es in Standard Szenarien benutze, hast du ja auch direkt mit geliefert

Ja, die Performance von Guid ist etwas schlechter als Int32, weswegen man auch Sequentiell Guids verwenden sollte. Ja, das Debugging macht es an manchen Stellen komplizierter.
Wenn wir aber von Ein-Instanz-Anwendungen mit ein paar (hundert)tausend Einträgen sprechen dann traue ich es mir zu sagen, dass es für die Anwendungen, die wir hier im Forum meistens behandeln, absolut wurst ist.

Bei Int32 ist die Performance besser und es ist leichter zu Debuggen. Ansonsten ist es "absolut wurst". Wenn es wutst, ist kann ich doch besser Int32 verwenden (Was meine Interpratration ist).

Grundlegend möchte ich auch keine Debatte Int32 vs. Guid einleiten. Ich hoffe einfach mal wir können uns darauf einigen, das Guids schlechter sind als Sequentiell Guids. Womit meine erste Aussage korrekt ist.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

Nein; Deine Aussage ist alles andere als korrekt. Sie ist fahrlässig falsch.

Du verteufelst per se alles zum Thema Guid, da Du Dich nur auf den konkreten Datentyp bezogen hast und überhaupt nicht auf die Generierung dessen.
Ja, Random Guids sind schlecht für die Performance (und wenn das heutzutage überhaupt noch ein Thema ist die Größe). Punkt. Das wars dann aber auch schon.
Und selbst gegenüber Sq. Guids ist Int32 in vielen Szenarien eben nicht langsamer. Wie gesagt: EF verwenden und sich zeitgleich beschweren, dass Guid langsam wäre.. falsche Prioritäten.

Alle anderen Dinge, die ganz klar für Guid sprechen und einem Schema und einem Vorgehen auf dem MSSQL eher gut tun als schlecht, kehrst Du komplett unter den Tisch durch den abgewatschten Satz "alles andere als gut".

Und das ist ganz deutlich einfach falsch.

3.003 Beiträge seit 2006
vor 8 Jahren

Nicht einmal die Vermutung (!) int sei prinzipiell performanter als Guid, ist so haltbar.

Kurzversion: es kommt drauf an. (Kernzitat:

The above considerations make the use of GUIDs unfavorable for a clustered index in environments which have large number of queries performing JOIN operations in OLTP and when referential integrity is enforced on the database among multiple tables. Throw non-clustered indexes that you created on the table as covering indexes for the frequently run queries against the database, you can have a significant performance bottleneck.

Langversion: http://blogs.msdn.com/b/sqlserverfaq/archive/2010/05/27/guid-vs-int-debate.aspx

Interessanter Lesestoff.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

502 Beiträge seit 2004
vor 8 Jahren

@LaTino: Ich gebe Dir zwar in weiten Teilen Recht - aber dennoch unterschlägst Du doch einen Punkt, der gerade aus dem von Dir verlinkten Blogeintrag hervorgeht: Das Verwenden (zufälliger) GUIDs als Primary Key führt a) zu einer (prinzipbedingten) Fragmentierung der zugrunde liegenden Pages und b) (für die meisten wohl wichtiger) zu einer signifikant größeren Zeitspanne, die nötig ist, um ein INSERT auszuführen.
[ACHTUNG: Bildlich gesprochen & grob vereinfacht!]
Der Grund hierfür liegt im wesentlichen in der nötigen "Umsortierung" beim Einfügen eines zufälligen Schlüssels, da der PK das physische Layout der Datenstrukturen bestimmt. D.h. wenn beim Einfügen ein neuer, zufälliger Key z.B. zwischen Position 10 und 11 eingefügt werden muss, dann muss die Tabelle ab Pos. 11 "neu sortiert und abgelegt" werden.

D.h., wenn es die Anwendung erfordert, sehr oft INSERTs auf Tabellen mit vielen vorhandenen Zeilen auszuführen, ist eine zufällige GUID als PK sehr wohl als suboptimal zu betrachten...

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

... aber halt auch nur für den Use Case "Insert".

3.003 Beiträge seit 2006
vor 8 Jahren

@Bart, ich hatte eigentlich der Diskussion entnommen, es ginge um sqGuid vs. int, nicht um Guid vs int. (Ich wäre auch ehrlich gesagt gar nicht auf die Idee gekommen, dass man überhaupt diskutieren muss, ob man lieber Guid oder sqGuid als Schlüssel in einer Tabelle nimmt.

Von daher bezog ich mich ausschließlich auf die leicht irritierende Aussage "int ist kleiner als Guid, also ist es schneller, also nehme ich int" (jaja, grob zusammengefasst). Nicht nur ignoriert das andere Vorteile von Guid (wie Abt schon schrieb), sondern geht von einer u.U. falschen Prämisse aus.

Wir können wohl festhalten, dass es auf die Verwendung ankommt und in den allermeisten Fällen keinen signifikanten Unterschied macht. Hand hoch, wer mehr als eine Datenbanktabelle unter MSSQL mit > 1 Mio Zugriffen in unter 30s hat, ohne sowieso andere leistungssteigernde Maßnahmen ergriffen zu haben. Aber auch, wenn man nicht betroffen ist, ist es gut, zumindest zu wissen, was man beachten müsste - daher mein Link.

LaTino
(guckt auf seinen Oracle-Cluster und seufzt)

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

502 Beiträge seit 2004
vor 8 Jahren

[Leicht Off-Topic, aber dennoch zum Thema...]

Mich würde mal interessieren, was Ihr denn so von dem bei uns (auf Anraten unseres DB-Gurus) standardmäßig implementierten "Mittelweg" zu dem Thema haltet:

Wir verwenden normalerweise int oder bigint als PKs haben dann aber normalerweise eine weitere GUID-Spalte (mit newid() gefüllt), auf die ein eindeutiger Schlüssel/Index gelegt wird. Dadurch wird alles was in der DB abgefackelt wird (z.B. JOINs), mit den int-Werten ausgeführt, extern (also z.B. in C#) wird aber die GUID zur Adressierung/Identifizierung der Datensätze verwendet (was durch den Index auch recht flott geht).

Was meint Ihr dazu?

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

Ich sehe keinen Grund, wieso das helfen soll. Es täuscht über den Insert-Schwachpunkt hinweg - man macht sich aber nachher riesen Arbeit und Abhängigkeiten mit dem doppelt geführten Identifier, wovon einer auch nur virtuell vorhanden ist.

Sehe daher keine Zwang, wieso ihr überhaupt den Int64 verwendet, statt nicht nur auf Guid zu setzen.

Ich weiß aber auch, dass aus Benutzerfreundlichkeit sowas vor allem bei Bestellungen bzw. Rechnungen durchaus gern verwendet wird.
Anderes Beispiel ist Facebook, die ihre Nachrichten in einer MongoDB mit Hilfe von ObjectId eindeutig speichern, dann aber doch auch immer einen Int64-Wert für die Konversation generieren.
Mag also durchaus Szenarien geben, wo sowas "legitim" ist.

PS: ObjectId ist übrigens von Haus aus - auch bei der Generierung in der Anwendung - sequentiell, was ein riesen Vorteil gegenüber Guid ist.

3.003 Beiträge seit 2006
vor 8 Jahren

Wie Abt. Da sowieso Guid-Schlüssel verwendet werden, sehe ich keinen Grund, int für die pk zu verwenden, außer Lesbarkeit. Und wenn man mal so drüber nachdenkt, sind die Schlüssel einer Tabelle eine Metainformation und nichts, was ein Mensch überhaupt lesen können sollte.

Insofern verstehe ich den Doppelansatz nicht.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

Schlüssel einer Tabelle eine Metainformation und nichts, was ein Mensch überhaupt lesen können sollte.

Dem stimme ich nicht zu. Oft hast Du zB bei Webanwendungen den Schlüssel als Teil der URL, was durchaus im Rahmen der Bedienung zum Tragen kommt.
Das gleiche bei der Rechnungsnummer. Kein Mensch hat bock dem Telefonsupport die Rechnungsnummer anhand von Hexwerten vorzulesen.

Es gibt durchaus Use Cases, wo eine Guid bei der Interaktion mit Menschen einen Ersatz braucht.

3.003 Beiträge seit 2006
vor 8 Jahren

Ich will dir nichts unterstellen, aber du verwechselst - so lese ich das - das Konzept eines Datenbankschlüssels mit dem Konzept "eindeutiges Datensatzmerkmal".

Ein Datenbankschlüssel ist syntaktisches Merkmal eines Datensatzes.
Ein eindeutiges Datensatzmerkmal ist semantisches Merkmal eines Datensatzes.

Wenn du erst einmal beginnst, Syntax und Semantik miteinander zu vermischen, begibst du dich auf eine Reise, die man potenziell mit AC/DC unterlegen könnte (Highway to Hell, weisst schon).

Rechnungsnummer als Datensatzschlüssel ist - im besten Fall - wagemutig. Für semantische Definitionen in einer Datenbank gibt es Constraints.

LaTino
[Edit] Grammatik

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

Das ist mir durchaus bewusst; dennoch Realität in vielen Anwendungen.

3.003 Beiträge seit 2006
vor 8 Jahren

Gut 😃. Für den zufälligen Mitleser:

Ist das nicht Haarespalterei? Wenn ich zum Beispiel eine Tabelle in einer Datenbank mit Blog-Einträgen habe, und jeder dieser Einträge hat eine eindeutige Nummer, die ich in der Form

http://www.beispielblog.org/myBlog/article/1234543

abrufen kann, wieso sollte ich dann nicht in der Tabellenstruktur diese Nummer als Primärschlüssel verwenden?

In der Realität sieht das so aus, dass das - wie Abt schreibt - gern gemacht wird. Und im täglichen Betrieb macht das genauso wenig Probleme. Aber ein paar Nachteile gibt's doch:

a) wenn man aus welchen Gründen auch immer Änderungen an der Bedeutung des Datensatzes (seiner Semantik) vornehmen möchte - sagen wir, man will eine andere Artikelnummer - muss man dazu den Primärschlüssel ändern. Möchte man gar die Struktur der Artikelnummer ändern - Buchstaben sind erlaubt, oder sonstiges - dann gerät man in Schwierigkeiten.

b) Migration auf andere Datenbanksysteme wird u.U. schwierig

  • und weitere. Das mag selten vorkommen, aber WENN es vorkommt, hat man im Fall des Falles ein echtes Problem. Oder man muss Code schreiben, um die Konsistenz der Datenbank zu erhalten. Oder Code schreiben, um die inhaltliche Konsistenz zu prüfen, was noch ekliger ist.

Diese Schwierigkeiten resultieren daraus, dass man im Code darauf Einfluss nimmt, WIE die Datenbank bei ihrer Selbstorganisation vorzugehen hat. Gutes Design trennt deshalb die innere Funktionsweise der Datenbank - Primary Keys, Foreign Keys, Indexing - vom DAL. Der Programmierer sollte im besten Fall nichts über die Datenbankdefinitionen wissen müssen.(Anm. unten)

Mir ist schon klar, dass im Bereich Softwaredesign gern geschlampt wird. Aber hier hat man eine saugute Gelegenheit, sich einmal Gedanken zu machen und dafür hinterher 'ne Menge Arbeit zu sparen.

LaTino

Anm: im Gegenzug weiß der gute Programmierer natürlich über das Datenbankdesign Bescheid. Schon allein, um Eigenheiten berücksichtigen oder Flaschenhälse vermeiden zu können. Siehe Diskussionsthema.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

502 Beiträge seit 2004
vor 8 Jahren

a) wenn man ... Änderungen an der Bedeutung des Datensatzes vornehmen möchte...
b) Migration auf andere Datenbanksysteme...

Das sind u.a. Gründe dafür, warum ich immer dafür plädiere, dass DB-Internas (und dazu gehören IMHO die PKs) nichts ausserhalb der DB verloren haben. Ob man das nun über eine GUID (die als Surogat nach aussen dient) geschieht oder über was anderes (will heißen: eine andere Datenstruktur) ist erst mal zweitrangig.
Alles andere führt immer zu einer Vermischung / unsauberen Trennung der Schichten und sollte tunlichst vermieden werden.

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

3.003 Beiträge seit 2006
vor 8 Jahren

Nur, um denjenigen, die dabei abwinken, ein Beispiel aus der vielbeschworenen Realität zu geben:

Ich habe erst letzten Donnerstag ein Stück Code schreiben müssen, um eine Guid, die eigentlich nur als primary key dient, sauber aus der Datenbank zu holen. Wieso? Weil Oracle so freundlich ist, Guid als raw(16) zu speichern. Das Problem dabei: Oracle benutzt eine andere Byte-Reihenfolge als MS. Um dem Client die Guid, die ihn eigentlich gar nicht interessieren sollte, also konsistent weiter zu geben, mussten die Bytes von Hand zurückgedreht werden. Hätte die DAL nicht völlig sinnlos den Primary Key als Datensatzinhalt benutzt, wäre das vollkommen egal gewesen.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

502 Beiträge seit 2004
vor 8 Jahren

...da setz ich mal noch einen drauf 😁
Wir sind hier Dienstleister für BPO und haben teilweise Projekte seit mehr als 10 Jahren am laufen (was in der IT quasi Äonen darstellt).
Und ich möchte dabei nur eines sagen: Man glaubt nicht, wie oft ein Kunde (...v.a. die "großen", Global Player...) in solchen Zeiträumen seine Meinung bezüglich eines Themas um 180° und wieder zurück drehen kann... X( Von daher kann man in der Entwicklung gar nicht sauber / flexibel / langfristig /... genug denken.

Bart Simpson

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

P
1.090 Beiträge seit 2011
vor 8 Jahren

Nein; Deine Aussage ist alles andere als korrekt. Sie ist fahrlässig falsch.

Dann nenne mir doch bitte den Anwendungsfall in dem eine Guid (immer) besser ist als Primäreschlüssel. Ob es nun Sequenzil Guid, int oder irgend ein andere Schlüssel.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

Einer reicht?
Verteilte Datenbank-Instanzen.

Kürzer zu beantworten wäre, wann Int32 besser geeignet wäre: kaum / sogut wie nie.
Ist kein Zufall, dass NoSQL-Datenbanken Int32 überhaupt gar nicht als Primärschlüssel zulassen.

P
1.090 Beiträge seit 2011
vor 8 Jahren

Einer reicht?
Verteilte Datenbank-Instanzen.

Guid ist da wirklich besser als eine Sequential Guid?

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

R
74 Beiträge seit 2006
vor 8 Jahren

Wenn DB-Instanzen einmal "vermischt" wurden, kann es dann noch eine
Sequential Guid geben ? Ich denke nicht ! Wenn es nur 2 DB-Instanzen
gibt wäre eine Lösung mit AI Int-PK's gerade noch möglich. Dann darf aber
keiner kommen und irgendwann später eine 3. DB-Instanz haben wollen.

Wenn Inserts mit GUID-PK's kostspielig sind, die sonstigen Anforderungen
jedoch GUID's als PK erfordern, dann sind die Kosten halt wie sie sind ...

Und vermutlich sind die Kosten geringer als die von schlampigen Queries.
Der Kunde hat zumindest die Möglichkeit die Kosten durch höhere Kosten
für seine Hardware zu reduzieren. Bei richtig schlampigen Queries hat er
diese Möglichkeit nicht !

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

Guid ist da wirklich besser als eine Sequential Guid?

Die Frage wirkt irgendwie so, als ob Dir der Unterschied von Guid und Seq. Guid nicht bekannt ist. Kann das sein?

P
1.090 Beiträge seit 2011
vor 8 Jahren

Wie genau möchtest du es denn Wissen?
Reicht die grobe Aussage. Das eine Guid "rein" zufällig generiert wird (Fragmentierung) und neu generierte Seq. Guid größer sind als ihr Vorgänger (gewissen Rahmenbedingungen vorausgesetzt und geringere Fragmentierung)?

Erläutre doch einfach mal wie so für dich an dem Punkt die Guid, besser ist als die Seq. Guid.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 8 Jahren

Ich weiß nicht genau, wo Deine Frage hin führt: aber wo habe ich denn gesagt, dass Guid besser als Seq. Guid ist? 🤔
Es ging beim Thema darum, dass Guid prinzipiell für eine DB Planung besser ist als eine Int32; einfach aufgrund der Skalierbarkeit und der Funktionen.
Und eine Seq. Guid beim Thema Performance den Nachteil beim Insert einer Random Guid ausgleicht bzw. ausgleichen kann.

Das Thema ist ein wenig abgewichen; zugegeben.
Aber im Prinzip ging es auch nur darum, dass Deine pauschale Aussage, dass eine Guid (ohne hier im Speziellen von Seq / Random) schlechter sei.
Und diese wurde nun durch verschiedene Aussagen von verschiedenen Personen mit entsprechenden Verweisen und Gründen ganz deutlich widerlegt.

Ich denke, dass die Diskussion nun thematisch ihr Ende sowie das passende Resultat gefunden hat.

P
1.090 Beiträge seit 2011
vor 8 Jahren

Ich hoffe einfach mal wir können uns darauf einigen, das Guids schlechter sind als Sequentiell Guids. Womit meine erste Aussage korrekt ist.

Nein; Deine Aussage ist alles andere als korrekt. Sie ist fahrlässig falsch.

Aber im Prinzip ging es auch nur darum, dass Deine pauschale Aussage, dass eine Guid (ohne hier im Speziellen von Seq / Random) schlechter sei.

Ich hab aber auch nicht von Seq Guid gesprochen, sondern von Guid. Kann man natürlich falsch verstehen, wenn man möchte. Aussagen wie "ist vollkommener Humbug" und ist "fahrlässig falsch", helfen da aber nicht, das Thema auf einer Sachlichen ebene zu Diskutieren.

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern

2.207 Beiträge seit 2011
vor 8 Jahren

Ich denke hier ist ebenfalls alles gesagt - ob nun sachlich oder nicht. Hilfesuchende bekommen hier mehr als nur eine Antwort und können sich ihr Bild machen. Daher wird der Thread sicher nicht besser...und ist damit zu.

Thema geschlossen