DynamoDB多对多关系模型

时间:2019-09-05 12:09:27

标签: database-design nosql amazon-dynamodb many-to-many adjacency-list

我正在尝试为多对多关系建立一个发电机表。我会尽量简化:

我有培训师和他们的客户。一个培训师可以有很多客户,而客户可以属于许多培训师-这是发电机的经典M-M问题。但是我似乎无法解决这个问题。

访问模式如下:

  • 培训师需要能够获得并列出所有客户
  • 客户需要能够获取并更新其信息

现在,到目前为止,我想到的两个解决方案非常相似,但并不令人满意:

  1. 我为客户保留一个对象,并在Trainer对象中保留一个对象列表-如果客户更新了他/她的信息,则必须在多个Trainer对象中完成
  2. 我为客户保留一个对象,为每个培训者保留一个对象-如果客户更新了他/她的信息,则还必须在多个对象中完成

按照下面的结构,我所有东西都放在一个表中,还没有GSI。

这是我当前的结构:

+------------+------------+-------------+
|PK          |SK          |Attributes   |
|------------|------------|-------------|
|trainer1_id |  TRAINER   |name, etc    |
|------------|------------|-------------|
|trainer2_id |  TRAINER   |name, etc    |
|------------|------------|-------------|
|client1_id  |  CLIENT    |name, etc    |
|------------|------------|-------------|
|client2_id  |  CLIENT    |name, etc    |
|------------|------------|-------------|
|client3_id  |  CLIENT    |name, etc    |
|------------|------------|-------------|

替代1:

+------------+------------+-------------+
|PK          |SK          |Attributes   |
|------------|------------|-------------|
|trainer1_id |  TRAINER   |[CLIENTLIST] |
|------------|------------|-------------|
|client1_id  |  CLIENT    |name, etc    |
|------------|------------|-------------|
|client2_id  |  CLIENT    |name, etc    |
|------------|------------|-------------|
|client3_id  |  CLIENT    |name, etc    |
|------------|------------|-------------|

替代2:

+------------+------------+-------------------+
|PK          |SK          |Attributes         |
|------------|------------------|-------------|
|trainer1_id |  TRAINER         |name, etc    |
|------------|------------------|-------------|
|client1_id  |  CLIENT          |name, etc    |
|------------|------------------|-------------|
|client2_id  |  CLIENT          |name, etc    |
|------------|------------------|-------------|
|trainer1_id |CLIENT#client1_id |name, etc    |
|------------|------------------|-------------|
|trainer1_id |CLIENT#client2_id |name, etc    |
|------------|------------------|-------------|
...etc

我想我的实际问题是:如果我想让一个客户端对象包含所有客户端信息,但同时列出属于培训师的所有客户端,那么正确的访问模式是什么?这是正确的方法吗?如果有不清楚的地方表示歉意

1 个答案:

答案 0 :(得分:0)

通常,在NoSQL数据库(尤其是DynamoDB)中,与关系数据库相比,您需要更频繁地对数据进行规范化。这简化了读取,但使更新/写入更加复杂。

具体来说,在您的情况下,我将选择一个包含所有clienttrainer详细信息的项目。

{ pk: '<some-unique-id>`, 
  clientId: '<some-unique-id>', 
  clientName: 'Bob',
  clientPhoneNumber: '...', 
  trainerId: '<some-unique-id>', 
  trainerName: 'Alice', trainerPhoneNumber: '....' }

要注意的是,(例如)更改客户名称时,您需要查找该客户的所有项目并进行更新。与clientPhoneNumbertrainerName等类似。

如果要快速查找与给定的clientId值关联的所有项目,则需要定义一个全局二级索引(GSI),该全局二级索引将clientId属性用作其分区键。需要trainerId属性上的第二个GSI,以查找与给定trainerId值关联的所有项目。

最后,由于您的更新过程不是原子的(由于各种错误/硬件故障/网络故障,在更新项目的过程中,您的程序可能会停止运行),您将需要设置一个程序来修复运行不一致的问题在定期。该程序将查找具有相同clientId值但具有不同clientName值的项目。 (分别为trainerIdtrainerName)。这会涉及其他属性(例如clientPhoneNumber)。

this answer

中查看更多详细信息