Using TNIDs where UUIDs are expected
A TNID is a valid UUID, so anything that stores or parses UUIDs accepts it. The differences below are the only places a system built for UUIDs behaves differently.
What stays the same
- A TNID fits in a UUID column or UUID type, such as Postgres
uuid, with no schema change. - In UUID form, a TNID passes through UUID parsers, drivers and tools unchanged. They can't read the TNID string; only TNID libraries can.
- Rows that already have UUID keys, and their indexes and foreign keys, need no change.
- The UUID form is another way to write the same 128 bits as the TNID string. Converting between the two loses nothing.
What is different, and what to do
| Difference | Why | What to do |
|---|---|---|
| Your code must create the TNID. | A database default such as Postgres gen_random_uuid() makes a UUID, not a TNID. | Generate the TNID in your application and include it in the INSERT. |
| Sorting by the primary key column can stop matching creation order. | TNIDs sort by name first, and every TNID sorts after every UUIDv7. | If one column mixes new UUIDv7s with TNIDs, or holds TNIDs with several names, don't sort or paginate by that column. Use a timestamp column that records when each row was created. |
| A case-insensitive text column treats two different TNID strings as equal. | Letter case is part of a TNID string, but not of UUID hex. | Store the UUID form, or give the column a binary collation. |
Some validators reject TNIDs by default, such as Yup's string().uuid() and Hibernate Validator's @UUID. | They accept only UUID versions 1–5, and TNIDs are version 8. Databases and standard-library UUID parsers accept any version. | Allow version 8 in those validators. |
| Existing UUIDs are not TNIDs and have no TNID string. | They have no name, and UUIDv4 and UUIDv7 aren't version 8. | Keep existing UUIDs as plain UUIDs. |
| A UUIDv8 from another scheme may parse as a TNID. | Its bits can fit the TNID layout by chance, so the name it parses to means nothing. | Tell existing UUIDs from new TNIDs by table or creation date, not by whether they parse. |
Rollout
- Make everything that reads your UUIDs or TNIDs accept both the TNID string and the UUID form.
- Generate TNIDs for new rows.
- Show TNID strings wherever people see IDs.