Czy mozna obejść się bez UUID

Czy mozna obejść się bez UUID
TM
  • Rejestracja:prawie 4 lata
  • Ostatnio:około miesiąc
  • Postów:91
0

Czy konieczne jest używanie UUID czy samo ID wystarczy i można to jakoś zabezpieczyć?

Chodzi mi o to że np przy autoryzacji użytkownika można użyać tylko ID i tylko ID się posługiwać ?

edytowany 1x, ostatnio: TakMaszRacje
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
9

Chyba powinieneś trochę więcej kontekstu napisać. Tak postawione pytanie nie ma sensu.

  1. Oczywiście, że samo ID wystarczy -> w pewnych systemach. Czasem wystarczy nawet dokłanie jedno ID = 42, a nawet i bez tego jednego ID można się obyć.
  2. Przed czym zabezpieczyć?

jeden i pół terabajta powinno wystarczyć każdemu
Zobacz pozostały 1 komentarz
ZD
Nie wybrnąłeś ze żle postawionego zagadnienia @TakMaszRacje opowiadasz 217 odcinek serialu, my nie znamy poprzednich
TM
Uzywam Springa Security do autoryzacji, ma to być backend pod apliakcję mobilna napisanąw react native. Moj model uzytkownika utworzyłem tylko z ID. Czy to wystarczy czy powinienem uzyć zamiast ID to UUID ?
jarekr000000
Wystawianie na zewnątrz ID (np. inkrementowanego) pozwala wyciągnąć trochę informacji o aplikacji oraz stanowi dodatkowy wektor ataku (i to nie tylko jeśli to ID usera, każde ID każdego obiektu). To nie zawsze jest problem, ale warto wiedzieć. Z ciekawostek: https://en.wikipedia.org/wiki/German_tank_problem
jarekr000000
W uproszczeniu - jeśli nie robisz bardzo poważnej aplikacji, która w razie problemów z bezpieczeństwem narazi kogoś na straty finansowe lub moralne, jeżeli nie jesteś Tutsi ani Hutu i te sprawy - to możesz sobie używać prostego, inkrementowanego ID do woli.
ZD
@jarekr000000: nie znałem tego zagadnienia z czołgami, fajnie coś z matematyki poczytać
obscurity
  • Rejestracja:około 6 lat
  • Ostatnio:22 minuty
3

Używając UUID łatwiej wyskalujesz aplikację np w chmurze, bo możesz bez synchronizacji między serwerami nadawać nowe ID-ki praktycznie bez martwienia się że został już w międzyczasie użyty na serwerze np w innym kraju. Widziałem obejścia tego w stylu że jeden node generuje ID-ki parzyste a drugi nieparzyste, przy stałej liczbie serwerów znając ich liczbę można to zrobić w ten sposób, ewentualnie dodać inny offset na każdym serwerze.

Dodatkowo możesz zrobić aplikację offline - wszystko może dziać się po stronie klienta, nawet dość skomplikowana logika a potem przy zapisie to wpisujesz do bazy, też nie martwiąc się że ID-ki w międzyczasie zostały zajęte. To też można ominąć przy odrobinie dodatkowej pracy, można zrobić mapowania wirtualnych IDków na wewnętrzne, ale to dużo bardziej skomplikowane.

Trzecim plusem UUID jest wyżej wspomniane bezpieczeństwo - nie musisz się martwić że userzy zgadną ID kolejnego resource'a. To też można rozwiązać np szyfrując ID lub mapując wewnętrzne ID na zewnętrzne, czyli każdy resource musi tak naprawdę dostać dwa ID-ki.

Jedynym minusem UUID jest nadmiarowa ilość przesyłanych danych i wolniejsze zapytania SQL, na przykład grupowanie po uuid będzie nieco wolniejsze i będzie wymagało więcej pamięci niż po 4 bajtowym IDku. Oszczędza za to dużo pracy i umożliwia bardziej skomplikowane scenariusze.


"A car won't take your job, another horse driving a car will." - Horse influencer, 1910
SL
  • Rejestracja:około 7 lat
  • Ostatnio:około godziny
  • Postów:896
2
TakMaszRacje napisał(a):

Czy konieczne jest używanie UUID czy samo ID wystarczy i można to jakoś zabezpieczyć?

Używaj tylko jednego idka. Im więcej rodzajów tym większy burdel i wprowadzenie czegoś takiego musi mieć jakieś wytłumaczenie. Jak wiesz, że potrzebujesz UUID to nie trzymaj numerycznego IDKa tylko niech UUID będzie kluczem w bazie.

obscurity napisał(a):

Jedynym minusem UUID jest nadmiarowa ilość przesyłanych danych i wolniejsze zapytania SQL, na przykład grupowanie po uuid będzie nieco wolniejsze i będzie wymagało więcej pamięci niż po 4 bajtowym IDku. Oszczędza za to dużo pracy i umożliwia bardziej skomplikowane scenariusze.

