序列数据库字段和查询以更新排序顺序

时间:2009-07-02 15:46:26

标签: c# linq-to-sql database-design types

我想让我的应用程序的用户定义一些(比方说的)电子邮件地址。然后我想让他们重新安排这些地址,因此主要地址位于顶部,次要地址位于其他地方等。

假设我在数据库中有一个UserEmailAddresses表,用于链接用户(UserId)和电子邮件地址(EmailAddressId)。

1)我应该使用哪种数据类型(int,float等)来保存按这些电子邮件地址排序的顺序?

2)当用户重新排列他们的位置时,更改这些序列号的查询效率是多少?它必须修改多条记录吗?

(我正在使用C#和Linq,但是psuedo-code welcome)。

2 个答案:

答案 0 :(得分:3)

您需要添加一个整数字段,用于存储电子邮件地址的排序顺序。

随着新电子邮件地址的添加,他们会被分配下一个排序顺序ID。如果地址需要在现有地址之上排序,我将使用更新语句更新排序顺序ID大于所需排序顺序索引的所有电子邮件地址,然后更新重新排序的电子邮件地址以获得所需的排序顺序索引。

Table Schema
-----------------------
EmailID INT primary Key //Auto increment
EmailAddress Varchar(N)
SortOrderIdx INT //This would control your display order
UserID INT //This would be the owner of this particular email list

Email Create Statement
-----------------------
SELECT @NewSortOrdrIdx = MAX(SortOrderIdx)+1
FROM EmailTable 
WHERE UserId = @UserID

INSERT INTO EmailTable (EmailAddress, SortOrderIdx, UserID)
VALUES (@EmailAddress, @NewSortOrdrIdx, @UserID)

Email Reorder Statement
-----------------------
UPDATE EmailTable
SET SortOrderIdx = SortOrderIdx + 1
WHERE SortOrderIdx >= @desired_Sort_Order_Idx AND UserID = @UserID

UPDATE EmailTable
SET SortOrderIdx = @desired_Sort_Order_Idx
WHERE EmailID = @resorted_Email_ID AND UserID = @UserID

Email Select Statement
-----------------------
SELECT EmailAddress 
FROM EmailTable
WHERE UserID = @UserID
ORDER BY SortOrderIdx ASC

答案 1 :(得分:1)

这是一个简单的设计,简化了“碰撞”的处理。您只需更新一行即可使用此方法:

UserEmailAddresses Table
------------------------
YourPKHere        <whatever you have, identity?>
UserId            <whatever you have>
EmailAddressId    <whatever you have>
DisplaySeq        INT
LastChgDate       datetime


SELECT * FROM UserEmailAddresses ORDER BY DisplaySeq ASC, LastChgDate DESC

编辑示例代码

DECLARE @UserEmailAddresses table
(
     YourPKHere        int identity(1,1) primary key
    ,UserId            int
    ,EmailAddressId    varchar(100)
    ,DisplaySeq        INT
    ,LastChgDate       datetime
)

--existing data
INSERT INTO @UserEmailAddresses values (1,'one@one.com',1,'1/1/2009')
INSERT INTO @UserEmailAddresses values (1,'two@two.com',2,'2/2/2009')
INSERT INTO @UserEmailAddresses values (1,'three@three.com',3,'3/3/2009')
INSERT INTO @UserEmailAddresses values (2,'one2@one2.com',1,'1/1/2009')
INSERT INTO @UserEmailAddresses values (2,'two2@two2.com',2,'2/2/2009')

--application updates one row, no locking or blocking
update @UserEmailAddresses set DisplaySeq=1,LastChgDate=getdate() where UserId=1 and EmailAddressId='two@two.com' --could say WHERE YourPKHere=n, but you don't give your complete table schema


--display the emails in proper order, with displayable continuous row numbers
SELECT 
    *, ROW_NUMBER() over(partition by UserId order by DisplaySeq ASC,LastChgDate DESC) AS ActualDuisplaySeq
    FROM @UserEmailAddresses
    WHERE UserId=1

--display the e-mails in proper order
SELECT * FROM @UserEmailAddresses Where UserId=1 ORDER BY DisplaySeq ASC, LastChgDate DESC