Контекст:
У меня есть база данных SQLite со столом, глядя, как это:
CREATE TABLE items (item TEXT, position INTEGER)
SQLite: как сгруппировать запросы UPDATE и задержать изменения после?
Эта таблица содержит несколько миллионов записей. Столбец position
индексируется.
Мой интерфейс иногда создает кучу обновлений для применения на столбце position
. Строки, которые необходимо обновить, не идентифицируются по их идентификатору, потому что обновления могут быть в широком диапазоне элементов, а список всех идентификаторов может быть очень дорогим. К примеру, куча может быть действие, как обновление "добавить в положение +10> = 500 & положение < = 10000" - "добавить в положение -3> = 100000 & положение < = 100003" и т.д.
Проблема: Условные позиции обновлений обновления обновления: все на основе значений позиций перед сгруппированным обновлением. Если я последовательно выполняю каждое действие обновления сгруппированного обновления, тогда, возможно, (и на самом деле есть) проблема «перекрытия» после одного обновления.
К примеру:
item | position
it1 | 1
it2 | 2
it3 | 3
it4 | 4
it5 | 5
it6 | 6
it7 | 7
Если у меня есть эта куча обновлений: "добавить + 2 в положение> = 5 & положение < = 6" - «добавить - 2 в положение> = 3 & положение < = 4" и преобразовать его в этом SQLite запросов:
UPDATE items SET position=position-2 WHERE position >= 5 AND position <= 6
UPDATE items SET position=position+2 WHERE position >= 3 AND position <= 4
Я буду иметь этот результат:
it1 | 1
it2 | 2
it3 | 5
it4 | 6
it5 | 5
it6 | 6
it7 | 7
Вместо того, что я хочу, это сказать:
it1 | 1 { it1 | 1 }
it2 | 2 { it2 | 2 }
it3 | 5 { it5 | 3 }
it4 | 6 ===> { it6 | 4 }
it5 | 3 { it3 | 5 }
it6 | 4 { it4 | 6 }
it7 | 7 { it7 | 7 }
Это из-за «перекрывание» от одной операции к другой.
Моя первая идея состояла в том, чтобы использовать СЛУЧАЙ так:
UPDATE items SET position=CASE WHEN position >= 5 AND position <= 6 THEN position-2 WHEN position >= 3 AND position <= 4 THEN position+2 ELSE position END
Это решение прекрасно работают, но это очень и очень медленно, так как это, кажется, что SQLite выполнить это на миллионы записей моей таблицы, даже если Обновленная информация не затрагивает основную сторону.
Так я изменил это так:
UPDATE items SET position=CASE WHEN position >= 5 AND position <= 6 THEN position-2 WHEN position >= 3 AND position <= 4 THEN position+2 ELSE position END WHERE (position >= 5 AND position <= 6) OR (position >= 3 AND position <= 4)
Это решение отлично работает, и это очень быстро, так как SQLite выполнить обновление только на соответствующих строках.
Вопрос: Как я могу иметь 10, или даже, возможно, 100 обновления действия, чтобы сделать в одной связке обновления, запрос может стать очень большим, и это не выглядит очень ... «красивый "/"хороший".
Как вы думаете, есть ли более красивый способ справиться с этим? Может ли SQLite выполнить некоторые запросы «UPDATE», выбирая затронутую строку в первый раз, а затем эффективно обновлять строку после?
Идеи? Думал ?
спасибо!
Благодарим вас за ответ. Эффективно это может быть решением. У меня была аналогичная идея: добавьте столбец «флаг». Перед каждым массовым обновлением установите для всех флагов строк значение 0 и запрос на обновление, обновите строку только с помощью флага «0» и установите флаг «1» в одно и то же время. Моя самая большая проблема: эта колонка занимает много места (значения хранятся в миллионы раз), и требуется время для обновления.И я чувствую, что создать дополнительную колонку для ответа на логическую проблему - это не очень хорошо. Что вы думаете об альтернативном решении? Возможно, я ошибаюсь с самого начала проблемы. –
В SQLite нет решения, которое я бы назвал исполнителем в пределах параметров, которые вы описали. –
Есть ли какая-либо документация/блог/лучшие практики о том, как управлять позиционированием строк в базе данных? –