I’m busy changing over to a UUID as a primary key on my models, but also have a custom User model, and was wondering if it’s safe to do the same on the User model. I don’t know if Django uses the primary key internally in any way, and whether that would then be adversely affected by changing the primary key field.
Why are you changing everything over to UUID PK’s? They won’t perform as well in your database as autoincrement ID’s. They use more storage space and because they are distributed randomly, they reduce the effect of your DB caching tables in memory.
Anyway I think you should be able to change the user PK. It should only be referred to as typeless PK in django.contrib.auth . I believe djangae gets away with random string ID’s for everything, because that’s what google app engine supports.
Performance is not an issue in my case, so that is not a worry. Using a UUID presents more advantages than disadvantages for what I need, so I’m happy to go that route. One article that influenced my decision most: https://devforth.io/blog/why-your-software-should-use-uuids
I decided to go with KSUIDs: https://github.com/saresend/KSUID
These can then be encoded as base62, and then only use up 27 characters, instead of the 40 that normal UUIDs use.
Anyway, thanks for your feedback on the User model. The reason why I was wondering: if the user ID is ever exposed on the front-end (even if just in a request URL or POST), a non-incremental one would not reveal anything potentially sensitive.
I think I’ll probably give it a try to replace the User PK with a UUID, and see if I run into any issues.
The sharding argument there is not very applicable to most use cases. Also you don’t want clients generating ID’s, whilst in theory they’ll be independent, in practice many things can remove sources of randomness.
Consider the opposite positions from Basecamp, who still have a single DB server:
Thanks for your thoughts, @adamchainz. As a result I will think through this one more time to carefully consider the pro’s and con’s.
I must say that I failed to mention in my last reply that the sharding was really not part of my reasoning, since I don’t expect to ever have to shard, just like Basecamp (thanks for those links, I dig the Basecamp gang).
And thanks for the hashid link, that looks really interesting. Definitely having a look at that right now.
While I didn’t end up switching my user model to a UUID-type primary key, I did switch my own models over. At first I started making migrations to change over step-by-step, but the foreign key relations were a major pain. In the end I just exported my data, re-created the database, and then imported the data again with a custom script which handles the relations with the new keys. Worked like a charm. I’ll report back on any future difficulties I might experience as a result of the UUID primary keys.