2011-12-24 71 views
3

我有一個(Postgres)數據庫表,我想添加一個手動「排序」字段。在應用程序的前端,我將有一個拖放字段,以便用戶可以手動重新排序條目,然後發佈一個AJAX請求,重新排序數據庫中的條目,我只是想知道如何在數據庫中進行編排。數據庫模式:手動排序表的標準方式是什麼?

例如,我能想到的最明顯的選擇是增加每個條目的'sort'整數,排序值> =新排序的選項,但這會過度(並且我認爲,不必要地)如果這些列表超出了少數幾個項目,那麼數據庫就會很重。

另一種選擇是讓「排序」列一個BigDecimal,並使其價值

SortValue[A] = SortValue[B] + (SortValue[C] - SortValue[B])/2 

其中A是我重新排序場,B是場直接在上面它和C是它下面的字段,但這似乎是一個非常混亂的解決方案,更不用說可能受小數點限制。

我確定這是一個非常普遍的問題。有效地允許手動排序數據庫表的標準方法是什麼?

乾杯......

+0

我猜你希望用戶能夠手動排序;例如,將歌曲拖放到有序播放列表中。之後,您希望能夠以用戶選擇的順序訪問或顯示它們。對? – 2011-12-24 08:09:56

+0

是的,這是正確的 – PlankTon 2011-12-24 08:39:48

回答

5

假設你有這樣一些數據:

id | pos 
---+---- 
8 | 1 
3 | 2 
6 | 3 
7 | 4 
2 | 5 
1 | 6 

,你想從位置5移動2到3位

所有你需要做的是這樣的:

update t set pos = pos + 1 where pos >= 3 and pos < 5 

打個洞:

id | pos 
---+---- 
8 | 1 
3 | 2 
    | 
6 | 4 
7 | 5 
2 | 5 
1 | 6 

然後將此:

update t set pos = 3 where id = 2 

用於填充孔:

id | pos 
---+---- 
8 | 1 
3 | 2 
2 | 3 
6 | 4 
7 | 5 
1 | 6 

你會的,當然,都包裹在一個事務中的所有這些更新。

如果你有pos限制,以避免重複(一個好主意),那麼你可以使用pos = 0作爲臨時值:

update t set pos = 0 where id = 2; 
update t set pos = post + 1 where pos >= 3 and pos < 5; 
update t set pos = 3 where id = 2; 

或者,如果您使用的是最新的版本的PostgreSQL(據我所知9.0 +),你可以defer your unique constraint到交易結束,而不必擔心臨時重複。

其他案例是相似的,留作練習。

+0

乾杯畝...這樣做。 – PlankTon 2011-12-24 08:38:45

0

你暗示,有沒有屬性在所有用戶使用的數據進行排序。如果這是真的,那麼我猜你不必擔心列表的大小,並使用那個bigdecimal,或者只是間隔一些被調整的值的整數 - 「標準化」 - 回到適當的值時需要(當空間用完時)。

相關問題