Generate unique memorable ids
I wanted to generate an 8 character web compatible (base64 encoded) id that is fairly easy to type or memorize from SQL, so came up with this inspired from this Postgres approach
SELECT randomId
from openjson(
(
SELECT randomBytes
FROM (SELECT CRYPT_GEN_RANDOM(6) as randomBytes) T
FOR JSON AUTO
)
) WITH(randomId varchar(max))
Which generates ids like this
syHJlOJv
XWLIxtId
jpjfi13W
r3E64qAZ
So how does this work?
The SQL function CRYPT_GEN_RANDOM is the key to generating the uniqueness and random bytes that the rest of the expression uses to give ids.
This SELECT CRYPT_GEN_RANDOM(6) as randomId
will generate a set of 6 random bytes like so B1 A6 68 FE D7 59
. Why did I use 6
- 8 bit
bytes? Because 6 * 8 = 48 bits
. Divide the 48 bits into base64 means that I should divide by 6
because each 6 bits represent a character in base64 so that gives me 48 / 6 = 8
base64 characters.
So what does that do? Let's break it down by separating all the statements
Examining the results by creating a temp table like so
DROP TABLE IF EXISTS #tempId
SELECT CRYPT_GEN_RANDOM(6) as randomId
INTO #tempId
SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE '#tempId%'
And we get
COLUMN_NAME | DATA_TYPE | CHARACTER_MAXIMUM_LENGTH |
---|---|---|
randomId | varbinary | 8000 |
Turn the varbinary bytes into a JSON field
SELECT randomId
FROM #tempId
FOR JSON AUTO
JSON_F52E2B61-18A1-11d1-B105-00805F49916B |
---|
{"randomId":"saZo/tdZ"}] |
Now extract the field automatically encoded data with OPENJSON and WITH like so
SELECT randomId
FROM OPENJSON
(
'[{"randomId":"saZo/tdZ"}]'
) WITH (randomId varchar(MAX))
and you get
randomId |
---|
saZo/tdZ |