Database Primary Keys and UUIDs

A TL;DR; regarding exposing database keys

Use incrementing numbers for primary keys. Next to it, have a surrogate key that is a UUIDv4, and is generated on insert. The primary key increases performance for joins and internal workings in the database, while the surrogate key can be used externally to identify resources (users, payments, etc).

Example orders table with a primary key and a surrogate key.

The primary key is an implementation detail. In case you migrate databases the primary keys may change (they might not even exist in the new place), while the surrogate key stays permanent. So any old links in emails, websites, or external systems should still work fine.

Exposing the primary key is not necessarily a security issue and is often fine to expose. Regardless you need to have security measures in place to prevent malicious behaviour in your database (Does this user have permissions to read/write this data? Are these valid values to send in to these fields? etc). It can, however, leak business information. If you have a incrementing primary key that is exposed for e.g. users or orders, then people can easily see how well (or not) your business is doing just by looking at your URL. If users don’t need to login to access some of your data, then they can very easily harvest/scrape that data by just incrementing numbers. UUIDs prevent that sort of brute forcing.

Looks like these guys are getting a lot of orders

Further reading: https://softwareengineering.stackexchange.com/questions/218306/why-not-expose-a-primary-key/218419#218419