我想让我的应用程序的用户定义一些(比方说的)电子邮件地址。然后我想让他们重新安排这些地址,因此主要地址位于顶部,次要地址位于其他地方等。
假设我在数据库中有一个UserEmailAddresses表,用于链接用户(UserId)和电子邮件地址(EmailAddressId)。
1)我应该使用哪种数据类型(int,float等)来保存按这些电子邮件地址排序的顺序?
2)当用户重新排列他们的位置时,更改这些序列号的查询效率是多少?它必须修改多条记录吗?
(我正在使用C#和Linq,但是psuedo-code welcome)。
答案 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