Подтвердить что ты не робот

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

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

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

Очевидным способом было бы просто вставить некоторый OrderField, где я бы назначил число от 0 до N и отсортировал его таким образом.

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

(я использую С# 3,5 с NHibernate и SQL Server 2005)

Спасибо

4b9b3361

Ответ 1

FWIW, я думаю, что способ, которым вы предлагаете (т.е. совершение заказа в базе данных), не является плохим решением вашей проблемы. Я также считаю, что это самый безопасный/самый надежный способ.

Ответ 2

Хорошо, вот мое решение сделать программирование проще для тех, кто происходит с этим потоком. трюк может обновить все индексы заказов выше или ниже вставки/удаления в одном обновлении.

Использование числового (целочисленного) столбца в вашей таблице, поддерживаемого SQL-запросами

CREATE TABLE myitems (Myitem TEXT, id INTEGER PRIMARY KEY, orderindex NUMERIC);

Чтобы удалить элемент в orderindex 6:

DELETE FROM myitems WHERE orderindex=6;    
UPDATE myitems SET orderindex = (orderindex - 1) WHERE orderindex > 6;

Чтобы поменять два элемента (4 и 7):

UPDATE myitems SET orderindex = 0 WHERE orderindex = 4;
UPDATE myitems SET orderindex = 4 WHERE orderindex = 7;
UPDATE myitems SET orderindex = 7 WHERE orderindex = 0;

то есть. 0 не используется, поэтому используйте его как манекен, чтобы избежать двусмысленного элемента.

Вставить в 3:

 UPDATE myitems SET orderindex = (orderindex + 1) WHERE orderindex > 2;
 INSERT INTO myitems (Myitem,orderindex) values ("MytxtitemHere",3)

Ответ 3

Лучшее решение - это Doubly Linked list. O (1) для всех операций, кроме индексации. Ничто не может индексировать SQL быстро, но за исключением предложения where для нужного элемента.

0,10,20 типов терпят неудачу. Последовательность столбцов не работает. Столбец столбца с плавающей точкой выходит из строя при перемещении группы

Doubly Linked list - это те же операции для добавления, удаления, удаления группы, добавления группы, перемещения группы. Одиночный список ссылок тоже работает. По-моему, двойное соединение лучше с SQL. Для одного связанного списка требуется, чтобы у вас был весь список.

Ответ 4

Как использовать реализацию связанного списка? При наличии одного столбца будет удерживаться значение (номер заказа) следующего элемента. Я думаю, что это намного проще использовать при вставке заказов между ними. Не нужно менять нумерацию.

Ответ 5

К сожалению, для этого нет волшебной пули. Вы не можете гарантировать порядок любого оператора SELECT БЕЗ заказа order by. Вам нужно добавить столбец и программу вокруг него.

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

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

Ответ 6

Я бы не рекомендовал подход A, AA, B, BA, BB вообще. Там много дополнительной обработки, чтобы определить иерархию и вставить записи между ними, совсем не забавно.

Просто добавьте OrderField, integer. Не используйте пробелы, потому что тогда вам придется либо работать с нестандартным "шагом" на вашей следующей средней вставке, либо сначала вам нужно повторно синхронизировать свой список, а затем добавить новую запись.

Имея 0... N, легко изменить порядок, и если вы можете использовать методы Array или методы List вне SQL, чтобы повторно заказать коллекцию в целом, обновите каждую запись или вы сможете определить, где вы находитесь вставка и +1 или -1 каждая запись после или после нее соответственно.

Как только у вас будет небольшая библиотека, написанная для него, это будет кусок пирога.

Ответ 7

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

Если по линии вы обнаружите это ограничение из-за плохой производительности при вставках и обновлениях, тогда можно использовать поле varchar, а не целое число. Это позволяет довольно высокий уровень точности при вставке. например, для вставки между элементами "A" и "B" вы можете вставить элемент, упорядоченный как "AA". Это почти наверняка лишнее для корзины покупок.

Ответ 8

На уровне абстракции над корзиной. Элементы позволяют утверждать, что CartOrder (который имеет 1-n с CartItem), вы можете поддерживать поле с именем itemOrder, которое может быть только списком идентификаторов (PK) данных CartItem, разделенных запятыми. Это будет на уровне приложения, который вам требуется для синтаксического анализа и упорядочения моделей товаров. Большой плюс для этого подхода будет в случае перестановки заказов, не может быть изменений на отдельных объектах, но поскольку заказ сохраняется как поле индекса внутри строк таблицы позиций заказа, вам придется выпустить команду обновления для каждой из строки, обновляющие их поле индекса.  Пожалуйста, дайте мне знать ваши критические замечания по этому подходу, мне любопытно узнать, каким образом это может потерпеть неудачу.

Ответ 9

Я решил его прагматически следующим образом:

  • Порядок определяется в пользовательском интерфейсе.

  • Бэкэнд получает запрос POST, содержащий идентификаторы и соответствующую позицию каждого элемента в списке.

  • Я начинаю транзакцию и обновляю позицию для каждого идентификатора.

Готово.

Поэтому заказ дорого, но чтение упорядоченного списка супер дешево.

Ответ 10

Я бы рекомендовал хранить пробелы в номере заказа, поэтому вместо 1,2,3 и т.д. используйте 10,20,30... Если вам нужно просто вставить еще один элемент, вы можете поставить его на 15, а чем переупорядочивать все в этот момент.

Ответ 11

Хорошо, я бы сказал, что короткий ответ:

Создайте первичный ключ autoidentity в таблице корзин, затем вставьте строки в правильном порядке сверху вниз. Затем, выбрав из таблицы порядок с помощью столбца автоидентификации первичного ключа, вы получите тот же список. Делая это, вы должны удалить все предметы и повторно вставить, а затем в случае внесения изменений в содержимое корзины. (Но это все еще довольно чистый способ сделать это) Если это невозможно, перейдите к столбцу порядка, как это было предложено другими.

Ответ 12

Когда я использую Hibernate и вам нужно сохранить порядок @OneToMany, я использую Map, а не List.

@OneToMany(fetch = FetchType.EAGER, mappedBy = "rule", cascade = CascadeType.ALL)
@MapKey(name = "position")
@OrderBy("position")
private Map<Integer, RuleAction>    actions             = LazyMap.decorate(new LinkedHashMap<>(), FactoryUtils.instantiateFactory(RuleAction.class, new Class[] { Rule.class }, new Object[] { this }));

В этом примере Java position является свойством Integer RuleAction, поэтому порядок сохраняется таким образом. Думаю, в С# это будет выглядеть довольно похоже.