如何建模多对多关系并维护 Azure 表存储中表之间的数据一致性?

问题描述

抱歉问了这么长的问题。我知道这听起来像是我希望你们为我做这项工作。但我是 Nosql 的新手,在思考 Nosql 方式时,我需要一些帮助来理清思路:)

比方说,我有 3 个不同的实体,Person、Group 和 Tags。一个人可以在多个组中。一个团体可以由很多人组成。 Group 和 Person 都可以分配多个标签

public class Person
{
  public string Name { get; set; }
  public List<Group> Groups { get; set; }
  public List<Tag> Tags { get; set; }
}
public class Group
{
  public string Name { get; set; }
  public List<Person> { get; set; }
  public List<Tag> Tags { get; set; }
}
public class Tag
{
  public string Name { get; set; }
}

这些数据可以被一些 API 检索和修改。 以下是可能发生的一些情况:

  1. 如果我修改一个人的名字,然后检索了一个包含该人的组,那么更改应该反映在响应中,反之亦然。
  2. 如果我更改了标签名称,则标签名称应在相应的人员和组中更新。
  3. 如果我删除一个标签,它们应该从个人和群组中删除

问题 1:我应该如何为 Azure 表存储对这些实体建模?

我的想法是按原样对每个实体进行建模。每个实体都有自己的表。每个属性都有自己的列(加上分区键和行键)。集合将被序列化并存储为字符串。

假设我需要更改组的名称,我需要:

  1. 更新群组
  2. 阅读群组以获取受影响人员列表。
  3. 读取列表中的所有人员
  4. 更新组集合中的组。

我知道 Nosql 模型应该是为快速读取而设计的,但是否有其他方法可以对数据进行建模,以便在更新时减少操作?或者这在 Nosql 中很常见?

当涉及到标签时,这种方法将是一个更大的问题。 如果我删除标签,我需要:

  1. 删除标签
  2. 扫描整个 Person 表以查找包含该标签的人员。
  3. 从 Persons 的标签集合中删除标签
  4. 将受影响的人写回表格
  5. 扫描整个 Groups 表以查找包含该标签的组。
  6. 从群组的标签集合中删除标签
  7. 将受影响的组写回表格。

感觉这种方法有太多的全表扫描。 (但是嘿,至少阅读会很快)

问题 2:如何保持跨表数据的一致性?

如果我上面的方法是正确的,更新操作将不会是原子的。如果其中一个写入中途失败,我应该如何处理?

我做了一些研究,发现了补偿交易模式,似乎需要某种消息代理。但是我在单个 Azure 函数应用程序中实现它并且无法访问服务总线或某种事件系统。我应该这样实施吗?

public void DeleteTag(Tag tag)
{
  try
  {
    // Delete Tag
  }
  catch(Exception)
  {
    // throw
  }

  try
  {
    // Read Person
    // Update Person
  }
  catch(Exception)
  {
    // Revert the changes to tag
    // throw
  }
  
  try
  {
    // Read Group
    // Update Group
  }
  catch(Exception)
  {
    // Revert the changes to Tag
    // Revert the changes to Person
    // throw
  }
}

但这也引发了一个问题,如果恢复操作失败会发生什么?

我有一个同事建议我应该把所有东西都放在同一个表和同一个分区中以避免这个问题(我们正在处理的数据集开始时非常小)。这不是说当我需要删除标签时我需要读取所有数据吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)