Przejdź do treści

Opublikowano 2024-07-08 · Baza danych, MySQL

Problemy z używaniem UUID jako klucza głównego w MySQL

UUID (Universally Unique Identifier) to standardowy format identyfikatorów używany do zapewnienia unikalności w różnych systemach informatycznych. Jego popularność wynika z możliwości generowania unikalnych identyfikatorów bez konieczności centralnej koordynacji. Jednakże, używanie UUID jako klucza głównego w bazach danych MySQL wiąże się z kilkoma istotnymi wyzwaniami. W tym artykule omówię te problemy, ich wpływ na wydajność oraz najlepsze praktyki, które mogą pomóc w minimalizacji negatywnych skutków.

Struktura i typy UUID

UUID składa się z 128 bitów i często jest reprezentowany jako 36-znakowy ciąg (np. 123e4567-e89b-12d3-a456-426614174000). Może być przechowywany w różnych formatach, w tym jako ciąg znaków (CHAR(36)) lub jako wartość binarna (BINARY(16)), co wpływa na sposób zarządzania danymi i ich wydajność.

UUID - Struktura i typy

Rodzaje UUID

  • UUIDv1: Bazuje na znaczniku czasu i adresie MAC, co może potencjalnie naruszać prywatność.
  • UUIDv4: Generowany losowo, najczęściej używany ze względu na prostotę.
  • UUIDv7: Czasoprzestrzenne UUID, które wykorzystuje znacznik czasu Unix Epoch, co poprawia jego porządkowanie.
  • UUIDv8: Najnowsza wersja, pozwalająca na implementacje specyficzne dla dostawców zgodnie ze standardami RFC.

Problemy z wydajnością

Wydajność wstawiania danych

Jednym z głównych problemów związanych z używaniem UUID jako klucza głównego jest wydajność wstawiania danych. MySQL używa struktury B+ Tree do indeksowania, co pozwala na szybkie wyszukiwanie danych. UUID, ze względu na swoją losowość, mogą prowadzić do częstych operacji dzielenia stron (page splitting) i rebalansowania drzewa, co znacząco obniża wydajność wstawiania danych​.

Zużycie pamięci

UUID zajmują znacznie więcej miejsca niż tradycyjne klucze autoinkrementacyjne (INT). Przechowywanie UUID jako CHAR(36) może zajmować aż 288 bitów, podczas gdy INT zajmuje tylko 32 bity. Nawet w formacie binarnym UUID (BINARY(16)) zużywa cztery razy więcej miejsca niż INT. Większe zużycie pamięci wpływa nie tylko na rozmiar indeksów, ale także zwiększa liczbę operacji I/O, co może spowolnić wydajność całej bazy danych​.

Najlepsze praktyki w używaniu UUID

Używanie formatu binarnego

Aby zminimalizować zużycie pamięci, zaleca się przechowywanie UUID w formacie binarnym (BINARY(16)) zamiast jako ciąg znaków (CHAR(36)). Zmniejsza to zapotrzebowanie na miejsce i może poprawić wydajność operacji na danych​.

Wersje UUID wspierające porządkowanie

Korzystanie z wersji UUID, które wspierają porządkowanie, takich jak UUIDv7 lub UUIDv8, może poprawić wydajność wstawiania danych. Te wersje generują wartości bardziej przewidywalne i sekwencyjne, co pozwala uniknąć problemów z dzieleniem stron i rebalansowaniem drzewa​.

Syntetyczne klucze główne

Rozważenie użycia syntetycznych kluczy głównych, takich jak autoinkrementujące INT, w połączeniu z unikalnymi kolumnami UUID, może być dobrym rozwiązaniem. Taka kombinacja pozwala korzystać z zalet UUID bez ponoszenia pełnych kosztów związanych z wydajnością i zużyciem pamięci. Klucz główny może być autoinkrementującym INT, a UUID może być używany jako unikalna kolumna do innych celów, takich jak synchronizacja danych między systemami​ ​.

