代码之家  ›  专栏  ›  技术社区  ›  Mike

dynamodb邻接表主键

  •  4
  • Mike  · 技术社区  · 7 年前

    我正在完成一个使用dynamodb来模拟多对多关系的练习。我需要允许帖子和标签之间的多对多关系。每个帖子可以有多个标签,每个标签可以有多个帖子。

    我有一把钥匙 id 主排序键打开 type 然后是另一个全球指数 身份证件 data ,我在上添加了另一个全局索引 身份证件 类型 再说一遍,但我认为这是多余的。

    这是我目前所拥有的。

    id(Partition key)      type(Sort Key)       target       data
    -------------          ----------           ------       ------
    1                      post                 1            cool post
    tag                    tag                  tag          n/a
    1                      tag                  tag          orange
    
    ---------------------------------------------
    ---- inserting another tag will overwrite ---
    ---------------------------------------------
    
    1                      tag                  tag          green
    

    我从这次精彩的演讲中得到了建议 https://www.youtube.com/watch?v=jzeKPKpucS0 而这些并不那么可怕的医生 https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html

    我遇到的问题是,如果我试图添加另一个带有 身份证件 “1”和 类型 “tag”它将覆盖现有的标记,因为它将具有相同的组合键。我错过了什么?似乎建议将主键和排序键设置为 身份证件 类型 是的。我应该让我的字体更像“橙色标签”吗?如果那样的话,我可以在 target 类型上有排序键。这样,我就可以通过查询target=“tag”来获取具有特定标记的所有帖子,并键入以“tag”开头的内容。

    只是想找一些建议来处理这种相邻列表数据与发电机,因为它似乎非常有趣。谢谢!

    2 回复  |  直到 7 年前
        1
  •  17
  •   Renato Byrro    7 年前

    邻接表的基本准则

    您需要对建模方式进行一些修改。在邻接列表中,有两种类型的项:

    1. 顶级(那些是你的 帖子 标签 )
    2. 关联(表示 标签 与每个 岗位 反之亦然)

    要构建这个邻接列表,您必须遵循两个简单的准则(我认为您的示例中缺少这两个准则):

    • 每个顶级项目(在您的情况下 岗位 或者 标签 )必须使用主键表示。而且,这些项在排序键和主键中的值应该相同
    • 对于关联,使用主键表示 来源 (或 起源 )以及表示 目标 (或 小孩 )中。

    根据我在您的示例中看到的,您设置了 帖子 标签 作为项目ID,同时还应该使用 类型 ;例如 Post-1 Tag-3 是的。在表示关联的项中,我也看不到您存储目标 身份证件 是的。

    例子

    假设你有:

    • 三个职位: “你好,世界” ,请 “Foo酒吧” “随便……”
    • 以及三个标签: “酷” 我是说, “太棒了” 我是说, “很好”
    • 岗位 “你好,世界” 有一个标记: “酷”
    • 岗位 “Foo酒吧” 有两个标记: “酷” “很好”
    • 岗位 “随便……” 没有任何标记

    你需要在发电机里这样做:

    PRIMARY-KEY   | SORT-KEY    | SOURCE DATA  | TARGET DATA
    --------------|-------------|--------------|-------------
    Post-1        | Post-1      | hello world  |
    Post-2        | Post-2      | foo bar      |
    Post-3        | Post-3      | Whatever...  |
    Tag-1         | Tag-1       | cool         |
    Tag-2         | Tag-2       | awesome      |
    Tag-3         | Tag-3       | great        |
    Post-1        | Tag-1       | hello world  | cool
    Post-2        | Tag-1       | foo bar      | cool
    Post-2        | Tag-3       | foo bar      | great
    Tag-1         | Post-1      | cool         | hello world
    Tag-1         | Post-2      | cool         | foo bar
    Tag-3         | Post-2      | great        | foo bar
    

    如何查询此邻接列表

    1)你需要一个特定的项目,比如 一号岗 以下内容:

    查询 primary-key == "Post-1" & sort-key == "Post-1" -返回:仅 一号岗

    2)您需要与 2号岗 以下内容:

    查询依据 primary-key == "Post-2" & sort-key BEGINS_WITH "Tag-" -返回: 标签1 标签-3 协会。

    支票 the documentation 关于begin_with key条件表达式 是的。

    3)你需要所有与 标签1 以下内容:

    查询依据 primary_key == "Tag-1" & sort-key BEGINS_WITH "Post-" -返回: 一号岗 2号岗 协会。

    请注意,如果更改给定文章的内容,则还需要更改所有关联项中的值。

    你也可以 不要储存 关联项中的post和tag内容,这节省了存储空间。但是,在本例中,在上面的示例查询2和3中需要两个查询:一个用于检索关联,另一个用于检索每个源项数据。因为查询比存储数据要贵,所以我更喜欢重复存储。但这取决于你的申请是否 阅读密集型 写密集型 是的。如果 阅读密集型 ,在关联中复制内容可以减少读取查询。如果 写密集型 ,不复制内容将保存写查询,以便在更新源项时更新关联。

    希望这有帮助!;)

        2
  •  2
  •   F_SO_K    7 年前

    我认为你没有遗漏任何东西。其思想是id对于项目类型是唯一的。通常,您会为该id生成一个长uuid,而不是使用序列号。另一种方法是使用您创建项的日期时间,可能添加一个随机数,以避免在创建项时发生冲突。

    我之前提供的这个答案可能有点帮助 DynamoDB M-M Adjacency List Design Pattern

    不要删除排序键-这无助于使您的项目更独特。