29 January 2008 .NET 3.5, LINQ, LINQ to SQL, SQL Server Robert Muehsig

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 ]


Written by Robert Muehsig

Software Developer - from Saxony, Germany - working on primedocs.io. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de