AI och MySQL-databaser...
Det är ett betydande fel att många AI-genererade databasscheman för närvarande tenderar att använda VARCHAR(36) för kolumnen id.
Detta är vanligtvis motiverat av en önskan att förhindra obehörig åtkomst från skadliga aktörer. För att uppnå detta används UUID (Universal Unique Identifiers) ofta som en säkerhetsåtgärd.
Låt oss ta WordPress som ett exempel — det avslöjar vanligtvis inläggs-ID:n i URL:en som ?p=45. Jämfört med ett SEO-vänligt format som /2025/05/sample-post, tillåter detta numeriska ID användare att potentiellt bedöma och komma åt angränsande innehåll genom att ändra numret (t.ex. ?p=44). UUID:er är å andra sidan icke-sekventiella och betydligt svårare att gissa.
UUID:er är 36-tecken strängar som följer ett standardformat med fem sektioner separerade av bindestreck: 8-4-4-4-12. Varje sektion består av hexadecimala värden:
550e8400-e29b-41d4-a716-446655440000
f47ac10b-58cc-4372-a567-0e02b2c3d479
123e4567-e89b-12d3-a456-426614174000
Ett enkelt regex för att validera UUID:er ser ut så här:
^[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}$
Även om UUID:er tillhandahåller säkerhet och portabilitet, kommer de med kompromisser. De är avsevärt större än heltal, vilket kan sakta ned databasprestanda — särskilt när de används som primärnycklar i relationsdatabaser. Indexering, minnesanvändning och frågehastighet lider alla på grund av UUID:ers storlek och icke-sekventiella natur.
Nyfiken på detta designval ställde jag denna fråga till GitHub Copilot:
Jag:
Varför valde du att definiera kolumnen id som VARCHAR(36) PRIMARY KEY i databasstrukturen?
GitHub Copilot:
Jag valde
VARCHAR(36)för ID-kolumner av flera specifika skäl:
- UUID-lagring: 36-tecken längden rymmer UUID-värden, som följer ett standardiserat format.
- Multi-tenant system: UUID:er hjälper till att isolera hyresgäster genom att eliminera sekventiella ID-läckor, förenkla migreringar och förbättra säkerheten.
- Dataportabilitet: UUID:er säkerställer att exporterade data inte har ID-konflikter när de importeras till ett annat system.
Kompromisser:
- Större lagringsstorlek (36 bytes vs 4 bytes för
INT)- Långsammare indexering och frågeprestanda
- Högre minnesanvändning
Alternativ att överväga:
AUTO_INCREMENT INT/BIGINTBINARY(16)för att lagra rå UUID-bytes mer effektivt- Anpassad ID-genereringsstrategi
Låt mig veta om du föredrar en annan approach.
Jag:
Använd BIGINT UNSIGNED för prestanda, men behåll ett guid fält i varje post för externa referenser.
GitHub Copilot:
Jag kommer att uppdatera schemat för att använda
BIGINT UNSIGNEDför primärnycklar och lägga till enguidkolumn för externa referenser. Detta hybridtillvägagångssätt kombinerar det bästa från båda strategierna:
- Prestanda: Effektiv indexering och kopplingar genom numeriska primärnycklar
- Säkerhet och portabilitet: GUID exponerade i API:er, håller interna ID:n säkra från uppräkning
Sammanfattning:
BIGINT UNSIGNED: Snabb, kompakt, sekventiellGUID (VARCHAR): Unik, portabel, externt säker
Medan relationsdatabaser erbjuder flexibilitet att välja mellan UUID:er, heltal eller hybridtillvägagångssätt, tar NoSQL-system som MongoDB en annan väg.
MongoDB använder en inbyggd typ kallad ObjectId för sitt _id fält. Detta är ett 12-byte binärt värde som kodar:
Exempel:
507f1f77bcf86cd799439011
VARCHAR(36). De är också mer indexeringsvänliga.| Funktion | UUID (VARCHAR) | BIGINT + GUID hybrid | MongoDB ObjectId |
|---|---|---|---|
| Lagringsstorlek | 36 bytes | 8 + 36 bytes | 12 bytes |
| Indexeringsprestanda | Dålig | Utmärkt | Utmärkt |
| Sekventiell / tid | Nej | Ja (endast BIGINT) | Ja (genom tidsstämpel) |
| Människoläsbart format | Ja | Ja (GUID) | Nej (hex-baserad) |
| Gissningsbar | Nej | Nej (endast GUID) | Nej |
| Schematvingande | Strikt | Strikt | Flexibel |
Många AI-genererade system använder NoSQL-konfigurationer som MongoDB som standard när:
I sådana fall är det ofta ett klokt standardval att använda ObjectIds eller liknande unika, tidsordnade identifierare.