The original implementation of conflict detection in the block_target table was faulty, with a race condition that we are hitting in production, causing multiple block_target rows for some users. The simplest way to fix this is probably to add a unique index to the block_target table.
bt_user and bt_address are nullable. A null value in either causes the index to compare non-equal, permitting duplicates:
```
MariaDB [mw]> create table t (a int, b int, unique key (a,b));
Query OK, 0 rows affected (0.008 sec)
MariaDB [mw]> insert into t values (1, 1), (1, 1);
ERROR 1062 (23000): Duplicate entry '1-1' for key 'a'
MariaDB [mw]> insert into t values (1, null), (1, null);
Query OK, 2 rows affected (0.008 sec)
Records: 2 Duplicates: 0 Warnings: 0
```
So a simple multi-column index doesn't work.
**DBMS-layer solutions:**
| | MariaDB | MySQL | PostgreSQL | SQLite |
|---|---|---|---|---|
| Index on generated column | ✓ | ✓ | ✓ | 3.31+
| Index on expression | x | 8.0.13+ | ✓ | 3.9+
| NULLS NOT DISTINCT | x | x | 15+ | x
**App-layer solutions:**
* Stop nulling the fields. I used nulls mostly because it useful to use COALESCE() in a few places.
* Leave it without a unique index and use GET_LOCK to synchronize externally.