Generierung von einzigartigen Identifikatoren
Als Computer angefangen haben, sich aktiv zu vernetzen, tauchte ein simples, aber ziemlich nerviges Problem auf: Wie kann man garantieren, dass zwei verschiedene Geräte, irgendwo auf der Welt, nicht denselben Identifikator erzeugen?
Stell dir vor: Zwei Server, einer in Tokio, einer in Berlin, erzeugen unabhängig voneinander IDs für Objekte. Wenn sie plötzlich dieselbe ID generieren – können Daten durcheinander geraten, überschrieben werden und das System crasht.
So entstand in den 1990ern, in der Zeit des rasanten Wachstums von verteilten Systemen und Netzwerkprotokollen, bei Microsoft und der Open Software Foundation (OSF) die Idee vom GUID — Globally Unique Identifier, oder auf Deutsch global eindeutiger Identifikator.
GUID (im ISO-Standard als UUID bekannt, Universally Unique Identifier) ist eine 128-Bit-Zahl, die zum Beispiel so aussieht:
550e8400-e29b-41d4-a716-446655440000
Das ist wie ein digitaler Fingerabdruck: so lang und chaotisch, dass die Wahrscheinlichkeit einer Kollision (zwei gleiche IDs) praktisch null ist.
Er wird generiert mit Hilfe von:
- Zeit,
- Zufallszahlen,
- MAC-Adresse des Geräts (bei alten Versionen),
- und sogar kryptografischen Hashfunktionen.
Warum war das wichtig? GUID hat es ermöglicht, eindeutige IDs ohne zentralen Server, ohne Koordination, ohne Locks und Verzögerungen zu erzeugen. Das war ein echter Gamechanger für:
- verteilte Datenbanken,
- Netzwerkprotokolle,
- Dokumentenmanagementsysteme,
- und natürlich moderne APIs.
UUID in PostgreSQL
GUID/UUID ist überall im Einsatz – von PostgreSQL bis zu Cloud-Services. Sie sind die unsichtbaren Baumeister des modernen Internets: Ohne sie könnten wir die Welt nicht so easy verbinden.
Im Grunde ist das einfach eine sehr lange Zufallszahl mit 16 Bytes, die im Hex-Format gespeichert wird. Einfach eine sehr lange Ganzzahl.
Dieser Datentyp ist perfekt, wenn du die Einzigartigkeit von Werten im ganzen System garantieren willst, ohne von einem zentralen ID-Generator abhängig zu sein. Besonders nützlich in verteilten Systemen oder wenn Daten auf verschiedenen Servern erzeugt werden.
Warum nicht einfach INTEGER?
Man könnte denken, wozu braucht man UUID, wenn man einfach eine auto-increment Zahl als ID nehmen kann? Lass uns das anschauen:
Globale Einzigartigkeit: Wenn deine Datenbank auf mehreren Servern läuft, ist es schwer, die Einzigartigkeit von INTEGER zu garantieren. Mit UUID ist das kein Problem.
Sicherheit und Datenverstecken: UUID ist schwerer vorherzusagen als eine fortlaufende Nummer. Das senkt das Risiko, dass Infos durch vorhersagbare IDs geleakt werden (z.B. /users/1, /users/2).
Verteilte Systeme: Wenn Daten in verschiedenen Teilen des Systems erzeugt werden, ist ein auto-increment INTEGER ohne komplexe Synchronisation nicht geeignet.
Ein weiterer Vorteil von UUID: Es ist ein Standard, der in vielen Programmiersprachen und Datenspeichersystemen unterstützt wird.
Vorteile der Nutzung von UUID
Die wichtigsten Pluspunkte:
- Einzigartigkeit: Die ID ist garantiert einzigartig, auch wenn Daten auf verschiedenen Servern oder Systemen erzeugt werden.
- Flexibilität: Kann als Primary Key, Foreign Key und für andere Aufgaben genutzt werden.
- Skalierbarkeit: Sehr praktisch bei verteilten Datenbanken.
Aber UUID hat auch Nachteile:
- Größe:
UUIDbraucht mehr Speicher (16 Bytes) alsINTEGER(4 Bytes). - Lesbarkeit: Ist schwerer zu lesen und zu merken.
Generierung von UUID in PostgreSQL
Eingebaute Funktion gen_random_uuid()
Ab PostgreSQL Version 13 gibt es die eingebaute Funktion gen_random_uuid() zur Generierung von zufälligen UUID. Diese Funktion gibt einen einzigartigen Identifikator zurück, den du als Wert für eine Spalte vom Typ UUID nutzen kannst.
Beispiel:
SELECT gen_random_uuid();
Ergebnis:
d17fc23b-22e5-4fcb-bf86-1b4c766d77b7
Stell sicher, dass das pgcrypto-Extension installiert ist (für PSQL 1-12)
In älteren PostgreSQL-Versionen (vor Version 13) ist die Funktion gen_random_uuid() nach Installation der Extension pgcrypto verfügbar. Wenn du auf der Arbeit gezwungen wirst, das zu nutzen, kannst du die Situation retten mit folgendem Befehl:
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
Damit kannst du dann zufällige UUID generieren.
Verwendung von UUID als Foreign Key
UUID ist super praktisch, um Beziehungen zwischen Tabellen zu bauen. Angenommen, du hast eine User-Tabelle:
| id | name | |
|---|---|---|
| d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | Alice | alice@example.com |
| a1d3e15a-abc1-4b51-a320-2d4c859f7467 | Bob | bob@example.com |
| 3c524998-5c24-4e73-836d-a4c6bb3cafcd | Charlie | charlie@example.com |
Erstellen der Tabelle orders
Lass uns die Tabelle orders erstellen, wo user_id als Foreign Key auf id in der users-Tabelle verweist.
| order_id | user_id | order_date |
|---|---|---|
| 1a5b7d9c-b1a2-4f8e-9e7a-0a1111111111 | d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | 2024-10-15 10:00:00 |
| 2b6c8e0d-c2b3-5a9f-af8b-1b2222222222 | a1d3e15a-abc1-4b51-a320-2d4c859f7467 | 2024-10-15 10:05:00 |
| 3c7d9f1e-d3c4-6baf-bc9c-2c3333333333 | 3c524998-5c24-4e73-836d-a4c6bb3cafcd | 2024-10-15 10:10:00 |
| 4d8eaf2f-e4d5-7cb0-cdab-3d4444444444 | d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | 2024-10-15 10:15:00 |
| 5e9fb030-f5e6-8dc1-debc-4e5555555555 | a1d3e15a-abc1-4b51-a320-2d4c859f7467 | 2024-10-15 10:20:00 |
Das Feld user_id ist mit dem Feld id der Tabelle users verbunden, was es ermöglicht, Beziehungen zwischen Usern und ihren Bestellungen zu bauen.
Datenabfrage mit JOIN
Schauen wir uns an, wie die Daten in den Tabellen users und orders verbunden sind:
SELECT
u.id AS user_id,
u.name,
o.order_id,
o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id;
Ergebnis:
| user_id | name | order_id | order_date |
|---|---|---|---|
| d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 | Alice | a1d3e15a-abc1-4b51-a320-2d4c859f7467 | 2024-10-20 12:34:56 |
Typische Anwendungsfälle für UUID
IDs für User und Bestellungen: in verteilten Systemen, wo Daten aus verschiedenen Quellen kommen können.
Tokens für APIs: UUID wird oft in REST APIs genutzt, um Entities zu identifizieren.
Globale Datensynchronisation: zum Beispiel, wenn Daten von verschiedenen Servern gesammelt werden.
Typische Fehler und Besonderheiten
Versuch, UUID manuell zu generieren: Nutze lieber eingebaute Funktionen wie gen_random_uuid(), um Fehler zu vermeiden.
Übermäßiger Einsatz: Nutze UUID nicht dort, wo ein auto-increment INTEGER reicht. Zum Beispiel in lokalen Tabellen, die nie skaliert werden.
Größe: UUID braucht mehr Platz, was die Performance von Abfragen beeinflussen kann, besonders bei Indizes.
GO TO FULL VERSION