DynamoDB 查询性能 - 唯一分区键与唯一分区+排序键
DynamoDB query performance with - a unique partition key vs a unique partition+sort key
假设我有一个名为 'student_course' 的 Dynamo 数据库 table。我想存储每个学生在大学上的课程。一个学生一次可以选修多门课程,一门课程可以同时有很多学生。所以基本上它是一个多重映射。
我的数据访问模式只有一个用例 -
- 一次获取一个学生和一门课程的记录,即获取每个 StudentId 和 CourseId 组合的数据。保证一个student-id和course-id的组合,只有一条记录可用。
为了实现这一点,我可以用这两种方式存储数据 -
- 分区键 = {student-id},排序键 = {course-id}
- Partition-key = "studentId:{student-id}_courseId:{course-id}", 排序键不存在
我的问题是 - 如果有任何差异,哪个查询会执行得更好?我应该选择哪一个而不是另一个,为什么?
在设计 DDB
性能方面,Get API
是 DDB 毫秒级数据检索能力的关键,因此围绕此 API 设计数据是合乎逻辑的
Table 分区键 + 排序键
Partition Key | Sort Key
--------------+-------------
Course1 | Student1
Course1 | Student2
优点:
- 能够使用
Get API
通过 Partition Key
和 Sort Key
获取单条记录,例如获取 Partition Key = "Course1" 和 Sort Key = "Student1" 的单个记录
- 仅通过
Partition Key
即可使用 Get API
获取记录列表,例如获取 Partition Key = "Course1" 的所有记录
缺点:
- 如果您只知道
Sort Key
(即学生)而不知道 Partition Key
(即课程),您将无法使用 Get API
检索记录只有 Sort Key
注意:一般来说,DDB Get API
查询的效率(这样查询就不会轻易命中 ReadThroughput
异常“屋顶”)与唯一性相结合和分布Partition Key
。您拥有和分布的分区键越多,性能越好
Table 仅使用分区键
Partition Key Only
--------------------
Course1#Student1
Course1#Student2
优点:
- 能够使用
Get API
通过 Partition Key
获取单条记录,例如获取 Partition Key = "Course1#Student1" 的单条记录
缺点:
- 将无法使用
Get API
仅使用 Partition key
的一个子集来获取记录列表,例如获取 Partition Key = "Course1" 的记录列表
关于 GSI
注意:在 Table 上添加 Global Secondary Index 以支持 Get API
调用是一种常见的情况键,例如 获取记录列表,其中 GSI Partition Key
= 课程名称
Partition Key Only | Non Key Attribute (Course) For GSI
---------------------+---------------------------
Course1#Student1 | Course1
Course1#Student2 | Course1
您最多可以有 20 个 GSI
索引(软限制),可以选择通过支持请求移除此限制
Partition Key Only | Non Key Attribute (Course) For GSI | Lecturer (For GSI 2)
---------------------+------------------------------------+---------------------
Course1#Student1 | Course1 | Lecturer1
Course1#Student2 | Course1 | Lecturer1
结论
如果性能是关键,我会设计一个 Table 为 Partition Keys
设置尽可能多的 Unique 值,即 Partition Key = Course1# Student1 VS Partition Key = Course1, Sort Key = Student1
添加GSIs
到Tables on-demand如果你需要通过备用键查询
(历史上 GSIs
每个 Table 限制为 5 个,并且必须在 Table 创建期间指定,但这些限制已解除)
假设我有一个名为 'student_course' 的 Dynamo 数据库 table。我想存储每个学生在大学上的课程。一个学生一次可以选修多门课程,一门课程可以同时有很多学生。所以基本上它是一个多重映射。
我的数据访问模式只有一个用例 -
- 一次获取一个学生和一门课程的记录,即获取每个 StudentId 和 CourseId 组合的数据。保证一个student-id和course-id的组合,只有一条记录可用。
为了实现这一点,我可以用这两种方式存储数据 -
- 分区键 = {student-id},排序键 = {course-id}
- Partition-key = "studentId:{student-id}_courseId:{course-id}", 排序键不存在
我的问题是 - 如果有任何差异,哪个查询会执行得更好?我应该选择哪一个而不是另一个,为什么?
在设计 DDB
性能方面,Get API
是 DDB 毫秒级数据检索能力的关键,因此围绕此 API 设计数据是合乎逻辑的
Table 分区键 + 排序键
Partition Key | Sort Key
--------------+-------------
Course1 | Student1
Course1 | Student2
优点:
- 能够使用
Get API
通过Partition Key
和Sort Key
获取单条记录,例如获取 Partition Key = "Course1" 和 Sort Key = "Student1" 的单个记录
- 仅通过
Partition Key
即可使用Get API
获取记录列表,例如获取 Partition Key = "Course1" 的所有记录
缺点:
- 如果您只知道
Sort Key
(即学生)而不知道Partition Key
(即课程),您将无法使用Get API
检索记录只有Sort Key
注意:一般来说,DDB Get API
查询的效率(这样查询就不会轻易命中 ReadThroughput
异常“屋顶”)与唯一性相结合和分布Partition Key
。您拥有和分布的分区键越多,性能越好
Table 仅使用分区键
Partition Key Only
--------------------
Course1#Student1
Course1#Student2
优点:
- 能够使用
Get API
通过Partition Key
获取单条记录,例如获取 Partition Key = "Course1#Student1" 的单条记录
缺点:
- 将无法使用
Get API
仅使用Partition key
的一个子集来获取记录列表,例如获取 Partition Key = "Course1" 的记录列表
关于 GSI
注意:在 Table 上添加 Global Secondary Index 以支持 Get API
调用是一种常见的情况键,例如 获取记录列表,其中 GSI Partition Key
= 课程名称
Partition Key Only | Non Key Attribute (Course) For GSI
---------------------+---------------------------
Course1#Student1 | Course1
Course1#Student2 | Course1
您最多可以有 20 个 GSI
索引(软限制),可以选择通过支持请求移除此限制
Partition Key Only | Non Key Attribute (Course) For GSI | Lecturer (For GSI 2)
---------------------+------------------------------------+---------------------
Course1#Student1 | Course1 | Lecturer1
Course1#Student2 | Course1 | Lecturer1
结论
如果性能是关键,我会设计一个 Table 为 Partition Keys
设置尽可能多的 Unique 值,即 Partition Key = Course1# Student1 VS Partition Key = Course1, Sort Key = Student1
添加GSIs
到Tables on-demand如果你需要通过备用键查询
(历史上 GSIs
每个 Table 限制为 5 个,并且必须在 Table 创建期间指定,但这些限制已解除)