MySQL ondersteunt functioneel belangrijkste onderdelen sinds 8.0.13 .
-
Als uw versie voldoende recent is, kunt u uw index definiëren als:
UNIQUE(`user_id`, `test_id`, (IFNULL(`completed_date`, -1)))Merk op dat de bovenstaande index ook dubbele datums voor voltooide uitvoeringen zal voorkomen. Als die geldig zouden zijn, zou een licht gewijzigde index werken:
UNIQUE(`user_id`, `test_id`, ( CASE WHEN `completed_date` IS NOT NULL THEN NULL ELSE 0 END))Al begint het dan een beetje vies aan te voelen;)
-
Als je ten minste versie 5.7 . hebt je kunt een (virtuele) gegenereerde kolom gebruiken als tijdelijke oplossing:
CREATE TABLE `executed_tests` ( `id` INTEGER AUTO_INCREMENT NOT NULL, `user_id` INTEGER NOT NULL, `test_id` INTEGER NOT NULL, `start_date` DATE NOT NULL, `completed_date` DATE, `_helper` CHAR(11) AS (IFNULL(`completed_date`, -1)), PRIMARY KEY (`id`), UNIQUE(`user_id`, `test_id`, `_helper`) ); -
Als je vastzit op 5.6 dan een combinatie van een gewone (niet-virtuele) kolom en een licht gewijzigde
INSERTuitspraken zouden werken:CREATE TABLE `executed_tests` ( `id` INTEGER AUTO_INCREMENT NOT NULL, `user_id` INTEGER NOT NULL, `test_id` INTEGER NOT NULL, `start_date` DATE NOT NULL, `completed_date` DATE, `is_open` BOOLEAN, PRIMARY KEY (`id`), UNIQUE(`user_id`, `test_id`, `is_open`) );In dit geval zou u
is_open. instellen naartruevoor onvolledige uitvoeringen en naarNULLna voltooiing, gebruikmakend van het feit dat tweeNULLs worden als ongelijk behandeld.