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

DynamoDB 新手。

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

UserID1
UserID2
Message
DateTime

问题:

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

【问题讨论】:

    标签: database-design amazon-dynamodb amazon


    【解决方案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】:
      1. 您可以将 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"));
        
      2. 我同意 Pooky 的观点,即无需在详细信息映射中复制 Hash+Range 键。您需要这两者才能使用 GetItem 来获取项目。

      【讨论】:

      • 您是否有示例或代码 sn-p 用于 Javascript 如何发布 JSON 文档。另外,我在 aws 网站上找不到关于使用 JSON 的 Javascript 的文档。我听说了一周前刚刚发布的这项新功能。
      【解决方案3】:
      1. 我假设“单独的项目”是指“单独的属性”,在这种情况下它并不重要。我可能会将它们存储为单独的属性,因为可以检索属性的子集(尽管您说您现在不需要此功能)。将来,如果您想查看用户发送了多少消息,但又不想等待慢速网络返回许多 KB 的消息,那么拥有单独的属性会很有用。

      2. 是的。

      【讨论】:

      • 只是为了遵循上下文术语:检索属性子集 = 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();
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多