sql >> Databáze >  >> RDS >> PostgreSQL

Jak vygenerovat náhodné, jedinečné, alfanumerické ID délky N v Postgresu 9.6+?

Přišel jsem na to, zde je funkce, která to udělá:

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;

A pak to jednoduše spustíte takto:

generate_uid(10)
-- '3Rls4DjWxJ'

Upozornění

Když to uděláte, musíte si být jisti, že délka ID, která vytváříte, je dostatečná k tomu, aby se časem zabránilo kolizím, protože počet objektů, které jste vytvořili, roste, což může být kontraintuitivní kvůli Birthday Paradox . Pravděpodobně budete chtít délku větší (nebo mnohem větší) než 10 pro jakýkoli rozumně běžně vytvářený objekt jsem právě použil 10 jako jednoduchý příklad.

Použití

S definovanou funkcí ji můžete použít v definici tabulky, například takto:

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

A pak při vkládání dat, třeba takto:

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

Automaticky vygeneruje id hodnoty:

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

Použití s ​​předponou

Nebo možná budete chtít přidat předponu pro usnadnění při prohlížení jediného ID v protokolech nebo v ladicím programu (podobně jako jak to Stripe dělá ), třeba takto:

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. Co se stane se závislými spouštěči, když je tabulka zrušena?

  2. při grabování nelze načíst příliš velký html soubor

  3. Proč se sekvence ID SQL nesynchronizují (konkrétně pomocí Postgres)?

  4. Spočítat počet řádků, které obsahují stejnou hodnotu