noSQL的新手,尤其是Firebase。我有一个从Firebase检索到的文章列表,其中包含以下基本结构:
{
"Items" : [ {
"ArticleID" : 0,
"Title" : "Article1",
"Teaser" : "Lorem Ipsum Dolor",
"PublishDate" : "2017-05-23",
"ArticleText" : "Some article text here...",
"Category" : "Sports"
},
{
"ArticleID" : 1,
"Title" : "Article2",
"Teaser" : "Lorem Ipsum Dolor",
"PublishDate" : "2017-05-22",
"ArticleText" : "Some article text here...",
"Category" : "World"
},
{
"ArticleID" : 2,
"Title" : "Article3",
"Teaser" : "Lorem Ipsum Dolor",
"PublishDate" : "2017-05-23",
"ArticleText" : "Some article text here...",
"Category" : "US News"
}
],
"UserActions" : [
{
"UID" : "3049873049870987x87098",
"ArticleID" : 0,
"Read" : true,
"Liked" : true,
"Saved" : false
},
{
"UID" : "3049873049870987x87098",
"ArticleID" : 2,
"Read" : true,
"Liked" : false,
"Saved" : false
}
]
}
当注册用户正在查看/浏览文章时,我们需要知道他们是否已经阅读过文章,喜欢它或保存它以供日后阅读,以便我们在文章旁边显示相应的图标。
我不确定我是否正确构建了这个。有些东西告诉我,我在这里潜入旧的关系数据库习惯。
答案 0 :(得分:4)
NoSQL数据库的建模最重要的是取决于应用程序中的用例。对于一些可预测的用例,我看到一件事你做得很好,有一件事可以改进。
对于想要在文章本身下嵌套用户操作的常见陷阱,你并没有堕落。我不确定这是你的SQL背景,但它是正确的解决方案。在大多数应用中,您不必在阅读文章列表的同时阅读用户操作。保持它们分开使这成为可能。它还允许您为文章和用户操作保留单独的安全规则。
但是...
在您当前的解决方案中,您已将用户操作建模为平面列表。此列表最常见的用例之一可能是针对特定用户的操作。现在,您需要查询(可能非常小的)操作子集的所有用户操作的列表。随着时间的推移,这可能会成为可扩展性限制。
最好根据您想要的方式构建数据。如果您想经常为用户获取操作,请存储每个用户的操作:
"UserActions": {
"3049873049870987x87098": {
"ArticleID" : 0,
"Read" : true,
"Liked" : true,
"Saved" : false
},
{
"ArticleID" : 2,
"Read" : true,
"Liked" : false,
"Saved" : false
}
}
现在阅读特定用户的操作列表就像在/users/<UID>
下阅读(而不是查询)数据一样简单。
如果您还希望用例能够显示喜欢特定文章的用户,那么您还希望保留上述结构的反转版本,例如ArticleActions
。这种重复数据一开始可能会感觉不自然,但是拥有一个随用户/文章/行动数量而扩展的数据库是关键。