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

Hvordan genererer man et tilfældigt, unikt, alfanumerisk ID med længde N i Postgres 9.6+?

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 |
 


  1. Star vs Snowflake skema i data warehousing?

  2. Følg ekstern database fra Heroku

  3. Sådan vælger du en enkelt række baseret på den maksimale værdi i flere rækker

  4. Hvordan finder man næsten lignende poster i sql?