Не соромтеся ставити обмеження на базу даних. Ви обов'язково матимете послідовну базу даних, і це одна з вагомих причин використовувати базу даних. Особливо, якщо у вас є кілька заявок, які це вимагають (або лише одна програма, але в прямому режимі та пакетному режимі з використанням різних джерел).
У MySQL у вас немає розширених обмежень, як у постгрега, але принаймні обмеження для зовнішніх ключів є досить розширеними.
Візьмемо для прикладу таблицю компанії з таблицею користувачів, що містить людей із тез компанії
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 :
- ON UPDATE RESTRICT : за замовчуванням : якщо ви спробуєте оновити company_id у таблиці КОМПАНІЯ, двигун відкине операцію, якщо один USER хоча б посилається на цю компанію.
- НА ОНОВЛЕННЯ НЕ ДІЙ : те саме, що і RESTRICT.
- НА ОНОВЛЕННЯ КАСКАДИ : найкращий, як правило : якщо ви оновите company_id у рядку таблиці КОМПАНІЯ, двигун оновить його відповідно до всіх рядків USER, на які посилається ця КОМПАНІЯ (але жодних тригерів, активованих на таблиці USER, попередження). Двигун буде відслідковувати зміни для вас, це добре.
- НА ОНОВЛЕННЯ НАСТРОЮЙТЕ НУЛЬ: якщо ви оновите company_id у рядку таблиці КОМПАНІЯ, двигун встановить відповідні USERs company_id на NULL (має бути доступним у полі USER company_id). Я не бачу нічого цікавого, що можна зробити з цим під час оновлення, але я можу помилятися.
А тепер на стороні ON DELETE :
- ON DELETE RESTRICT : за замовчуванням : якщо ви спробуєте видалити ID company_id з таблиці КОМПАНІЯ, двигун відкине операцію, якщо один користувач, принаймні, посилається на цю компанію, може врятувати ваше життя.
- НА ВИДАЛЕННЯ НЕ ДІЙ : те саме, що і RESTRICT
- ON DELETE CASCADE : небезпечно : якщо ви видалите рядок компанії в таблиці КОМПАНІЯ, двигун також видалить пов’язані з цим ПОТРІБНИКИ. Це небезпечно, але може бути використане для автоматичного очищення на вторинних таблицях (тому це може бути щось, що вам хочеться, але абсолютно точно не для КОМПАНІЇ <-> ПРИКЛАДНИЙ приклад)
- ON DELETE SET NULL : пригорща : якщо ви видалите рядок COMPANY, відповідні ПОТРІБНИКИ автоматично матимуть відношення до NULL. Якщо Null - це ваша цінність для користувачів, які не мають компанії, це може бути хорошою поведінкою, наприклад, можливо, вам потрібно буде тримати користувачів у вашій програмі як авторів певного вмісту, але видалення компанії не є проблемою для вас.
як правило, моїм замовчуванням є: ВИДАЛИТИ ОГРАНИЧЕННЯ НА ОНОВЛЕННЯ КАСКАДИ . з деякими 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
- візьміть із щіпкою солі.