The discussion about what to use for database keys has come up a few times on HN. Integers or UUID, or maybe ULID/UUIDv7 with a time component. One that also comes up is prefixes (as used by Stripe, most famously).<p>The biggest downside (imo) of the Stripe approach is that you either have to store them as strings, which isn't great, or strip/prepend in your API layer.<p>So I made a new thing called UPID. It's most similar to ULID, as it includes a time-component (but with lower precision) and also encodes to a base32 alphabet. But it also includes a 20-bit prefix (allowing four characters). So it can be stored as a UUID or anywhere a 128-bit blob goes, and it always knows what its prefix is because it's baked in.<p>I've made implementations for Python, Rust and TypeScript, as well as a Postgres extension (with a upid datatype). Mentioned it a few weeks ago in a HN discussion and people seemed pretty interested so thought I'd post it as a submission.<p>In Rust it looks like this:<p><pre><code> use upid::Upid;
Upid::new("post"); // post_2acqyme2ygscyguveuhj5a
</code></pre>
There are more examples in the repositories.<p>Repo (Python, Rust, Postgres): <a href="https://github.com/carderne/upid">https://github.com/carderne/upid</a><p>TypeScript: <a href="https://github.com/carderne/upid-ts">https://github.com/carderne/upid-ts</a><p>Demo site: <a href="https://upid.rdrn.me/" rel="nofollow">https://upid.rdrn.me/</a>
Blog post:<p>UPID is as UPID does<p><a href="https://rdrn.me/upid/" rel="nofollow">https://rdrn.me/upid/</a><p>---<p>BTW: Hi/Lo scheme for Primary Keys / IDs was invented long before Stripe existed. Partcularly, I used short up to 3 letters prefixes to make IDs Human-readable (and writable!) more than 20 years ago. 5 years later Amazon started using similar scheme in their AWS product, i.e i-NNNNN for instances, etc.[1].<p>In theory there are 2 kinds of ID schemes: technical/surrogate and natural/business/semantic (i.e. those derived from the natural properties of the object the ID refers to).<p>Adding a prefix with the type, makes ID scheme hybrid. "Hi" part (prefix) is natural, and "Lo" part is technical. In case of UPID/ULID/UUIDv7 even the "Lo" part is hybrid, since it includes an information when the entity was created (or at least inserted into the database/system).<p>---<p>[1] List of some AWS ID prefixes:<p><pre><code> i-
vol-
snap-
ami-
eni-
sg-
vpc-
subnet-
acl-
rtb-
igw-
dopt-
vpn-
vgw-
cgw-
nat-
rds-
lb-</code></pre>