Mongo架构:带有组的待办事项列表

时间:2014-08-19 12:44:52

标签: mongodb nosql

我想学习mongo并决定为学习目的创建一个更复杂的待办事项。

基本思想是任务列表,其中任务分组在文件夹中。用户可以对这些文件夹(读取,写入)具有不同的访问权限,并且可以将任务移动到其他文件夹。通常(特别是对于同步)任务将由文件夹而不是单独请求。

基本上我考虑了三种方法,并希望听取您的意见。也许我错过了一些观点或者只是错误的思考方式。

A - 参考列表

  • 收藏集:UserFolderTask
  • Folders包含对Users
  • 的引用
  • Folders包含对Tasks
  • 的引用

问题

  • 更新Task时,需要对Folder的引用。这些引用都存储在Task(冗余)中,或者必须在每次API调用时传递。

B - 子文档

  • 收藏集:UserFolder
  • Folders包含对Users
  • 的引用
  • TasksFolders
  • 中的子文档

问题

  • 无法在不知道Task的情况下更新Folder。两者都需要传输,但与A相比没有冗余。

C - 参考文献

  • 收藏集:UserFolderTask
  • Folders包含对Users
  • 的引用
  • Tasks保留对Folders
  • 的引用

问题

  • 申请文件夹意味着在长列表中搜索而不是直接引用(A)或只返回文件夹(B)。

1 个答案:

答案 0 :(得分:7)

如果您不需要该文件夹的任何元数据,除了您可以使用的名称:

  • 收藏集:UserTask
  • Task有字段folder
  • User包含数组read_accesswrite_access

然后

  • 您可以使用

    获取所有文件夹的列表

    db.task.distinct("夹&#34)

  • 当您检索用户文档时,将自动检索特定用户可以访问的文件夹,以便在登录时基本知道这些文件夹。

  • 您可以使用

    获取用户可以阅读的所有任务

    db.task.find({folder:{$ in:read_access}})

    read_access使用您从用户文档中获得的相应数组。与write_access相同。

  • 您可以使用文件夹名称的简单查找查询找到文件夹中的所有任务。

  • 可以通过对每个集合进行一次更新查询来重命名文件夹。

  • 创建文件夹或将任务移动到另一个文件夹也可以通过简单的方式实现。

因此没有文件夹的元数据就是我要做的。如果您需要文件夹的元数据,它可能会变得有点复杂,但基本上您可以使用包含_id元数据的文件夹集合来管理独立于上述任务和用户的那些元素usertask


修改

不同方法的比较

偶然发现this link可能对你感兴趣。在讨论从关系数据库模型转换到mongo。您通常会尝试使用关系数据库中的差异third normal form,其中一个目标是避免偏向任何形式的访问模式,在mongodb中,您可以尝试对数据建模以最适合您的访问模式(同时请记住不要通过冗余引入可能的数据异常)。

考虑到这一点:

  • 您的模型 A 是您在关系数据库中执行此操作的方式(通过ID引用的一个表中的每种类型的信息)
  • 模型 B 将针对访问模式进行定制,您始终会列出完整的文件夹,并且只有在打开文件夹时才会编辑任务(如果您检索一个文件夹,则无需额外的任务即可完成所有任务查询)
  • C 将是一个与 A 不同的关系模型,我认为更接近第三范式(不知道确切的表格)
  • 我的建议是支持文件夹访问不如 B 那样最佳,但会更容易显示和编辑单个任务

模式可能出现的问题:由于 A C 基本上是关系型的,因此你可能会遇到外键问题,因为mongodb不会强制执行外键约束(例如,您可以删除文件夹,但仍有任务在 C 中引用它,或者在 A 的文件夹中没有删除其引用的任务时删除。您可以通过从应用程序强制执行它来规避此问题。对于 B ,通过允许文件夹在达到特定任务计数时拆分为多个文档,16MB文档限制可能成为一个可以避免的问题。

所以新的结论:我认为 A C 可能不会向您显示mongodb的优势(甚至可能在mongodb中构建比在sql中更多的工作)它们就是你在传统的关系数据库上所做的,这是mongodb的设计方式(例如缺少连接语句,没有外键约束)。总而言之, B 大多数都匹配您的访问模式"通常(特别是对于同步)任务将按文件夹"同时在文件夹打开后仍然可以轻松编辑和移动任务。