The first 2 characters of the UUID value comes from the MD5 hash of a supplied UUID. The next 3 characters are the MD5 hash of the concatenation of the current year and week number -- this value is, of course, static over a week. The remaining of the UUID value comes from the MD5 of a random value and the current time at a precision of 1us. The third field is prefixed with a “4” to indicate it is a version 4 UUID type.
Last active
June 21, 2020 09:54
-
-
Save pyramation/6fe371f7dc9258efdeff0cfc73614811 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DROP FUNCTION IF EXISTS f_pseudo_order_with_prefix_uuid(); | |
CREATE FUNCTION f_pseudo_order_with_prefix_uuid () | |
RETURNS uuid | |
AS $$ | |
DECLARE | |
new_uuid char(36); | |
md5_str char(32); | |
BEGIN | |
md5_str := md5(concat(random(), now())); | |
new_uuid := concat( | |
LEFT (md5('c44dceee-ee67-4bfc-35c1-3a3d66a1d66e'), 2), | |
LEFT (md5(concat(extract(year FROM now()), extract(week FROM now()))), 3), | |
LEFT (md5_str, 3), '-', substring(md5_str, 5, 4), '-4', substring(md5_str, 9, 3), '-', substring(md5_str, 13, 4), '-', substring(md5_str, 17, 12) | |
); | |
RETURN new_uuid; | |
END; | |
$$ | |
LANGUAGE plpgsql; | |
DROP FUNCTION IF EXISTS f_pseudo_order_with_prefix_uuids(); | |
CREATE FUNCTION f_pseudo_order_with_prefix_uuids () | |
RETURNS SETOF uuid | |
AS $$ | |
BEGIN | |
RETURN QUERY SELECT f_pseudo_order_with_prefix_uuid() FROM generate_series(1,10,1); | |
END; | |
$$ | |
LANGUAGE plpgsql; | |
SELECT | |
* | |
FROM | |
f_pseudo_order_with_prefix_uuids (); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DROP FUNCTION IF EXISTS f_pseudo_order_with_prefix_uuid() cascade; | |
CREATE FUNCTION f_pseudo_order_with_prefix_uuid () | |
RETURNS uuid | |
AS $$ | |
DECLARE | |
new_uuid char(36); | |
md5_str char(32); | |
uid text; | |
BEGIN | |
uid = uuid_generate_v4(); | |
new_uuid := concat( | |
LEFT (md5('c44dceee-ee67-4bfc-35c1-3a3d66a1d66e'), 2), | |
LEFT (md5(concat(extract(year FROM now()), extract(week FROM now()))), 2), | |
substring(uid, 1, 4), | |
'-', | |
substring(uid, 10, 4), | |
'-', | |
substring(uid, 15, 4), | |
'-', | |
substring(uid, 20, 4), | |
'-', | |
substring(uid, 25, 12) | |
); | |
RETURN new_uuid; | |
END; | |
$$ | |
LANGUAGE plpgsql; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- was able to generate 1000000 with no dups! and this was 2X faster than using another UUID for randomness. So was better to use 2 md5 calls... | |
CREATE FUNCTION f_pseudo_order_prefixed_uuid () | |
RETURNS uuid | |
AS $$ | |
DECLARE | |
new_uuid char(36); | |
md5_str char(32); | |
md5_str2 char(32); | |
uid text; | |
BEGIN | |
md5_str := md5(concat(random(), now())); | |
md5_str2 := md5(concat(random(), now())); | |
new_uuid := concat( | |
LEFT (md5('c44dceee-ee67-4bfc-35c1-3a3d66a1d66e'), 2), | |
LEFT (md5(concat(extract(year FROM now()), extract(week FROM now()))), 2), | |
substring(md5_str, 1, 4), | |
'-', | |
substring(md5_str, 5, 4), | |
'-4', | |
substring(md5_str2, 9, 3), | |
'-', | |
substring(md5_str, 13, 4), | |
'-', | |
substring(md5_str2, 17, 12) | |
); | |
RETURN new_uuid; | |
END; | |
$$ | |
LANGUAGE plpgsql; |
testing uuid version
drop table if exists insertids;
DROP FUNCTION IF EXISTS f_pseudo_order_with_prefix_uuid() cascade;
CREATE FUNCTION f_pseudo_order_with_prefix_uuid ()
RETURNS uuid
AS $$
DECLARE
new_uuid char(36);
md5_str char(32);
uid text;
BEGIN
uid = uuid_generate_v4();
-- md5_str := md5(concat(random(), now()));
new_uuid := concat(
LEFT (md5('c44dceee-ee67-4bfc-35c1-3a3d66a1d66e'), 2),
LEFT (md5(concat(extract(year FROM now()), extract(week FROM now()))), 2),
substring(uid, 1, 4),
--'-', substring(md5_str, 5, 4), '-4', substring(md5_str, 9, 3), '-', substring(md5_str, 13, 4), '-', substring(md5_str, 17, 12)
'-',
substring(uid, 10, 4),
'-',
substring(uid, 15, 4),
'-',
substring(uid, 20, 4),
'-',
substring(uid, 25, 12)
);
RETURN new_uuid;
END;
$$
LANGUAGE plpgsql;
create table insertids ( id uuid not null primary key default uuid_generate_v4() );
DROP FUNCTION IF EXISTS gen();
CREATE FUNCTION gen ()
RETURNS void
AS $$
DECLARE
c int = 0;
BEGIN
WHILE c < 100000
LOOP
INSERT INTO insertids DEFAULT VALUES;
c = c + 1;
END LOOP;
END;
$$
LANGUAGE plpgsql;
select gen();
results in zero duplicates
with regular uuid, generating 100,000 rows takes 5.5 seconds.
with these new uuids, generating 100,000 rows takes 6.8 seconds.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
testing
After running this a bunch, I did get a duplicate