Как сохранить определенный, изменяемый «порядок» в базе данных - PullRequest
24 голосов
/ 31 января 2009

Предположим, у меня есть некоторые объекты, и я хочу, чтобы пользователь мог переупорядочивать их любым желаемым образом, скажем, перетаскивая их. Так что я бы

  • Сыр
  • Кексы
  • Молоко

А затем пользователь перетаскивает «молоко» наверх, делая новый заказ

  • Молоко
  • Сыр
  • Кексы

Есть ли лучшая практика, как хранить порядок этих объектов в базе данных? Наивный подход, вероятно, заключался бы в том, чтобы просто хранить числовое значение, называемое «порядок», для каждого объекта, но это кажется мне слишком хлопотным, потому что вам придется перетасовывать значения порядка в большинстве случаев.

Ответы [ 7 ]

16 голосов
/ 04 февраля 2014

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

Это дешево как для чтения, так и для записи. Единственным недостатком является то, что поплавки продолжают увеличиваться:)

12 голосов
/ 31 января 2009

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

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

12 голосов
/ 31 января 2009

«Наивный» подход, который вы предлагаете, также является лучшей практикой!

5 голосов
/ 31 января 2009

Если посмотреть на ответы Тони Эндрю и Марка, в частности, кажется, что у меня действительно есть только две альтернативы:

  • Сохранение «следующего» значения, при котором объекты ведут себя как связанный список (см. Ответ Марка)
    При этом изменение заказа обходится дешево, но мне придется получить элементы и , а затем отсортировать их по их «следующему» значению, что дорого
  • Сохранение значения 'заказа' (см. Ответ Тони Эндрю)
    Это делает поиск дешевым, но сохранение нового заказа потенциально дорогостоящим, потому что в худшем случае мне придется изменить все значения заказа. Клетус указывает, что можно использовать большое число в форме 2 ^ n для умножения порядка.

Мета: Все эти ответы хорошие и правильные, какой из них я должен выбрать как правильный?

3 голосов
/ 31 января 2009

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

Также, как уже упоминалось, если вы извлекаете подмножество данных (фильтр по типу или что-то в этом роде), остальные элементы все еще находятся в правильном порядке сортировки.

Помните мантру К.И.С.С.

2 голосов
/ 31 января 2009

Да, в реляционной базе данных нет порядка, это одна из фундаментальных концепций. Так что просто нет способа без числового значения или чего-то в этом роде.

2 голосов
/ 31 января 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...