Поддержание/обновление порядка записей в MySQL

StackOverflow https://stackoverflow.com/questions/481789

  •  20-08-2019
  •  | 
  •  

Вопрос

У меня есть таблица записей в mySql.Мне нужно поддерживать для них порядок, указанный пользователем.Поэтому я добавил столбец «Позиция».

Каким будет оператор SQL для обновления всех записей при перемещении определенной записи?У меня есть что-то вроде:

UPDATE items SET position = '2' WHERE id ='4';
UPDATE items SET position = position+1 WHERE position >= '2' AND id != '4';

Но чем больше, тем меньше будет, чем если бы рекорд опустился вниз.В чем хитрость?Спасибо!

Это было полезно?

Решение

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

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

Другие советы

Поможет ли что-то подобное?

UPDATE items 
SET position = CASE position 
  WHEN $oldpos THEN $newpos 
  ELSE position + SIGN($oldpos-$newpos)
 END
WHERE position BETWEEN LEAST( $newpos, $oldpos ) 
                AND GREATEST( $newpos, $oldpos );

Я проверил это пару раз, и это, кажется, работает.

Вот мой взгляд на это:мой столбец row_index имеет номер с шагом 10 (например:0, 10, 20 и т. д.).Когда пользователь обновляет одну из строк, вам нужно знать, увеличивается она или уменьшается.Если вам нужно переместить 2-ю строку на 4-ю (вниз, желаемый row_index = 30), вы устанавливаете row_index на 35;в противном случае (при повышении) установите значение 25.Установите это значение:

UPDATE your_table SET row_index = 35 WHERE your_id = 1234

Теперь у вас правильный порядок, но row_indexes перепутаны.Чтобы это исправить, выполните два запроса:

SET @pos:=-10;
UPDATE your_table SET row_index = @pos:=@pos+10 WHERE ...

Это обновит все ваши строки (или ту, которую вы выбираете с помощью оператораwhere) и установите столбец row_index без пробелов (0, 10, 20, 30 и т. д.).Конечно, такой способ добавляет нагрузку на операции записи, но я думаю, что это самый быстрый способ получить порядок во время операций чтения.Если вы удалите строку, вы можете просто повторно запустить запросы на фиксацию порядка.

Я бы предложил, как минимум, использовать большие приращения (скажем, 10 000) между элементами.Тогда просто делаю заказ.Если вам нужно переместить 11000 между 9000 и 10000, просто установите значение 9500 и готово.

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

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

Интересный!Ладно, простого ответа нет.Я думал, что просто что-то упускаю.Я думал о сохранении внешнего массива.Это звучит как лучшая идея.

Может быть, что-то вроде этого?

$item_id = $_GET['item_id']; 
$position = $_GET['new_position']; 
$old_position = $_GET['old_position'];

if($new_position < $old_position) {
    SQL: UPDATE items SET position = position+1 WHERE position >= $new_position AND position < $old_position  
} else {  
SQL: UPDATE items SET position = position-1 WHERE position <= $new_position AND position > $old_position
}  

SQL: UPDATE items SET position = $new_position WHERE item_id = $item_id 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top