Упорядоченные списки в Django - PullRequest
13 голосов
/ 09 января 2009

У меня очень простая проблема. Мне нужно создать модель, которая представляет элемент упорядоченного списка. Эта модель может быть реализована так:

class Item(models.Model):
    data = models.TextField()
    order = models.IntegerField()

или как это:

class Item(models.Model):
    data = models.TextField()
    next = models.ForeignKey('self')

Какой способ предпочтительнее? Какие недостатки есть у каждого решения?

Ответы [ 3 ]

21 голосов
/ 09 января 2009

По сути, второе решение, которое вы предлагаете, - это связанный список. Связанные списки, реализованные на уровне базы данных, обычно не очень хорошая идея. Чтобы получить список n элементов, вам потребуется n доступ к базе данных (или использование сложных запросов). С точки зрения производительности извлечение списка в O (n) ужасно неэффективно.

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

UPDATE item.order = item.order + 1 FROM item WHERE order > 3
INSERT INTO item (order, ...) VALUES (3, ...)

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

Подводя итог, определенно используйте решение № 1 и держитесь подальше от решения № 2, если у вас нет очень веских причин не делать этого!

6 голосов
/ 09 января 2009

Это зависит от того, что вы хотите сделать.

Первый, кажется, лучше сделать один запрос в базе данных и получить все данные в правильном порядке

Второй, кажется, лучше вставить элемент между двумя существующими элементами (потому что в первом вам придется изменить много элементов, если числа последовательные)

Я бы использовал первый, потому что он, кажется, лучше подходит для таблицы базы данных, именно так django хранит данные модели за укрытием.

0 голосов
/ 09 января 2009

Есть и другое решение.

class Item(models.Model):
    data = models.TextField()

Вы можете просто выбрать или собрать список Python в поле данных и загрузить его. Это хорошо для обновления и чтения, но не для поиска, например выборка всех списков, которые содержат определенный элемент.

...