在DynamoDB中选择PK和SK



我有以下两个项目需要存储在dynamodb 中

  • 艺术家
  • 歌曲

艺术家有一个ID(艺术家唯一)、姓名和性别。歌曲有一个ID(歌曲唯一),标题,流派,艺术家和评级。

我应该如何在DynamoDB中对此进行建模?。

我在想:ID作为主键,并具有包含艺术家或歌曲的排序键,以便区分它们。这是个好选择吗?在一些例子中,我发现排序键有更多的变化。

歌曲项目中的现场艺术家呢?我应该指出艺术家的身份证吗?

更新:我有许多常见的访问模式。我可能可以通过创建一些索引来解决它,但我仍然必须选择一个好的PK/SK:

get songs based on title
get songs based on rating
get songs based on genre
get songs based on artist
get artist based on rating
get artist based on gender
get artist based on name

感谢

关于NoSQL(DynamoDB)建模,我发现了一件事(困难的方法),那就是在建模表之前,您需要了解所有访问模式。在和RDBMS中,通常先建模,然后随着访问模式的变化优化索引。这在NoSQL建模中并不简单(否则会有从RDBMS到NoSQL的大规模迁移)。

话虽如此,我现在将提出一个简单化的模型,随着问题的访问模式更新,我将更新我的答案(即"我需要为一位艺术家获取所有歌曲")。

艺术家:

PK:Artist-<Artist ID>,即Artist-1234SK:<Name>属性:性别等

歌曲:

PK:Song-<Song ID>,即Song-5678SK:<Genre>属性:流派,艺术家ID,评级

这种方法只允许您使用ID获取实体。

虽然NoSQL中通常会对数据进行去规范化(即将艺术家数据存储在歌曲中),以实现最简单/更高效的访问,但我还是选择存储艺术家ID,因为它可以更容易地更新并提高一致性。

DynamoDb是一个与SQL世界截然不同的世界。要获得无限的可扩展性,需要权衡取舍。

如果以下内容对你来说是荒谬的或新的,不要急于为你的Db建模。慢慢来读更多的书来理解。

  1. DynamoDb表有分区键,用于自动确定将存储在哪个物理分区数据。不要将其误认为主键(也称为PK)。分区键通常不是唯一的。

  2. 单个表应该存储多个实体(与SQL世界不同)。例如,用户配置文件和用户订单可以这样存储。

    PK:用户#1,SK:PROFILE#,用户名:dixitsandeep,地址:[]

    PK:用户#1,SK:订单#109,项目:["项目#1122","项目#9977]

    PK:用户#1,SK:订单#2090,项目:["项目#22288","项目#6655]

  3. 当使用分区键和排序键的组合访问数据时,会产生一个唯一的项。

  4. 没有跨表联接的概念。联接发生在存储在单个表中的多个实体中。您需要将传统的规范化排除在外。

  5. 有许多模式可以模拟联接。其中之一是只使用分区键(不指定排序键)或在排序键上使用一些过滤器来获取数据。例如,您可以使用PK User#1在单个查询中获取PROFILE和ORDERS。

换句话说,当使用Partition Key和Sort Key的组合访问数据时,会产生一个唯一的项。当您扩大排序键时,您会得到多个项目。可以通过加宽"排序关键字"过滤器来模拟联接。

  1. 您几乎总是需要为查询指定一个分区键。没有分区键的查询可能返回部分数据。

  2. 一个表最多可以创建20个索引。创建索引时,通常会使属性成为索引的PK、SK。与SQL世界不同,在DynamoDb中,当您想使用索引获取数据时,您可以指定索引。插入数据时不需要指定索引。索引可以帮助您根据主表的PK、SK以外的属性筛选数据。

考虑到以上几点,分区键的选择应该有很多可能的值。一种思考方式可能如下:如果有数百万用户每秒发送100万个查询,那么这些查询应该登录到不同的分区键。在高负载情况下,如果太多查询想要使用相同的分区键访问数据,则分区键可能会成为性能瓶颈。这意味着分区键的选择在很大程度上取决于应用程序访问数据的方式:访问模式

例如,UserRole是PartitionKey的一个糟糕选择,因为它可能会将大量数据分组在一个分区中。

AWS关于DynamoDb数据建模的资源。

https://youtu.be/KYy8X8t4MB8

https://youtu.be/0uLF1tjI_BI

最新更新