我注意到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万,而不是大型文档。谢谢。
答案 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在评论中提到的,请同时查看以下答案: