Как выполнить редактирование в таблице соединений

#mysql #sql #database #sql-server-2008 #database-design

#mysql #sql #База данных #sql-server-2008 #база данных-дизайн

Вопрос:

Какова наилучшая практика для редактирования в таблицах соединений?

 Items{ItemId, Name, Price...}
Shops{ShopId, Name, Address...}
ItemsInShops{ItemId, ShopId, DeliveryDate...}
  

Теперь у меня есть 30 товаров в одном магазине. Я хочу отредактировать этот список, и я снимаю галочки с 10 элементов и проверяю 50 новых элементов.

Я делаю это следующим образом: удаляю все строки из ‘ItemsInShops’ по ‘ItemId’ и добавляю новые значения. Я не думаю, что это хорошее решение. Есть ли лучший способ выполнить такого рода обновление?

Возможно, я не выразил проблему хорошим примером. Взгляните на это:

 User{UserId, Username, Password...}
Roles{RoleId, Name, Description} // Admin, Member, Superuser, Junior etc
UsersInRoles{UserId,RoleId}
  

Пользователь может иметь любое количество ролей.

 John > Admin, Member, Superuser
  

Это три строки в таблице соединений ‘UserInRoles’.
Если я хочу обновить этого пользователя, чтобы у него были следующие роли:

 John > Member, Junior
  

Теперь я делаю это обновление базы данных следующим образом:
Я удаляю все роли Джона из таблицы ‘UserInRoles’ и добавляю новые данные. Я не знаю, есть ли лучший способ выполнить это обновление, кроме как удалить все и вставить новое? Что делать, если по какой-либо причине произойдет сбой обновления (например, потеряно подключение к Интернету)?

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

1. Что вы подразумеваете под «проверить» и «снять флажок»?

2. Установите / снимите флажок в моем приложении. Добавлять и удалять из базы данных.

Ответ №1:

Я не знаю, есть ли лучший способ выполнить это обновление, кроме как удалить все и вставить новое?

Вам не нужно удалять все строки для начала.

Вы можете удалить только те строки, которые больше не применяются, и вставить только те строки, которые являются новыми. Или вы можете обновить значение, которое больше не применяется, значением, которое применяется.

Итак, чтобы получить из этого

 Name    Role
--
John    Admin
John    Member
John    Superuser
  

к этому

 Name    Role
--
John    Member
John    Junior
  

Вы можете удалить то, что больше не применяется . . .

 delete from userinroles
where Name = 'John' 
  and (Role = 'Admin' or Role = 'Superuser');
  

и вставьте то, что действительно применимо.

 insert into userinroles (Name, Role)
values ('John', 'Junior');
  

Или вы можете обновить значение новым значением.

 delete from userinroles
where Name = 'John' 
  and Role = 'Admin';
  

За которым следует

 update userinroles
set Role = 'Junior'
where 'Name' = 'John' and Role = 'Superuser';
  

Вы сказали

Что делать, если по какой-либо причине произойдет сбой обновления (например, потеряно подключение к Интернету)?

Для этого и нужны транзакции. Несколько инструкций в рамках одной транзакции SQL — это все или ничего — либо все они выполняются успешно, либо изменения не вносятся.

Ответ №2:

Основываясь на комментариях, нет лучшего способа добавить / удалить данные базы данных, чем добавить / удалить данные базы данных.

В качестве альтернативы, у вас могут быть столбцы в базе данных для информации о статусе, например «оплачено», «продано», «дата доставки», «отменено» и т.д. Тогда вместо удаления записей вы бы обновили статус. Это упрощает проверку прошлых транзакций и корректность записей (например, «отменить»).

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

1. что произойдет, если отменить отмену? (мне пришлось)

2. кто-то всегда должен. Архивируйте каждую транзакцию в вашей базе данных с отметкой времени. Но я делаю это только под угрозой пыток.

3. но можно ли отменить отмененное отменение? (первый комментарий был неудачной попыткой пошутить 😉

Ответ №3:

Вы могли бы посмотреть в онлайн-КНИГАХ ключевое слово MERGE.

Ответ №4:

Ваш обновленный вопрос интересен.

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

Что касается двух запросов, выполняемых подряд, когда они действительно образуют один процесс, вам нужны транзакции. Это настройки «все или ничего», так что набор запросов либо завершается успешно, либо завершается неудачей (все они «откатываются»). Транзакции очень полезны, например, «пользователь платит товар доставлен» или «прошлые данные архивируются удалены», и они подробно обсуждаются во многих учебниках и веб-сайтах.