DynamoDB 的新手。
我正在使用主键“UserID”、复合键“DateTime”创建一个表,然后我将以下值作为值(注意:我不需要查询以下数据中的任何细节 - 只需编写和阅读它) :
UserID1
UserID2
Message
DateTime
问题:
- 将这 4 个值存储为单独的项目或一个 JSON 字符串有什么好处吗?
- 存储值中的 UserID1 和 Datetime 也构成主/复合键 - 我是否正确假设将这些存储在数据/值中没有意义,因为我可以在查询时从返回的键中访问它?
DynamoDB 的新手。
我正在使用主键“UserID”、复合键“DateTime”创建一个表,然后我将以下值作为值(注意:我不需要查询以下数据中的任何细节 - 只需编写和阅读它) :
UserID1
UserID2
Message
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
两者都是可行的选择,并且选择取决于您希望如何读取数据,如果您对每个项目都有一个属性,那么您可以单独请求这些属性。
我们倾向于根据我们的使用模式使用混合方法。我们需要单独访问的元素被赋予了它们自己的属性。我们只想访问的元素以及其他元素的集合都被分配了一个属性,然后存储为 JSON 字符串的单个 blob 或 base64 编码数据。
对于第二部分,确实,您是对的,您不需要再次将用户 ID 和日期时间存储为属性的一部分,因为它们是哈希和范围键,当您发出请求时会返回它们。
您可以将 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 来获取项目。
DynamoDB 现在支持 json 对象直接存储。阅读:http ://aws.amazon.com/blogs/aws/dynamodb-update-json-and-more/
我假设“单独的项目”是指“单独的属性”,在这种情况下它并不重要。我可能会将它们存储为单独的属性,因为可以检索属性的子集(尽管您说您现在不需要此功能)。将来,如果您想查看用户发送了多少条消息,但又不想等待慢速网络返回许多 KB 的消息,则具有单独的属性会很有用。
是的。
您始终可以将数据存储为 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();
}