我正在创建一个主键'UserID',复合键'DateTime'的表,然后我有以下值(注意:我不需要查询下面数据中的任何细节-只需写入和读取它):
UserID1
UserID2
Message
DateTime
问题:
- 存储这4个值作为单独的项目或作为一个JSON字符串有任何优势吗?
- UserID1和Datetime在存储值中也构成主/复合键-我是否正确假设在数据/值中存储这些没有意义,因为我可以在查询时从返回的键访问它?
所以你的选项是:
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
都是可行的选项,选择取决于您想要如何读取数据,如果每个项目都有一个属性,那么您可以单独请求这些属性。
根据我们的使用模式,我们倾向于使用混合方法。我们需要单独访问的元素被赋予了自己的属性。我们只希望与其他元素集合一起访问的元素都被赋予单个属性,然后存储为单个blob的JSON字符串或base64编码的数据。
对于第二部分,确实,您是对的,您不需要再次将用户id和日期时间存储为属性的一部分,因为它们是哈希值和范围键,在发出请求时返回。
-
您可以将条目存储在JSON blob中作为单独的AttributeValues。在DynamoDB引入JSON文档支持之前,您的选项将被限制为单独的属性,或者存储这些属性的JSON表示的一个"String"属性。既然Amazon向DynamoDB引入了JSON文档支持,您就可以将这种详细的属性映射直接存储在项中。使用DynamoDB的新Java文档SDK,使用Item.withJSON()方法添加JSON值,如下所示:
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获取项目,您需要这两个元素。
-
我假设你说的"单独的项目"是指"单独的属性",在这种情况下,这并不重要。我可能会将它们存储为单独的属性,因为可以检索属性的子集(尽管您说现在不需要此功能)。在将来,如果您想查看用户发送了多少消息,但不想等待慢速网络返回许多kb的消息,那么具有单独的属性将是有用的。
-
是的。
DynamoDB现在支持json对象直接存储。阅读:http://aws.amazon.com/blogs/aws/dynamodb-update-json-and-more/
您始终可以将数据存储为JSON并轻松查询。
{
sequence: "number",
UserID1: "id",
UserID2: "id",
Message: "message text",
DateTime: "1234567890"
}
我假设你的目的是某种消息传递系统。在本例中,UserID1 &UserID2不能是哈希键,因为很明显会有重复的条目(例如UserID1有多个消息)。
您可以有一个索引,它是排序的会话ID。
您可以在结构的[DateTime]部分上创建二级索引,以便您可以查询比某个给定时间戳更早的会话消息
使用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();
}