GUIDs vs. auto-increment IDs

Ich oute mich mal als ein “ehemaliger” PHP Entwickler. MySQL ist natürlich die Standarddatenbank für PHP Anwendungen. Man macht über phpmyadmin (ich war noch jung und kannte nichts anderes ;) ) seine Datenbanken und wie es sich so gehört, hat jeder Datensatz in einer X-beliebigen Tabelle eine eindeutige ID. Die “ID” Spalte wird einfach ein Integer und setzt diese als den primären Schlüssel und schaltet noch ein, dass diese Spalte automatisch hochgezählt werden soll.

So für sich gesehen, ist es recht simpel und funktioniert gut. Dieses Prinzip wird aber dann schwieriger umzusetzen, wenn bestimmte Abhängigkeiten zu anderen Tabellen bestehen sollen.

Aber erstmal ganz langsam… unser Szenario:

Wir haben Produkte, welche wir in eine “Products” Tabelle speichern:

  • Id
  • Name
  • Price

Jedes Produkt kann ähnliche Produkte haben, welche in einer “ReleatedProducts” Tabelle gespeichert wird:

  • Id (diese Spalte könnte man auch weglassen – spielt aber jetzt keine große Rolle).
  • ProductFirstId
  • ProductSecondId

Wir haben jetzt ein Anwendung, in dem wir 2 Produkte erstellen wollen und diese in Beziehung setzen. Wenn wir dies jetzt mit “normalen” autoincrement IDs umsetzen, wird es etwas knifflig…

Warum? Das geht ganz einfach…

Natürlich geht das mit dem autoincrement IDs. Allerdings muss man quasi folgende Schritte machen:

  1. Erstes Produkt erstellen
  2. Erstelltes Produkt in die DB speichern
  3. Eben erstellte ID als Rückgabewert bekommen
  4. Zweites Produkt erstellen
  5. Erstelltes Produkt in die DB speichern
  6. Eben erstelle ID als Rückgabewert bekommen
  7. Beziehung setzen mit den beiden Rückgabewerten

Das ist nur teilweise schön – das liegt nunmal an der Natur von autoincrement IDs:

Die Verwaltung der eindeutigen IDs wird der Datenbank überlassen!

Man kann nicht 100% die nächste ID erraten. Wenn man nun einen Datensatz mit einem anderen Verknüpfen möchte, muss man vorher immer die DB befragen. Falls in der Zwischenzeit was schief geht und auch keine referenzielle Integrität angeschaltet ist, bleiben im schlimmsten Falle leichen übrig.

Was gibts für eine Alternative?

GUIDs bieten eine nette Abhilfe und sind insbesondere im Microsoft Umfeld stark vertreten.

Im .NET Framework gibt es direkt eine GUID Klasse zum Erzeugen solcher IDs. Im SQL Server ist der Datentyp “uniqueidentifer” dafür vorgesehen.

Was sind die Vorteile?

  • Die Kontrolle der eindeutigen IDs kann direkt im Programm gesteuert werden.
  • Die Daten brauchen erst zur DB gespeichert werden, wenn dies nötig ist.
  • Bei einer evtl. Zusammenführung von 2 Tabellen hat man das ID Problem nicht.

Was sind die Nachteile?

  • Performance? Jedenfalls aus dem Microsoft SQL Lager hört man sowas nicht – zwar ist eine GUID länger als eine “normale” ID, allerdings fällt dies kaum ins Gewicht.
  • Ids sind etwas unschöner und man kann schlechter nachvollziehen und mal einzelne Daten Testen:
    • Webseiten mit …?id=2312 sind (wie z.B. bei WordPress) durch konkrete Titel ersetzt wurden – die IDs “sieht” der Benutzer (oder die Suchmaschine) kaum. Das man einzelne Daten schlechter Nachverfolgen kann, ist allerdings wahr.

Demoprojekt nötig?

Ich habe ein Demoprojekt mit VS 2008 Express Edition und LINQ to SQL erstellt – dort wird einmal mit GUIDs und ohne GUIDs gearbeitet – allerdings habe ich nur den GUID Teil bis zum Ende geführt – weil es für mich simpler war ;)

