【发布时间】:2014-01-08 16:18:08
【问题描述】:
我正面临一个反复出现的问题。我必须让用户重新排序一些存储在数据库中的列表。
我能想到的第一个直接的方法是有一个“位置”列,其中的排序保存为整数。 p.e.
Data, Order
A 1
B 2
C 3
D 4
这里的问题是,如果我必须在位置 2 中插入 FOO,现在我的表变成了
Data, Order
A 1
FOO 2
B 3
C 4
D 5
所以要插入一个新行,我必须对一个包含五个元素的表执行一个 CREATE 和三个 UPDATE。
所以我的新想法是使用实数而不是整数,我的新表变成了
Data, Order
A 1.0
B 2.0
C 3.0
D 4.0
如果我想在 A 之后插入一个元素 FOO,这就变成了
Data, Order
A 1.0
FOO 1.5
B 2.0
C 3.0
D 4.0
只执行了一个 SQL 查询。
这适用于理论实数,但浮点数的精度有限,我想知道这是多么可行,我是否以及如何优化它以避免通过合理数量的修改来避免超过双精度
编辑:
这就是我现在在 python 中实现它的方式
@classmethod
def get_middle_priority(cls, p, n):
p = Decimal(str(p))
n = Decimal(str(n))
m = p + ((n - p)/2)
i = 0
while True:
m1 = round(m, i)
if m1 > p and m1 < n:
return m1
else:
i += 1
@classmethod
def create(cls, data, user):
prev = data.get('prev')
if prev is None or len(prev)<1:
first = cls.list().first()
if first is None:
priority = 1.0
else:
priority = first.priority - 1.0
else:
prev = cls.list().filter(Rotator.codice==prev).first()
next = cls.list().filter(Rotator.priority>prev.priority).first()
if next is None:
priority = prev.priority + 1.0
else:
priority = cls.get_middle_priority(prev.priority, next.priority)
r = cls(data.get('codice'),
priority)
DBSession.add(r)
return r
【问题讨论】:
-
用户对数据应该如何排序的解释是什么?
-
您实际期望插入多少次?
-
对我来说,这听起来像是您试图创建一个链接列表?为什么不存储 parentId 并使用 CTE 递归生成排序列表?
-
这不仅关乎插入,还关乎利用现有数据。我想要尽可能强大的东西。
-
如果你想控制一些不是 ORDER BY 的自然结果的用户定义的订单,那么你需要指向下一个项目。