The probability of a collision is roughly the same as the probability of a fully grown dinosaur spontaneously manifesting in your bedroom due to quantum fluctuations.
The probability of a collision is roughly the same as the probability of a fully grown dinosaur spontaneously manifesting in your bedroom due to quantum fluctuations.
More seriously, If you can use them, good old increments are probably best. They are fast and cheap. Especially in a database. They can have privacy/security issues (you could guess things by the values of ids of stuff). UUIDs are better in those case or when you deal with a distributed system.
Push them through a secure hash function, and that problem is solved too (assuming you can keep the base counter private).
I guess you could do this with complete table scans, hashing the ids and looking for matches, but that would be horribly inefficient. You could maintain your own internal reverse index of hash -> id but now I have to ask what's the point? You aren't saving any storage and you're adding a lot of complexity.
Seems like if you want random unguessable external ids, you're always better off just generating them and using them as primary keys.
Also, you aren't protecting your database "from collisions under all circumstances" - there's no guarantee your hash won't collide even if the input is small.
Is generating UUIDv4 or UUIDv7 really too much effort? I'd assume that writing the row to the database takes longer than generating the UUID.
If I'm in a scenario where I think I need consecutive ids internally and random ones externally, I'll just have two fields in my tables.
This keeps your database simple and performant, and pushes complexity and work to the backend servers. This can be nice because developers are typically more at home at that layer, and scaling the backend can be a lot easier than scaling your database. But it also comes with the downsides listed in this thread.
If you want a secure identifier, make a random 64 or 128 bits number (a UUID type 4). And do not use this number as an internal identifier, because identifiers performance is all about predictability and low entropy.
I'd love to see the math for the probability of the second option.
But now the probability of bad things happening increased by about a factor of two, which is not acceptable.
(Anyways, comparing the probabilities does not necessarily mean that the things being compared are both bad or both good.)
In the end we have to make some assumptions about the correctness of (some of the) components.
So depending on the consequences you might opt to reduce the risk or help mitigate the consequences.
To just state that it is about as likely as my coffee maker being a portal to the future isn't very helpful. Poor entropy sources or bugs are not uncommon.