KI und MySQL-Datenbanken

Ein bemerkenswerter Fehler ist, dass viele KI-generierte Datenbankschemas derzeit VARCHAR(36) für die id-Spalte bevorzugen.

16 May 2025

5

Min. Lesezeit

KI-Innovation

Adrian Sweeney

Ein bemerkenswerter Fehler ist, dass viele KI-generierte Datenbankschemas derzeit die Verwendung von VARCHAR(36) für die id-Spalte bevorzugen.

Dies ist typischerweise durch den Wunsch motiviert, unbefugten Zugriff durch böswillige Akteure zu verhindern. Um dies zu erreichen, werden UUIDs (Universell Eindeutige Identifikatoren) oft als Sicherheitsmaßnahme eingesetzt.

Nehmen wir WordPress als Beispiel — es zeigt typischerweise Post-IDs in der URL wie ?p=45. Verglichen mit einem SEO-freundlichen Format wie /2025/05/sample-post ermöglicht diese numerische ID Benutzern, potentiell benachbarte Inhalte zu erraten und darauf zuzugreifen, indem sie die Nummer ändern (z.B. ?p=44). UUIDs hingegen sind nicht sequenziell und viel schwerer zu erraten.

UUIDs sind 36-Zeichen-Strings, die einem Standardformat mit fünf durch Bindestriche getrennten Abschnitten folgen: 8-4-4-4-12. Jeder Abschnitt besteht aus hexadezimalen Werten:

550e8400-e29b-41d4-a716-446655440000
f47ac10b-58cc-4372-a567-0e02b2c3d479
123e4567-e89b-12d3-a456-426614174000

Ein einfacher Regex zur Validierung von UUIDs sieht so aus:

^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$

Während UUIDs Sicherheit und Portabilität bieten, bringen sie Kompromisse mit sich. Sie sind deutlich größer als Ganzzahlen, was die Datenbankperformance verlangsamen kann — besonders wenn sie als Primärschlüssel in relationalen Datenbanken verwendet werden. Indizierung, Speichernutzung und Abfragegeschwindigkeit leiden alle unter der Größe und der nicht-sequenziellen Natur von UUIDs.

Ein KI-Gespräch über ID-Strategie

Neugierig auf diese Designentscheidung, stellte ich GitHub Copilot folgende Frage:

Ich:
Warum haben Sie sich entschieden, die id-Spalte als VARCHAR(36) PRIMARY KEY in der Datenbankstruktur zu definieren?

GitHub Copilot:

Ich habe VARCHAR(36) für die ID-Spalten aus einigen spezifischen Gründen gewählt:

  1. UUID-Speicherung: Die 36-Zeichen-Länge passt zu UUID-Werten, die einem standardisierten Format folgen.
  2. Multi-Mandanten-Systeme: UUIDs helfen dabei, Mandanten zu isolieren, indem sie sequenzielle ID-Lecks eliminieren, Migrationen vereinfachen und die Sicherheit verbessern.
  3. Datenportabilität: UUIDs stellen sicher, dass exportierte Daten nicht unter ID-Kollisionen beim Import in ein anderes System leiden.

Kompromisse:

  • Größere Speichergröße (36 Bytes vs. 4 Bytes für INT)
  • Langsamere Indizierungs- und Abfrageleistung
  • Erhöhte Speichernutzung

Zu berücksichtigende Alternativen:

  1. AUTO_INCREMENT INT/BIGINT
  2. BINARY(16) zur effizienteren Speicherung roher UUID-Bytes
  3. Eine benutzerdefinierte ID-Generierungsstrategie

Lassen Sie mich wissen, wenn Sie einen anderen Ansatz bevorzugen.

Ich:
Verwenden Sie BIGINT UNSIGNED für Performance, aber behalten Sie ein guid-Feld in jedem Datensatz für externe Referenzen.

GitHub Copilot:

Ich werde das Schema aktualisieren, um BIGINT UNSIGNED als Primärschlüssel zu verwenden, während ich eine guid-Spalte für externe Referenzen hinzufüge. Dieser Hybridansatz kombiniert das Beste beider Strategien:

  • Performance: Effiziente Indizierung und Joins über numerische Primärschlüssel
  • Sicherheit & Portabilität: GUIDs in APIs exponiert, wodurch interne IDs vor Aufzählung sicher sind

Zusammenfassung:

  • BIGINT UNSIGNED: Schnell, kompakt, sequenziell
  • GUID (VARCHAR): Eindeutig, portabel, extern sicher

NoSQL-Datenbanken und MongoDB ObjectIds

Während relationale Datenbanken Flexibilität bei der Wahl zwischen UUIDs, Ganzzahlen oder Hybriden bieten, gehen NoSQL-Systeme wie MongoDB einen anderen Weg.

MongoDB verwendet einen eingebauten Typ namens ObjectId für sein _id-Feld. Dies ist ein 12-Byte-Binärwert, der kodiert:

  • 4 Bytes – Zeitstempel (Sekunden seit Epoche)
  • 5 Bytes – Zufallswert (oft basierend auf Maschine + Prozess-ID)
  • 3 Bytes – Inkrementierender Zähler

Beispiel:

507f1f77bcf86cd799439011

Warum MongoDB ObjectId wählt

  1. Global eindeutig ohne Koordination
    Ähnlich wie UUIDs benötigen ObjectIds keine zentrale Autorität zur Sicherstellung der Eindeutigkeit, was sie ideal für verteilte Umgebungen macht.
  2. Zeitlich geordnet
    Der eingebettete Zeitstempel bedeutet, dass Dokumente standardmäßig grob chronologisch sortiert sind, was bei Zeitreihenanwendungen die Performance unterstützen kann.
  3. Kompakt und effizient
    In Binärformat gespeichert, nehmen ObjectIds nur 12 Bytes ein — viel kleiner als eine VARCHAR(36)-UUID. Sie sind auch indexfreundlicher.

Vergleich von ID-Strategien

EigenschaftUUID (VARCHAR)BIGINT + GUID HybridMongoDB ObjectId
Speichergröße36 Bytes8 + 36 Bytes12 Bytes
IndizierungsleistungSchlechtAusgezeichnetAusgezeichnet
Sequenziell / ZeitordnungNeinJa (nur BIGINT)Ja (via Zeitstempel)
Lesbares FormatJaJa (GUID)Nein (hex-basiert)
ErratbarNeinNein (nur GUID)Nein
Schema-DurchsetzungStriktStriktFlexibel

KI-Präferenzen in NoSQL-Kontexten

Viele KI-generierte Systeme verwenden standardmäßig MongoDB-ähnliche NoSQL-Setups, wenn:

  • Hoher Schreibdurchsatz oder Sharding erwartet wird
  • Schemas flexibel oder halbstrukturiert sein müssen
  • Datenportabilität und verteilte Skalierung Prioritäten sind

In diesen Fällen ist die Verwendung von ObjectIds oder ähnlichen eindeutigen, zeitsortable Identifikatoren oft eine vernünftige Vorgabe.

PrimeCRM

Zurück zum Wissenszentrum