Сохранение предпочтения порядка в SQL - PullRequest
3 голосов
/ 07 декабря 2009

Я пытаюсь понять, как лучше всего справиться со следующим сценарием

У меня есть таблица с именем, скажем, User, и у меня есть таблица с именем items. Каждый пользователь может добавить несколько элементов в свой аккаунт. У меня есть другая таблица, скажем, AssociateItem, которая поддерживает связь между пользователем и элементами. (связывает идентификатор пользователя с ItemID). Пользователь может иметь несколько элементов, поэтому между пользователем и элементами существует отношение один ко многим. Порядок, в котором отображаются эти элементы, важен, и пользователь меняет порядок с пользовательского интерфейса (что-то вроде очереди Netflix :)). Поэтому мне нужен способ сохранить заказ где-нибудь, скажем, в таблице предпочтений. поэтому для каждого пользователя я могу сохранить порядок отображения.

Я подумал о простом XML для сохранения заказа. Допустим, у пользователя есть элементы 1, 3 и 5 в его учетной записи, а порядок отображения - 3, 5, 1. Я могу поддерживать xml и изменять его каждый раз, когда пользователь изменяет свои настройки отображения

<order>
<item>3</item>
<item>5</item>
<item>1</item>
<order>

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

Ответы [ 6 ]

9 голосов
/ 07 декабря 2009

Вы можете добавить код заказа в таблицу AssociateItem. Затем вы можете получить товары, заказанные по этому номеру заказа.

, например

TABLE AssociateItem(UserId, ItemId, SortNumber)

SELECT * FROM User U
INNER JOIN AssociateItem AI ON U.UserId = AI.UserID
INNER JOIN Item I ON AI.ItemId = I.ItemId
ORDER BY AI.SortNumber

Беспорядочная часть возникает, когда вы хотите переместить элементы, так как вы хотите, чтобы числа были синхронизированы.

Если SortNumber является целым числом, вам нужно обновить все номера сортировки следующих элементов до числа +1.

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

например. Если вы хотите вставить что-то в позицию 2 последовательности 0,1,2,3, вы можете присвоить ей число 0,5, давая 0, 0.5, 1, 2, 3

Если затем вы хотите вставить что-то новое в позицию 2, вы можете назначить его как 0,25, давая 0, 0.25, 0.5, 1, 2, 3 и т. Д. Очевидно, это перестанет работать в точке, когда у вас недостаточно точности, чтобы правильно представить число, но это подойдет для небольших списков.

2 голосов
/ 07 декабря 2009

Вот как я бы смоделировал это:

CREATE TABLE Application_Users
(
     user_id     INT NOT NULL,  -- Maybe do without this if the user_name is unique
     user_name   VARCHAR(20) NOT NULL,
     ...
     CONSTRAINT PK_Application_Users PRIMARY KEY CLUSTERED (user_id)
)

CREATE TABLE Widgets     -- Items is a really bad table name generally
(
     widget_id     INT NOT NULL,
     widget_name   VARCHAR(20) NOT NULL,
     description   VARCHAR(2000) NOT NULL,
     ...
     CONSTRAINT PK_Widgets PRIMARY KEY CLUSTERED (widget_id)
)

CREATE TABLE User_Widgets
(
     user_id     INT NOT NULL,
     widget_id   INT NOT NULL,
     ranking     SMALLINT NOT NULL,
     CONSTRAINT PK_User_Widgets PRIMARY KEY CLUSTERED (user_id, ranking)
)

ПК на User_Widgets является дискуссионным. Если они могут иметь только один экземпляр определенного виджета в своей очереди за один раз, вы можете теоретически включить PK (user_id, widget_id). Если у них могут быть связи для ранжирования, вы можете поместить PK во все три столбца. Это зависит от бизнес-требований.

Если вы включаете ранжирование в PK, имейте в виду, что это может усложнить перемещение ранжирования по предметам. Обычно вы решаете проблему, удаляя и вставляя изменения, а не обновляя строки. Например, чтобы поменять местами ранги 4 и 5, нужно удалить обе строки, а затем добавить элементы обратно с исправленными рейтингами. Лично я не думаю, что это плохо, но вы должны помнить об этом.

2 голосов
/ 07 декабря 2009

Два очка:

1) Чтобы ответить на ваш вопрос, вы можете сохранить заказ в таблице ассоциации. Добавьте поле «OrderNumber» вместе с «userId» и «itemId». Сохраняйте это поле так же, как вы упоминали в xml. Есть только несколько конкретных случаев, когда вы хотите сохранить данные в формате XML в веб-приложении, управляемом SQL, и это не один из них. Сохраняйте эту информацию в базе данных для согласованности и скорости.

2) Это похоже на отношения «многие ко многим», а не «один ко многим». Вы дали понять, что у одного пользователя может быть много элементов, так что это говорит мне об одном из этих вариантов. Остается вопрос, может ли один товар принадлежать многим клиентам? Если это так, его многие-ко-многим, и вам нужна таблица AssociateItem. Однако, если каждый элемент может принадлежать только одному клиенту, то у вас есть отношение один ко многим, и вам не нужна таблица AssociateItem. Вместо этого добавьте userId в таблицу элементов, а также добавьте новое поле «OrderNumber» непосредственно в таблицу элементов. Просто о чем подумать.

0 голосов
/ 07 декабря 2009

Это должно сделать это; заказ относится к отношениям между user и item. Если элемент может принадлежать только одному пользователю, поместите дополнительное ограничение уникальное на ItemID in UserItem.

itemorder_model_01

0 голосов
/ 07 декабря 2009

Добавьте к таблице товаров столбец, в котором указан их порядок. Кстати, какую СУБД вы используете?

0 голосов
/ 07 декабря 2009

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

Итак, у вас есть таблица «Пользователь» и таблица «Предметы». Вы захотите создать третью таблицу с именем что-то вроде «UserItems».

Эта новая таблица будет иметь свой собственный первичный ключ, но затем будет содержать два внешних ключа; один в таблицу User и один в таблицу Items. Согласно вашему требованию вы также захотите добавить столбец для хранения приоритета или последовательности.

Из внешнего интерфейса, когда пользователь добавляет элемент и дает ему приоритет, вы просто добавляете строку в таблицу UserItems. Переназначение приоритета приведет к обновлению строки и т. Д. И т. Д.

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