2017-05-07 49 views
0

我对如何为给定查询需求设置表和索引的最佳实践感兴趣。我对分区和排序键或LSI和GSI二级索引等相关概念有了基本的了解,但是将它们放在一起并设计一个或多个支持可触及示例的索引的表存在问题。DynamoDB中的数据库设计:书签存储

我看到的例子是“书签存储”,其中多个用户可以将书签存储到URL并用一些标签对其进行注释。 A User有多个Urls(=书签)。每个Url都有一个日期,可以有一个或多个Tags

的书签可能具有以下基本结构:

{ 
    "user": "watQuadrat", 
    "url": "http://stackoverflow.com", 
    "date": 1494161436362, 
    "tags": [ "forum", "programming" ] 
} 

在这一点上我最大的问题是如何建立的表结构,这样我可以适应各种不同的方式中的数据可以查询,例如:

  • 列出所有TagsUser,由用户多久使用的标签
  • 列出所有Tags为排序,按字母顺序
  • 列出所有Tags分类为Url,通过这个标签是如何经常地给出了网址
  • 列出所有Tags匹配一个给定的搜索字符串,排序排序多久使用了标签(例如搜索“店”,返回匹配所有的标记,如由他们是如何经常使用“购物”的顺序)
  • 列出所有UrlsUser,按日期排序
  • 列出所有UrlsUserTag,按日期排序
  • 列出所有UrlsTag,由标签是如何经常地给每个URL
  • 列出所有UsersUrl,按日期排序排序

这将如何设计,以便我可以以高性能的方式执行所有这些查询?当您另外尝试降低成本时,您是否会设计出任何不同?

回答

1

考虑到您描述的情况,我会按照下面提到的设计表格。在这里,我假定一个用户只能从给定的url创建一个书签。此外,我还使用了一个名为TagCount的新派生属性,它表示该书签的标签计数。

表结构

主分区键:用户名

主排序关键字:URL

本地二级索引

指数1

分区键:用户名

排序键:日期

指数2

分区键:用户名

排序键:TagCount

全球辅助索引

指数1

分区键:URL

排序键:日期

指数2

分区键:URL

排序键:TagCount

有了这个设计您可以按照以下方式进行查询。

  • 列出所有标签的用户,通过数排序利用LSI用户名,TagCount

  • 列出所有标签为一个网址,通过计数

    查询排序

    查询使用GSI Url-TagCount

  • 列出匹配给定字符串的所有标签,按数量排序

    我假设您在此处指的字符串属于url。如果是这样,你将不得不进行扫描

  • 列出的所有URL的用户,按日期排序利用LSI用户id-日期

  • 列出所有网址,用户和

    查询标签,按日期排序

    查询LSI用户ID,日期表过滤器表达式搜索标签

  • 列出的所有URL的标签,通过数排序

    你必须做一个扫描这里

  • 列出所有用户一个网址,按日期排序

    查询URL-GSI日期

如果您关心成本。您可以根据您所期望的查询模式放弃一些GSI。

更新1

考虑到更新的要求,因为有基于标签的许多问题,我觉得应该有第二个表结构如下

主分区键:标签名 主排序关键字:用户名

全球二次Indexe

分区键:用户名

排序键:用途 - 衍生属性相似的标记计数,标签的总使用

+0

我想使用的用户标识作为分区键和URL作为排序关键也是。通过阅读你的答案,我意识到我没有足够精确地描述我的查询需求,所以我相应地更新了我的问题。我希望现在查询要求是可以理解的。 感谢您的帮助和见解! – Codepunkt

+1

嘿,这很有趣。我根据您提到的更新要求更新了答案。 – Asanka