At the end of the day a UUID is just a 128 bit integer with:
- A special formatting rule used to display it to humans.
- A non-sequential generation rule.
Note: there are multiple UUID generation formats and nothing stopping
you from inventing your own sequential one (although I would question
the value of doing that).
Performance
Generally speaking processing less data (i.e. smaller 32 or 64 bit integers) is quicker than processing more data. However having non sequential data can have some advantages for example, when indexing it means that the majority of new records are not all being inserting at the end of the index.
However there is an open question of whether the extra 8 or 12 bytes per record have a significant impact on overall system performance - frankly you will have to benchmark it and weigh the pro's and con's against the other factors.
Leaking Growth/Size Information
If you use a sequential number for anything and an adversary has the ability to see newly created numbers on some frequent basis, then the adversary is able to identify how many of that thing are being created in a set time frame.
One adversarial use case would be in conjunction with the financial markets for estimating new customer or order growth - however any use case that relies on data growth numbers would also benefit.
Data Sparseness
If you had 10,000 widgets, but store the widget ID in a short (16 bit) integer, even if you distribute the ID's across the entire range (0 - 65535) it would still be practical for an attacker to brute force all of them by iterating through the entire range.
Hence with UUID's it is the combination of both the size of the range (128 bits) and the non sequential generation that provides the sparseness benefit.
Human Entry
Typically businesses use "short" numeric IDs for customer, order or account numbers as it is likely someone will telephone a call center and need to give the number verbally to a representative, who will type it into a computer.
If you expose an API to a third party that also interacts with humans they may need a lookup function, to identify a record by a "Human ID" however after the initial lookup they can probably use a UUID for all future functionality.
Unfortunately these human ID's likely violate the previous two points (Data Growth and Sparseness), however its going to be difficult to avoid that and still keep the ID's small for humans.
Summary
There is no "right" answer here its all trade offs, I typically make my life simple by using UUID's for everything I can:
- Primary keys
- Foreign keys between tables
- ID's in API/URL paths.
Then supplement these with Human ID's where required for business functions.
However your milage may vary - for example you might choose to use a composite key of the OrderID and a simple line number on an OrderLines
table.