替代在数据库表中使用排序顺序列

时间:2017-01-23 04:50:26

标签: sorting database-design django-models relational-database database-schema

this question类似,但这些答案都不理想。

考虑一下与PostgreSQL一起使用的Django模型:

class Parent(models.Model):
    id = models.AutoField(primary_key=True)

class Child(models.Model):
    id = models.AutoField(primary_key=True)
    parent = models.ForeignKey(Parent)

在SQL中(希望我的代码正确):

CREATE TABLE parent (
    id integer PRIMARY KEY
);

CREATE TABLE child (
    id integer PRIMARY KEY
    parent_id integer REFERENCES parent
);

如何才能对属于特定Child的{​​{1}}个对象进行重新排序?即,使用拖放UI,用户可以拖动Parent ren并保存更新的顺序。创建,更新和删除Child只需要一次操作,即不需要在Child上更新内容。

我有一些不完美的想法,原因是每个想法都不理想:

  1. 使用用户提供的varchar按字母顺序排序Parent - 这会强制用户考虑以某个字母或数字开头的名称,无需合理的理由需要大量的创造力。 / p>

  2. Child中,存储一个与Parent个对象的主键对应的整数数组 - 创建和删除操作需要多个操作,Child中的数组需要每次都更新。没有数据库强制执行数据完整性。

  3. 按整数列排序Parent - 创建Child时需要额外读取才能找到要使用的下一个整数。另一个问题(无论在生产中发生的可能性如何)是当整数之间的差距用完时,对象"背后"必须推回插入的对象。这种情况可以通过反复取出最后一个物体并将其放在第一位来人为强迫。

  4. 在每个Child中,存储引用下一个/上一个Child的整数id - 这解决了3.中的一些hacky问题,但这看起来非常低效,并且是一个后勤挑战

  5. 这个要求是否有任何雄辩的解决方案(不涉及额外加入或用Child替换第二个表格)?

1 个答案:

答案 0 :(得分:0)

如何将float用作排序顺序列。在项目之间插入/移动时,请将sortorder设置为(previus-item.sortorter + next-item.sortorder)/ 2。 这不会无限期地运行,但根据系统,你不应该遇到现实世界的问题。此外,您可以使用一项服务任务来重置您孩子的排序顺序中的差距。