如何在NoSQL中为经典的用户->许多关系应用程序数据建模

时间:2019-01-05 12:16:59

标签: nosql google-cloud-firestore

我注意到Google NoSQL,Firestore和DynamoDB等巨头提供的NoSQL解决方案没有联接查询(我不包括MongoDB和RethinkDB)。

我喜欢将它们用于简单性和成本优势的想法。

我喜欢JSON样式的文档数据库,并且不想回到VARCHAR等黑暗的日子。因此,我想知道如何利用它们来构建99%的Web数据库。

采取这种情况:

  

用户可以是许多项目的成员,他们可以在“项目列表”页面上查看其项目,并向下钻取到一个项目   详细信息页面。

相对来说这很简单:

user: { ..., projects: [projectId1, ...] }
project: { ..., users: [userId1, ...] }

然后您可以加入联接以在“项目列表”等上显示一些基本详细信息。

但是非关系NoSQL呢?我们将如何对此进行非规范化?

您是否只需:

user: { no project IDs },
project: { users: [userId1, ...] }

然后对于“项目列表”页面或“项目详细信息”页面,您只需对每个项目运行过滤器,然后返回用户所属的过滤器?就效率而言,这就是NoSQL所追求的吗?我在这里不处理庞大的数据集,我希望项目小于1万,而不是大型文档。谢谢。

1 个答案:

答案 0 :(得分:2)

针对您的应用用例的可能数据库架构可能是:

Firestore-root
   |
   --- users (collection)
   |    |
   |    --- userId (document)
   |         |
   |         --- userName: "John"
   |         |
   |         --- emailAddress: "john@gmail.com"
   |         |
   |         --- uid: "uidOfTheUser"
   |         |
   |         --- //other user data
   |
   --- projects (collection)
         |
         --- projectId (document)
               |
               --- projectName: "ProjectName"
               |
               --- projectId: "projectId"
               |
               --- users: ["uidOfTheUser", "uidOfTheUser"]

使用此数据库模式,您可以简单地:

  • 仅使用CollectionReference获取所有用户的所有项目:

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    CollectionReference projectsRef = rootRef.collection("projects");
    projectsRef.get().addOnCompleteListener(/* ... */);
    
  • 获取与单个用户对应的所有项目:

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    Query query = rootRef.collection("projects").whereArrayContains("users", uid);
    query.get().addOnCompleteListener(/* ... */);
    
  

我们将如何对此进行非规范化?

在这种情况下,无需对数据进行非规范化。但是,在Firebase上,这种denormalization做法是常见的做法。如果您不熟悉NoQSL数据库,建议您观看此视频Denormalization is normal with the Firebase Database,以更好地理解。它用于Firebase实时数据库,但相同的规则适用于Cloud Firestore。

此外,在复制数据时,需要记住一件事。用与添加数据相同的方式,您需要对其进行维护。换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。

另请参阅:

正如@FrankvanPuffelen在评论中提到的,请同时查看以下答案: