0

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对象属于特定Parent可以重新排序吗?即使用拖放UI,用户可以拖动Child ren并保存更新的排序。创建,更新和删除Child应只需要一次操作,即不应要求更新Parent上的内容。

我有原因的一些不完善的想法,为什么每个想法并不理想:

  1. 排序Child字母顺序由用户提供的VARCHAR - 这会强制用户想开始具有一定的字母名称或数字,因为没有正当理由而需要大量的创造力。

  2. Parent,存储对应于Child对象的主键的整数数组 - 需要一个以上的操作创建和删除,在Parent阵列将需要每次都被更新。没有数据库强制数据完整性。

  3. 按整数列排序Child - 创建Child以查找要使用的下一个整数时需要额外读取。另一个问题(无论在生产中发生的可能性不大),当​​整数之间的差距用完时,插入对象“落后”的对象必须被推回。这种情况可以通过反复考虑最后一个对象并把它放在第一位来人为地强制。

  4. 在每个Child中,存储引用下一个/前一个的整数ID Child - 这解决了一些来自3.的hacky问题,但它看起来荒谬的是效率低下,并且是后勤方面的挑战。

是否有此规定(即不涉及另外加入或与jsonb替换第二表)任何雄辩的解决方案?

+1

使用3.您描述的问题是真实的,但可能并不重要,除非您每个父母的孩子数量非常多。 –

回答

0

如何使用float作为排序顺序列。当您插入/移动到项目时,将sortorder设置为(previus-item.sortorter + next-item.sortorder)/ 2. 这不会无限运行,但取决于系统,您不应该遇到现实世界问题。此外,你可以有一个服务任务,在你的孩子的整理顺序中重置空白。

+0

如果我不想要一夜之间的服务任务,最终浮动将会用完精确度,并且会默默无闻地维持秩序。这与整数的问题是一样的,唯一不同的是浮点数更容易使用,但是它在什么时候会“缺口”模糊不清。 – dtgq