数据库设计- DynamoDB +存储值作为项目或JSON



我正在创建一个主键'UserID',复合键'DateTime'的表,然后我有以下值(注意:我不需要查询下面数据中的任何细节-只需写入和读取它):

UserID1
UserID2
Message
DateTime

问题:

  1. 存储这4个值作为单独的项目或作为一个JSON字符串有任何优势吗?
  2. 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和日期时间存储为属性的一部分,因为它们是哈希值和范围键,在发出请求时返回。

  1. 您可以将条目存储在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"));
    
  2. 我同意Pooky的观点,没有必要在细节映射中复制Hash+Range键。要使用GetItem获取项目,您需要这两个元素。

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

  2. 是的。

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();
}

最新更新