如何使用 DynamoDB 有一个可选的主键?
How to have an optional primary key with DynamoDB?
我有一个关系,每个 SITE 可以有一个或多个 CAMERA。
所以父子关系就是SITE->CAMERA[s]。
我 99% 的查询将是“给我指定站点的所有摄像头”和“给我摄像头 XYZ”和“给我所有启用===true 的摄像头”——大约 1:1:1比率.
如果我理解正确的话,DynamoDB 的设计应该是分区键为 'SITE_ID',排序键为 'CAMERA_ID'。大功告成。
.....
但是,并不是每个 CAMERA 都属于一个 SITE。我的 CAMERA 中大约有 10% 与站点无关。我 可以 只是将 'noSite' 或其他东西作为 Partitionkey,但这似乎是一个混乱......或者是吗?
我是 DynamoDB 的新手,不确定如何最好地建立这种关系。我一直只使用 MongoDB 而从来没有花时间在 SQL 世界中,所以需要担心索引不是我的经验。成本比原始速度更重要,数据库将保持较小(目前大约有 500 个摄像头,可能永远不会超过 10k)。
设置此 table 的最佳方法是什么?
首先是详细问题:noSite
键对于未分配的相机来说是一个不错的设计选择。 SiteID
很重要而且
键不能为空。
您的访问模式为您提供了灵活性。您的低数据量降低了设计决策的风险。
Partion Key
和 Sort Key
名称是什么? 无论您最终为键选择了哪些“列”,命名键 PK
和 SK
让您可以选择稍后在 single-table design 中添加其他记录类型。这是一种常见的做法。
PK
和 SK
列是什么?
您有两个不错的 PK 和 SK 选项用于相机记录:
# Option 1 - marginally better, CameraID has the higher cardinality
PK: CameraID, SK: SiteID
# Option 2
PK: SiteID, SK: CameraID
此时,您的“查询”中的 1 个将作为 query
(更快且更便宜)执行,另外 2 个将作为 scans
(更慢且更昂贵)执行。不过,扫描 500 条记录不算什么,所以您可以像您所说的那样“大功告成”。
迟早或永不
如果需要,我们可以通过添加 secondary indexes 来删除 scan
操作。二级索引增加了存储成本(记录实际上是重复的)但降低了访问成本。净净变化视情况而定。性能会提高。
# Add an index to query "Give me all the cameras at a given site"
GSI1PK: SiteID, GSI1SK: CameraID # reverse your choice for primary keys
# or, to get fancy and be able to query enabled cameras by site, too, use a concatenated SK with a begins_with query
GSI1PK: SiteID, GSI1SK: Enabled#True#CameraID
# Add an index to query "Give me all cameras where enabled===true"
# Concatenate SiteID and CameraID in the GSI Sort Key to enable 2 types of queries
# 1. all enabled cameras? GSI2PK = true and GSI2SK > ""
# 2. all enabled cameras at Site123? GSI2PK = true and GSI2SK begins_with("Site123")
GSI2PK: Enabled, GSI2SK: SiteID#CameraID
我有一个关系,每个 SITE 可以有一个或多个 CAMERA。
所以父子关系就是SITE->CAMERA[s]。
我 99% 的查询将是“给我指定站点的所有摄像头”和“给我摄像头 XYZ”和“给我所有启用===true 的摄像头”——大约 1:1:1比率.
如果我理解正确的话,DynamoDB 的设计应该是分区键为 'SITE_ID',排序键为 'CAMERA_ID'。大功告成。
.....
但是,并不是每个 CAMERA 都属于一个 SITE。我的 CAMERA 中大约有 10% 与站点无关。我 可以 只是将 'noSite' 或其他东西作为 Partitionkey,但这似乎是一个混乱......或者是吗?
我是 DynamoDB 的新手,不确定如何最好地建立这种关系。我一直只使用 MongoDB 而从来没有花时间在 SQL 世界中,所以需要担心索引不是我的经验。成本比原始速度更重要,数据库将保持较小(目前大约有 500 个摄像头,可能永远不会超过 10k)。
设置此 table 的最佳方法是什么?
首先是详细问题:noSite
键对于未分配的相机来说是一个不错的设计选择。 SiteID
很重要而且
键不能为空。
您的访问模式为您提供了灵活性。您的低数据量降低了设计决策的风险。
Partion Key
和 Sort Key
名称是什么? 无论您最终为键选择了哪些“列”,命名键 PK
和 SK
让您可以选择稍后在 single-table design 中添加其他记录类型。这是一种常见的做法。
PK
和 SK
列是什么?
您有两个不错的 PK 和 SK 选项用于相机记录:
# Option 1 - marginally better, CameraID has the higher cardinality
PK: CameraID, SK: SiteID
# Option 2
PK: SiteID, SK: CameraID
此时,您的“查询”中的 1 个将作为 query
(更快且更便宜)执行,另外 2 个将作为 scans
(更慢且更昂贵)执行。不过,扫描 500 条记录不算什么,所以您可以像您所说的那样“大功告成”。
迟早或永不
如果需要,我们可以通过添加 secondary indexes 来删除 scan
操作。二级索引增加了存储成本(记录实际上是重复的)但降低了访问成本。净净变化视情况而定。性能会提高。
# Add an index to query "Give me all the cameras at a given site"
GSI1PK: SiteID, GSI1SK: CameraID # reverse your choice for primary keys
# or, to get fancy and be able to query enabled cameras by site, too, use a concatenated SK with a begins_with query
GSI1PK: SiteID, GSI1SK: Enabled#True#CameraID
# Add an index to query "Give me all cameras where enabled===true"
# Concatenate SiteID and CameraID in the GSI Sort Key to enable 2 types of queries
# 1. all enabled cameras? GSI2PK = true and GSI2SK > ""
# 2. all enabled cameras at Site123? GSI2PK = true and GSI2SK begins_with("Site123")
GSI2PK: Enabled, GSI2SK: SiteID#CameraID