gpt4 book ai didi

java - 如何使用 Java SDK 在 DynamoDB 中建模多对多关系

转载 作者:行者123 更新时间:2023-12-02 01:14:32 28 4
gpt4 key购买 nike

我已经查看了一些关于 DynamoDB 多对多关系的文章。

据我了解;
应该有一个表,我需要使用复合主键。

对于书籍项目;
hashKey(partionKey) 应该是 book id;并且 RangeKey(sortKey) 应该是作者 ID;
对于作者项目;
hashKey(partionKey) 应该是作者 id;和 RangeKey(sortKey) 应该是书 id;

我已经创建了这些模型;

 @Data
@DynamoDBTable(tableName = "author_book_table")
public class Book {

@Id
private BookId id;

private String name;

private Integer pages;

}



@Data
@DynamoDBTable(tableName = "author_book_table")
public class Author {

@Id
private AuthorId id;
@DynamoDBAttribute
private String name;

}

Id 模型如下所示;
@Data
public class BookId {

@DynamoDBHashKey
private String bookId;

@DynamoDBRangeKey
private String authorId;
}


@Data
public class AuthorId {
@DynamoDBHashKey
private String authorId;
@DynamoDBRangeKey
private String bookId;
}

但我无法想象如何使用它,如何按作者查询书籍或按书籍作者。
正确的方法是什么?

我找不到任何关于 java 关系的例子。
我还使用 Spring data dynamoDB moodule。

最佳答案

[旁注:你确定spring数据dynamodb模块允许你读/写两个不同的@Data在同一张 table 上上课?如果答案是“否”,那么您将需要使用两个单独的表格。无论如何,我的其余答案不受此影响(因为在使用其他 SDK 时,您当然可以在同一个 DDB 表中存储不止一种类型的项目]

我能想到四个用例:

(a) 给定作者的 ID,您想获取她写的所有书籍的 ID

(b) 给定一个作者的 ID,你想得到她写的所有书的名字

(c) 给定一本书的 ID,您想获取该书所有作者的 ID

(d) 给定一本书的 ID,您想获取该书所有作者的姓名

快速的回答是,给定这个数据模型 (a) 和 (c) 可以通过单个查询轻松实现。但是,(b)和(d)不能通过单个查询来实现(参见下面的答案 1)。但是,DDB 中的“正确”方法是对事物进行不同的建模(参见下面的答案 2)

回答 1

如前所述here当你做 query在 DDB 表上,您可以给它一个分区键(又名:哈希键)。该查询将返回具有按范围键排序的分区键的所有项目。由于每个作者项目都有(作为范围键)书籍 ID,这意味着当您传入作者 ID 时,您将获得所有书籍 ID。同样,如果查询给定的图书 ID,您将获得所有作者 ID。

如果您还想获取书名(从给定的作者 ID),您必须首先获取所有书名(如上一段所述),然后使用 BatchGetItem获取单个书籍项目。请注意 BatchGetItem一个 upper limit of 100 items所以你可能需要做多个 BatchGetItem调用。 (当然,这个解决方案也可以在另一个方向上起作用:书->作者,你只需要在心里用作者替换书,反之亦然)

回答 2

在 DDB 和许多其他 NoSql 数据库中,您可以使用数据的非规范化(即跨多个项目复制同一条信息)来塑造数据,以便它已经以适合您的检索用例的方式存储。在这里,它归结为包含作者详细信息和书籍详细信息的单一类型的项目。

@Data
@DynamoDBTable(tableName = "author_book_table")
public class Book {

@DynamoDBHashKey
@DynamoDBIndexRangeKey(globalSecondaryIndexName="ByAuthor")
private String bookId;

@DynamoDBRangeKey
@DynamoDBIndexHashKey(globalSecondaryIndexName="ByAuthor")
private String authorId;

private String bookName;
private String authorName;
private Integer pages;
}

使用此数据模型,您仍然可以查询对图书 ID 发出查询的图书的所有作者。查询结果返回的项目将包含所有作者姓名。对于另一个方向(作者 ID -> 书籍),您还需要执行查询,但这次针对您需要定义的全局二级索引 ( ByAuthor )。在这个索引中,角色是相反的:作者 ID 是哈希键,书籍 ID 是范围键。

缺点是当一条数据发生变化时需要更新多条记录。例如,如果您需要将作者 ID“100”的姓名从“Alice”更新为“Beth”,则需要查找所有作者 ID 为“100”的项目并在那里更新作者姓名。同样,如果您需要更新表的数量,您将需要更新多个项目(如果这本书有三个作者,则需要更新三个具有该书 ID 的项目)。

重要提示:您可以从您的应用程序/服务中发布此更新。但是,您需要为您的服务(或底层硬件)在更新过程中失败的情况做好准备。这可能会导致数据不一致(在某些项目中作者姓名为“Beth”,但在某些项目中仍为“Alice”)。 Transaction可以帮助您,但它们仅限于更新 25 个项目。如果您无法在单个事务中更新,则需要进行纠正测量:例如,您可以定期扫描数据库并修复您发现的任何不一致之处。最重要的是,您可以让该服务在其“常规”操作期间主动检查其获取的项目中的不一致之处。如果它发现不一致,它可以启动对这些特定项目的修复。

关于java - 如何使用 Java SDK 在 DynamoDB 中建模多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57665608/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com