Přišel jsem na to, zde je funkce, která to udělá:
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 pak to jednoduše spustíte takto:
generate_uid(10)
-- '3Rls4DjWxJ'
Upozornění
Když to uděláte, musíte si být jisti, že délka ID, která vytváříte, je dostatečná k tomu, aby se časem zabránilo kolizím, protože počet objektů, které jste vytvořili, roste, což může být kontraintuitivní kvůli Birthday Paradox
. Pravděpodobně budete chtít délku větší (nebo mnohem větší) než 10
pro jakýkoli rozumně běžně vytvářený objekt jsem právě použil 10
jako jednoduchý příklad.
Použití
S definovanou funkcí ji můžete použít v definici tabulky, například takto:
CREATE TABLE collections (
id TEXT PRIMARY KEY DEFAULT generate_uid(10),
name TEXT NOT NULL,
...
);
A pak při vkládání dat, třeba takto:
INSERT INTO collections (name) VALUES ('One');
INSERT INTO collections (name) VALUES ('Two');
INSERT INTO collections (name) VALUES ('Three');
SELECT * FROM collections;
Automaticky vygeneruje id
hodnoty:
id | name | ...
-----------+--------+-----
owmCAx552Q | ian |
ZIofD6l3X9 | victor |
Použití s předponou
Nebo možná budete chtít přidat předponu pro usnadnění při prohlížení jediného ID v protokolech nebo v ladicím programu (podobně jako jak to Stripe dělá ), třeba takto:
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 |