2010-09-28 30 views
7

Tôi có một bảng hồ sơ người dùng. Mỗi người dùng có thể có nhiều hồ sơ và người dùng có khả năng sắp xếp thứ tự cách chúng sẽ được hiển thị trong một mạng lưới.Cách tốt nhất để lưu trữ thứ tự bản ghi trong SQL

Có 2 bảng Users and Profiles (1: M)

Tôi đã thêm một cột orderby vào bảng Users nơi sẽ giá trị như 1,2,3 ..

Cho đến nay nó có vẻ ổn. Nhưng khi một người dùng sẽ thay đổi thứ tự của bản ghi cuối cùng là người đầu tiên tôi phải trải qua tất cả các bản ghi và tăng giá trị của họ +1. Điều này dường như với tôi khá xấu xí.

Có giải pháp nào thuận tiện hơn cho loại tình huống này không?

Trả lời

3

Giải pháp tốt nhất là giải pháp gương và đó là danh sách các số nguyên đơn giản. Việc giữ danh sách theo thứ tự chỉ là một vài câu lệnh SQL và dễ hiểu hơn các giải pháp khác được đề xuất (nổi, số nguyên được gapped).

Nếu danh sách của bạn quá lớn (trong hàng chục nghìn) thì các cân nhắc về hiệu suất có thể phát huy, nhưng tôi cho rằng các danh sách này không dài.

+0

+1 Khi ngữ nghĩa của vấn đề phù hợp với vấn đề của giải pháp, sẽ có ít địa điểm hơn để ẩn. –

8

Để lại các khoảng trống trong chuỗi hoặc sử dụng số thập phân thay vì kiểu dữ liệu số nguyên.

+2

Tốt hơn là thứ hai. –

1

Khi người dùng thêm tiểu sử, hãy đặt số đơn đặt hàng của mỗi hồ sơ mới thành số trước +1000000. ví dụ. để bắt đầu với:

p1 1000000 
p2 2000000 
p3 3000000 

Khi sắp xếp lại, thiết lập trật tự của hồ sơ đến giữa hai nó sẽ ở giữa:

p1 1000000 
p2 2000000 
p3 1500000 

này cung cấp cho các p1 trật tự, p3, p2

3

Làm thế nào về việc sử dụng các điểm nổi cho đơn đặt hàng theo cột? Bằng cách này, bạn luôn có thể ép một hồ sơ giữa hai người khác, mà không cần phải thay đổi hai giá trị đó. Ví dụ: nếu tôi muốn đặt tiểu sử A giữa các tiểu sử B (ordervalue 1) và C (ordervalue 2), tôi có thể chỉ định ordervalue 1.5 đến A. Để đặt nó lên trên, nơi trước khi đầu sử dụng để có ordervalue nói 1, bạn có thể sử dụng ordervalue 0,5

Không có lý do gì để có số nguyên cho orderby và không có lý do để có gia số 1 giữa thứ tự cấu hình.

+0

+1 - Đánh bại tôi. – JNK

+4

Giả sử bạn có 3 bản ghi, bạn chỉ định số 1,2,3 cho chúng. Sau đó, bạn sắp xếp lại cái cuối cùng là giữa hai cái đầu tiên và nhận được số 1,5 cho nó. Sau đó lặp lại quy trình, và mỗi lần bạn sẽ đến gần 1, như 1,25, 1,125, v.v. Cho đến khi bạn đạt được giới hạn chính xác, và điều này đến rất sớm, 50 lần lặp lại. Sau đó, bạn có lỗi khó chịu ... :( – Hrissan

1

Tôi nghĩ rằng ý tưởng để lại những khoảng trống giữa các đơn đặt hàng là thú vị nhưng tôi không biết nếu nó là một giải pháp "thuận tiện hơn" cho vấn đề của bạn.

Tôi nghĩ rằng bạn sẽ tốt hơn hết chỉ cần cập nhật cột order by của bạn. Bởi vì bạn vẫn sẽ phải xác định những hàng nào các trạng thái đã di chuyển giữa, và phải làm gì nếu hai trạng thái được chuyển sang vị trí (Bạn có tính toán thứ tự mới theo giá trị cho vị trí đầu tiên sau đó thứ hai). Điều gì sẽ xảy ra nếu khoảng cách giữa không đủ lớn?

Nó không phải là dữ liệu chuyên sâu để chỉ liệt kê xuống thứ tự mà họ đặt nó vào và cập nhật từng bản ghi theo thứ tự.

2

Nếu tập dữ liệu nhỏ (có vẻ như vậy), tôi muốn sử dụng danh sách số nguyên bình thường và cập nhật chúng theo lô khi một cấu hình nhận vị trí mới.Điều này phản ánh tốt hơn chức năng ứng dụng.

Trong SQL Server, cho bảng sau User_Profiles (user_id, profile_id, position), tôi muốn có một cái gì đó như thế này:

--# The variables are: 
--# @user_id - id of the user 
--# @profile_id - id of the profile to change 
--# @new_position - new position that the profile will take 
--# @old_position - current position of the profile 

select @old_position = position 
from User_Profiles where 
user_id = @user_id and profile_id = @profile_id 

update p set position = pp.new_position 
from User_Profiles p join (
    select user_id, profile_id, 
    case 
    when position = @old_position then @new_position 
    when @new_position > @old_position then --# move up 
     case 
     when @old_position < position and 
      position <= @new_position 
     then position - 1 
     else position 
     end 
    when @new_position < @old_position then --# move down 
     case 
     when position < @old_position and 
      @new_position <= position 
     then position + 1 
     else position 
     end 
    else position --# the same 
    end as new_position 
    from User_Profiles p where user_id = @user_id 
) as pp on 
p.user_id = pp.user_id and p.profile_id = pp.profile_id 
0

Tôi nghĩ thay vì giữ trật tự trong orderby cột bạn có thể giới thiệu khái niệm LINKLIST để thiết kế của bạn. Thêm cột như nextId sẽ chứa cấu hình tiếp theo trong chuỗi. Khi bạn truy vấn bảng profiles, bạn có thể sắp xếp các cấu hình trong mã của mình (java, C#, v.v.)

Các vấn đề liên quan