DynamoDB + 将值存储为项目或 JSON

Posted

技术标签:

【中文标题】DynamoDB + 将值存储为项目或 JSON【英文标题】:DynamoDB + Store Values as Items or JSON 【发布时间】:2012-12-14 18:07:45 【问题描述】:

DynamoDB 新手。

我正在使用主键“UserID”、复合键“DateTime”创建一个表,然后我将以下值作为值(注意:我不需要查询以下数据中的任何细节 - 只需编写和阅读):

UserID1
UserID2
Message
DateTime

问题:

    将这 4 个值存储为单独的项目或存储为一个 JSON 字符串有什么好处? 存储值中的 UserID1 和 Datetime 也构成主键/复合键 - 我是否正确假设将这些存储在数据/值中没有意义,因为我可以在查询时从返回的键中访问它?

【问题讨论】:

【参考方案1】:

所以你的选择是:

Hash Key | Range Key  | Attributes
----------------------------------
user id  | utc time   | json data
----------------------------------
user123  | 1357306017 | UserID1:0, UserID2:0, Message:"", DateTime:0

Hash Key | Range Key  | Attributes
--------------------------------------------------------------
user id  | utc time   | UserID1 | UserID2 | Message | DateTime
--------------------------------------------------------------
user123  | 1357306017 | 0       | 0       | ""      | 0

两者都是可行的选择,选择取决于您希望如何读取数据,如果您对每个项目都有一个属性,那么您可以单独请求这些属性。

我们倾向于根据我们的使用模式使用混合方法。我们需要单独访问的元素被赋予了它们自己的属性。我们只想访问的元素以及其他元素的集合都被分配一个属性,然后存储为 JSON 字符串的单个 blob 或 base64 编码数据。

确实,对于第二部分,您是对的,您不需要再次将用户 ID 和日期时间作为属性的一部分存储,因为它们是哈希和范围键,当您发出请求时会返回它们。

【讨论】:

【参考方案2】:

    您可以将 JSON blob 中的条目存储为单独的 AttributeValue。在 DynamoDB 引入 JSON 文档支持之前,您的选项将仅限于单独的属性,或者一个“字符串”属性,您可以在其中存储这些属性的 JSON 表示。现在亚马逊为 DynamoDB 引入了 JSON 文档支持,您可以将这种详细的属性映射直接存储在项目中。使用适用于 DynamoDB 的新 Java 文档 SDK,添加 JSON 值使用 Item.withJSON() 方法,如下所示:

    DynamoDB dynamodb = new DynamoDB(client);
    Table messagesTable = dynamodb.getTable("MESSAGES");
    
    // create the item
    Item item = new Item().withString("UserID", "user123").withString("DateTime", "1357306017")
        .withJSON("Details", " \"UserID1\": 0, \"UserID2\": 0, \"Message\": \"my message\", \"DateTime\": 0");
    
    // put the item
    messagesTable.putItem(item);
    
    // get the item
    Item itemGet = messagesTable.getItem(new KeyAttribute("UserID", "user123"), new KeyAttribute("DateTime", "1357306017"));
    

    我同意 Pooky 的观点,即无需在详细信息映射中复制 Hash+Range 键。您需要这两者才能使用 GetItem 来获取项目。

【讨论】:

您是否有示例或代码 sn-p 用于 javascript 如何发布 JSON 文档。另外,我在 aws 网站上找不到关于使用 JSON 的 Javascript 的文档。我听说了一周前刚刚发布的这项新功能。【参考方案3】:

    我假设“单独的项目”是指“单独的属性”,在这种情况下它并不重要。我可能会将它们存储为单独的属性,因为可以检索属性的子集(尽管您说您现在不需要此功能)。将来,如果您想查看用户发送了多少消息,但又不想等待慢速网络返回许多 KB 的消息,那么拥有单独的属性会很有用。

    是的。

【讨论】:

只是为了遵循上下文术语:检索属性子集 = Projection【参考方案4】:

DynamoDB 现在支持 json 对象直接存储。阅读:http://aws.amazon.com/blogs/aws/dynamodb-update-json-and-more/

【讨论】:

这篇博文现在过时了吗?其中的代码看起来不像我在任何地方看到的任何其他代码【参考方案5】:

您始终可以将数据存储为 JSON 并轻松查询。


  sequence: "number",
  UserID1: "id",
  UserID2: "id",
  Message: "message text",
  DateTime: "1234567890"

我假设您的目的是某种消息传递系统。 在这种情况下,UserID1 和 UserID2 不能是 Hash Key,因为您显然会有重复的条目(例如 UserID1 有多个消息)。

您可以有一个索引,它是一个排序的会话 ID。

然后,您可以在结构的 [DateTime] 部分创建二级索引,以便查询该会话的早于某个给定时间戳的消息。

【讨论】:

【参考方案6】:

使用 DynamoMapper,您可以在 Java 中执行此操作:

@DynamoDBTable(tableName = "myClass")
public class MyClass 

    @DynamoDBHashKey(attributeName = "id")
    private String id;

    @DynamoDBRangeKey(attributeName = "rangeKey")
    private long rangeKey;

    @DynamoDBTypeConvertedJson
    private Content content;


内容类可以是:

public class Content 

    @JsonProperty
    private List<Integer> integers = new ArrayList();

    @JsonProperty
    private List<String> strings = new ArrayList();


【讨论】:

以上是关于DynamoDB + 将值存储为项目或 JSON的主要内容,如果未能解决你的问题,请参考以下文章

DynamoDB 核心组件

如何在AWS DynamoDB中存储图像配置文件(jpg文件)和PDF文档?

Aurora vs Redshift vs DynamoDB for Indie Game Backend?

如何在dynamoDB,嵌套字典或多个项目中构建数据?

dynamodb 中的查询与扫描操作

DynamoDB - 如何计算查询的读取吞吐量