CodeGym /Kurslar /SQL SELF /Unikal identifikatorların generasiyası

Unikal identifikatorların generasiyası

SQL SELF
Səviyyə , Dərs
Mövcuddur

Kompyuterlər şəbəkəyə qoşulmağa başlayanda çox sadə, amma ciddi bir problem ortaya çıxdı: necə təmin etmək olar ki, dünyanın fərqli yerlərində olan iki fərqli cihaz eyni identifikatoru yaratmasın?

Təsəvvür elə: iki server, biri Tokioda, biri Berlində, obyektlər üçün identifikatorlar yaradır. Birdən eyni ID yaratsalar — məlumatlar qarışa bilər, üst-üstə yazıla bilər və sistem çökə bilər.

90-cı illərdə, paylanmış sistemlər və şəbəkə protokolları sürətlə inkişaf edəndə, Microsoft və Open Software Foundation (OSF) içində GUID ideyası yarandı — Globally Unique Identifier, yəni qlobal unikal identifikator.

GUID (ISO standartında — UUID, Universally Unique Identifier) — bu, məsələn, belə görünən 128-bitlik bir rəqəmdir:

550e8400-e29b-41d4-a716-446655440000

Bu, sanki rəqəmsal barmaq izidir: o qədər uzun və xaotikdir ki, kolliziya ehtimalı (iki identifikatorun üst-üstə düşməsi) praktiki olaraq sıfırdır.

O, aşağıdakılardan istifadə edilərək yaradılır:

  • vaxt,
  • təsadüfi rəqəmlər,
  • cihazın MAC-adresi (köhnə versiyalarda),
  • və hətta kriptoqrafik hash-funksiyalar.

Niyə bu vacib idi? Çünki GUID imkan verdi ki, unikal identifikatorlar mərkəzi server olmadan, koordinasiyasız, bloklanma və gecikmələrsiz yaradılsın. Bu, əsl xilas oldu:

  • paylanmış verilənlər bazaları,
  • şəbəkə protokolları,
  • sənəd dövriyyə sistemləri,
  • və əlbəttə, müasir API-lər üçün.

PostgreSQL-də UUID

GUID/UUID hər yerdə istifadə olunur — PostgreSQL-dən tutmuş bulud servislərinə qədər. Onlar müasir internetin görünməyən inşaatçılarıdır: onsuz dünyanı belə asan birləşdirə bilməzdik.

Əslində bu sadəcə çox uzun təsadüfi rəqəmdir, 16 baytdan ibarət, 16-lıq formatda yazılıb. Sadəcə çox uzun bir tam ədəddir.

Bu data tipi idealdır, əgər sənə bütün sistem səviyyəsində unikal dəyərlər lazımdırsa və mərkəzləşdirilmiş identifikator generatorundan asılı olmaq istəmirsənsə. Xüsusilə paylanmış sistemlərdə və ya məlumatlar fərqli serverlərdə yaradılırsa, çox faydalıdır.

Niyə sadəcə INTEGER istifadə etməyək?

Elə bil ki, UUID nəyə lazımdır, axı sadəcə auto-increment olan bir rəqəm identifikator kimi istifadə oluna bilər? Gəlin baxaq:

Qlobal unikalıq: Əgər sənin verilənlər bazan bir neçə serverdə işləyirsə, INTEGER ilə unikalığı təmin etmək çətin olacaq. UUID ilə bu problem olmur.

Təhlükəsizlik və məlumatların gizliliyi: UUID ardıcıl nömrədən fərqli olaraq, proqnozlaşdırmaq çətindir. Bu, məlumat sızması riskini azaldır (məsələn, /users/1, /users/2 kimi).

Paylanmış sistemlər: Əgər məlumatlar sistemin müxtəlif hissələrində yaradılırsa, auto-increment INTEGER olmadan mürəkkəb sinxronizasiya mümkün deyil.

UUID-nin başqa bir üstünlüyü — bu standartdır və bir çox proqramlaşdırma dilləri və data storage sistemləri tərəfindən dəstəklənir.

UUID istifadə etməyin üstünlükləri