Der ConnectionString muss natürlich angefasst werden:

[ Download Democode ]


Kick It auf dotnet-kicks.de
Wenn dir der Blogpost gefallen hat, dann hinterlasse doch einen Kommentar. Wenn du auf dem Laufenden bleiben willst, abonniere unseren RSS Feed oder folge uns auf Twitter.

About the author

Written by Robert Mühsig

Robert Mühsig (@robert0muehsig) ist Webentwickler und beschäftigt sich mit Web-Frameworks (vor allem dem ASP.NET MVC Framework) und scheut sich auch nicht vor Javascript. Ansonsten bloggt er über all jene Probleme, die ihm über den Weg laufen. Seit 2008 ist er Microsoft MVP für ASP.NET und er arbeitet bei der T-Systems Multimedia Solutions GmbH in Dresden. Treffen kann man ihn online via Twitter (@robert0muehsig) oder dieser Seite oder bei der .NET User Group Dresden.

12 Responses

  1. Hi Robert,

    scope_identity() kennste schon? :-)

    Reply
  2. Hallo Thomas,
    in T-SQL bin ich jetzt weniger eingeweiht, aber nach 1 Minute suchen weiß ich jetzt was es ist.
    Das meinte ich mit “Eben erstellte ID als Rückgabewert bekommen” – ich kannte es auch von MySQL, dort gibt es eine ähnliche Funktion.
    Natürlich geht es mit IDs – aber ich fande irgendwann GUIDs netter gemacht ;)

    Reply
  3. Hum – GUID als ID in der Datenbank, da muss man doch ein wenig aufpassen bzgl. Datenfragmentierung, was eine Abhängigkeit zu bestimmten DB Implementierungen schafft. MS SQL 2005 bietet newsequentialid() um unnötiges Clustering zu vermeiden.

    Reply
  4. Jeff Atwood hat auch einen solchen Artikel veröffentlich (erst jetzt gefunden) und er fasst auch nochmal die Pros und Contras zusammen:
    http://www.codinghorror.com/blog/archives/000817.html

    Reply
  5. Ich habe inzwischen meine größteren Webanwendungen auch auf GUIDs umgestellt. Der Mysql Server bietet dazu eine Funktion namens UUID() die eine eindeutige ID erzeugen soll. Bisher hab ich recht gute erfahren damit gemacht.

    Reply
  6. Das größe “Problem” von Guids ist letztlich, dass sie nicht lesbar und sehr lang sind. Das stört sowohl u.U. bei der Administration in der Datenbank selbst (wenn man mal kein LINQ benutzt ;-) ) und es verbietet vor allem sie z.B. im Web öffentlich in der URL zu nutzen, Integer-IDs kann man hier noch reinpacken.

    Ich nutze jedenfalls beides, überall da wo es keinen Benutzerkontakt gibt und ich die Eindeutigkeit sicherstellen will vor allem Guids, andernfalls Integer-IDs

    Reply
  7. In einer URL ist so eine GUID etwas ungünstig unterzubringen – da geb ich Thomas absolut recht. Aber wie man immer häufiger sieht, wird dieses “?id=123″ immer mehr zu SEO tauglichen URLs, wie z.B. bei WordPress:
    “2008/01/29/guids-vs-auto-increment-ids/”
    Das geht natürlich auch mit ASP.NET :)

    Am Ende ist es sicherlich auch eine kleine “Geschmacksfrage”.

    Reply
  8. Ob ?id=123 oder /123/Hallo-Welt/ ist ja Jacke wie Hose, die ID muss zur Eindeutigkeit so oder so rein. Ich habe es bei einer CMS-Software auch mal eine Zeit ohne ID probiert – aber das kann man den Benutzern (=Admins) nicht zuordnen, da der Titel der in der URL verwendet wird immer eindeutig sein muss.

    Mit ASP.NET geht das freilich easy: http://www.urlrewriting.net ;-)

    Reply
  9. Es kommt sicherlich auf die Anforderung drauf an – GUIDs sehen schon recht kryptisch aus – eine ID ist da schon flüssiger zu lesen.

    Auf das urlrewriting Projekt wollte ich hinaus ;)
    ASP.NET MVC setzt ja auch stark solch eine URL Rewriting Funktion ein um eben diese “hässlichen”(ob mit GUID oder mit ID) URLs gegen SEO taugliche einzutauschen.

    Die GUID vs. ID Diskussion ist aber doch immer recht interessant – solch eine ähnliche Diskussion habe ich bereits in einigen Foren oder Blogs beobachtet.
    *Notiz an mich: Mehr kontroverse Themen behandeln* ;)

    Reply
  10. Wenn man gezwungen ist eine GUID in einer URL zu verweden
    kann man auch auf diese Methode zurückgreifen:
    http://www.darkleo.com/blog/2008/01/24/eigener-datentyp-smallguid/

    Reply
  11. Ich habe inzwischen viele Projekte mit Access, ASP.NET, Dynamics AX, … gemacht. Mit Access bzw. SQL Server ist es ganz schlimm, da das AutoIncrement keinem wirklich was bringt.

    AX macht das relativ gut, indem es Nummernkreise abbildet (z.B RExxxx für Rechnungen).

    GUID’s habe ich im neuesten Web-Projekt gemacht. Das werde ich auch nie wieder machen, das ist unglaublich schwierig zu überschauen.

    Also am Besten finde ich die Nummernkreis-Sache. Das muss jedoch in einem Layer gebaut werden.

    Reply

