Во-первых, я прошу прощения, если это обман - я подозреваю, что это может быть, но я не могу найти его.
Скажите, у меня есть таблица компаний:
id | company_name
----+--------------
1 | Someone
2 | Someone else
... и таблица контактов:
id | company_id | contact_name | is_primary
----+------------+--------------+------------
1 | 1 | Tom | 1
2 | 2 | Dick | 1
3 | 1 | Harry | 0
4 | 1 | Bob | 0
Можно ли настроить таблицу contacts
таким образом, чтобы требовалось , чтобы для одной и только одной записи был установлен флаг is_primary
для каждой общей company_id
?
Так что, если я попытался сделать:
UPDATE contacts
SET is_primary = 1
WHERE id = 4
... запрос не будет выполнен, поскольку Tom
(id = 1
) уже помечен как основной контакт для company_id = 1
. Или, что еще лучше, можно ли построить триггер так, чтобы запрос выполнялся успешно, но флаг Tom
is_primary
будет сброшен той же самой операцией?
Меня не слишком беспокоит проверка того, существует ли company_id
в таблице companies
, мой PHP-код уже выполнил бы эту проверку, прежде чем я добрался до этой стадии (хотя, если есть способ сделать это в той же операция была бы неплохой, наверное).
Когда я сначала подумал об этом, я подумал: «это будет легко, я просто добавлю уникальный индекс в столбцы company_id
и is_primary
», но, очевидно, это не сработает, поскольку ограничит меня одним основной и один неосновной контакт - любая попытка добавить третий контакт потерпит неудачу. Но я не могу не чувствовать, что есть способ настроить уникальный индекс, который дает мне минимальные функциональные возможности, которые мне требуются - отклонить попытку добавления второго основного контакта или отклонить попытку покинуть компанию без основного контакта.
Мне известно, что я мог бы просто добавить поле primary_contact
к таблице companies
с FK к таблице contacts
, но это выглядит грязно. Мне не нравится идея, что обе таблицы имеют FK для другой - мне кажется, что одна таблица должна опираться на другую, а не обе таблицы полагаться друг на друга. Я думаю, я просто думаю, что со временем есть больше шансов, что что-то пойдет не так.
Подводя итог:
- Как я могу ограничить таблицу контактов, чтобы одна и только одна запись с данным
company_id
имела установленный флаг is_primary
?
- У кого-нибудь есть мысли о том, является ли две или две таблицы, имеющие FK друг другу, хорошей / плохой идеей?