在SQL

问题描述:

我想看看是处理以下情形在SQL

我有一个名为表的最佳方式保存顺序优先性,可以说,用户,和我有一个表称为项目。每个用户可以将多个项目添加到他的帐户。我有另一个表,让我们说AssociateItem,它维护用户和项目之间的关联。 (将用户ID链接到ItemID)。用户可以有多个项目,因此用户和项目之间存在一对多的关系。这些项目的显示顺序很重要,并且用户从UI改变顺序(类似Netflix队列:))。所以我需要一种方法来在某个地方保存订单,让我们说偏好表。所以对于每个用户我可以保存显示顺序。

我想过一个简单的XML用于保存订单。比方说,一个用户,3项1和5在他的帐户,并显示顺序为3,5,1。我可以保持一个XML和改变它每次用户改变其显示的偏好

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

这似乎是一个笨拙这样做的方式。我不是数据库专家。所以如果有人可以提供更好的解决方案。我会很感激它。对不起,如果情况不是很清楚。

您可以在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是一个整数,那么你就需要将以下物品的所有SortNumbers更新到数+ 1

您可能能够欺骗并通过实数避免所有这些更新和在上一个和下一个项目SortNumbers之间的中点对新项目进行排序。

例如如果你想在序列中第2位置插入一些0,1,2,3你可以将其分配给0, 0.5, 1, 2, 3

然后,如果您想插入位置2处新的东西,你可以将其指定为0.25给人0, 0.25, 0.5, 1, 2, 3等。显然,这将数0.5当你没有足够的精确度来正确表示号码时停止工作,但对于小名单应该没问题。

+1

或者你可以建立一个触发来维持秩序。 – HLGEM 2009-12-07 18:12:51

我会考虑两个项目之间的链接表和(我认为)这是一个相当行业标准的方法。

所以你有一个名为“User”的表和一个名为“Items”的表。你会想创建一个名为“UserItems”的第三个表。

这个新表将有自己的主键,但包含两个外键;一个用于用户表,另一个用于物品表。按照您的要求,您还需要添加一列来存储优先级或顺序。

从前端,当用户添加一个项目并给它一个优先级时,您只需将一行添加到UserItems表中。重新分配优先级将更新一行等。

两点:

1)要回答你的问题,你可以保存在关联表的顺序。添加“OrderNumber”字段以及“userId”和“itemId”。保持该字段正如你暗示的那样使用xml。只有少数几个特定的​​实例需要在SQL驱动的Web应用程序的xml中维护数据,但这不是其中之一。将这些信息保存在数据库中以保持一致性和速度。

2)这看起来像是多对多的关系而不是一对多的关系。你明确指出,一个用户可以有很多项目,所以告诉我其中的一个选项。剩下的问题是一件物品是否属于许多客户?如果是这样,它是一个多对多,你需要AssociateItem表。但是,如果每个项目只能属于一个客户端,则您拥有一对多的关系,并且不需要AssociateItem表。将userId添加到items表中,并将新的“OrderNumber”字段直接添加到items表中。只是想一想。

+1

而不是OrderNumber,这通常意味着其他的东西,如何命名新的列ItemSequence? 用户和项目之间的关系可能是多对多的,但每个用户可能有不同的顺序,对吧? – DOK 2009-12-07 16:57:02

+0

对不起,实际上一个项目可以属于多个用户。所以它是一个多对多的关系 – user171034 2009-12-07 17:56:01

向项目表添加一个指定其顺序的列。 顺便说一句,你使用哪个DBMS?

+0

即时通讯使用MS SQL 2008 – user171034 2009-12-07 17:52:07

这是我会怎么模型,可以:

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) 
) 

的PK上User_Widgets是值得商榷的。如果他们一次只能在其队列中有一个特定小部件的实例,那么理论上可以将PK放在(user_id,widget_id)上。如果他们可以有排名关系,那么你可以把PK放在所有三列。这取决于业务需求。

如果您确实在PK中包含排名,请记住,它可能会使项目的排名变得更加困难。您通常会通过删除和插入更改而不是更新行来解决问题。例如,要交换等级4和等级5,您将删除两行,然后将这些项目重新添加到更正的等级中。我个人认为这不是一件坏事,但你需要牢记它。

这应该做到这一点;该订单属于useritem之间的关系。如果一个项目只能属于一个用户,请在ItemID in UserItem上额外添加唯一约束。

itemorder_model_01

+0

是的我在UserItem中有一个唯一的约束 – user171034 2009-12-07 17:49:55