Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

270
Views
¿Cómo dar un valor predeterminado de ksuid en postgres a una columna? ¿Hay alguna alternativa de ksuid en postgres?

Tengo un campo char cuyo valor predeterminado debería ser un ksuid. ¿Cómo generar un ksuid en postgres?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Sugiero que su mejor opción es crear un DOMINIO de usuario. Luego defina una función para generar su ksuid. Luego modifique el dominio para usar esta función como predeterminada. Cuando sea necesario, defina su columna como ese tipo de DOMINIO.

 -- setup domain and the generating function create domain ksuid character varying(27); create or replace function generate_ksuid() returns ksuid language sql as $$ select substring( replace(to_char(clock_timestamp(),'yyyymmddhh24missus') || (to_char(random()*1e9,'000000000') ),' ',''),1,27)::ksuid; $$; alter domain ksuid set default generate_ksuid();

Vea el ejemplo completo, incluido el uso, aquí . Por supuesto, la función generar_ksuid deberá adaptarse a sus necesidades. El ejemplo solo se basa en clock_timestamp y un número aleatorio.

over 4 years ago · Santiago Trujillo Report

0

Esta función genera KSUID en PostgreSQL. Utiliza tipos de datos numeric para convertir el tiempo y la carga útil a base62.

Crea una carga útil pseudoaleatoria usando la MD5() nativa. Si desea utilizar pgcrypto , consulte el comentario de @ssz. ¡Gracias @ssz!

Los KSUID generados por la función cumplen con la implementación de referencia .

 /** * Returns a Segment's KSUID. * * Reference implementation: https://github.com/segmentio/ksuid * Also read: https://segment.com/blog/a-brief-history-of-the-uuid/ */ create or replace function fn_ksuid() returns text as $$ declare v_time timestamp with time zone := null; v_seconds numeric := null; v_payload bytea := null; v_numeric numeric := null; v_base62 text := ''; v_epoch numeric = 1400000000; -- 2014-05-13T16:53:20Z v_alphabet char array[62] := array[ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; i integer := 0; begin -- Get the current time v_time := clock_timestamp(); -- Extract seconds from the current time and apply epoch v_seconds := EXTRACT(EPOCH FROM v_time) - v_epoch; -- Generate a numeric value from the seconds v_numeric := v_seconds * pow(2::numeric, 128); -- Generate a pseudo-random payload -- v_payload := gen_random_bytes(16); -- to be used with `pgcrypto` v_payload := decode(md5(v_time::text || random()::text || random()::text), 'hex'); -- Add the payload to the numeric value while i < 16 loop i := i + 1; v_numeric := v_numeric + (get_byte(v_payload, i - 1) * pow(2::numeric, (16 - i) * 8)); end loop; -- Encode the numeric value to base62 while v_numeric <> 0 loop v_base62 := v_base62 || v_alphabet[mod(v_numeric, 62) + 1]; v_numeric := div(v_numeric, 62); end loop; v_base62 := reverse(v_base62); v_base62 := lpad(v_base62, 27, '0'); return v_base62; end $$ language plpgsql;

Enlace a GitHub Gist .

over 4 years ago · Santiago Trujillo Report

0

Me gustaría sugerir un ligero cambio en la solución de fabiolimace. En cambio:

 v_payload := decode(md5(v_time::text || random()::text || random()::text), 'hex');

use una función más fuerte gen_random_bytes() :

 v_payload := gen_random_bytes(16);

Requiere que la extensión pgcrypto esté habilitada:

 CREATE EXTENSION pgcrypto;

Actualización importante

En algunos casos raros, esta función devuelve NULL . Se produce un error en la línea:

 v_base62 := v_base62 || v_alphabet[mod(v_numeric, 62) + 1];

Ejemplo:

 mod(v_numeric, 62) 'Let`s say this function returns 61.7977600000000000000000' mod(v_numeric, 62) + 1 '62.7977600000000000000000' v_alphabet[62.7977600000000000000000 => 63] => NULL '62.7977600000000000000000 rounds to 63, there is no element with index 63' v_base62 || NULL 'v_base62 becomes NULL because || operator always returns NULL if at least one of the operands is null'

Cómo reproducir:

 SELECT COUNT(*) FROM (SELECT fn_ksuid() AS id FROM GENERATE_SERIES(1, 1000)) q WHERE q.id IS NULL;

Solución:

 v_base62 := v_base62 || v_alphabet[floor(mod(v_numeric, 62)) + 1];

Siempre convierta el valor mod a la parte entera usando la función floor() .

En la vida real, el error ocurre cuando se inserta una gran cantidad de filas al mismo tiempo.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!