PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie generiert man eine zufällige, eindeutige, alphanumerische ID der Länge N in Postgres 9.6+?

Hab das herausgefunden, hier ist eine Funktion, die das macht:

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;

Und dann, um es auszuführen, tun Sie einfach:

generate_uid(10)
-- '3Rls4DjWxJ'

Warnung

Dabei müssen Sie darauf achten, dass die Länge der von Ihnen erstellten IDs ausreicht, um Kollisionen mit der Zeit zu vermeiden, wenn die Anzahl der von Ihnen erstellten Objekte zunimmt, was aufgrund des Birthday Paradox . Also werden Sie wahrscheinlich eine Länge größer (oder viel größer) als 10 wünschen für jedes einigermaßen häufig erstellte Objekt habe ich einfach 10 verwendet als einfaches Beispiel.

Nutzung

Wenn die Funktion definiert ist, können Sie sie wie folgt in einer Tabellendefinition verwenden:

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

Und dann beim Einfügen von Daten wie folgt:

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

Es wird automatisch die id generiert Werte:

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

Verwendung mit Präfix

Oder vielleicht möchten Sie der Einfachheit halber ein Präfix hinzufügen, wenn Sie sich eine einzelne ID in den Protokollen oder in Ihrem Debugger ansehen (ähnlich wie wie Stripe das macht ), etwa so:

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 |