Typ danych uuid
jest idealnie nadaje się do tego zadania. Zajmuje tylko 16 bajtów w przeciwieństwie do 37 bajtów w pamięci RAM dla reprezentacji varchar
lub text
. (Lub 33 bajty na dysku, ale w wielu przypadkach liczba nieparzysta wymagałaby uzupełnienia, aby efektywnie osiągnąć 40 bajtów.) A ten uuid
typ ma jeszcze więcej zalet.
Przykład:
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash
Szczegóły i więcej wyjaśnień:
Możesz rozważyć inne (tańsze) funkcje haszujące, jeśli nie potrzebujesz komponentu kryptograficznego md5, ale wybrałbym md5 dla twojego przypadku użycia (głównie tylko do odczytu).
Słowo ostrzeżenia : W twoim przypadku ( immutable once written
) funkcjonalnie zależna (pseudo-naturalna) PK jest w porządku. Ale to samo będzie bolało,text
gdy możliwe są aktualizacje . Pomyśl o poprawieniu literówki: PK i wszystkie zależne indeksy, kolumny FK dozens of other tables
i inne odniesienia również musiałyby się zmienić. Nadęty tabel i indeksów, problemy z blokowaniem, powolne aktualizacje, utracone referencje, ...
Jeśli text
może się zmienić podczas normalnej pracy, lepszym wyborem byłby zastępczy PK . Proponuję bigserial
kolumnę (zakres -9223372036854775808 to +9223372036854775807
- to dziewięć kwintillion dwieście dwadzieścia trzy biliard trzysta siedemdziesiąt dwa tryliony trzydzieści sześć coś miliard ) odrębnych wartości billions of rows
. W każdym razie może to być dobry pomysł : 8 zamiast 16 bajtów na dziesiątki kolumn i indeksów FK!). Lub losowy UUID dla znacznie większych liczności lub systemów rozproszonych. Zawsze można przechowywać powiedział md5 (a uuid
) dodatkowo do szybko znaleźć wiersze w tabeli głównej z oryginalnego tekstu. Związane z:
Jeśli chodzi o twoje zapytanie :
Aby odpowiedzieć na komentarz @ Daniela : Jeśli wolisz reprezentację bez łączników, usuń łączniki do wyświetlenia:
SELECT replace('90b7525e-84f6-4850-c2ef-b407fae3f271', '-', '')
Ale nie zawracałbym sobie głowy. Domyślna reprezentacja jest w porządku. A problemem tak naprawdę nie jest tutaj reprezentacja.
Jeśli inne strony powinny mieć inne podejście i wrzucać ciągi bez łączników do miksu, nie stanowi to również problemu. Postgres akceptuje kilka rozsądnych reprezentacji tekstowych jako dane wejściowe dla uuid
. Dokumentacja :
PostgreSQL akceptuje także następujące alternatywne formy wprowadzania danych: użycie wielkich liter, standardowy format otoczony nawiasami klamrowymi, pomijanie niektórych lub wszystkich łączników, dodawanie łącznika po dowolnej grupie czterech cyfr. Przykładami są:
A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
a0eebc999c0b4ef8bb6d6bb9bd380a11
a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
Co więcej, md5()
funkcja zwraca text
, należałoby użyć decode()
do konwersji bytea
i domyślnej reprezentacji , które brzmi:
SELECT decode(md5('Store hash for long string, maybe for index?'), 'hex')
\220\267R^\204\366HP\302\357\264\007\372\343\362q
Musisz encode()
ponownie uzyskać oryginalną reprezentację tekstu:
SELECT encode(my_md5_as_bytea, 'hex');
Co więcej, wartości przechowywane jako bytea
zajmowałyby 20 bajtów w pamięci RAM (i 17 bajtów na dysku, 24 z wypełnieniem ) z powodu wewnętrznego varlena
obciążenia , co jest szczególnie niekorzystne dla rozmiaru i wydajności prostych indeksów.
Wszystko działa na korzyść uuid
tutaj.