Głównym argumentem przeciwko UUID jest ich losowość, co sprawia, że słabo pasują do BTree indeksu. Polecam dokument o dość nowych wersjach UUID, które opisują dobrze ten problem https://www.ietf.org/archive/id/draft-peabody-dispatch-new-uuid-format-04.html

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 3 godziny
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0

W niektórych systemach nawet brak id by wystarczył. Jeśli operujemy tylko na danych, które nie mogą mieć powtórzeń, np mamy aplikację w której użytkownicy są indetyfikowani np używając PESEL; ponieważ dwie osoby nie mogą mieć tego samego PESEL, wtedy możemy użyć tego numeru do unikanlnego znalezienia użytkownika. Id również nie potrzebujemy, kiedy nie musimy nigdy identyfikować konkretnego rekordu, np. tabele łącznikowe w bazach relacyjnych też nie mają id, bo i po co?

Odn. @KamilAdam: Oczywiście nie mówię tutaj, że pesel to jest dobry substytut, i należy go od razu ustawiać jako PRIMARY KEY, tylko ilustruję po co jest id - po to żeby uniknalnie zidentyfikować record, są przypadki kiedy mamy takie pole w recordach, i ono wystarczy. Są też przypadki kiedy takiego nie ma, i musimy dodać pole w bazie tylko do tego celu. Dodatkowo, niewiele osób się zastanawia nad tym po co jest id, i po prostu dodaje je z automatu, jest to częsta praktyka.

Skąd więc wiadomo, kiedy użyć id, a kiedy nie. Wtedy, kiedy potrzebujemy odnieść się do jakiegoś recordu, ale w tym recordzie nie ma żadnych danych po których jest 100% pewności że można po nich unikalnie zidentyfikować record (czyli pewnie 95% przypadków i więcej). Zwykły integer wystarczy, jeśli mamy pojedynczą bazę. Taki id może nadać aplikacja, lub niektóre bazy (albo może nawet wszystkie?) mają wbudowane funkcje, które mogą same nadawać kolejny integer (auto increament).

Co jest złego z id? W aplikacjach z pojedynczą bazą - nic.

Jeśli jednak więcej niż jedna aplikacja ma dostęp do jednej bazy, albo przetwarzanie takich danych jest rozproszone; wtedy możę dojść do sytuacji w której dwie aplikacje będą chciały wygenerować nowy id, (np kolejny to 43), i obie będą chciały go dodać. Spowoduje to niekonsystencje systemu. Można oczywiście próbować to obejść; np pozwolić jednej aplikacji, drugiej odrzucić, i niech druga wybierze nowy id; ale to jest słabe rozwiązanie. Lepiej wygenerować taki id, którego szansa na powtórzenie jest bardzo niska lub zerowa, i tutaj wchodzi uuid.

edytowany 2x, ostatnio: Riddle
MA
Bez sensu, wtedy tworzysz serwis komunikujący się z bazą, najlepiej używający kolejki. O eventual consistency trzeba zawsze myśleć nistety
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:około miesiąc
  • Lokalizacja:Silesia/Marki
  • Postów:5505
3

Co do numeru PESEL to faktycznie w teorii jest unikalny. A w praktyce były przypadki że PESEL się powtarzał. W dodatku PESEL koduje płeć więc w przypadku zmiany płci zmienia się też PESEL (rzadkie, ale się zdarza). Gorsze jest że PESEL to dana osobowa więc trzeba uważać z użyciem :D

Co do wydajności id numerycznego vs UIDD. W Postgresie integer (int4) zajmuje 32 bity, bigint (int8) - 64 bity, a UUID zajmuje 128 bitów. więc różnica IMHO niewielka. Oczywiście jak używamy prymitywną bazę która nie ma tyku UUID to jest gorzej :D
Ale trzeba tez pamiętać że UUID nie daje pełnej losowości. Nie po to był projektowany. Podstawową ideą było to żeby numery się nie powtarzały, a nie zapewnienie nieprzewidywalności numerów
BTW istnieją conajmniej 4 sposoby generacji UUIDów i jeden z nich zapewnia że kolejne UUIDy będą rosnące co może być przydatne przy niektórych zapytaniach, ale znów zmniejsza losowość

