Last active
December 18, 2024 10:52
-
-
Save PatrickChoDev/6c386384e933622889bd8324b47c992d to your computer and use it in GitHub Desktop.
Generating CUID2 with PostgreSQL
This file contains hidden or 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
CREATE OR REPLACE FUNCTION generate_cuid2(target_length INT DEFAULT 24) | |
RETURNS TEXT AS $$ | |
DECLARE | |
timestamp_part TEXT; -- Encoded timestamp in base36 | |
random_part TEXT; -- Random string for uniqueness | |
random_length INT; -- Length of the random part | |
characters TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; -- Alphanumeric characters | |
result TEXT; -- Final result to return | |
BEGIN | |
-- Validate input length | |
IF target_length < 8 THEN | |
RAISE EXCEPTION 'Target length must be at least 8 characters'; | |
END IF; | |
-- Generate the time-based prefix (always 8 characters) | |
timestamp_part := LPAD(TO_HEX(EXTRACT(EPOCH FROM clock_timestamp())::BIGINT), 8, '0'); | |
-- Calculate the length of the random part | |
random_length := target_length - LENGTH(timestamp_part); | |
-- Generate the random part | |
random_part := ( | |
SELECT STRING_AGG(SUBSTRING(characters, FLOOR(1 + RANDOM() * 62)::INT, 1), '') | |
FROM generate_series(1, random_length) | |
); | |
-- Combine timestamp and random parts | |
result := LEFT(timestamp_part || random_part, target_length); | |
RETURN result; | |
END; | |
$$ LANGUAGE plpgsql; |
This file contains hidden or 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
select gen_cuid2() cuid, clock_timestamp()-statement_timestamp() time_taken; | |
CREATE TABLE users ( | |
user_id CHAR(24) PRIMARY KEY DEFAULT generate_cuid2(), -- Generate a 24-character cuid2 | |
username TEXT NOT NULL UNIQUE, -- Username must be unique | |
email TEXT NOT NULL UNIQUE, -- Email must be unique | |
password_hash TEXT NOT NULL, -- Securely store password hashes | |
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Automatically set creation time | |
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Automatically set update time | |
); | |
CREATE TABLE longer_users ( | |
user_id CHAR(32) PRIMARY KEY DEFAULT generate_cuid2(32), -- Generate a 32-character cuid2 | |
username TEXT NOT NULL UNIQUE, -- Username must be unique | |
email TEXT NOT NULL UNIQUE, -- Email must be unique | |
password_hash TEXT NOT NULL, -- Securely store password hashes | |
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Automatically set creation time | |
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- Automatically set update time | |
); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment