Работа с внешними ключами и каскадами в InnoDB / MySQL - PullRequest
1 голос
/ 06 января 2011

У меня довольно большая реляционная база данных InnoDB / MySQL. Я использовал ограничения внешнего ключа везде, в сочетании с «ON UPDATE CASCADE» (и «ON DELETE CASCADE»).

Эта база данных является частью системы CRM и, следовательно, содержит пользователей, а затем к этим пользователям присоединяются учетные записи.

Часто мы обнаруживаем, что в пользовательской таблице есть повторяющиеся записи, и мы хотели бы объединить их.

Один из вариантов - написать скрипт, который проходит через базу данных, обновляя столбец user_id во всех зависимых таблицах. Но это, несомненно, будет нарушаться при каждом изменении структуры базы данных.

Другой вариант, который я хочу изучить, - это использование CASCADE. Если я хочу объединить человека A и человека B, я могу сделать что-то вроде этого:

UPDATE user SET id = $A.id$ WHERE id = $B.id$ limit 1

Затем это изменение должно распространяться на все таблицы, зависящие от пользовательской таблицы.

Затем я должен удалить одну из дублирующихся строк от пользователя:

DELETE FROM user WHERE id = $A.id$ LIMIT 1

К сожалению, у этого подхода есть две проблемы.

Во-первых, столбец user.id является первичным ключом и, следовательно, уникальным.

Во-вторых (при условии, что я преобразовал user.id из ПЕРВИЧНОГО КЛЮЧА в обычный ИНДЕКС), если у пользователя есть повторяющиеся идентификаторы, и я удаляю один, тогда удаляются все строки из зависимых таблиц.

Есть ли способ обойти эти проблемы?

1 Ответ

0 голосов
/ 06 января 2011

Проблема слияния дублирующихся пользователей (или дублирующихся объектов) - это не то, чему я бы доверял при удалении каскада и при обновлении каскада.Во-первых, как узнать, какие данные следует хранить при возникновении конфликтов (например, два разных домашних адреса и разрешен только один)?Дедупирование почти всегда лучше всего выполнять вручную из приложения, созданного для этой цели, где вы можете выбрать значение, которое будет иметь приоритет при достижении уникального ограничения.Если вы делаете это вручную, вам необходимо определить правила определения приоритета (обычно это самая последняя обновленная запись, что означает, что вы должны записывать ее в последний раз).Вы также хотите иметь таблицы аудита для этого времени, поэтому вы можете отменить «дубликат», который оказывается не один.

...