Я хочу использовать внешние ключи, чтобы сохранить целостность и избежать сирот (я уже использую innoDB).
Как сделать SQL-оператор, который удаляет CASCADE?
Если я удаляю категорию, то как мне убедиться, что она не удалит товары, которые также относятся к другим категориям.
Сводная таблица «category_products» создает отношение «многие ко многим» между двумя другими таблицами.
categories
- id (INT)
- name (VARCHAR 255)
products
- id
- name
- price
categories_products
- categories_id
- products_id
mysql
foreign-keys
innodb
Cudos
источник
источник
Ответы:
Если ваш каскад удаляет ядерный продукт, потому что он был членом убитой категории, то вы неправильно настроили свои внешние ключи. Учитывая ваши примеры таблиц, вы должны иметь следующую настройку таблицы:
Таким образом, вы можете удалить продукт ИЛИ категорию, и только связанные записи в category_products умрут вместе с ним. Каскад не пройдет дальше по дереву и не удалит родительскую таблицу товаров / категорий.
например
Если вы удалите «красную» категорию, то умирает только «красная» запись в таблице категорий, а также две записи prod / cats: «красные сапоги» и «красные пальто».
Удаление не будет касаться дальше и не удалит категории «ботинки» и «пальто».
продолжение комментария:
Вы все еще не понимаете, как работает каскадное удаление. Они влияют только на таблицы, в которых определен «каскад удаления». В этом случае каскад устанавливается в таблице «category_products». Если вы удалите «красную» категорию, единственными записями, которые будут каскадно удаляться в category_products, являются те, где
category_id = red
. Он не будет касаться записей, где «category_id = blue», и не будет перемещаться дальше к таблице «products», потому что в этой таблице не определен внешний ключ.Вот более конкретный пример:
Допустим, вы удалили категорию № 2 (синяя):
СУБД рассмотрит все таблицы с внешним ключом, указывающим на таблицу «категорий», и удалит записи, для которых совпадает идентификатор 2. Поскольку мы определили только отношение внешнего ключа
products_categories
, вы получите эту таблицу, как только удаление завершено:В
products
таблице не определен внешний ключ , поэтому каскад не будет работать там, поэтому у вас все еще есть ботинки и рукавицы. Просто больше нет «синих сапог» и «синих варежек».источник
CASCADE
работать. В противном случае будет использоваться MyISAM по умолчанию, MyISAM, и MyISAM не поддерживаетCASCADE
операции. Для этого просто добавьтеENGINE InnoDB
перед последним;
.Ответ на этот вопрос меня смутил, поэтому я создал тестовый пример в MySQL, надеюсь, это поможет
источник
Я думаю (я не уверен), что ограничения внешнего ключа не будут делать именно то, что вы хотите, учитывая дизайн вашей таблицы. Возможно, лучше всего определить хранимую процедуру, которая удалит категорию так, как вы хотите, и затем вызывать эту процедуру всякий раз, когда вы хотите удалить категорию.
Вам также необходимо добавить следующие ограничения внешнего ключа в таблицу ссылок:
Предложение CONSTRAINT может, конечно, также появляться в операторе CREATE TABLE.
Создав эти объекты схемы, вы можете удалить категорию и получить желаемое поведение, выдав
CALL DeleteCategory(category_ID)
(где category_ID - категория, которую нужно удалить), и она будет вести себя так, как вы хотите. Но не выполняйте нормальныйDELETE FROM
запрос, если только вы не хотите более стандартного поведения (т.е. удалите только из таблицы ссылок и оставьтеproducts
таблицу в покое).источник
KEY pkey (product_id),
третийCREATE TABLE
запрос в принятом ответе?