Adding a virtual unique key constraint in MySQL
with support of soft deletions

Software Engineer at BMW, Oracle Certified Professional Java SE 11 Developer
Search for a command to run...
with support of soft deletions

Software Engineer at BMW, Oracle Certified Professional Java SE 11 Developer
No comments yet. Be the first to comment.
Two whole days of my life, down the drain! Thankfully, it was just my pet project, but I ended up sacrificing an entire weekend wrestling with this enigma. So, I'm writing this blog post to save you from the same fate. Problem: I am using Quarkus and...

Shebang Shebang is a combination of bash # and bang ! followed the the bash shell path. Shebang is simply an absolute path to the bash interpreter. #! /bin/bash Make a file executable To make a .sh file executable only for your user, use: chmod u+x...

1. Show tables The command \dt stands for describe tables and shows all tables in the database, equivalent to show tables in MySQL. \dt 2. Create user Run the following SQL command to create a user. Replace and 'password' with the desired username a...

How to set JAVA_HOME on macOS Monterey? First check which shell you are using (either bash or zsh). For zsh shell, we can put the environment variables at ~/.zshenv or ~/.zshrc.echo $SHELL /bin/zsh On Mac OS X 10.5 or later, we can use /usr/libexe...

Fork your open source project you want to contribute into your GitHub and clone your fork. git clone git@github.com:dcnis/mockito.git Show current configured remote repositories. The origin repo points to your fork on GitHub. git remote -v > origin ...

Let's say in our system we track owners and their corresponding cats.
| id | owner_id | cat_name | is_deleted |
|----|----------|------------|------------|
| 1 | 100 | Puddy Tat | 0 |
| 2 | 101 | Katy Purry | 0 |
We don't allow owners to give multiple cats the same name. But if one cat dies, the next cats can still have the same name. In order to enforce this rule we can add a virtual unique key.

Allowed state: In this scenario we can see that owner_id=101 gave two cats the name Katy Purry. This is fine because one of them already passed away (is_deleted=1) so the next cat can have the same name.
| id | owner_id | cat_name | is_deleted |
|----|----------|------------|------------|
| 1 | 100 | Puddy Tat | 0 |
| 2 | 101 | Katy Purry | 1 |
| 3 | 101 | Katy Purry | 0 | <- this insert is ok
Disallowed state: But at every point in time an owner can only have one cat with the same name.
| id | owner_id | cat_name | is_deleted |
|----|----------|------------|------------|
| 1 | 100 | Puddy Tat | 0 |
| 2 | 101 | Katy Purry | 0 |
| 3 | 101 | Katy Purry | 0 | <- this insert should fail
We are adding a column virtual_uk and setting a UNIQUE KEY on this very column.
CREATE TABLE owner_cat (
id int(11) unsigned auto_increment,
owner_id INT(11) unsigned not null,
cat_name VARCHAR(32) not null,
is_deleted TINYINT(4) not null default 0,
virtual_uk VARCHAR(64) GENERATED ALWAYS AS (if(is_deleted = 0, concat(owner_id, '_', cat_name), NULL)),
PRIMARY KEY(id),
UNIQUE KEY `uk` (virtual_uk)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Explanation: If is_deleted=0, this code will concat owner_id _ cat_name, otherwise it will set the column to NULL. If the column is set to NULL it will not violate our UNIQUE KEY constraint.
virtual_uk VARCHAR(64) GENERATED ALWAYS AS (
if (is_deleted = 0
,CONCAT(owner_id, '_', cat_name)
,NULL)
)
If we are now inserting data into our table, it will look like this.
| id | owner_id | cat_name | is_deleted | virtual_uk |
|----|----------|------------|------------|----------------|
| 1 | 100 | Puddy Tat | 0 | 100_Puddy_Tat |
| 2 | 101 | Katy Purry | 1 | NULL |
| 3 | 101 | Katy Purry | 1 | NULL |
| 4 | 101 | Katy Purry | 0 | 101_Katy_Purry |
In this article we have learned how to create a virtual unique key, which allows us to enforce strict UNIQUE KEY constraints while still supporting soft deletions.