Comment on this post

Letzte Posts

  • image.png
    RavenHQ–RavenDB in der Cloud

    Ayende Rahien hat es heute verkündet – RavenHQ, der RavenDB Cloud Hoster (natürlich von und mit Ayende) ist ab heute raus aus der Beta und man kann es von überall aus nutzen. In der Betaphase waren nur Nutzer von AppHarbor zugelassen. Was ist RavenHQ? RavenHQ ist im Grunde ein gehostes RavenDB in den Rechenzentren von ...

  • image.png
    GitHub for Windows–erste Eindrücke

    Git ist schon eine tolle Sachen und eröffnet viele neue Möglichkeiten – allerdings ist der Einstieg recht hart und selbst wenn man die guten Hilfsanleitungen auf GitHub befolgt, kommt man am Anfang nur langsam vorwärt. Insbesondere ist das Tooling für Windows / .NET Entwickler auch nicht gerade “bekanntes Terrain”. GitHub to the rescue! Die GitHub ...

  • image.png
    Chocolatey–apt-get für Windows

    Durch Zufall bin ich auf das Tool “Chocolatey” gestoßen. Wer die Website sich anschaut, wird evtl. eine Verwandschaft mit NuGet ausmachen. Was macht Chocolatey? Chocolatey ist ein “Maschine Package Manager”, das bedeutet, dass man für seine Maschine einfach Tools runterladen und Updaten kann – direkt über die Konsole. Was ist der Unterschied zu NuGet? NuGet ...

  • image.png
    SASS, LESS & Coffeescript in Visual Studio mit der Web Workbench

    CSS und Javascript sind die “kleinste” Schnittmenge von allen Browsern für die Erstellung von Web-Applikationen. Leider geht dabei etwas komfort verloren, daher lieben alle Webentwickler jQuery! SASS und LESS sind zwei Varianten, wie man “schöner” CSS schreiben kann und Coffeescript versucht Javascript Entwicklung zu vereinfachen. Aber immer der Reihe nach… Was ist SASS? SASS steht ...

  • image.png
    Code-Inside Sample nun auf GitHub: Google Code zu GitHub Migration

    Seit einiger Zeit habe ich Beispielcode auf Google Code bereitgestellt. Einfach nur noch weg von Google Code O-Ton damals war: Ich hatte mich für Google Code entschieden, weil ich hoffe dass früher oder später die Google Code Suche nutzbar ist und es dadurch wenigstens ein kleiner Mehrwert entsteht. Allerdings wirft es momentan noch ein Fehler. ...

Auf Amazon einkaufen & unterstützen

Facebook