PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come generare un ID alfanumerico casuale, univoco di lunghezza N in Postgres 9.6+?

Capito questo, ecco una funzione che lo fa:

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;

E poi per eseguirlo basta fare:

generate_uid(10)
-- '3Rls4DjWxJ'

Avviso

Quando fai ciò devi essere sicuro che la lunghezza degli ID che stai creando sia sufficiente per evitare collisioni nel tempo man mano che il numero di oggetti che hai creato cresce, il che può essere controintuitivo a causa del Paradosso del compleanno . Quindi probabilmente vorrai una lunghezza maggiore (o molto maggiore) di 10 per qualsiasi oggetto creato ragionevolmente comunemente, ho semplicemente usato 10 come semplice esempio.

Utilizzo

Con la funzione definita, puoi usarla in una definizione di tabella, in questo modo:

CREATE TABLE collections (
  id TEXT PRIMARY KEY DEFAULT generate_uid(10),
  name TEXT NOT NULL,
  ...
);

E poi quando si inseriscono i dati, in questo modo:

INSERT INTO collections (name) VALUES ('One');
INSERT INTO collections (name) VALUES ('Two');
INSERT INTO collections (name) VALUES ('Three');
SELECT * FROM collections;

Genererà automaticamente l'id valori:

    id     |  name  | ...
-----------+--------+-----
owmCAx552Q | ian    |
ZIofD6l3X9 | victor |

Utilizzo con un prefisso

O forse vuoi aggiungere un prefisso per comodità quando guardi un singolo ID nei log o nel tuo debugger (simile a come fa Stripe ), così:

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 |