单次写入订单项

时间:2018-04-24 12:08:03

标签: amazon-web-services database-design amazon-dynamodb

高级概述,使用简单的整数order值来表达我的观点:

   id (primary)   |    order (sort)   |    attributes .. 
----------------------------------------------------------
    ft8df34gfx             1                   ...
    ft8df34gfx             2                   ...
    ft8df34gfx             3                   ...
    ft8df34gfx             4                   ...
    ft8df34gfx             5                   ...

通常很容易更改order(例如,如果用户在前端拖放列表项):轮换项目,计算新的order值并更新数据库中受影响的项目新order

约束:

  • 一次没有所有项目,只有一部分(想想分页)
  • 如果移动单个项目(每班1个项目),则仅更新数据库中的单个项目

我最初的想法:

将纪元用作order并添加一些独特的内容,以避免重复的纪元时间,例如<epoch>#<something-unique-to-item>。初始值是插入时间(因此默认顺序是最新的)。

客户端/服务器(计算order的任何人)知道其所有项目子集中每个项目的纪元。

如果项目被移动,请查看上一个和下一个项目的时期(如果有上一个或下一个 - 可以移到第一个或最后一个),在两者之间选择一个值并更新。超过1班?重复这个过程。

可是..

  1. 如果项目移动的次数足够多,则纪元值会越来越接近,直到您找不到具有整数的中间地点。
    • 在插入时添加大量零到epoch?在某些时候仍然达到极限..
  2. 如果项目转移到第一个或最后一个并且上一页或下一页中有项目(请记住,分页),我们不知道这些值并且无法可靠地找到“值之间”。
    • 从上一页和下一页获取1个额外的隐藏项?查询变得复杂..
  3. 这甚至可能吗?我应该将哪种类型/值用作order

1 个答案:

答案 0 :(得分:0)

DynamoDB不允许为特定项目更改分区和排序键(要更改它们,需要删除项目并使用新键值重新创建),所以你可能会想要使用本地或全球二级索引。

假设您提到的分区/排序键是二级索引,我建议为订单存储自然数(1,2,3等),然后根据需要更新它们。

实际上,您需要考虑三种情况:

  • 添加新项目 - 您将使用ScanIndexForward = false(以反转结果顺序)对辅助分区键执行查询,并在“order”属性上进行投影,限制为1结果。到目前为止,这将为您提供最大订单价值。新商品的订单只是这个最大值+1。
  • 删除项目 - 一开始可能看起来很不安,但您可以自由删除项目而无需触及其他项目的订单。您的订购顺序可能有一些漏洞,但没关系。
  • 更改订单 - 实际上并没有办法解决问题;您的应用程序逻辑需要获取受影响项目的列表,并将所有新订单写入表中。如果以前的项目是(A,1),(B,2),(C,3)并且它们变为A,C,B,则您需要同时写入B和C以更新其订单所以他们最终成为(A,1),(C,2),(B,3)。