Представлять порядок в реляционной базе данных - PullRequest
33 голосов
/ 22 августа 2008

У меня есть коллекция объектов в базе данных. Изображения в фотогалерее, товары в каталоге, главы в книге и т. Д. Каждый объект представлен в виде строки. Я хочу иметь возможность произвольно упорядочивать эти изображения, сохраняя этот порядок в базе данных, чтобы при отображении объектов они были в правильном порядке.

Например, допустим, я пишу книгу, и каждая глава - это объект. Я пишу свою книгу и располагаю главы в следующем порядке:

Введение, Доступность, Форма против Функции, Ошибки, Согласованность, Заключение, Индекс

Идет к редактору и возвращается в следующем предложенном порядке:

Введение, форма, функция, доступность, согласованность, ошибки, заключение, индекс

Как я могу сохранить этот порядок в базе данных надежным и эффективным способом?

У меня были следующие идеи, но я не в восторге ни от одной из них:

  1. Массив. Каждая строка имеет идентификатор заказа, при изменении заказа (путем удаления с последующей вставкой) идентификаторы заказа обновляются. Это делает поиск легким, так как это всего лишь ORDER BY, но его легко сломать.

    // REMOVAL
    UPDATE ... SET orderingID=NULL WHERE orderingID=removedID
    UPDATE ... SET orderingID=orderingID-1 WHERE orderingID > removedID
    // INSERTION
    UPDATE ... SET orderingID=orderingID+1 WHERE orderingID > insertionID
    UPDATE ... SET orderID=insertionID WHERE ID=addedID

  2. Связанный список. В каждой строке есть столбец для идентификатора следующей строки в порядке. Обход здесь кажется дорогостоящим, хотя может каким-то образом использовать ORDER BY, о котором я не думаю.

  3. Разнесенный массив. Установите orderingID (как в # 1), чтобы он был большим, поэтому первый объект равен 100, второй - 200 и т. Д. Затем, когда происходит вставка, вы просто помещаете его в (objectBefore + objectAfter)/2. Конечно, иногда это необходимо перебалансировать, чтобы у вас не было слишком близко друг к другу вещей (даже с плавающей точкой вы в конечном итоге столкнетесь с ошибками округления).

Ничто из этого не кажется мне особенно элегантным. У кого-нибудь есть лучший способ сделать это?

Ответы [ 11 ]

0 голосов
/ 28 января 2016

У меня была та же проблема, и я, вероятно, потратил как минимум неделю на размышления о правильном моделировании данных, но я думаю, что наконец-то понял. Используя тип данных массива в PostgreSQL, вы можете хранить первичный ключ каждого упорядоченного элемента и соответствующим образом обновлять этот массив, используя вставки или удаления при изменении вашего заказа. Ссылка на одну строку позволит вам отобразить все ваши объекты на основе порядка в столбце массива.

Это все еще немного нестабильное решение, но оно, вероятно, будет работать лучше, чем вариант № 1, поскольку вариант 1 требует обновления порядкового номера всех остальных строк при изменении порядка.

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