Как правильно сделать position у записи в бд?

Всем привет.
Есть пользователи, у каждого пользователя есть свой todo список на 2000-4000 записей, у каждой записи должна быть позиция в todo списке. Если пользователь вставил между первой и второй записью, новую запись то позиция следующих записей должна быть +1. Номер позиции у записей должен быть уникальный.
Как можно такое правильно реализовать на стороне бэкэнда? Каждую запись пересохранять при каждом измении списка? или хранить в БД JSON объект который будет хранить позиции записей для каждого пользователя?
  • Вопрос задан
  • 169 просмотров
Решения вопроса 1
Вот отличная статья с подходящими вариантами, их плюсами и минусами.
https://begriffs.com/posts/2018-03-20-user-defined...
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
aleksejjjj
@aleksejjjj
Лучше хранить позицию у каждой записи. Самый простой и очевидный вариант. Это и сортировка и пагинация из коробки. В чём проблема увеличить счётчик?
// Вставить запись с position=2

// Увеличиваем у кого нужно - 1 запрос
Auth::user()->tasks()->where('position', '>=', 2)->increment('position');

// Добавляем запись
Auth::user()->tasks()->create([
    //...
    'position' => 2,
]);
Ответ написан
@dimuska139
Backend developer
Сам недавно с такой же примерно задачей столкнулся, правда в Питоне. Храню позицию в базе, а при смене позиции "сдвигаю" нужные элементы, чтобы нужные позиции перестраивались. Возможно, Вам пригодится:
touched_question = TestQuestion.objects.get(id=kwargs['question_id'])
questions = TestQuestion.objects.filter(test_id=touched_question.test_id)
for question in questions:
    if question.id != kwargs['question_id']:
        if touched_question.number < question.number <= new_number:  # Сдвиг вправо
            question.number -= 1
            question.save()
        if new_number <= question.number < touched_question.number:  # Сдвиг влево
            question.number += 1
            question.save()
    touched_question.number = new_number
    touched_question.save()

Правда в моем случае данных мало, а в Вашем это решение, возможно, не будет оптимальным. Потому что тут запросы в цикле))
Ответ написан
Вы можете хранить номер записи с отступом в 10 или даже 100 пунктов и вставлять новую запись в середину между двумя соседними (т.е. присваивать номер 15 между 10 и 20).
Таким образом полностью перестраивать нумерацию вам придется только если промежуток для вставки новой записи уже отсутствует, а это будет гораздо реже чем при +1.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы