2012-06-13 44 views
14

將「有序列表」存儲在數據庫中的最佳方式是什麼,以便更新它們(添加,刪除和更改條目順序)很容易完成?將有序列表存儲在數據庫中的最佳方法?

考慮一個數據庫,其中有一張用戶和電影的表格。每個用戶都有一個喜歡的電影列表。

由於許多用戶可以喜歡同一部電影,因此我將用戶和電影製作成單獨的表格,並使用第三個表格將它們與用戶電影相連接。

usermovies包含用戶和電影的id以及「訂單號」。訂單號用於爲用戶訂購電影列表。

例如,用戶喬希可能有以下列表:

  1. 普羅米修斯
  2. 黑衣人3
  3. 獨裁者

和用戶傑克可能有這樣的列表:

  1. 獨裁者
  2. 普羅米修斯
  3. 戰艦
  4. 白雪公主與獵人

因此,他們分享一些我的最愛,但不一定以相同的順序。

我可以使用查詢獲取電影ID列表中的每個用戶:

SELECT movie_id FROM usermovies WHERE user_id =? ORDER BY order_number 

然後,有序movie_ids,我可以用另一個查詢

SELECT name FROM movies WHERE id in (?,?,?) ORDER BY FIELD (id, ?,?,?) 

獲得電影列表所以查詢工作,但更新列表似乎現在真的很複雜 - 是否有更好的方式來存儲這些信息,以便很容易地獲得用戶x的電影列表,添加電影,刪除它們並更改列表的順序?

+0

要獲得所有的電影你可以使用一個用戶一個 像這樣的單個查詢:'SELECT name FROM movies INNER JOIN usermovie ON usermovie.movi​​e_id = movies.id AND usermovie.user_id =? ORDER BY usermovie.order_number'。我不明白目前的做法有什麼困難?要將電影添加到用戶,只需在鏈接表中插入一個新條目並將其刪除即可刪除條目。 – Cyclonecode

+0

謝謝!這會很方便,但我的真正問題在於更新。 – wannabeartist

回答

5

對於電影和用戶之間的關聯屬性,帶有附加列的聯結/鏈接表是實現與關聯類的多關聯的標準方式 - 因此,您所做的事似乎是正確的。

關於插入/更新/刪除的簡易性,每次執行插入/更新/刪除操作時都必須管理整個關聯(用戶電影FK的所有行)。 有可能不是一個神奇/簡單的方法來做到這一點。

話雖如此,您還需要在事務中運行這些操作,如果您的應用程序具有多用戶功能,則更重要的是在此交接表上有一個「版本」列。

+0

實際上,*有*這樣的「神奇」的方式來完成改變只有一行而不是所有行的任務:http://stackoverflow.com/a/3399334/2947812 –

3

檢索用戶收藏的電影,你可以使用一個單一的查詢:

SELECT um.order_number, m.name FROM movies m 
INNER JOIN usermovies um ON m.id = um.movie_id 
WHERE um.user_id = ? 
ORDER BY um.order_number 

要添加/移除一個最喜歡的電影只需添加/刪除相關記錄在usermovies表。
要更改電影訂單,只需更改與用戶相關的user_movies表中的所有order_number字段。

+0

謝謝, 我仍然不確定如何處理這些更改:例如,刪除第一部電影也意味着更改所有其他電影的順序號,不是嗎? – wannabeartist

+0

@wannabeartist:是的,當然 – Marco

+0

那麼在更新時重新創建列表是否有意義,而不是更新單個行? 例如,用戶x取他的名單,進行更改並點擊「保存」 - > 1.先前的條目一次刪除 2.新條目一次插入 – wannabeartist

4

除了別人的說法之外,重新排序現有的收藏夾可以在單個UPDATE語句中完成,如here所述。

鏈接的答案解釋了兩個項目的重新排序,但可以很容易地推廣到任意數量的項目。

3

如果你是不是在找一個「向上/向下移動」有點溶液中,然後默認爲在列表的底部加入,這裏有幾個指針:

插入新行到一個特定的位置可以這樣做:

UPDATE usermovies SET order_number = ordernumber + 1 
    WHERE ordernumber > 3 and user_id = ?; 
INSERT INTO usermovies VALUES (?, 3, ?); 

(第3位的插入),你可以以類似的方式刪除:(刪除位置6)

DELETE usermovies WHERE order_numer = 6 and user_id=?; 
UPDATE usermovies SET order_number = ordernumber - 1 
    WHERE ordernumber > 6 and user_id = ?; 
相關問題