#mysql #innodb #myisam
#mysql #innodb #myisam
Вопрос:
Ну, мой друг сказал мне, что я должен начать использовать InnoDB для своей базы данных, поэтому я попробовал в первый раз. И у меня проблема с удалением записей / индексов / полей / таблиц. Всякий раз, когда я пытаюсь удалить запись, я должен перейти ко ВСЕМ относительным записям, удалить их, а затем вернуться к удалению моей исходной записи. И я вообще не могу удалить индексы! Есть ли более простой способ сделать это (поскольку, когда я собираюсь запустить PHP, он ничего не удалит) или я должен просто вернуться к MyISAM? Какая из них, по вашему мнению, лучше?
Ответ №1:
Если вы хотите, чтобы зависимые записи автоматически удалялись при удалении записи в основной таблице, вам необходимо указать ON DELETE CASCADE
в ваших внешних ключах.
Согласно руководству, ваш выбор ограничения на внешние ключи является одним из таких:
КАСКАД: удалите или обновите строку из родительской таблицы и автоматически удалите или обновите соответствующие строки в дочерней таблице. Поддерживаются как КАСКАД УДАЛЕНИЯ, так и КАСКАД ОБНОВЛЕНИЯ. Между двумя таблицами не определяйте несколько каскадных предложений ON UPDATE, которые действуют на один и тот же столбец в родительской таблице или в дочерней таблице.
Обратите внимание, что в настоящее время каскадные действия с внешним ключом не активируют триггеры.
УСТАНОВИТЬ значение NULL: удалить или обновить строку из родительской таблицы и установить значение NULL для столбца или столбцов внешнего ключа в дочерней таблице. Поддерживаются предложения как для УДАЛЕНИЯ, так и для установки NULL, так и для ОБНОВЛЕНИЯ.
Если вы укажете действие SET NULL, убедитесь, что вы не объявили столбцы в дочерней таблице как NOT NULL.
ОГРАНИЧИТЬ: отклоняет операцию удаления или обновления для родительской таблицы. Указание RESTRICT (или NO ACTION) — это то же самое, что опустить предложение ON DELETE или ON UPDATE.
НЕТ ДЕЙСТВИЯ: ключевое слово из стандартного SQL. В MySQL эквивалентно RESTRICT. InnoDB отклоняет операцию удаления или обновления для родительской таблицы, если в таблице, на которую ссылается ссылка, есть соответствующее значение внешнего ключа. Некоторые системы баз данных имеют отложенные проверки, и НИКАКОЕ ДЕЙСТВИЕ не является отложенной проверкой. В MySQL ограничения внешнего ключа проверяются немедленно, поэтому НИКАКОЕ ДЕЙСТВИЕ не совпадает с RESTRICT.
По умолчанию, если вы ничего не укажете, это NO ACTION
— вот почему ваши удаления ничего не делают прямо сейчас.
Комментарии:
1.
NO ACTION
иRESTRICT
функционально, я думаю, это одно и то же. Я думаю, что MySQL согласен.NO ACTION
это означало бы, что ограничение не выполняется, поэтому обновление невозможно.RESTRICT
сделал бы то же самое.2. @Rudie: Конечно, это так, в самом первом предложении
NO ACTION
описания так сказано.3. Мой плохой. Этого не видел. По крайней мере, я помнил это с самого начала.
Ответ №2:
Если вам нравится удалять вещи, InnoDB может быть не для вас. InnoDB намного, намного строже, чем MyISAM. Это быстрее при выполнении запросов ( SELECT
, SHOW
и т.д.), Но медленнее при выполнении обновлений ( UPDATE
, INSERT
и т.д.).
КАСКАД InnoDB — это волшебство, но будьте очень осторожны. Это также очень медленно (потому что механизм базы данных сам проверит все ограничения). Если вы удаляете записи, которые каскадом переходят в другие удаления, которые каскадом переходят в другие обновления, которые каскадом переходят в другие удаления и т.д. и т.п., вам придется долго ждать.
Если вы удаляете в dev и вас раздражают ограничения InnoDB, они могут оказаться SET FOREIGN_KEY_CHECKS = 0;
очень полезными:
SET FOREIGN_KEY_CHECKS = 0;
/* do all kinds of dangerous deletes, eg. delete everything in the db */
SET FOREIGN_KEY_CHECKS = 1;
Не используйте это в самом приложении или будьте абсолютно уверены, что вы не нарушите никаких зависимостей.
Комментарии:
1. Да, дизайн БД в значительной степени завершен, но я нахожусь на очень ранних стадиях разработки приложения, и тестирование довольно сложно с проверкой ключей, но я думаю, что вместо удаления я предприму другое действие, потому что я хочу сохранить некоторые данные с внешними ключами.
Ответ №3:
Именно так это и должно работать.
Это сохраняет так называемую целостность данных. Если у вас есть пользователь и связанный с ним адрес, вы не сможете удалить пользователя, если сначала не удалите адрес — в противном случае вы оставляете посторонние данные в своей базе данных.
Ваше приложение должно позаботиться о том, чтобы убедиться, что все связанные данные удалены, если они не используются ON DELETE CASCADE
для принудительного применения.
Как правило, innoDB
это намного лучше для сохранения целостности ваших данных, поэтому придерживайтесь этого и не возвращайтесь к myISAM
(существует также вопрос о том, какой движок лучше всего использовать, но если вы не предоставите нам более подробную информацию, нет смысла останавливаться на этом).