use*_*021 15 database-design couchdb transactions atomicity data-structures
我在couchdb文档中有一个列表元素.假设这些是3个文档中的3个元素:
{ "id" : "783587346", "type" : "aList", "content" : "joey", "sort" : 100.0 }
{ "id" : "358734ff6", "type" : "aList", "content" : "jill", "sort" : 110.0 }
{ "id" : "abf587346", "type" : "aList", "content" : "jack", "sort" : 120.0 }
视图检索所有"aList"文档并按"sort"排序显示它们.
现在我想移动元素,当我想将"jack"移动到中间时,我可以在一次写入中执行此原子操作并将其排序键更改为105.0.视图现在以新的排序顺序返回文档.
经过大量的排序后,我可能会在几年后使用50.99999和50.99998之类的排序键,并且在极端情况下会耗尽数字?
您能推荐什么,有更好的方法吗?我宁愿将这些元素保存在单独的文档中.不同的用户可以并行编辑不同的列表元素.
用户也可能同时更改文档顺序(当2个用户想要将两个不同的文档(如joey和jill)移动到最后时,也可能会变得棘手,让我们说"sort"= 130.0同时).
也许有更好的方法?
我错过了CouchDb交易的内容吗?
Jas*_*ith 20
您正在使用实数的通用模式来进行用户对排序的控制.这是一个很好的技术,Damien Katz推荐.相邻的文档之间进行切换A,并B,然后您将设置sort场平均的A.sort和B.sort.
这个问题有几个部分.
Javascript Number是双精度IEEE-754浮点数.它们的精度有限.
双打有很多精确度.如果这是人为启动的活动,那么在拖放达到极限之前将是很长时间.但你有两个选择:
还记得在BASIC中重写你的行号吗?一样.
有一个cron作业或其他任务(NodeJS越来越流行)来检查不可接受的接近排序值并将它们分开.这可以使用复杂的启发式,例如:
sortssort的时间之前处于非活动状态X时间sort值超出但不会更改视图结果.换句话说,如果你有0.001,0.002和0.003,将第0.003一个移到eg 0.100,然后0.002改为0.005.这可能会对用户界面产生轻微的帮助,但请记住,复制可能不会以相同的顺序复制这些,因此利益是微不足道的,也许不值得复杂.它可以存储一个字符串,
 但不包括通过(例如,100个数字),而不是sort存储Javascript .然后字符串排序也是数字排序.(你有0.0和1.0的"锚点"对文档无效.要在第一个位置插入文档,设置为0.0的平均值和当前的第一个文档.对于最后一个位置,是最后一个文档的平均值和1.0.)Number "0.0""1.0"sortsort
接下来,您的客户端(无论谁计算该sort值)都需要任意精度的实数类型.Java,Ruby,Python,几乎所有语言都有它们.这篇文章甚至激励我制作一个快速项目,
 BigDecimal for Javascript,这是BigDecimal
来自Google Web Toolkit 的代码(它本身来自Apache Harmony).但也有其他实现.
我个人喜欢BigDecimal.但是,在您的情况下,您必须更改代码以使用字符串sort.然而,好处是,您永远不必重新规范化sorts以解决精度问题.
CouchDB很轻松.会发生什么是用户期望的.CouchDB文档模仿现实世界.正如克里斯安德森所说,"现实生活中没有任何交易."
对于UI中的三个元素:
如果我移动A后C你移动BC怎么办?显然,该列表将是
 C B A或C A B.应该是哪个?这取决于你的申请?
要么,没关系:太好了!CouchDB将任意订购A,B你会没事的.用户将推断(或查看您的UI是否良好)其他人移动了其他项目.
或者,B必须在A之前来,因为[某种原因]:那么,你的sort价值是错误的.它应包括所有相关数据以决定子类别.例如,你可以
 emit([120.000, doc.userLastName], doc).当用户将文档移动到同一位置时,排序将按字母顺序排列.
如果你说,A移动后不能很快移动A那么这也是必须实现的应用程序代码,无论数据存储如何.换句话说,它不是事务性的东西,而是软件逻辑.对于拖放UI元素,我的感觉是,它不值得,"无关紧要"的解决方案是最好的.