Sprawdź artykuł o nowym hooku w React

Zalety i wady używania UUID

Zalety

  • Unikalność: Gwarantują unikalność w skali globalnej, co jest kluczowe w systemach rozproszonych.
  • Bezpieczeństwo: Trudne do przewidzenia, co może zwiększyć bezpieczeństwo danych.
  • Skalowalność: Pozwalają na skalowanie systemów bez konieczności centralnej koordynacji generowania identyfikatorów.

Wady

  • Wydajność: Losowość UUID wpływa negatywnie na wydajność wstawiania danych i może powodować fragmentację indeksów.
  • Zużycie Pamięci: Większe zapotrzebowanie na miejsce do przechowywania i większe indeksy.
  • Złożoność: Trudniejsze do debugowania i zarządzania w porównaniu z prostymi kluczami numerycznymi.

Przykłady implementacji

CREATE TABLE uuids(
UUIDAsChar CHAR(36) NOT NULL,
UUIDAsBinary BINARY(16) NOT NULL
);

INSERT INTO uuids (UUIDAsChar, UUIDAsBinary) VALUES
('d211ca18-d389-11ee-a506-0242ac120002', UUID_TO_BIN('d211ca18-d389-11ee-a506-0242ac120002'));

SELECT * FROM uuids;

Wnioski – czy to odpowiedni wybór?

Wybór UUID jako klucza głównego w MySQL zależy od specyfiki projektu i wymagań systemowych. W wielu przypadkach UUID może być odpowiednim wyborem, zwłaszcza w systemach rozproszonych, gdzie unikalność identyfikatorów jest kluczowa. Jednakże, dla systemów o wysokiej intensywności operacji wstawiania danych, może być korzystniejsze zastosowanie tradycyjnych kluczy autoinkrementacyjnych lub kombinacji obu podejść.

Więcej o opcjach optymalizowania bazy danych dowiesz się na MySQL Performance Blog

Artykul przygotowal

Marcin Dymek

Marcin Dymek

KemuriCodes

Full Stack Developer w Brainbox (Gdynia), po godzinach buduję strony i sklepy jako Kemuri. Łączę development z projektowaniem — dbam o wydajność, SEO i detale interfejsu, od makiety w Figmie po wdrożenie.

Udostępnij X LinkedIn Facebook

Oceń ten artykuł

4.8 5 22 ocen

Powiazane wpisy

Jesli ten temat jest Ci bliski, sprawdz kolejne materialy z podobnego obszaru.

Czytaj wpis: Jak skonfigurować Redis w WordPress i Bedrock

01

· Programowanie

Jak skonfigurować Redis w WordPress i Bedrock

Redis to popularny system pamięci podręcznej typu open-source, który może znacznie zwiększyć wydajność strony internetowej. W tym artykule omówimy, jak poprawnie skonfigurować Redis w standardowej instalacji WordPress oraz w instalacji Bedrock od Roots. Ponadto, przedstawimy rozwiązanie problemu z błędem „Filesystem not writeable” w Redis Object Cache. Instalacja Redis w standardowej instalacji WordPress Krok 1: Uzyskaj … Czytaj dalej

Czytaj wpis: Optymalizacja wydajności zapytania SQL w WordPress

02

· Programowanie

Optymalizacja wydajności zapytania SQL w WordPress

Wydajność zapytań SQL w WordPressie jest kluczowym aspektem, który wpływa na szybkość i responsywność strony. Wolne zapytania mogą znacznie spowolnić działanie witryny, co negatywnie wpływa na doświadczenia użytkowników oraz SEO. W tym artykule omówimy różnorodne techniki optymalizacji zapytań SQL, podając praktyczne przykłady, rekomendując wtyczki oraz dzieląc się najlepszymi praktykami. Podstawowe techniki optymalizacji Indeksowanie Indeksowanie jest … Czytaj dalej