在 DynamoDB 中选择 PK 和 SK
Choice PK and SK in DynamoDB
我有以下两个项目需要存储在 dynamodb
- 艺术家
- 歌曲
艺术家有ID(艺术家唯一)、姓名和性别。歌曲有一个 ID(歌曲唯一)、标题、流派、艺术家和评级。
我应该如何在 DynamoDB 中对其进行建模?。
我在想这个:
ID 作为主键并具有包含艺术家或歌曲的排序键,以便区分它们。这是一个好的选择吗?在示例中,我发现我在排序键中看到了更多变化。
歌曲项目中的现场艺术家呢?我应该只指向艺术家的 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) 建模,我发现(困难的)一件事是您需要了解 所有 您的访问模式 在你为你的table建模之前。在 RDBMS 和 RDBMS 中,随着访问模式的变化,先建模然后优化索引是很常见的。这在 NoSQL 建模中并不简单(否则会有从 RDBMS 到 NoSQL 的大量迁移)。
话虽如此,我现在将建议一个简单的模型,并且我将在问题更新为访问模式(即 "I need to get all songs for an artist")时更新我的答案。
艺术家:
PK:Artist-<Artist ID>
,即 Artist-1234
SK:<Name>
属性:性别等
歌曲:
PK:Song-<Song ID>
,即 Song-5678
SK:<Genre>
属性:流派、艺术家 ID、评分
这种方法只允许您使用实体的 ID 来获取实体。
虽然为了 easiest/more 高效访问而对数据进行反规范化(即将艺术家数据存储在歌曲中)在 NoSQL 中很常见,但我会继续存储艺术家 ID,因为它允许更容易的更新和更好的一致性。
DynamoDb 是一个与 SQL 截然不同的世界。需要权衡取舍才能获得无限的可扩展性。
如果以下内容对您来说显得荒谬或陌生,请不要急于为您的 Db 建模。花点时间阅读更多内容以了解。
Tables 具有分区键,用于自动确定将存储哪个物理分区数据。不要将它们与主键(也称为 PK)混淆。分区键通常不是唯一的。
单个 table 应该存储多个实体(不同于 SQL 世界)。例如,用户资料和用户订单可以这样存储。
PK:用户#1,SK:配置文件#,username:dixitsandeep,地址:[]
PK:用户#1,SK:订单#109,项目:[“ITEM#1122”,“ITEM#9977]
PK:用户#1,SK:ORDER#2090,项目:[“ITEM#2288”,“ITEM#6655]
当使用分区键和排序键的组合访问数据时,它会产生一个唯一的项目。
没有 JOIN ACROSS TABLES 的概念。联接发生在存储在单个 Table 中的多个实体中。您需要将传统规范化排除在外。
有很多模式可以模拟连接。其中之一是仅使用分区键(不指定排序键)或在排序键上使用某些过滤器来获取数据。例如,您可以使用 PK User#1 在单个查询中获取 PROFILE 和 ORDERS。
换句话说,当使用分区键和排序键的组合访问数据时,它会产生一个唯一的项目。当您扩大排序键时,您会得到多个项目。您通过扩大排序键过滤器来模拟连接。
您几乎总是需要为查询指定分区键。没有分区键的查询可能 return 部分数据。
您最多可以在 table 上创建 20 个索引。当您创建一个索引时,您通常将一个属性设为索引的 PK、SK。与 SQL 世界不同,在 DynamoDb 中,您可以在要使用该索引获取数据时指定索引。插入数据时不需要指定索引。索引可能会帮助您根据主要 table.
的 PK、SK 以外的属性过滤数据
考虑到以上几点,分区键的选择应该有很多可能的值。一种思考方式可能如下:如果您有数百万用户每秒触发 100 万个查询,那么这些查询应该登陆不同的分区键。在高负载情况下,如果太多查询想要访问具有相同分区键的数据,分区键可能会成为性能瓶颈。这意味着分区键的选择在很大程度上取决于应用程序访问数据的方式:访问模式。
例如,UserRole 是 PartitionKey 的错误选择,因为它可能会将大量数据分组到一个分区中。
关于 DynamoDb 数据建模的 AWS 资源。
我有以下两个项目需要存储在 dynamodb
- 艺术家
- 歌曲
艺术家有ID(艺术家唯一)、姓名和性别。歌曲有一个 ID(歌曲唯一)、标题、流派、艺术家和评级。
我应该如何在 DynamoDB 中对其进行建模?。
我在想这个: ID 作为主键并具有包含艺术家或歌曲的排序键,以便区分它们。这是一个好的选择吗?在示例中,我发现我在排序键中看到了更多变化。
歌曲项目中的现场艺术家呢?我应该只指向艺术家的 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) 建模,我发现(困难的)一件事是您需要了解 所有 您的访问模式 在你为你的table建模之前。在 RDBMS 和 RDBMS 中,随着访问模式的变化,先建模然后优化索引是很常见的。这在 NoSQL 建模中并不简单(否则会有从 RDBMS 到 NoSQL 的大量迁移)。
话虽如此,我现在将建议一个简单的模型,并且我将在问题更新为访问模式(即 "I need to get all songs for an artist")时更新我的答案。
艺术家:
PK:Artist-<Artist ID>
,即 Artist-1234
SK:<Name>
属性:性别等
歌曲:
PK:Song-<Song ID>
,即 Song-5678
SK:<Genre>
属性:流派、艺术家 ID、评分
这种方法只允许您使用实体的 ID 来获取实体。
虽然为了 easiest/more 高效访问而对数据进行反规范化(即将艺术家数据存储在歌曲中)在 NoSQL 中很常见,但我会继续存储艺术家 ID,因为它允许更容易的更新和更好的一致性。
DynamoDb 是一个与 SQL 截然不同的世界。需要权衡取舍才能获得无限的可扩展性。
如果以下内容对您来说显得荒谬或陌生,请不要急于为您的 Db 建模。花点时间阅读更多内容以了解。
Tables 具有分区键,用于自动确定将存储哪个物理分区数据。不要将它们与主键(也称为 PK)混淆。分区键通常不是唯一的。
单个 table 应该存储多个实体(不同于 SQL 世界)。例如,用户资料和用户订单可以这样存储。
PK:用户#1,SK:配置文件#,username:dixitsandeep,地址:[]
PK:用户#1,SK:订单#109,项目:[“ITEM#1122”,“ITEM#9977]
PK:用户#1,SK:ORDER#2090,项目:[“ITEM#2288”,“ITEM#6655]
当使用分区键和排序键的组合访问数据时,它会产生一个唯一的项目。
没有 JOIN ACROSS TABLES 的概念。联接发生在存储在单个 Table 中的多个实体中。您需要将传统规范化排除在外。
有很多模式可以模拟连接。其中之一是仅使用分区键(不指定排序键)或在排序键上使用某些过滤器来获取数据。例如,您可以使用 PK User#1 在单个查询中获取 PROFILE 和 ORDERS。
换句话说,当使用分区键和排序键的组合访问数据时,它会产生一个唯一的项目。当您扩大排序键时,您会得到多个项目。您通过扩大排序键过滤器来模拟连接。
您几乎总是需要为查询指定分区键。没有分区键的查询可能 return 部分数据。
您最多可以在 table 上创建 20 个索引。当您创建一个索引时,您通常将一个属性设为索引的 PK、SK。与 SQL 世界不同,在 DynamoDb 中,您可以在要使用该索引获取数据时指定索引。插入数据时不需要指定索引。索引可能会帮助您根据主要 table.
的 PK、SK 以外的属性过滤数据
考虑到以上几点,分区键的选择应该有很多可能的值。一种思考方式可能如下:如果您有数百万用户每秒触发 100 万个查询,那么这些查询应该登陆不同的分区键。在高负载情况下,如果太多查询想要访问具有相同分区键的数据,分区键可能会成为性能瓶颈。这意味着分区键的选择在很大程度上取决于应用程序访问数据的方式:访问模式。
例如,UserRole 是 PartitionKey 的错误选择,因为它可能会将大量数据分组到一个分区中。
关于 DynamoDb 数据建模的 AWS 资源。