2013-07-31 2 views
1

Чтобы быть справедливым, я видел некоторые подобные вопросы here и here, но я считаю, что эти вопросы в первую очередь задают вопрос об обновлениях одной строки, а также о том, что фактические данные не изменяются.Есть ли технические преимущества команд UPDATE или INSERT для DELETE ALL и INSERT?

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

master_table

ID | Name | status 
--------------------- 
1 | prod1 | 1 
2 | prod2 | 1 
3 | prod3 | 0 
4 | prod4 | 1 

, где состояние представляет собой активный (1) или неактивным (0). Неактивный продукт недоступен для любого представителя для продажи независимо от их настроек в таблице rep.

rep_table

ID | repID | status 
------------------------ 
1 | rep1 | 1 
2 | rep1 | 1 
3 | rep1 | 1 
1 | rep2 | 0 
2 | rep2 | 1 
3 | rep3 | 0 

, где положение в этой таблице активно (1) или неактивный (0). Опять же, статус главной таблицы всегда переопределяет статус rep_table с точки зрения определения того, какие продукты может предложить представитель по продажам.

Основная проблема, с которой я столкнулся, заключается в том, когда мы вводим новые продукты для повторных продаж. На портале администрирования rep (s) он может активировать или деактивировать любой набор продуктов, которые они хотят предложить. Когда пользователь выбирает (формирует флажки) все товары, которые он/она хочет продать, и ударил, начнется серия проверок:

  1. Выбрал ли представитель набор продуктов?
  2. Являются ли продукты подбираются в лучшем формате?
  3. Отличается ли список выбранных продуктов от того, который они уже установили при входе в систему (если нет, то предупреждение о том, что обновление не произойдет)? ?
  4. ли все продукты, выбранные в форме существуют и настроены на «активные» в master_table

В этот момент логика затем переходит (в настоящее время) к следующему для каждого выбранного продукта:

  1. обновление всех продуктов rep_table в неактивное (для этого конкретного повторении)
  2. Если продукт существует в текущем наборе продуктов на входе и текущий статус был установлен в неактивное состояние, то в очередь идентификатор продукта для активного.
  3. Если переданный продукт не существовал в текущем наборе продуктов при входе в систему, вставьте новый продукт в rep_table и установите на активный.

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

Мне интересно, если вместо того, чтобы пытаться выяснить статус текущего выбора продукта по сравнению с тем, который был зарегистрирован в реестре, не просто удалить сначала все идентификаторы продуктов для определенного реплива в rep_table затем вставьте все сразу. Я знаю, что в этом случае я запускаю 2 запроса, но в сценариях, где у меня есть обновления и вставки в одну и ту же команду, каждый раз я запускаю как минимум 2+ запросов.

Существуют ли «технические» последствия для удаления и вставки таким образом?

Примечания: моя таблица является InnoDB, и я бегу MySQL

+0

Можете ли вы показать нам инструкцию create table с индексами? –

ответ

1

это обычно то, что я делаю, когда приходит время, чтобы обновить варианты, как это. Обычно проще начать транзакцию, nuke - старый список опций, а затем вставить новые параметры, выбранные пользователем. Это могут быть два запроса, но это простые запросы.

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

2

В зависимости от того, как вы индексированы, удаление и вставка могут быть технически наилучшим вариантом для производительности. Тем не менее, если у вас есть хорошие индексы, оператор UPDATE или REPLACE, который использует индекс, не должен стоить проблем с удалением всех ваших данных, а затем повторной установкой.

Что делать, если инструкция «Удалить» прошла, но прежде чем вы сможете выпустить вставку, ваш сервер перезапустит apache и память сбрасывается ... кажется, далека, но может произойти. Больше пользователей, больше обновлений, скорее всего, изменится ... Вы можете поместить DELETE и INSERT в одну транзакцию, но теперь, возможно, заблокируйте таблицу - это также повлияет на производительность.

+0

, если мне не хватает чего-то, это то, что мой PDO пытается поймать блоки и использовать commit(). Если транзакция действительно блокирует эту таблицу для запроса, то это то, о чем я не знал некоторое время. – JM4

+0

@ JM4 Уловка try будет обрабатываться, если одна команда завершится неудачно, но если вы не заблокируете на уровне таблицы, 2 человека могут запустить ту же пару delete/insert, и вы можете получить условие гонки. Я не уверен, что если транзакции INNODB являются атомарными для всей вставки/удаления ... только для отдельных строк, но, возможно, кто-то будет лучше понимать это. – Ray

+2

Сделки не блокируют таблицу - потому что это транзакции. Они должны немного блокировать доступ, потому что в какой-то момент изменение должно быть записано на диск, но это верно для любого запроса. Вы также можете явно заблокировать либо определенные наборы данных, либо полную таблицу - и это действительно единственный способ, которым база данных может безопасно записывать в таблицу, если нет доступных транзакций. Просто посмотрите на MyISAM: никаких транзакций, и любой запрос на запись заблокирует всю таблицу и остановит все запросы на чтение. InnoDB полностью поддерживает транзакции и блокирует только заблокированные строки. – Sven

0

Просто для завершения других ответов, с концептуальной точки зрения, UPDATE изменить существующие строки. DELETE + INSERT создаст новые строки.

Хотя скорее теоретический на первом, это имеет практическое значение:

  • К примеру, на ссылочную целостности базы данных (внешних ключей ограничений, каскадов).
  • Это может привести к срабатыванию пушек .
  • Наконец DELETE + INSERT может (и, вероятно,) столкнуться с одновременным UPDATES в тех же строках.
+0

Не уверен, что я понимаю ваш ответ. В моем сценарии есть (почти) никогда UPDATE только или Delete + Insert, это (было бы редко). Общий сценарий будет UPDATE несколько (и это несколько запросов из-за характера отправляемых данных) И вызов INSERT против одного DELETE + один INSERT. Ваша точка взята, но никогда не будет (стукнуть по дереву), в которой элемент delete + будет когда-либо возникать одновременно с обновлением. – JM4

Смежные вопросы