Поле базы данных последовательности и запрос на обновление порядка сортировки

2

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

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

1) Какой тип данных (int, float и т.д.) я должен использовать для поля, которое будет содержать последовательность, в которой эти адреса электронной почты будут отсортированы с помощью?

2) Какой запрос был бы эффективен при изменении этих порядковых номеров, когда пользователь перестраивает свои позиции? Должен ли он изменять несколько записей?

(Я использую С# и Linq, но приветствую psuedo-code).

Теги:
types
database-design
linq-to-sql

2 ответа

3
Лучший ответ

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

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

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
  • 0
    Я полагаю, мне нужно запросить самый большой порядковый номер, прежде чем добавить новый адрес тоже. Похоже, я выбрал чертовски из БД таким образом ... это только цена за эту функциональность?
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

Код 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
  • 0
    Это довольно умно ... однако, скажем, я изменил два адреса, чтобы они были "верхним" адресом, каждый с DisplaySeq 1, но с разным временем, чтобы различать их. Теперь, допустим, я хочу разместить третий адрес в месте № 2 (между первыми двумя) ... Я не вижу способа сделать это с вашим предложением.
  • 0
    это зависит от вашего пользовательского интерфейса. если вы отображаете таблицу, где каждый телефонный номер находится в отдельной строке, и вы позволяете им вводить значение сортировки в текстовом поле, и они хотят иметь несколько повторяющихся значений одновременно, сортировка будет выполнена так, как вы описали. но если они входят в них однозначно, это не проблема. Если вы хотите, чтобы программа исправила порядок последовательности, вам всегда нужно запускать дополнительное обновление.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню