Kom på det här, här är en funktion som 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;
Och sedan för att köra det gör du helt enkelt:
generate_uid(10)
-- '3Rls4DjWxJ'
Varning
När du gör detta måste du vara säker på att längden på ID:n du skapar är tillräcklig för att undvika kollisioner över tid när antalet objekt du har skapat växer, vilket kan vara kontraintuitivt på grund av Birthday Paradox
. Så du vill troligen ha en längd större (eller mycket större) än 10
för alla någorlunda vanligt skapade objekt använde jag bara 10
som ett enkelt exempel.
Användning
Med funktionen definierad kan du använda den i en tabelldefinition, som så:
CREATE TABLE collections (
id TEXT PRIMARY KEY DEFAULT generate_uid(10),
name TEXT NOT NULL,
...
);
Och sedan när du infogar data, som så:
INSERT INTO collections (name) VALUES ('One');
INSERT INTO collections (name) VALUES ('Two');
INSERT INTO collections (name) VALUES ('Three');
SELECT * FROM collections;
Den genererar automatiskt id
värden:
id | name | ...
-----------+--------+-----
owmCAx552Q | ian |
ZIofD6l3X9 | victor |
Användning med ett prefix
Eller så kanske du vill lägga till ett prefix för enkelhetens skull när du tittar på ett enskilt ID i loggarna eller i din debugger (liknande hur Stripe gör det ), som så:
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 |