Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Ustaw unikatowe ograniczenie tylko wtedy, gdy pole ma wartość NULL

MySQL obsługuje funkcjonalne kluczowe części od 8.0.13 .

  • Jeśli Twoja wersja jest wystarczająco aktualna, możesz zdefiniować swój indeks jako:

    UNIQUE(`user_id`, `test_id`, (IFNULL(`completed_date`, -1)))
    

    (Demo na dbfiddle.uk )

    Należy pamiętać, że powyższy indeks zapobiegnie również powielaniu dat ukończonych egzekucji. Jeśli te powinny być prawidłowe, zadziałałby nieznacznie zmodyfikowany indeks:

    UNIQUE(`user_id`, `test_id`, (
        CASE WHEN `completed_date` IS NOT NULL
        THEN NULL
        ELSE 0
    END))
    

    (Demo na dbfiddle.uk )

    Chociaż wtedy zaczyna się czuć trochę brudno;)

  • Jeśli masz co najmniej wersję 5.7 możesz użyć (wirtualnej) wygenerowanej kolumny jako obejście:

    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`)
    );
    

    (Demo na dbfiddle.uk )

  • Jeśli utkniesz na 5.6 następnie połączenie zwykłej (niewirtualnej) kolumny i nieznacznie zmodyfikowanej INSERT oświadczenia zadziałałyby:

    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`)
    );
    

    W takim przypadku ustaw is_open na true dla niekompletnych wykonań i do NULL po zakończeniu, korzystając z faktu, że dwa NULL s są traktowane jako nierówne.

    (Demo na dbfiddle.uk )




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL str_to_date generuje NULL pomimo prawidłowego formatowania

  2. mysqli - wywołanie błędu fetch_Array do funkcji składowej fetch_array() na nieobiektowym mysqli

  3. MySQL select different nie działa

  4. Kryptowaluta Typy danych MySQL ?

  5. Płaski plik XML a backend relacyjnej bazy danych