Django - 有序表

Yoa*_*rtz 3 python sql database django

我希望我的用户能够向数据库添加一个对象(在我的例子中是一个文件),并且该对象自动转到最后一个“位置”,稍后该用户将能够使用某种 UI 来更改该对象位于表格“上方”或“重新排序”。

同样的问题未得到解答: django & sql - how can I effective storage and update sort order information related to record in my database table?

显然,表没有顺序,它是数据表基础的一部分。阅读了一些帖子后,我发现我有两个选择:

  1. 代表该项目优先级的“order”整数值
  2. “下一个”指针使其成为有序列表。

对我来说,我从数据库中读取的次数比写入的次数多得多,所以我选择了第一个。我的问题是如何实现添加新文件、删除旧文件和更改顺序。

目前,正如我每次对数据库进行任何更改时看到的那样,我都必须调用 ORDER_BY 整数字段,然后:

  1. 删除:删除该项目并更新-1“订单”中紧随其后的所有内容
  2. 新:排序并给它与最后一项相同的编号+1
  3. 重新排序:给它超过的对象的“顺序”值,并更新+1以下的所有内容。

唯一的问题是,我觉得为每一个小变化进行调用和更改如此多的数据库行确实非常昂贵。还有其他办法吗?我确信这是一个非常常见的问题。

Joe*_*Joe 5

我要做的(以及我所做的)是存储一个“订单”字段。当您选择并按顺序取回记录时,可以按此栏进行排序。

至于如何插入和重新排序,那就要看数据量了。对于一个简单的“Todo”类型应用程序,其中您有 < 100 个项目(我从空中抓取了这个数字),加载这么多Model对象、更新它们的计数并保存它们没有任何问题。

如果您有模型排序列表,您可以使用以下命令更新顺序:

for i, model in enumerate(models):
    model.sort_order = i
    model.save()
Run Code Online (Sandbox Code Playgroud)

在优化方面:

  • 您的数字不必是连续的。如果删除一条记录,则不必修改任何其他记录,它们仍然按顺序排列。这就是一次操作。

  • 如果您想经常插入,那么您可以进行的一种优化是留下间隙(例如model.sort_order = i * 10),然后您就有空间可以在两条记录之间插入。如果空间不足,您可以根据您的用例采取以下两种策略之一:

    • 如果您经常插入,那么您可以重新编号,如上所述(留下更大的空间)。重新编号的成本很高,但您不必经常这样做

    • 如果不频繁插入,则可以将数字向下洗牌(即在插入的元素后增加数字)。在最坏的情况下,这与完全重新编号一样昂贵,但在平均情况下,成本会减半。

  • 如果你想交换两个项目,只需交换它们的排序顺序即可。这只需要两次更新。

因此,唯一需要更新 2 条以上记录的情况是当空间不足或想要完全更改所有记录的顺序时。

对于更大的列表,您可以编写一些自定义 SQL 来重新排列数字,但只有在开始注意到问题时才应该这样做。