Не стесняйтесь накладывать ограничения на базу данных. Вы обязательно будете иметь согласованную базу данных, и это одна из веских причин использовать базу данных. Особенно, если у вас есть несколько приложений, запрашивающих его (или только одно приложение, но с прямым режимом и пакетным режимом с использованием разных источников).
В MySQL у вас нет расширенных ограничений, как в postgreSQL, но, по крайней мере, ограничения внешнего ключа достаточно продвинуты.
Мы возьмем пример, корпоративную таблицу с пользовательской таблицей, содержащей людей из этой компании
CREATE TABLE COMPANY (
company_id INT NOT NULL,
company_name VARCHAR(50),
PRIMARY KEY (company_id)
) ENGINE=INNODB;
CREATE TABLE USER (
user_id INT,
user_name VARCHAR(50),
company_id INT,
INDEX company_id_idx (company_id),
FOREIGN KEY (company_id) REFERENCES COMPANY (company_id) ON...
) ENGINE=INNODB;
Давайте посмотрим на предложение ON UPDATE :
- ОГРАНИЧЕНИЕ ОБНОВЛЕНИЯ : по умолчанию : если вы попытаетесь обновить company_id в таблице COMPANY, механизм отклонит операцию, если хотя бы один ПОЛЬЗОВАТЕЛЬ ссылается на эту компанию.
- ОБНОВЛЕНИЕ НЕТ ДЕЙСТВИЙ : так же, как ОГРАНИЧЕНИЕ.
- ОБ ОБНОВЛЕНИИ КАСКАДА : обычно лучший : если вы обновите company_id в строке таблицы COMPANY, механизм обновит его соответствующим образом для всех строк USER, ссылающихся на эту COMPANY (но триггеры не активированы в таблице USER, предупреждение). Двигатель будет отслеживать изменения для вас, это хорошо.
- ON UPDATE SET NULL : если вы обновите company_id в строке таблицы COMPANY, механизм установит для соответствующих USER company_id значение NULL (должно быть доступно в поле USER company_id). Я не вижу ничего интересного в обновлении, но могу ошибаться.
А теперь на стороне ON DELETE :
- ON DELETE RESTRICT : по умолчанию : если вы попытаетесь удалить идентификатор company_id в таблице COMPANY, механизм отклонит операцию, если хотя бы один пользователь USER хотя бы ссылается на эту компанию, может спасти вам жизнь.
- В УДАЛЕНИИ НЕТ ДЕЙСТВИЙ : так же, как ОГРАНИЧЕНИЕ
- ON DELETE CASCADE : опасно : если вы удалите строку компании в таблице COMPANY, механизм удалит также и соответствующих пользователей. Это опасно, но его можно использовать для автоматической очистки вторичных таблиц (поэтому это может быть то, что вам нужно, но совершенно точно не для примера COMPANY <-> USER)
- ON DELETE SET NULL : handful : если вы удалите строку COMPANY, соответствующие пользователи автоматически будут иметь отношение к NULL. Если значение Null для пользователей без компании, это может быть хорошим поведением, например, может быть, вам нужно сохранить пользователей в вашем приложении как авторов некоторого контента, но удаление компании не является для вас проблемой.
обычно по умолчанию используется: ON DELETE RESTRICT ON UPDATE CASCADE . с некоторыми ON DELETE CASCADE
для таблиц дорожек (журналы - не все журналы - и тому подобное) и ON DELETE SET NULL
когда главная таблица является «простым атрибутом» для таблицы, содержащей внешний ключ, например таблица JOB для таблицы USER.
редактировать
Прошло много времени с тех пор, как я это написал. Теперь я думаю, что я должен добавить одно важное предупреждение. MySQL имеет одно большое документированное ограничение каскадами. Каскады не являются спусковыми механизмами стрельбы . Поэтому, если вы были достаточно уверены в этом движке, чтобы использовать триггеры, вам следует избегать каскадных ограничений.
Триггеры MySQL активируются только для изменений, внесенных в таблицы операторами SQL. Они не активируются ни для изменений в представлениях, ни для изменений в таблицах, сделанных API, которые не передают операторы SQL на MySQL Server
==> См. Ниже последнего редактирования, все движется в этом домене
Триггеры не активируются действиями внешнего ключа.
И я не думаю, что это будет исправлено однажды. Ограничения внешнего ключа управляются хранилищем InnoDb, а триггеры - движком MySQL SQL. Оба разделены. Innodb - это единственное хранилище с управлением ограничениями, возможно, они добавят триггеры непосредственно в механизм хранения данных, а может и нет.
Но у меня есть собственное мнение о том, какой элемент следует выбирать между плохой реализацией триггера и очень полезной поддержкой ограничений внешних ключей. И как только вы привыкнете к согласованности базы данных, вы полюбите PostgreSQL.
12/2017-Обновление этой правки о MySQL:
Как заявил @IstiaqueAhmed в комментариях, ситуация на эту тему изменилась. Поэтому перейдите по ссылке и проверьте реальную актуальную ситуацию (которая может измениться в будущем).
ON DELETE CASCADE : dangerous
- взять со щепоткой соли.