我“即将”在我的一个应用程序上实现一项功能,该功能需要存储大量数据(播放列表)。
假设以下场景:
播放列表条目由以下类表示:
public class Item {
private Long owner; // User
private String data;
private String name;
private String author;
private int index; // Index of this item on the list
}
Run Code Online (Sandbox Code Playgroud)
TL;DR:List< Item >对于每个用户(每个用户超过 1 个),此列表可以扩展到 500k+ 个条目。
目前,我为此使用了基于 SQL 的存储,但是,它很慢,特别是当我需要移动索引时 - 慢到我的数据库驱动程序认为连接失败并泄漏的程度。
解释“移位索引”:假设我正在删除第 3 个索引 ( i = 3)处的一个项目,这意味着它之后的所有其他项目都需要向下移动一个索引,因此我稍后可以请求索引 3 并获取该项目以前是索引 4。
目前,我会在Order删除后减少所有元素的播放列表的列值。
Id (Ordering/Index) | PlayList (Id) | Owner (User) | Name | Author | Data
Run Code Online (Sandbox Code Playgroud)
哪种方法可以更好/更有效地存储这种“批量”数据,同时仍然能够查询和修改它?
我可以为此类数据更改/实施新的数据库软件,因为它非常大(我目前使用 Redis 和 MariaDB)。但是,我很想避免这样做。
Vérace的答案是正确的,只是它忽略了每个用户可能拥有多个播放列表的事实。
所以这是我的桌子设计图。我将一个列名更改为“sort_order”,因为在数据库和编程中名称“index”会引起各种混乱。
基本上,我怀疑您没有注意到“播放列表”中的“列表”,将每个人的收藏夹列表与可能选择的完整列表混为一谈。每个播放列表都是对所需项目(歌曲、书籍或任何您的问题 - 在问题中不清楚)的引用的集合。
至于在现有行的排序顺序编号中插入新/更改的行时的性能问题,您可以显着降低此杂项的频率。
将您的排序顺序值增加一百、一千或一百万而不是一。您可以通过在现有行的编号之间分配一个排序顺序编号来插入新行,而无需进行任何移位。仅当 99 或 999 或 999,999 行碰巧已插入到递增行之间时,您才需要执行完整移位。在此之前,当出现带有中间数字的块时,您可能需要进行微调,但在行的小子集上,<100 或 <1,000 或 <1,000,000。
如果您需要向用户显示连续的 1、2、3……数字,请让数据库动态创建这些数字作为SELECT语句的一部分。