#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;
Ваши варианты следующие
- Создайте триггер для выполнения перед операторами INSERT и UPDATE, который может обрабатывать ваше уникальное ограничение, т. Е. установив для этого
IsDefault
значение 0 для всех других строкUserID
(это можно оптимизировать, т. Е. игнорировать обновляемую в данный момент строку вUPDATE
и обновлять только там, гдеIsDefault
фактически 1) (как предложено Fabricator) - Добавьте
DefaultCountry
столбец в таблицу users, в которой хранится эта информация (как предложено wils484) - Используйте базу данных, отличную от MySQL. SQL Server, PostgreSQL и SQLite могут поддерживать частичные индексы