To tyle jeśli używa się normalnej, tradycyjnej bazy danych jak PostgreSQL. Jak się używa jakiegoś NoSQL jak Cassandra to UUID jest obowiązkowy. Bo w Cassandra jest dynamiczna ilość węzłów nadających UUIDy


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
edytowany 2x, ostatnio: KamilAdam
Zobacz pozostałe 5 komentarzy
Koziołek
@KamilAdam: problem z sekwencyjnym ID i UUIDem nie polega na wielkości pojedynczego elementu, ale na tym, w jaki sposób baza danych będzie z nim pracować. W przypadku UUIDa można zrobić np. batch insert w wielu wątkach, bo nie musisz czekać na kolejny odczyt z sekwencji.
KamilAdam
@Koziołek: To raczej zaleta a nie "problem" :P Ja tylko chciałem napisać że z dwóch głownych "wad" UUIDa to jedna to pierdółka (8 czy 12 bajtów więcej na rekord) a drugi da się rozwiązać stosujac odpowiednią generacja UUID. Z trzy lata temu przy podobnej dyskusji ID z sekwencji vs UUID "urósł" tu do niesamowitych rozmiarów
Koziołek
@KamilAdam: no to nie wszystko. UUID ma też przykrą tendencję do psucia indeksów w MySQLu i MSSQL, bo ze względu na losowość trzeba częściej rebalansować b+drzewo, które siedzi pod spodem.
SO
@Koziołek: a tego w jakimś stopniu nie rozwiązują sekwencyjne UUIDy? Btw. w Postgresie nie ma tego problemu?
Koziołek
Dlatego niżej w poście wspominam o ULIDach, ale to też kwestia wyborów podejmowanych przez implementujących poszczególne bazy
Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:około 4 godziny
0
KamilAdam napisał(a):

Co do wydajności id numerycznego vs UIDD. W Postgresie integer (int4) zajmuje 32 bity, bigint (int8) - 64 bity, a UUID zajmuje 128 bitów. więc różnica IMHO niewielka. Oczywiście jak używamy prymitywną bazę która nie ma tyku UUID to jest gorzej :D

a oracle to w ogóle ma typy liczbowe chyba zmiennej długości :)

https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Data-Types.html#GUID-9401BC04-81C4-4CD5-99E7-C5E25C83F608

NUMBER Data Type
The NUMBER data type stores zero as well as positive and negative fixed numbers with absolute values from 1.0 x 10-130 to but not including 1.0 x 10126. If you specify an arithmetic expression whose value has an absolute value greater than or equal to 1.0 x 10126, then Oracle returns an error. Each NUMBER value requires from 1 to 22 bytes.

nie testowałem, ani nie czytałem o wydajności typów liczbowych w oracle'u. na oko i tak nie wyglądają na demony szybkości, więc skoro oracle się nie martwi, to po co ja mam się martwić dodatkowo? :)


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit
Koziołek
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:17 dni
  • Lokalizacja:Stacktrace
  • Postów:6821
2

@TakMaszRacje: mówiąc o ID, masz zapewne na myśli liczbę całkowitą generowaną przez jakąś sekwencję. Przy takim założeniu, to jak pisał @jarekr000000 trafiasz na problemy z przewidywalnością numerów i analiza aplikacji staje się prostsza. Pytanie, jak jeszcze wykorzystujesz takie ID? Czy jest ono podstawą do sortowania danych w czasie prezentacji? Jeżeli tak, to zrobiłeś sobie krzywdę w naprawdę paskudny sposób. Jeżeli jednak nie ma żadnego innego zastosowania, to możesz użyć UUID. Otrzymasz wtedy pseudolosowy, unikalny i niesortowalny identyfikator.

I w tym momencie ci zamieszam :)

Jeżeli jednak potrzebujesz używać identyfikatora do sortowania, to zamiast sekwencyjnego ID użyj ULID, czyli odmiany UUID, która jest w pewnym zakresie sortowalna. W tym momencie użytkownicy będą mogli zostać uszeregowani, pod warunkiem że nie pojawi się dwóch stworzonych w tej samej milisekundzie, według czasu powstania. Identyfikator będzie pseudolosowy, więc jedyne co będzie można powiedzieć o aplikacji na jego podstawie, to kiedy dany użytkownik został utworzony. Jednak nie będzie można w łatwy sposób znaleźć kolejnego/poprzedniego identyfikatora.


Sięgam tam, gdzie wzrok nie sięga… a tam NullPointerException
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:6 dni
  • Postów:2370
0

Czy konieczne jest używanie UUID czy samo ID wystarczy i można to jakoś zabezpieczyć?

Nie jest konieczne używanie UUIDa (identyfikatora unikalnego w czasie i przestrzeni), ale bywa czasem potrzebne, np. jak robisz system rozproszony i masz do rozwiązania problem unikalności identyfikatorów. Tak jak z "volatile", jak będziesz potrzebował, to będziesz wiedział dlaczego ;)

Chodzi mi o to że np przy autoryzacji użytkownika można użyać tylko ID i tylko ID się posługiwać ?

Autoryzację (sprawdzenie uprawnień do zasobu/akcji) mylisz z uwierzytelnieniem (weryfikacją, czy użytkownik jest tym za kogo się podaje).

W Spring Security masz możliwość stworzenia własnego AuthenticationProvider , więc jeśli w systemie masz użtykowników zapisanych w jakiejś tabelce jako : MY_USER (ID_Z_SEKWENCJI, DATA_URODZENIA, NR_TELEFONU, ...., to w procesie uwierzytelnienia (logowania) nie masz potrzeby korzystania z tego IDka i wystawiania go na świat. Uwierzytelnienie może być realizowane w oparciu o NR_TELEFONU + SMS z kodem, albo o certyfikat SSL klienta, itp.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.