Əsas pluslar:

  • Unikalıq: identifikatorun unikalığı təmin olunur, hətta məlumatlar fərqli serverlərdə və ya sistemlərdə yaradılsa belə.
  • Elastiklik: primary key, foreign key və başqa tapşırıqlarda istifadə oluna bilər.
  • Miqyaslana bilmək: paylanmış verilənlər bazaları ilə işləyəndə rahatdır.

Amma UUID-nin də öz minusları var:

  • Ölçü: UUID yaddaşda daha çox yer tutur (16 bayt), INTEGER isə (4 bayt).
  • Oxunaqlılıq: oxumaq və yadda saxlamaq nisbətən çətindir.

PostgreSQL-də UUID generasiyası

Daxili gen_random_uuid() funksiyası

PostgreSQL 13-dən başlayaraq, təsadüfi UUID yaratmaq üçün daxili gen_random_uuid() funksiyası var. Bu funksiya unikal identifikator qaytarır və onu UUID tipli sütun üçün dəyər kimi istifadə edə bilərsən.

Nümunə:

SELECT gen_random_uuid();

Nəticə:

d17fc23b-22e5-4fcb-bf86-1b4c766d77b7

Əmin ol ki, pgcrypto extension-u quraşdırılıb (PSQL 1-12 üçün)

PostgreSQL-in köhnə versiyalarında (13-dən əvvəl) gen_random_uuid() funksiyası pgcrypto extension-u quraşdırılandan sonra əlçatandır. Əgər işdə səni məcbur edirlərsə, vəziyyəti belə xilas edə bilərsən:

CREATE EXTENSION IF NOT EXISTS "pgcrypto";

Bu, təsadüfi UUID generasiyasını istifadə etməyə imkan verəcək.

UUID-ni xarici açar kimi istifadə etmək

UUID ilə cədvəllər arasında əlaqə qurmaq çox rahatdır. Tutaq ki, səndə istifadəçilər üçün bir cədvəl var:

id ad email
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

orders cədvəlinin yaradılması

Gəlin orders cədvəli yaradaq, burada user_id xarici açar kimi users cədvəlindəki id-yə istinad edəcək.

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

user_id sahəsi users cədvəlindəki id sahəsi ilə bağlıdır və bu, istifadəçilərlə onların sifarişləri arasında əlaqə qurmağa imkan verir.

JOIN ilə məlumat seçimi

Görək, usersorders cədvəllərində məlumatlar necə əlaqəlidir:

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;

Nəticə:

user_id ad order_id order_date
d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 Alice a1d3e15a-abc1-4b51-a320-2d4c859f7467 2024-10-20 12:34:56

UUID istifadə üçün əsas ssenarilər

İstifadəçi və sifariş identifikatorları: paylanmış sistemlərdə, məlumatlar müxtəlif mənbələrdən gələndə.

API üçün markerlər: UUID REST API-də tez-tez entity-ləri identifikasiya etmək üçün istifadə olunur.

Qlobal məlumat sinxronizasiyası: məsələn, məlumatlar müxtəlif serverlərdən toplananda.

Tipik səhvlər və xüsusiyyətlər

UUID əl ilə yaratmağa cəhd: səhvlərdən qaçmaq üçün ən yaxşısı daxili funksiyalardan, məsələn, gen_random_uuid() istifadə etməkdir.

Artıq istifadə: UUID istifadə etmə, əgər sadə auto-increment INTEGER kifayət edirsə. Məsələn, heç vaxt miqyaslanmayacaq lokal cədvəllərdə.

Ölçü: UUID daha çox yer tutur, bu isə sorğuların performansına, xüsusilə indeksləşdirmədə təsir edə bilər.

2
Tapşırıq
SQL SELF, səviyyə, dərs
Bağlanıb
UUID yaradılması
UUID yaradılması
2
Tapşırıq
SQL SELF, səviyyə, dərs
Bağlanıb
UUID-lərin əlaqəli cədvəllərdə bağlanması
UUID-lərin əlaqəli cədvəllərdə bağlanması
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION