JavaRush /Курси /SQL SELF /Генерація унікальних ідентифікаторів

Генерація унікальних ідентифікаторів

SQL SELF
Рівень 16 , Лекція 0
Відкрита

Коли компи тільки почали активно з'єднуватися в мережу, з'явилась проста, але дуже гостра проблема: як гарантувати, що два різних пристрої, які знаходяться в різних куточках світу, не згенерять один і той самий ідентифікатор?

Уяви собі: два сервери, один у Токіо, інший у Берліні, незалежно створюють ідентифікатори для об'єктів. Якщо вони раптом створять однакові ID — дані можуть переплутатись, перезаписатись, а система впасти.

Так у 1990-х, в епоху бурхливого розвитку розподілених систем і мережевих протоколів, у надрах Microsoft і Open Software Foundation (OSF) з'явилась ідея GUIDGlobally Unique Identifier, або глобально унікальний ідентифікатор.

GUID (а по ISO — UUID, Universally Unique Identifier) — це 128-бітне число, яке виглядає, наприклад, ось так:

550e8400-e29b-41d4-a716-446655440000

Це як цифровий відбиток: він настільки довгий і хаотичний, що ймовірність колізії (співпадіння двох ідентифікаторів) практично нульова.

Створюється він з використанням:

  • часу,
  • рандомних чисел,
  • MAC-адреси пристрою (у старих версіях),
  • і навіть криптографічних hash-функцій.

Чому це було важливо? Фішка в тому, що GUID дозволив створювати унікальні ідентифікатори без центрального сервера, без координації, без блокувань і затримок. Це стало справжнім спасінням для:

  • розподілених баз даних,
  • мережевих протоколів,
  • систем документообігу,
  • і, звісно, сучасних API.

UUID у PostgreSQL

GUID/UUID юзається всюди — від PostgreSQL до хмарних сервісів. Вони стали невидимими будівельниками сучасного інтернету: без них ми б не змогли так просто об'єднувати світ.

Фактично це просто дуже довге рандомне число з 16 байт, яке записане у шістнадцятковому форматі. Просто дуже довге ціле число.

Цей тип даних ідеально підходить, якщо тобі треба гарантувати унікальність значень на рівні всієї системи, без залежності від централізованого генератора ідентифікаторів. Це особливо корисно в розподілених системах або коли дані генеруються на різних серверах.

Чому не юзати просто INTEGER?

Здавалось би, навіщо потрібен UUID, якщо можна просто юзати автоінкрементне число як ідентифікатор? Давай розберемось:

Глобальна унікальність: Якщо твоя база даних працює на кількох серверах, гарантувати унікальність INTEGER буде складно. З UUID ця проблема вирішується.

Безпека і приховування даних: UUID важче вгадати, ніж послідовний номер. Це знижує ризик витоку інфи через передбачувані ідентифікатори (наприклад, /users/1, /users/2).

Розподілені системи: Якщо дані генеруються в різних частинах системи, автоінкрементний INTEGER не підходить без складної синхронізації.

Ще один плюс UUID — це стандарт, який підтримується у багатьох мовах програмування і системах зберігання даних.

Переваги використання UUID

Основні плюси:

  • Унікальність: гарантується унікальність ідентифікатора, навіть якщо дані створюються на різних серверах чи системах.
  • Гнучкість: можна юзати для primary key, foreign key та інших задач.
  • Масштабованість: зручно при роботі з розподіленими базами даних.

Але у UUID є й свої мінуси:

  • Розмір: UUID займає більше місця в пам'яті (16 байт), ніж INTEGER (4 байта).
  • Читабельність: порівняно складніше читати і запам'ятовувати.

Генерація UUID у PostgreSQL

Вбудована функція gen_random_uuid()

У PostgreSQL з версії 13 з'явилась вбудована функція gen_random_uuid() для генерації рандомних UUID. Ця функція повертає унікальний ідентифікатор, який можна юзати як значення для стовпця типу UUID.

Приклад:

SELECT gen_random_uuid();

Результат:

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

Перевір, що розширення pgcrypto встановлено (для PSQL 1-12)

У ранніх версіях PostgreSQL (до 13-ї версії) функція gen_random_uuid() доступна після встановлення розширення pgcrypto. Якщо на роботі тебе змушують ним користуватись, то ти можеш врятувати ситуацію, виконавши команду:

CREATE EXTENSION IF NOT EXISTS "pgcrypto";

Це дозволить юзати генерацію рандомних UUID.

Використання UUID як зовнішнього ключа

UUID зручно юзати для побудови зв'язків між таблицями. Припустимо, у тебе є таблиця користувачів:

id name 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

Давай створимо таблицю orders, де user_id буде зовнішнім ключем, що посилається на id у таблиці users.

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 пов'язане з полем id таблиці users, що дозволяє створювати зв'язки між користувачами і їх замовленнями.

Вибірка даних з JOIN

Подивимось, як пов'язані дані в таблицях users і orders:

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;

Результат:

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

Основні сценарії використання UUID

Ідентифікатори користувачів і замовлень: у розподілених системах, де дані можуть надходити з різних джерел.

Мітки для API: UUID часто юзається в REST API для ідентифікації сутностей.

Глобальна синхронізація даних: наприклад, коли дані збираються з різних серверів.

Типові помилки та особливості

Спроба генерувати UUID вручну: краще юзати вбудовані функції, такі як gen_random_uuid(), щоб уникнути помилок.

Надмірне використання: не юзай UUID там, де достатньо автоінкрементного INTEGER. Наприклад, у локальних таблицях, які ніколи не будуть масштабуватись.

Розмір: UUID займає більше місця, що може вплинути на продуктивність запитів, особливо при індексуванні.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