PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment générer un ID alphanumérique aléatoire et unique de longueur N dans Postgres 9.6+ ?

J'ai compris cela, voici une fonction qui le fait :

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;

Et puis pour l'exécuter, faites simplement :

generate_uid(10)
-- '3Rls4DjWxJ'

Avertissement

Ce faisant, vous devez vous assurer que la longueur des identifiants que vous créez est suffisante pour éviter les collisions au fil du temps à mesure que le nombre d'objets que vous avez créés augmente, ce qui peut être contre-intuitif en raison de la Anniversaire Paradoxe . Vous voudrez donc probablement une longueur supérieure (ou bien supérieure) à 10 pour tout objet créé raisonnablement couramment, j'ai juste utilisé 10 comme exemple simple.

Utilisation

Avec la fonction définie, vous pouvez l'utiliser dans une définition de table, comme ceci :

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

Et puis lors de l'insertion de données, comme ceci :

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

Il générera automatiquement le id valeurs :

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

Utilisation avec un préfixe

Ou peut-être souhaitez-vous ajouter un préfixe pour plus de commodité lorsque vous consultez un seul identifiant dans les journaux ou dans votre débogueur (similaire à comment Stripe le fait ), comme ceci :

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 |