Prefer UUID for your Primary Key
Autor
Marcus HeldIn my last post
I discussed the downsides of using numerical types
for the primary key of an entity. We should avoid these issues all together by using UUID
instead and in this post I
will discuss the up- and downsides of this approach.
Using a UUID as the primary ID is simple:
@Entity
class Flat(
@Id
val id: UUID = UUID.randomUUID()
)
Generate the ID on the application
Similar to numerical ids we can generate it on the database as well. But for UUID
this is not necessary. The reason we
did this in the first place is that we needed to make sure that an ID is not used twice. A collision of UUID
is very
unlikely to occur.
And what do we do when such error happens? We don’t need to establish any special handling of it. We throw an exception, cancel the transaction and let the client redo the operation. Like we would always do when something happens that we can’t handle.
But we get extraordinary benefits from UUID
:
Offline Capability
We don’t need to generate the UUID
on the database. We don’t even need to generate it on the backend. We can create it
in the client. And this enables the client to create new entities without synchronizing them to the backend. This
enables us to make the client very resilient to network issues. E.g. I implemented such behavior in a game I developed
and that enabled us to support playing the game even in unstable environments like when you play on the train and drive
through tunnels. It is an awesome experience for the users and does not require a lot of work on the application to
achieve.
Easier (Unit) Testing
When you generate the UUID
on the client or server you have much more control over it. And this is beneficial when you
want to write unit tests for your entities. You can simply use the constructor. Generating it on the database relied on
reflection and in the runtime between the setting of the id and the creation of the object it is in an unstable
state. Have a look at the “Collection Problem” in my previous post
.
Tedious Debugging
UUID
s are unhandy. Remembering that E209C805-C7D5-4C7A-8F02-37BEA845A405
is the ID of the entity you look at is of
course harder than remembering 2837
. This is a downside and everyone needs to decide whether that is a strong
argument.
More Space
Of course UUID
are larger than Int
. You can do a whole evaluation of this aspect. You can even fill pages and whole
blogs about it. But I don’t do that. In relation to all the other kind of data that we store nowadays it is a waste of
time and energy. Space - in this scale - does not matter for 99% of the applications out there. If you work in an
environment where it matters, sure, do the evaluation and make a proper decision. But for most of the developers our
there it shouldn’t matter at all.