Zorientowałem się, oto funkcja, która to robi:
CREATE OR REPLACE FUNCTION generate_uid(size INT) RETURNS TEXT AS $$
DECLARE
characters TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
bytes BYTEA := gen_random_bytes(size);
l INT := length(characters);
i INT := 0;
output TEXT := '';
BEGIN
WHILE i < size LOOP
output := output || substr(characters, get_byte(bytes, i) % l + 1, 1);
i := i + 1;
END LOOP;
RETURN output;
END;
$$ LANGUAGE plpgsql VOLATILE;
A następnie, aby go uruchomić, po prostu wykonaj:
generate_uid(10)
-- '3Rls4DjWxJ'
Ostrzeżenie
Robiąc to, musisz mieć pewność, że długość tworzonych identyfikatorów jest wystarczająca, aby uniknąć kolizji w miarę wzrostu liczby utworzonych obiektów, co może być sprzeczne z intuicją ze względu na Paradoks urodzinowy
. Więc prawdopodobnie będziesz potrzebować długości większej (lub znacznie większej) niż 10
dla każdego rozsądnie często tworzonego obiektu, po prostu użyłem 10
jako prosty przykład.
Użycie
Po zdefiniowaniu funkcji możesz użyć jej w definicji tabeli, na przykład:
CREATE TABLE collections (
id TEXT PRIMARY KEY DEFAULT generate_uid(10),
name TEXT NOT NULL,
...
);
A potem podczas wstawiania danych, tak jak:
INSERT INTO collections (name) VALUES ('One');
INSERT INTO collections (name) VALUES ('Two');
INSERT INTO collections (name) VALUES ('Three');
SELECT * FROM collections;
Automatycznie wygeneruje id
wartości:
id | name | ...
-----------+--------+-----
owmCAx552Q | ian |
ZIofD6l3X9 | victor |
Użycie z prefiksem
A może chcesz dodać prefiks dla wygody podczas przeglądania pojedynczego identyfikatora w dziennikach lub w debugerze (podobnie do jak Stripe to robi ), jak na przykład:
CREATE TABLE collections (
id TEXT PRIMARY KEY DEFAULT ('col_' || generate_uid(10)),
name TEXT NOT NULL,
...
);
INSERT INTO collections (name) VALUES ('One');
INSERT INTO collections (name) VALUES ('Two');
INSERT INTO collections (name) VALUES ('Three');
SELECT * FROM collections;
id | name | ...
---------------+--------+-----
col_wABNZRD5Zk | ian |
col_ISzGcTVj8f | victor |