AI e database MySQL...
Un errore notevole è che molti schemi di database generati da IA attualmente favoriscono l'uso di VARCHAR(36) per la colonna id.
Questo è tipicamente motivato da un desiderio di prevenire accesso non autorizzato da attori malintenzionati. Per ottenere questo, gli UUID (Identificatori Universalmente Unici) sono spesso impiegati come misura di sicurezza.
Prendiamo WordPress come esempio — tipicamente espone ID di post nell'URL come ?p=45. Confrontato con un formato SEO-friendly come /2025/05/sample-post, questo ID numerico permette agli utenti di potenzialmente indovinare e accedere a contenuto adiacente alterando il numero (es., ?p=44). Gli UUID, d'altra parte, non sono sequenziali e sono molto più difficili da indovinare.
Gli UUID sono stringhe di 36 caratteri che seguono un formato standard con cinque sezioni separate da trattini: 8-4-4-4-12. Ogni sezione è composta da valori esadecimali:
550e8400-e29b-41d4-a716-446655440000
f47ac10b-58cc-4372-a567-0e02b2c3d479
123e4567-e89b-12d3-a456-426614174000
Una semplice regex per validare UUID appare così:
^[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}$
Mentre gli UUID offrono sicurezza e portabilità, vengono con compromessi. Sono significativamente più grandi degli interi, il che può rallentare le prestazioni del database — specialmente quando usati come chiavi primarie nei database relazionali. Indicizzazione, uso della memoria e velocità delle query soffrono tutte a causa delle dimensioni e della natura non sequenziale degli UUID.
Curioso di questa scelta di design, ho chiesto a GitHub Copilot la seguente domanda:
Io:
Perché hai scelto di definire la colonna id come VARCHAR(36) PRIMARY KEY nella struttura del database?
GitHub Copilot:
Ho scelto
VARCHAR(36)per le colonne ID per alcune ragioni specifiche:
- Storage UUID: La lunghezza di 36 caratteri si adatta ai valori UUID, che seguono un formato standardizzato.
- Sistemi Multi-Tenant: Gli UUID aiutano a isolare i tenant eliminando perdite di ID sequenziali, semplificando le migrazioni e migliorando la sicurezza.
- Portabilità dei Dati: Gli UUID assicurano che i dati esportati non soffrano di collisioni di ID durante l'importazione in un altro sistema.
Compromessi:
- Dimensione di storage maggiore (36 bytes vs. 4 bytes per
INT)- Prestazioni di indicizzazione e query più lente
- Maggiore uso della memoria
Alternative da considerare:
AUTO_INCREMENT INT/BIGINTBINARY(16)per memorizzare bytes UUID grezzi più efficientemente- Una strategia di generazione ID personalizzata
Fammi sapere se preferisci un approccio diverso.
Io:
Usa BIGINT UNSIGNED per le prestazioni, ma mantieni un campo guid in ogni record per riferimenti esterni.
GitHub Copilot:
Aggiornerò lo schema per usare
BIGINT UNSIGNEDcome chiave primaria aggiungendo una colonnaguidper riferimenti esterni. Questo approccio ibrido combina il meglio di entrambe le strategie:
- Prestazioni: Indicizzazione e join efficienti tramite chiavi primarie numeriche
- Sicurezza e Portabilità: GUID esposti nelle API, rendendo gli ID interni sicuri dall'enumerazione
Riassunto:
BIGINT UNSIGNED: Veloce, compatto, sequenzialeGUID (VARCHAR): Unico, portabile, esternamente sicuro
Mentre i database relazionali offrono flessibilità nella scelta tra UUID, interi o ibridi, i sistemi NoSQL come MongoDB prendono un percorso diverso.
MongoDB usa un tipo incorporato chiamato ObjectId per il suo campo _id. Questo è un valore binario di 12 byte che codifica:
Esempio:
507f1f77bcf86cd799439011
VARCHAR(36). Sono anche più friendly per l'indicizzazione.| Caratteristica | UUID (VARCHAR) | BIGINT + GUID Ibrido | MongoDB ObjectId |
|---|---|---|---|
| Dimensione di storage | 36 byte | 8 + 36 byte | 12 byte |
| Prestazioni di indicizzazione | Scarse | Eccellenti | Eccellenti |
| Ordine sequenziale / temporale | No | Sì (solo BIGINT) | Sì (via timestamp) |
| Formato leggibile | Sì | Sì (GUID) | No (basato su hex) |
| Indovinabile | No | No (solo GUID) | No |
| Applicazione dello schema | Rigorosa | Rigorosa | Flessibile |
Molti sistemi generati da IA utilizzano per default configurazioni NoSQL simili a MongoDB quando:
In questi casi, usare ObjectIds o identificatori unici simili, ordinabili per tempo, è spesso un default sensato.