Составной ключ MySQL для разрешения одной записи по умолчанию

#mysql #sql #composite-key

#mysql #sql #составной ключ

Вопрос:

У меня есть таблица, подобная этой:

 ID  UserID  Country IsDefault
1   7       90      0
2   7       93      0
3   7       95      1
4   7       88      0 

5   8       34      0
6   8       55      1
7   8       27      0
8   8       12      0
  

Идентификатор является первичным ключом.
Идентификатор пользователя берется из таблицы users. Идентификатор страны берется из таблицы countries. IsDefault показывает, какая из стран является страной по умолчанию для пользователя.

Возможно ли разрешить только один IsDefault = 1 для идентификатора пользователя с использованием составного ключа? Т.е. комбинация userId = 7 должна иметь только один экземпляр с IsDefault = 1. Все остальные экземпляры userId 7 должны иметь IsDefault 0. То же самое касается идентификатора пользователя 8, который должен иметь только одну страну по умолчанию.

Комментарии:

1. возможно, использовать триггер?

2. Почему бы просто не указать страну по умолчанию в качестве поля в таблице пользователей?

3. Вы, ребята, правы. Но мне было любопытно, возможно ли добавить подобное ограничение.

Ответ №1:

То, что вы ищете, называется частичным индексом (фильтрованный индекс в SQL server), однако MySQL их не поддерживает, т. Е. следующее в другой базе данных (это не будет работать в MySQL)

 CREATE UNIQUE INDEX yourIndexNameHere
ON yourTableNameHere (UserID) 
WHERE IsDefault=1;
  

Ваши варианты следующие

  1. Создайте триггер для выполнения перед операторами INSERT и UPDATE, который может обрабатывать ваше уникальное ограничение, т. Е. установив для этого IsDefault значение 0 для всех других строк UserID (это можно оптимизировать, т. Е. игнорировать обновляемую в данный момент строку в UPDATE и обновлять только там, где IsDefault фактически 1) (как предложено Fabricator)
  2. Добавьте DefaultCountry столбец в таблицу users, в которой хранится эта информация (как предложено wils484)
  3. Используйте базу данных, отличную от MySQL. SQL Server, PostgreSQL и SQLite могут поддерживать частичные индексы