2015-08-28 29 views
1

的顺序。如果我有属性:fruit实体:存储实体

apple 
banana 
grapes 
tomato 

,并允许功能用户订购自己的水果:

1 grapes 
2 apple 
3 tomato 
4 banana 

是否有储存水果的好方法为了数据库,期望可以删除一个水果,一个结果增加,并且水果重新排序?

一个天真的解决方案是添加一个订单列。与此有关的问题是昂贵的更新。假设我有一个实体:1000000 durian。我突然决定这是我最喜欢的水果,并将它推到了顶峰。这导致999999水果需要订单更新。

+0

下面是一篇博客文章,介绍如何进行这种昂贵的更新:http://augustl.com/blog/2013/ordering_cardinality_many_in_datomic/ –

回答

1

在任何数据库中都没有内置的方法来实现您的目标,无论是PostgreSQL,Datomic还是其他任何内容。但是,有一个简单的答案。

只需将您建议的“优先级”列从整数转换为浮点值即可。然后,您总是可以在任何两个现有项目之间插入新条目,而无需更改任何内容。假设你开始

1.0 grape 
2.0 apple 
3.0 tomato 
4.0 banana 

,然后你决定增加一个peargrapeapple之间。只需插入如:

1.0 grape 
1.5 pear 
2.0 apple 
3.0 tomato 
4.0 banana 

你再决定grapepear之间插入cherry,使您得到:

1.0 grape 
1.25 cherry 
1.5 pear 
2.0 apple 
3.0 tomato 
4.0 banana 

然后,每当你想检查你的列表中,您只需取两者的优先级列和名称列,按优先级排序,然后完成。

+1

优先解决方案:请注意,随着列表的演变,逐步减半,像渐进式加倍,会很快耗尽甚至64位浮点数的精度。对于长期存在的任何事情,我都会有严肃的保留意见。 –

+0

如果你想成为真正的病态,你总是可以使用像'1.5M'这样的BigDecimal值。 –

+0

是的,但'病态'可能是描述非常大BigDecimals结果的极好方法;) –

3

简短的回答是否定的,Datomic没有这个内置的,并且公平的也没有其他许多数据库。

你有你提到的“订单”列方法,它也有你提到的问题。差距并不是最差的部分,因为你仍然可以通过一些差距获得正确的排序,如果你想在中间插入一个项目,情况会变得更糟,那么就会有来更新下列实体。除非您确定您的对等设备是单线程的,否则您应该在交易功能中完成所有操作。

还有链表方法,其中每个实体指向下一个,最后一个不指向任何东西。在中间追加,预先设定和切片成为恒定的操作。