10

DynamoDB 的新手。

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

UserID1
UserID2
Message
DateTime

问题:

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

6 回答 6

8

所以你的选择是:

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 和日期时间存储为属性的一部分,因为它们是哈希和范围键,当您发出请求时会返回它们。

于 2013-01-04T12:35:38.373 回答
6
  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 来获取项目。

于 2014-10-10T22:03:27.977 回答
3

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

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

  2. 是的。

于 2012-12-31T06:53:23.057 回答
2

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

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

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

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

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

于 2015-07-02T18:38:15.453 回答
1

使用 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();

}
于 2017-07-06T16:18:41.290 回答