Всем привет!
Вопрос такой. У каждого пользователя на сайте есть список, не важно какой.
У каждого элемента из списка есть своя позиция, допустим вытаскивая элементы из таблицы мы отсортируем их по полю id, где каждый элемент имеет свой уникальный id.
Нужно сделать так чтобы пользователь мог менять позицию элемента в списке.
Но не пойму как это сделать.
Есть лишь одна идея, это задать отдельное поле для позиции в таблице, пусть оно называется position и каждый раз когда человек меняет позицию элемента в списке, это нужно вытаскивать весь список пользователя и просчитывать для каждого элемента позицию и в цикле апдейтить каждую запись из списка.
А если этих списков 100 ? Не думаю что это нормально, хотя и допускаю что это ок, потому не представляю как по другому.
Если еще мысль на счет весов, задать какое-то поле weight в таблице списка.
Вытаскивать все id и weight элементов и проводить какие-то расчеты с учетом уже имеющихся весов. Но не менять при этом веса всех элементов, а лишь задать правильный весь для конкретно элемента.
То есть допустим каждому элементу мы даем каждый раз вес 100 и увеличиваем эту цифру в двое для нового элемента списка. А потом если добавим какой-нибудь элемент новый и захотим поставить его первым, то делаем весь меньше на единицу. Но тут есть какой-то потолок, что если мы каждый раз новый элемент будем ставить первым, то сможем поставить только 100 элементов, хотя может это и вовсе бредовая идея.
Может кто подсказать как более правильно решить такую задачу ?
Чисто алгоритмически-теоретически, можно организовать связный список.
Например, двусвязный. У каждой строки ещё 2 поля: следующий_id, предыдущий_id
Когда позиция элемента меняется, это два действия:
выемка элемента: обновляются два его соседа, чтобы связаться напрямую.
пример
id next prev
1 2 null
2 3 1 <-- этого забираем
3 4 2
--------------
1 3 null
3 4 1
вставка: рвётся связь двух и заменяются их указатели на вставленный, и у вставленного тоже.
пример
id next prev
7 8 6 <-- вставить после этого
8 9 7
--------------
7 2 6
2 8 7
8 9 2
При переносе элемента понадобится обновить не более 2 + 2 + 1 = 5 строк.
Получать такой список в нужном порядке средствами MySQL - нетривиально. Но можно просто вынимать весь целиком, а рисовать-сортировать в правильном порядке уже на клиенте.
Сергей Соколов, наверное это самое лучшее решение.
Я так понимаю что для изменений в списке необходимо использовать транзакции, иначе если какой-то запрос не пройдет, то связанный список будет поломан если я захочу его отсортировать, так как ссылки next, prev будут неправильно ссылаться. Верно ?
Сергей Соколов, не могли бы еще подсказать как эффективно делать перестановки в таком списке ?
Потому что вот сейчас у меня допустим приходит позиция и номер списка который нужно переставить.
Я достаю весь список, сортирую и переставляю в нем элементы в массиве, а затем записанные id элементов которые я должен поменять и делаю запросы. Код кажется таким громоздким.
Могли бы вы подсказать верно ли я решаю задачу ?