sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo generar una ID alfanumérica, única y aleatoria de longitud N en Postgres 9.6+?

Resolví esto, aquí hay una función que lo hace:

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;

Y luego para ejecutarlo simplemente haz:

generate_uid(10)
-- '3Rls4DjWxJ'

Advertencia

Al hacer esto, debe asegurarse de que la longitud de las ID que está creando sea suficiente para evitar colisiones con el tiempo a medida que crece la cantidad de objetos que ha creado, lo que puede ser contrario a la intuición debido a la La paradoja del cumpleaños . Así que probablemente querrá una longitud mayor (o mucho mayor) que 10 para cualquier objeto creado razonablemente comúnmente, solo usé 10 como un ejemplo simple.

Uso

Con la función definida, puede usarla en una definición de tabla, así:

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

Y luego, al insertar datos, así:

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

Generará automáticamente el id valores:

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

Uso con un prefijo

O tal vez desee agregar un prefijo para mayor comodidad cuando busque una sola ID en los registros o en su depurador (similar a cómo lo hace Stripe ), así:

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 |