我正在尝试为多对多关系建立一个发电机表。我会尽量简化:
我有培训师和他们的客户。一个培训师可以有很多客户,而客户可以属于许多培训师-这是发电机的经典M-M问题。但是我似乎无法解决这个问题。
访问模式如下:
现在,到目前为止,我想到的两个解决方案非常相似,但并不令人满意:
按照下面的结构,我所有东西都放在一个表中,还没有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
我想我的实际问题是:如果我想让一个客户端对象包含所有客户端信息,但同时列出属于培训师的所有客户端,那么正确的访问模式是什么?这是正确的方法吗?如果有不清楚的地方表示歉意
答案 0 :(得分:0)
通常,在NoSQL数据库(尤其是DynamoDB)中,与关系数据库相比,您需要更频繁地对数据进行规范化。这简化了读取,但使更新/写入更加复杂。
具体来说,在您的情况下,我将选择一个包含所有client
和trainer
详细信息的项目。
{ pk: '<some-unique-id>`,
clientId: '<some-unique-id>',
clientName: 'Bob',
clientPhoneNumber: '...',
trainerId: '<some-unique-id>',
trainerName: 'Alice', trainerPhoneNumber: '....' }
要注意的是,(例如)更改客户名称时,您需要查找该客户的所有项目并进行更新。与clientPhoneNumber
,trainerName
等类似。
如果要快速查找与给定的clientId
值关联的所有项目,则需要定义一个全局二级索引(GSI),该全局二级索引将clientId
属性用作其分区键。需要trainerId
属性上的第二个GSI,以查找与给定trainerId
值关联的所有项目。
最后,由于您的更新过程不是原子的(由于各种错误/硬件故障/网络故障,在更新项目的过程中,您的程序可能会停止运行),您将需要设置一个程序来修复运行不一致的问题在定期。该程序将查找具有相同clientId
值但具有不同clientName
值的项目。 (分别为trainerId
,trainerName
)。这会涉及其他属性(例如clientPhoneNumber
)。