sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur genererar man ett slumpmässigt, unikt, alfanumeriskt ID med längden N i Postgres 9.6+?

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 |


  1. Fatalt fel:Anrop till odefinierad funktion mysqli_connect() i... när PHP 5.4.22 och MySQL 5.5 ansluts till Apache 2.4.7

  2. Fel vid körning av mysql_install_db:kunde inte hitta ./bin/my_print_defaults

  3. 5 praktiska databastips för nybörjare

  4. Hur du vårrensar din databas