在数据库中存储“有序列表”的最佳方法是什么,以便更新它们(添加,删除和更改条目的顺序)很容易完成?
考虑一个数据库,其中包含用户和电影的表格。每个用户都有一个喜欢的电影列表。
由于许多用户都喜欢同一部电影,因此我将用户和电影分开,并使用第三张表连接它们,即用户电影。
usermovies包含用户和电影的ID以及“订单号”。订单号用于为用户订购电影列表。
例如,用户Josh可能有以下列表:
用户杰克可能有一个列表:
所以,他们分享一些最爱,但不一定按照相同的顺序。
我可以使用查询获取每个用户的电影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 :(得分:5)
结合/链接表以及用于电影和用户之间关联属性的附加列是实现与关联类的多个关联的标准方式 - 所以你所做的似乎是正确的。
关于插入/更新/删除的简易性,每次执行插入/更新/删除时,您都必须管理整个关联(用户电影FK的所有行)。 可能没有一种神奇/简单的方法可以做到这一点。
话虽如此,您还需要在事务中运行这些操作,如果您的应用程序具有多用户功能,则更重要的是在此联结表上有一个“版本”列。
答案 1 :(得分:5)
如果你不是在寻找一个“向上/向下移动”的解决方案,然后默认添加到列表的底部,这里还有一些指示:
将新行插入特定位置可以这样做:(在第3位插入)
UPDATE usermovies SET order_number = ordernumber + 1
WHERE ordernumber > 3 and user_id = ?;
INSERT INTO usermovies VALUES (?, 3, ?);
你可以用类似的方式删除:(删除位置6)
DELETE usermovies WHERE order_numer = 6 and user_id=?;
UPDATE usermovies SET order_number = ordernumber - 1
WHERE ordernumber > 6 and user_id = ?;
答案 2 :(得分:4)
除了其他人所说的内容之外,可以在单个UPDATE语句中重新排序现有收藏夹,如here所述。
链接的答案解释了两个项目的重新排序,但可以很容易地推广到任意数量的项目。
答案 3 :(得分: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
表格中添加/删除相关记录即可
要更改电影订单,只需更改与用户相关的order_number
表格中的所有user_movies
字段。