Using UUID as a Primary Key
MySQL UUIDs
A UUID
is a 128-bit number represented by a utf8
string of five hexadecimal numbers separated by dashes. A UUID
value looks like:
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
There are 5 different versions. MySQL uses UUID
version 1.
1 2 3 4 5 6 7 8 9 10 |
mysql> SELECT uuid(); +--------------------------------------+ | uuid() | +--------------------------------------+ | d1887e80-4579-11eb-891b-a47b7d0394de | +--------------------------------------+ |
- Part 1:
aaaaaaaa
is generated from timestamp. Also referred to astime-low
part - Part 2:
bbbb
is also generated fromtime-mid
part of timestamp - Part3:
cccc
again generated fromtime-hi
part of timestamp. The firstc
is the UUID version number (1 in this case) - Part4:
dddd
clock sequence - Part5:
eeeeeeeeeeee
Host unique identifier – provides spacial uniqueness. Generally MAC address of the main network interface or a random number if MAC address is not available.
The other commonly used UUID version is 4 – purely random values. The uuidgen
tool found in most *NIX based systems, produces UUID version 4 values.
1 2 3 4 5 6 7 8 9 10 |
MacBook>for i in $(seq 1 5); do uuidgen; done 832A0ACD-F9D9-4D4C-ABC6-48BE4089E519 C9E39649-E62C-4684-B8AA-828293679EC4 AABFCF66-17CF-4FD3-B53E-AA32CCF8EC0F EB1AB6D0-B91C-4BE8-8AEC-E2F50F8B87B0 F7DC8D3D-F079-459A-9B45-ABF81359F373 |
UUID values as Primary Key
Pros:
- UUID values are globally unique across servers, databases and tables. This is particularly helpful in event driven system architecture.
- Unique primary keys allow for merging or distribute data from different databases across servers.
- Not easy to guess when using a web application URL e.g. https://domain.com/view/user/id/20 exposes the fact that users exist in the database that have numerical ids and this info can be exploited
Cons:
- In the context of MySQL/InnoDB (detailed explanation at UUIDs are Popular, but Bad for Performance — Let’s Discuss)
- Not efficient inserting purely random data into a B-Tree.
- Secondary keys store Primary key values at leaf level. This increases the storage requirements with the number of secondary indexes you have.
- Comparing integers is a lot faster that comparing strings.
- UUID values (16 bytes) need more storage than integers (4 bytes) / bigint (8 bytes).
MySQL 8 Solution:
From MySQL v8.x, UUID values can be stored in a compact format (BINARY) and displayed in human-readable format (VARCHAR) with the help of following functions:
- UUID_TO_BIN(string_uuid), UUID_TO_BIN(string_uuid, swap_flag)
- BIN_TO_UUID
- IS_UUID
- Use UUID_TO_BIN() with the second parameter set to
true/1
. This will swap thetime-low
andtime-hi
parts of the generated UUID values. This makes the value more useful to the B-Tree arrangement.
1 2 3 4 5 6 7 8 9 10 |
mysql> SELECT HEX(UUID_TO_BIN(UUID())),HEX(UUID_TO_BIN(UUID(),1)); +----------------------------------+----------------------------------+ | HEX(UUID_TO_BIN(UUID())) | HEX(UUID_TO_BIN(UUID(),1)) | +----------------------------------+----------------------------------+ | 21EBF644458511EB891BA47B7D0394DE | 11EB458521EBF658891BA47B7D0394DE | +----------------------------------+----------------------------------+ 1 row in set (0.00 sec) |
- Use BIN_TO_UUID() to do the reverse. If you produce a binary UUID by calling
UUID_TO_BIN()
with a second argument of 1 to swap time parts, you should also pass a second argument of 1 toBIN_TO_UUID()
to unswap the time parts when converting the binary UUID back to a string UUID:
1 2 3 4 5 6 7 8 |
mysql> SELECT BIN_TO_UUID(UUID_TO_BIN(UUID())),BIN_TO_UUID(UUID_TO_BIN(UUID(),1),1); +--------------------------------------+--------------------------------------+ | BIN_TO_UUID(UUID_TO_BIN(UUID())) | BIN_TO_UUID(UUID_TO_BIN(UUID(),1),1) | +--------------------------------------+--------------------------------------+ | 1f1742ce-4586-11eb-891b-a47b7d0394de | 1f1742ec-4586-11eb-891b-a47b7d0394de | +--------------------------------------+--------------------------------------+ |
Recent Posts
- Enable http/2 in Apache 16th Jan 2021
- MySQL Shell 8.x 16th Jan 2021
- vi/vim tricks 30th Dec 2020
- SELinux on CentOS 29th Dec 2020
- ssh-copy-id (password less ssh login) 26th Dec 2020
- MySQL auto_increment capacity calculation 26th Dec 2020
- Using UUID as a Primary Key 24th Dec 2020
- Keycloak and InnoDB Cluster 29th Nov 2020
- How to create Column in MySQL only if one does not exist? 19th Mar 2019
- Inject empty transactions in MySQL 5.6 GTID based Replication 25th Dec 2018
- Adding a new disk to CentOS 26th Aug 2018
- mysqldump extended inserts 26th Jun 2018
- CentOS Logical Volume Manager (LVM) 26th Oct 2017
- How to prepare SD Card for Raspberry Pi on a MAC 26th Jun 2017
- Convert .dmg file on a MAC to .iso 26th Apr 2017
Categories
- CentOS (4)
- CentOS 8 (2)
- InnoDB cluster (1)
- mysql (7)
- Raspberry Pi (1)
- ssh (1)
- Technical (3)
Tag cloud
Archives
- January 2021 (2)
- December 2020 (5)
- November 2020 (1)
- March 2019 (1)
- December 2018 (1)
- August 2018 (1)
- June 2018 (1)
- October 2017 (1)
- June 2017 (1)
- April 2017 (1)
- February 2016 (1)