Я хотел бы включить пользователей моего приложения для определения нескольких (скажем) адресов электронной почты. Затем я хотел бы дать им возможность переупорядочить эти адреса, поэтому первичный адрес сверху, вторичный и т.д.
Предположим, что у меня есть таблица UserEmailAddresses в базе данных, которая связывает пользователя (UserId) и адрес электронной почты (EmailAddressId).
1) Какой тип данных (int, float и т.д.) я должен использовать для поля, которое будет содержать последовательность, в которой эти адреса электронной почты будут отсортированы с помощью?
2) Какой запрос был бы эффективен при изменении этих порядковых номеров, когда пользователь перестраивает свои позиции? Должен ли он изменять несколько записей?
(Я использую С# и Linq, но приветствую psuedo-code).
Вам нужно будет добавить целое поле, в котором хранится порядок сортировки адресов электронной почты.
По мере добавления новых адресов электронной почты им присваивается следующий идентификатор порядка сортировки. Если адрес нужно сортировать выше существующего адреса, я бы использовал инструкцию обновления для обновления всех адресов электронной почты с идентификаторами порядка сортировки, превышающими требуемый индекс порядка сортировки, а затем обновил переупорядоченный адрес электронной почты, чтобы иметь нужный индекс порядка сортировки.
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
Вот простой дизайн, который упрощает обработку "коллизий". Вам нужно только ОБНОВИТЬ одну строку для работы этого метода:
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
Код EDIT
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,'[email protected]',1,'1/1/2009')
INSERT INTO @UserEmailAddresses values (1,'[email protected]',2,'2/2/2009')
INSERT INTO @UserEmailAddresses values (1,'[email protected]',3,'3/3/2009')
INSERT INTO @UserEmailAddresses values (2,'[email protected]',1,'1/1/2009')
INSERT INTO @UserEmailAddresses values (2,'[email protected]',2,'2/2/2009')
--application updates one row, no locking or blocking
update @UserEmailAddresses set DisplaySeq=1,LastChgDate=getdate() where UserId=1 and EmailAddressId='[email protected]' --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