Ecco una soluzione per MySQL e MariaDB che utilizzano colonne virtuali un po 'più eleganti. Richiede MySQL> = 5.7.6 o MariaDB> = 5.2:
MariaDB [db]> create table foo(bar varchar(255), chk boolean);
MariaDB [db]> describe foo;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| bar | varchar(255) | YES | | NULL | |
| chk | tinyint(1) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
Creare una colonna virtuale che è NULL se non si desidera applicare il controllo univoco:
MariaDB [db]> ALTER table foo ADD checked_bar varchar(255) as (IF(chk, bar, null)) PERSISTENT UNIQUE;
(Per MySQL, utilizzare STORED
invece di PERSISTENT
.)
MariaDB [db]> insert into foo(bar, chk) values('a', false);
Query OK, 1 row affected (0.00 sec)
MariaDB [db]> insert into foo(bar, chk) values('a', false);
Query OK, 1 row affected (0.01 sec)
MariaDB [salt_dev]> insert into foo(bar, chk) values('a', false);
Query OK, 1 row affected (0.00 sec)
MariaDB [db]> insert into foo(bar, chk) values('a', true);
Query OK, 1 row affected (0.00 sec)
MariaDB [db]> insert into foo(bar, chk) values('a', true);
ERROR 1062 (23000): Duplicate entry 'a' for key 'checked_bar'
MariaDB [db]> insert into foo(bar, chk) values('b', true);
Query OK, 1 row affected (0.00 sec)
MariaDB [db]> select * from foo;
+------+------+-------------+
| bar | chk | checked_bar |
+------+------+-------------+
| a | 0 | NULL |
| a | 0 | NULL |
| a | 0 | NULL |
| a | 1 | a |
| b | 1 | b |
+------+------+-------------+