АИ и MySQL базе података...
То је значајна грешка што многе схеме база података генерисане од стране ВИ тренутно теже да користе VARCHAR(36) за колону id.
Ово је обично мотивисано жељом да се спречи неовлашћен приступ од стране злонамерних актера. Да би се то постигло, УУИ-ови (Universal Unique Identifiers) се често користе као безбедносна мера.
Узмимо WordPress као пример — он обично открива идентификаторе постова у УРЛ-у као ?p=45. У поређењу са СЕО-пријатељским форматом као што је /2025/05/sample-post, овај нумерички идентификатор омогућава корисницима да потенцијално процене и приступе суседном садржају мењањем броја (нпр. ?p=44). УУИ-ови су, с друге стране, неузастопни и значајно тежи за погађање.
УУИ-ови су 36-карактерни стрингови који следе стандардни формат са пет секција раздвојених цртицама: 8-4-4-4-12. Свака секција се састоји од хексадецималних вредности:
550e8400-e29b-41d4-a716-446655440000
f47ac10b-58cc-4372-a567-0e02b2c3d479
123e4567-e89b-12d3-a456-426614174000
Једноставан regex за валидацију УУИ-ова изгледа овако:
^[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}$
Иако УУИ-ови пружају безбедност и преносивост, долазе са компромисима. Они су значајно већи од целих бројева, што може успорити перформансе базе података — посебно када се користе као примарни кључеви у релационим базама података. Индексирање, коришћење меморије и брзина упита сви пате због величине и неузастопне природе УУИ-ова.
Заинтригиран овом дизајнерском одлуком, поставио сам ово питање GitHub Copilot-у:
Ја:
Зашто сте изабрали да дефинишете колону id као VARCHAR(36) PRIMARY KEY у структури базе података?
GitHub Copilot:
Изабрао сам
VARCHAR(36)за ИД колоне из неколико специфичних разлога:
- Складиштење УУИ-а: Дужина од 36 карактера одговара УУИ вредностима, које следе стандардизовани формат.
- Мулти-тенант системи: УУИ-ови помажу у изолацији закупаца елиминацијом цурења узастопних ИД-ова, поједностављују миграције и побољшавају безбедност.
- Преносивост података: УУИ-ови осигуравају да извезени подаци немају конфликте ИД-ова када се уносе у други систем.
Компромиси:
- Већа величина складиштења (36 бајтова против 4 бајта за
INT)- Спорија перформанса индексирања и упита
- Већа употреба меморије
Алтернативе за разматрање:
AUTO_INCREMENT INT/BIGINTBINARY(16)за ефикаснији начин складиштења сирових УУИ бајтова- Прилагођена стратегија генерисања ИД-а
Обавестите ме ако бисте радије другачији приступ.
Ја:
Користите BIGINT UNSIGNED за перформансе, али задржите поље guid у сваком запису за спољне референце.
GitHub Copilot:
Ажурираћу схему да користи
BIGINT UNSIGNEDза примарне кључеве и додати колонуguidза спољне референце. Овај хибридни приступ комбинује најбоље од обе стратегије:
- Перформансе: Ефикасно индексирање и спајање кроз нумеричке примарне кључеве
- Безбедност и преносивост: GUID изложени у АПИ-јима, држећи унутрашње ИД-ове безбедне од набрајања
Резиме:
BIGINT UNSIGNED: Брз, компактан, узастопанGUID (VARCHAR): Јединствен, преносив, спољно безбедан
Док релационе базе података нуде флексибилност у избору између УУИ-ова, целих бројева или хибридних приступа, NoSQL системи као што је MongoDB иду другачијим путем.
MongoDB користи уграђени тип званичан ObjectId за своје поље _id. Ово је 12-бајтовска бинарна вредност која кодира:
Пример:
507f1f77bcf86cd799439011
VARCHAR(36). Они су такође прије према индексирању.| Карактеристика | УУИ (VARCHAR) | BIGINT + GUID хибрид | MongoDB ObjectId |
|---|---|---|---|
| Величина складиштења | 36 бајтова | 8 + 36 бајтова | 12 бајтова |
| Перформанса индексирања | Лоша | Одлична | Одлична |
| Узастопно / време | Не | Да (само BIGINT) | Да (кроз временски жиг) |
| Људски читљив формат | Да | Да (GUID) | Не (засновано на hex) |
| Погодљив | Не | Не (само GUID) | Не |
| Спровођење схеме | Строго | Строго | Флексибилно |
Многи ВИ генерисани системи користе NoSQL конфигурације као што је MongoDB по подразумеваним вредностима када:
У таквим случајевима, често је паметан подразумевани избор да се користе ObjectIds или слични јединствени, временски уређени идентификатори.