Обычно я добавляю столбец типа int или smallint с именем что-то вроде 'Ordinal' или 'PositionOrdinal', как вы предлагаете, и с точным предупреждением, которое вы упомянули & mdash; необходимость обновления потенциально значительного числа записей каждый раз, когда одна запись переупорядочивается.
Преимущество состоит в том, что при наличии ключа для конкретной задачи и новой позиции для этой задачи код для перемещения элемента представляет собой всего два оператора:
UPDATE `Tasks` SET Ordinal= Ordinal+1 WHERE Ordinal>=@NewPosition
UPDATE `Tasks` SET Ordinal= @NewPosition WHERE TaskID= @TaskID
Существуют и другие предложения для двусвязного списка или лексического порядка. Любой из них может быть быстрее, но за счет гораздо более сложного кода, а производительность будет иметь значение, только если у вас есть лот элементов в одной группе.
Важность производительности или сложности кода будет зависеть от вашей ситуации. Если у вас есть миллионы записей, дополнительная сложность может стоить того. Однако я обычно предпочитаю более простой код, потому что пользователи обычно заказывают только небольшие списки вручную . Если в списке не так много элементов , дополнительные обновления не будут иметь значения. Обычно это может обрабатывать тысячи записей без какого-либо заметного влияния на производительность.
При обновлении примера следует помнить, что столбец используется только для сортировки и не отображается непосредственно пользователю. Таким образом, при перетаскивании элемента сверху вниз, как показано, единственное, что вам нужно изменить, - это одна запись. Неважно, что вы оставите первую позицию пустой. Это означает, что существует небольшая вероятность переполнить целочисленную сортировку достаточным переупорядочением, но позвольте мне повторить: пользователи обычно заказывают только небольшие списки вручную . Я никогда не слышал об этом риске, который действительно вызывает проблемы.