Рефакторинг отношения «один ко многим» на отношение «Многие ко многим» в MySQL: как сформулировать запрос?

#mysql #database #database-design #refactoring

#mysql #База данных #database-design #рефакторинг

Вопрос:

В начальной «версии» приложения, над которым я работаю, не учитывались соображения дизайна — никто об этом не подумал.

Однако, похоже, что исходное отношение «один ко многим» необходимо преобразовать в отношение «многие ко многим». Мой вопрос в том, как лучше всего это сделать? Я использую MySQL для сохранения.

Заполнение таблицы отношений потребует только одноразовых усилий, я бы предпочел использовать простой запрос или подход с использованием хранимых процедур (я не очень хорошо разбираюсь в последнем); вместо того, чтобы писать логику на основе java / jdbc для этого (я знаю, что могу, и это не слишком сложно, ноэто не то, чего я хочу)

Итак, вот пример отношения:

 |VirtualWhiteBoard| -1------*- |Post|
  

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

Схема выглядит следующим образом:

 VirtualWhiteBoard (wallName, projectName,dateOfCreation,..., Primary_Key(wallName, projectName));
Post(post_id, wallName,postData,..., Primary_Key(post_id), Foreign_Key(wallName, projectName));
  

Виртуальная белая доска имеет составной первичный ключ (wallName, ProjectName), и каждая запись имеет post_id в качестве первичного ключа

Вопрос: Возьмите первичные ключи из VirtualWhiteBoard и Post и добавьте их в новое отношение ‘has_posts’:

 |VirtualWhiteBoard| -1------*- |has_Post| -*------1- |Post|
  

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

Как лучше всего этого добиться? Будет ли достаточно запроса или потребуются хранимые процедуры?

(Хотя я могу сделать это в «приложении», я бы предпочел сделать это таким образом, поскольку такие рефакторинги неизбежно возникнут, и я не хочу, чтобы вокруг лежал ненужный java-код, который нужно поддерживать, и лично предпочел бы иметь такой навык 🙂

Комментарии:

1. Что-то кажется неправильным? PK of VirtualWhiteBoard is (WallName, ProjectName) . Тем не менее Post , FK имеет WallName значение только?

Ответ №1:

Создайте свою таблицу has_Post с двумя столбцами post_id и wallName и заполните ее этим запросом:

 INSERT INTO has_Post(post_id, wallName) SELECT post_id, wallName FROM Post
  

Затем удалите столбец wallName из таблицы Post.

Комментарии:

1. Серьезно? Это просто? Я немного смущен вопросом!

2. Я предполагаю, что ProjectName также должен быть частью этого запроса, правильно? Поскольку это составной первичный ключ