Old question but I think that it should be mentioned that "short ids" are a common practice exactly to present more human-friendly codes and they're not meant to replace the full ids entirely. Also, this is valid for any identifier, be it a number, UUID, SHA, or whatever.
As other answers already mentioned, you should always use the full UUID as the de facto key for your records.
The implementation of short ids will vary greatly depending on your needs but two things are really common across implementations:
- The interfaces/systems dealing with short ids do not resolve ambiguity silently. (note that collisions can happen but not be ambiguous depending on the context)
- Users can choose which to use in a transparent fashion, the short id or the full id.
Here are some common implementations:
- Generate two ids for each resource where one of the ids is an incremental integer. This is the approach I've seen the most as it is the simplest and dispenses the two points I've just mentioned as collisions will never occur and you only use the integer-based id in end-user interfaces.
- Allow any short form of the original id but either return an error when the short id is ambiguous or return all matches.
git
commits are an example but they use SHA instead of UUID.
- Use a fixed number of chars to extract a short id but increase the number of chars as they collide and use the length of the short id as information to resolve collisions. It's good if the context allows the invalidation of old records so you can also come back to shorter ids as they're freed up.
- Use a fixed number of chars as a short id and combine it with context information to minimize ambiguity, like reducing the search scope only to resources a user is allowed to access. Use this approach with caution, if the number of valid resources keeps increasing up to a certain threshold (which depends on the number of chars of the short id) new records will start conflicting with old ones all the time. An example fit for this approach would be insurance records where you can expect that after some time the insurance will expire allowing the system to handle conflicts gracefully: enter the first N digits to search for active insurances but make a separate search requiring all the digits to search for all or inactive ones.
As a bonus, if you just want to display lettered codes instead of numbers you can encode number-based ids as codes with libs like hashids.