@BarneyGumble

Как удалить дубли строк в MySQL в таблице, связанной с другими?

Есть большая БД на 50гб, и стоит задача удалить дубли в одной из таблиц. Погуглил, вроде как все советуют такое решение:

CREATE TEMPORARY TABLE tmp_tab AS SELECT DISTINCT * FROM your_table;
DELETE FROM your_table;
INSERT INTO your_table SELECT * FROM tmp_tab;
DROP TABLE tmp_tab;


Но проблема в том что в других таблицах есть связи через внешние ключи с моей основной. И когда я делаю DELETE FROM your_table; то начинает ругаться:

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails


Какое есть решение для такой ситуации?
  • Вопрос задан
  • 34 просмотра
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Зависит от того, что надо делать со связанными данными.
Если их можно удалить, то достаточно сменить свойства связи на ON DELETE CASCADE.
Если их надо перепривязать к остающимся строкам основной таблицы, то только писать свой скрипт, который будет искать дубли, выполнять перепривязку к основной записи и только после этого удалять дубли.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Stalker_RED
@Stalker_RED
Для начала четко определите что именно вы считаете дублями. Если другие таблицы ссылаются только на более ранний из дублей, или более поздний, например, то все довольно просто. Если могут ссылаться на оба одновременно, то у вас три варианта:
1. склеить - обновить связи так, чтобы ссылались только на один из дублей, тогда второй можно удалить.
2. удалить связи потеряв целостность базы
3. выставить "on delete cascade" чтобы связанные данные из другой таблицы удалялись автоматически.
Ответ написан
@Akina
Сетевой и системный админ, SQL-программист.
Погуглил, вроде как все советуют такое решение:

Дерьмо. Забудь.

Есть большая БД на 50гб, и стоит задача удалить дубли в одной из таблиц.
[skipped]
Но проблема в том что в других таблицах есть связи через внешние ключи с моей основной.


Порядок действий.

Запрос 0. Выполнить полное резервное копирование. Убедиться, что полученный бэкап валиден.

Запрос 1. Для каждого набора дубликатов изменить реферальные значения в связанных таблицах, присвоить значению реферального поля значение, взятое из записи с минимальным (или максимальным) значением первичного индекса. Выполняется отдельно для каждой таблицы, имеющей внешний ключ в целевую.

Запрос 2. Удалить все записи-дубликаты, кроме имеющих минимальное (или максимальное) значение первичного индекса.

DEMO fiddle
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы