Jeg fandt ud af det, her er en funktion, der gør det:
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;
Og for at køre det skal du blot gøre:
generate_uid(10)
-- '3Rls4DjWxJ'
Advarsel
Når du gør dette, skal du være sikker på, at længden af de id'er, du opretter, er tilstrækkelig til at undgå kollisioner over tid, efterhånden som antallet af objekter, du har oprettet, vokser, hvilket kan være kontraintuitivt på grund af Fødselsdagsparadoks
. Så du vil sandsynligvis have en længde større (eller meget større) end 10
for ethvert rimeligt almindeligt oprettet objekt brugte jeg bare 10
som et simpelt eksempel.
Brug
Med funktionen defineret kan du bruge den i en tabeldefinition, som sådan:
CREATE TABLE collections (
id TEXT PRIMARY KEY DEFAULT generate_uid(10),
name TEXT NOT NULL,
...
);
Og så når du indsætter data, som sådan:
INSERT INTO collections (name) VALUES ('One');
INSERT INTO collections (name) VALUES ('Two');
INSERT INTO collections (name) VALUES ('Three');
SELECT * FROM collections;
Det vil automatisk generere id
værdier:
id | name | ...
-----------+--------+-----
owmCAx552Q | ian |
ZIofD6l3X9 | victor |
Brug med et præfiks
Eller måske vil du tilføje et præfiks for nemheds skyld, når du ser på et enkelt ID i logfilerne eller i din debugger (svarende til hvordan Stripe gør det ), sådan:
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 |