用于聊天应用程序的 Dynamo DB ERD
Dynamo DB ERD for Chat application
我正在尝试将我的聊天应用程序从 Firestore 迁移到 DynamoDB。
目前我在 firebase 中有 2 个集合:Rooms
和 Users
。
Users
集合包含用户所属的所有房间 ID。
Rooms
集合有一些元数据,例如名称、图标等以及 Messages
子集合。 Messages
子集合具有与消息相关的整个负载。
我在为此设计我的 Dynamo DB ERD 时感到困惑。我开发了以下 ERD 以及列出的访问模式,但如果需要,我无法计算出 PK、SK 和二级索引。
2021 年 6 月 14 日更新:
根据我收到的答案和帮助,我成功地进行了以下设计,我认为这将支持我的所有访问模式。
一个主要查询我想运行是通过用户ID获取所有房间的配置项,我不确定我是否能够在一个单个查询。
现在最简单的解决方案是获取用户的所有房间,然后获取所有获取房间的所有配置(SK),我认为这不是一个好的解决方案。
支持的访问模式:
- 获取房间内的所有用户 (PK=
ROOM#rid
&& SK=Begins_with(USER#)
)
- 获取单个房间的Config(PK=
ROOM#rid
&& SK=CONFIG
)
- 获取单个房间的消息(PK=
ROOM#rid
&& SK=Begins_with( MESSAGE#)
)
支持的访问模式:
- 获取某个用户的所有房间(PK=
USER#uid
&& SK=Begins_with(ROOM#)
)
建模实体和列出访问模式做得很好。这是成功使用 NoSQL 数据建模的第一步!
我将概述一种可以对此应用程序建模的方法。请记住,这不是为该应用程序建模访问模式的 唯一 方法,它可能无法处理您将遇到的所有边缘情况。不过,我希望这个例子能让你摆脱困境!
下面是我在基础 table 中定义 PK/SK 模式的方式。请注意,我向每个项目添加了一个 type
字段。由于每个项目可以是任何类型,所以我想添加这个字段来帮助我理解每个项目代表什么!
此 table 支持以下访问模式:
- 为用户获取房间(查询 PK=USER#userId SK beings_with ROOM)
- 通过 ID 获取消息(获取项目,其中 PK=MSG#messageId SK=MSG#messageId
我选择使用 KSUID 作为消息 ID。 KSUID 是按创建时间排序的唯一标识。这在我们为房间获取消息时会很有用。
我还在属性 GSI1PK 和 GSI1SK 上创建了一个名为 GSI1 的全局二级索引。
GSI1 支持:
- 按房间获取消息,按创建日期排序(在 GSI1 中查询 PK=ROOM#roomId SK begins_with MSG#)。由于我们使用的是 KSUID!
,因此消息将按创建顺序返回 date/time
- 按房间获取所有用户(为 PK=ROOM#roomId SK begins_with USER 查询 GSI1)
我正在尝试将我的聊天应用程序从 Firestore 迁移到 DynamoDB。
目前我在 firebase 中有 2 个集合:Rooms
和 Users
。
Users
集合包含用户所属的所有房间 ID。
Rooms
集合有一些元数据,例如名称、图标等以及 Messages
子集合。 Messages
子集合具有与消息相关的整个负载。
我在为此设计我的 Dynamo DB ERD 时感到困惑。我开发了以下 ERD 以及列出的访问模式,但如果需要,我无法计算出 PK、SK 和二级索引。
2021 年 6 月 14 日更新: 根据我收到的答案和帮助,我成功地进行了以下设计,我认为这将支持我的所有访问模式。
一个主要查询我想运行是通过用户ID获取所有房间的配置项,我不确定我是否能够在一个单个查询。 现在最简单的解决方案是获取用户的所有房间,然后获取所有获取房间的所有配置(SK),我认为这不是一个好的解决方案。
支持的访问模式:
- 获取房间内的所有用户 (PK=
ROOM#rid
&& SK=Begins_with(USER#)
) - 获取单个房间的Config(PK=
ROOM#rid
&& SK=CONFIG
) - 获取单个房间的消息(PK=
ROOM#rid
&& SK=Begins_with( MESSAGE#)
)
支持的访问模式:
- 获取某个用户的所有房间(PK=
USER#uid
&& SK=Begins_with(ROOM#)
)
建模实体和列出访问模式做得很好。这是成功使用 NoSQL 数据建模的第一步!
我将概述一种可以对此应用程序建模的方法。请记住,这不是为该应用程序建模访问模式的 唯一 方法,它可能无法处理您将遇到的所有边缘情况。不过,我希望这个例子能让你摆脱困境!
下面是我在基础 table 中定义 PK/SK 模式的方式。请注意,我向每个项目添加了一个 type
字段。由于每个项目可以是任何类型,所以我想添加这个字段来帮助我理解每个项目代表什么!
此 table 支持以下访问模式:
- 为用户获取房间(查询 PK=USER#userId SK beings_with ROOM)
- 通过 ID 获取消息(获取项目,其中 PK=MSG#messageId SK=MSG#messageId
我选择使用 KSUID 作为消息 ID。 KSUID 是按创建时间排序的唯一标识。这在我们为房间获取消息时会很有用。
我还在属性 GSI1PK 和 GSI1SK 上创建了一个名为 GSI1 的全局二级索引。
GSI1 支持:
- 按房间获取消息,按创建日期排序(在 GSI1 中查询 PK=ROOM#roomId SK begins_with MSG#)。由于我们使用的是 KSUID! ,因此消息将按创建顺序返回 date/time
- 按房间获取所有用户(为 PK=ROOM#roomId SK begins_with USER 查询 GSI1)