Я думаю, что вопрос, который вы пытаетесь задать, это больше о дизайне базы данных .
Когда вы хотите иметь возможность поддерживать порядок с группой предметов, имея возможностьЧтобы изменить их порядок, вам понадобится столбец, чтобы сохранить порядок.
Вы столкнетесь с проблемой, когда попытаетесь заказать их, если они заказаны последовательно.
Пример
Например, если вы хотите переместить Item1
за Item4
:
До
Элемент с индексом заказа.
1. Item1, order: 1
2. Item2, order: 2
3. Item3, order: 3
4. Item4, order: 4
5. Item5, order: 5
6. Item6, order: 6
После
Проблема : нам приходилось обновлять каждую запись между перемещаемым элементом и местом его размещения.
Почему этоэто проблема : это Большой O (n) - для каждого перемещаемого пространства мы должны обновить столько записей.По мере того, как вы получаете больше задач, это становится все более серьезной проблемой, так как это займет больше времени и будет плохо масштабироваться.Было бы неплохо иметь Большой O (1), где у нас есть постоянное количество изменений или как можно меньше.
1. Item2, order: 1 - Updated
2. Item3, order: 2 - Updated
3. Item4, order: 3 - Updated
4. Item1, order: 4 - Updated
5. Item5, order: 5
6. Item6, order: 6
Возможное решение № 1 (ОК, может быть?) - Интервал
Вы можете попытаться придумать хитрый метод, в котором вы попытаетесь разместить номера заказов так, чтобы у вас были дыры, которые можно заполнить, не обновляя несколько записей.
Хотя это может быть сложно, и вы можетеПодумайте: «Почему бы не хранить Item1 в заказе: 4.5?» Я добавил связанный вопрос ниже, который подходит к этой идее и почему вам следует ее избегать.
Возможно, вы сможете проверить безопасностьсо стороны клиента заказа и избегайте попадания в базу данных для определения нового идентификатора заказа перемещения.
Это также имеет ограничения, так как вам, возможно, придется сбалансировать интервал или, возможно, у вас закончились числа к элементам.Возможно, вам придется проверить наличие конфликта, и при возникновении конфликта вы выполняете перебалансировку всего или рекурсивно проверяете элементы вокруг конфликта, следя за тем, чтобы другие обновления балансировки не вызывали больше конфликтов и чтобы разрешались дополнительные конфликты.
1. Item2, order: 200
2. Item3, order: 300
3. Item4, order: 400
4. Item1, order: 450 - Updated
5. Item5, order: 500
6. Item6, order: 600
Возможное решение № 2 (лучше) - Связанные списки
Как упомянуто в связанной ссылке ниже , вы можете использовать структуру данных, такую как связанный список.Это сохраняет постоянное количество изменений для обновления, так что это Big O (1).Я немного перейду к связанному списку, если вы еще не поработали со структурой данных.
Как вы можете видеть ниже, для этого изменения потребовалось только 3 обновления, я считаю, что максимальное значение будет 5, как показано вExpected Updates
.Вы можете подумать: «Ну, это заняло столько же с первой оригинальной проблемой / примером!»Дело в том, что это всегда будет максимум 5 обновлений по сравнению с тысячами или миллионами при первоначальном подходе [Big O (n)].
1. Item2, previous: null, next: Item3 - Updated // previous is now null
2. Item3, previous: Item2, next: Item4
3. Item4, previous: Item3, next: Item1 - Updated // next is now Item1
4. Item1, previous: Item4, next: Item5 - Updated // previous & next updated
5. Item5, previous: Item1, next: Item4 - Updated // previous is now Item1
6. Item6, previous: Item6, next: null
Ожидаемые обновления
- Элемент перемещается (предыдущий, следующий)
- Старый предыдущий элемент следующий
- Старый следующий элемент предыдущего
- Новый предыдущий элемент следующий
- Новый следующий элементпредыдущий
Связанные списки
Полагаю, я использовал double linked list
.Вы, вероятно, могли бы избежать использования только одного связанного списка, у которого нет атрибута previous
и только next
.
Идея связанного списка состоит в том, чтобы думать о нем как о цепочке.ссылка, когда вы хотите переместить один элемент, вы должны отделить его от ссылки перед ним и позади нее, а затем связать эти ссылки вместе.Затем вы откроете место, где вы хотите разместить его, теперь у него будут новые ссылки с каждой стороны, и для этих новых ссылок они теперь будут связаны с новой ссылкой, а не друг с другом.
Возможное решение № 3 - Хранение документов / Json / Array
Вы сказали, что хотите держаться подальше от массивов, но вы можете использовать хранилище документов.Вы все еще можете иметь доступную для поиска таблицу элементов, и тогда каждая коллекция элементов будет иметь только массив идентификаторов / ссылок элементов.
Таблица элементов
- Item1, id: 1
- Item2, id: 2
- Item3, id: 3
- Item4, id: 4
- Item5, id: 5
- Item6, id: 6
Коллекция элементов
[2, 3, 4, 1, 5, 6]
Похожие вопросы
Ресурсы для Big O
Другие вопросы
Дизайн вашей базы данных будет зависеть от того, чего вы пытаетесь достичь.Могут ли элементы принадлежать нескольким доскам или пользователям?
Можете ли вы переложить некоторые заказы на клиентскую сторону и позволить ему сообщить серверу, каков новый заказ?Вы все равно должны избегать неэффективных алгоритмов упорядочения на стороне клиента, но вы можете заставить их выполнять некоторую грязную работу, если вы им доверяете и не испытываете никаких проблем с целостностью данных, если несколько человек работают над одними и теми же элементами одновременно.время (это другие проблемы проектирования, которые могут или не могут быть связаны с БД, в зависимости от того, как вы их обрабатываете.)