每当我考虑使用NoSQL解决方案时,我总是对缺乏丰富的查询功能感到困惑。我认为很好的是我对NoSQL缺乏了解。这也可能是因为我对SQL非常熟悉。根据我的理解,NoSQL非常适合简单的架构场景(因此对于你有50多个表的关系数据库来说,它可能不会很好用)。即使对于琐碎的场景,我似乎总是想要丰富的查询功能。让我们把食谱数据库作为一个简单的例子。
虽然这个计划,毫无疑问,琐碎的你肯定会想要丰富的查询能力。您可能希望通过以下(以及更多)进行搜索:
您还希望将这些条件组合成您想要的任何组合。虽然我知道大多数NoSQL解决方案都有二级索引,但这种查询能力是否严重限制了NoSQL与之相关的解决方案数量?我通常需要这种丰富的查询能力。另一个很好的例子是bug跟踪应用程序。
我不认为你想在每次想要搜索数据库时开始减少作业(我认为这类似于在传统的关系模型中大多数情况下进行表扫描)。所以我认为会有很多查询,你必须遍历每个实体并寻找你想要搜索的标准(这可能会很慢)。据我所知,您可以运行夜间地图减少作业,以分析数据或将其标准化为典型的报告关系数据库结构。
现在我可以看到它对于你很可能总是必须阅读所有数据的场景非常有用。想想一个Web服务器日志,或者可能是IoT类型的应用程序,您可以收集大量数据(如审查员收集)并进行夜间分析。
对NoSQL的了解是否正确,或者我与之合作的场景数量是否有限制?
答案 0 :(得分:2)
我认为您遇到的问题是您正在使用与SQL相同的设计思维方式来接近noSQL。你提到了#34;富查询"几次。对我来说,这指向设计缺陷(仅使用参考ID /尝试定义关系)。 noSQL中的一个重要概念是数据可以重复(通常应该是)。您的配方示例实际上是noSQL的一个很好的用例。以下是我使用你提到的3个模型(为简单起见)接近它的方法:
Recipe = {
_id: a001,
name: "Burger",
ingredients: [
{
_id: b001,
name: "Beef"
},
{
_id: b002,
name: "Cheese"
}
],
createdBy: {
_id: c001,
firstName: "John",
lastName: "Doe"
}
}
Person = {
_id: c001,
firstName: "John",
lastName: "Doe",
email: "jd@email.com",
preferences: {
emailNotifactions: true
}
}
Ingredient = {
_id: b001,
name: "Beef",
brand: "Agri-co",
shelfLife: "3 days",
calories: 300
};
我以这种方式设计它的原因明确是为了它的存在(假设它像allrecipes.com一样)。搜索/过滤食谱时,您可以按作者进行过滤,但其电子邮件首选项无关紧要。同样,成分的保质期和品牌也无关紧要。该架构是针对特定用例而设计的,不仅仅是因为您需要保存数据。现在,这里有一些你提到的查询(mongo):
db.recipes.find({name: "Burger"});
db.recipes.find({ingredients: { $nin: ["Cheese", "Milk"]}}) // dietary restrictions
您的丰富查询问题现已减少为单个集合中的单个查询。
这种设计的缺点是写入速度较慢。在后端需要更多逻辑,可能会出现更多程序员错误。由于访问各种模型以获取相关信息,写入速度也比SQL慢。话虽如此,它的查看频率与编写/编辑的频率有多长? (这是我对阅读特朗普写作的评论)另一个主要缺点是远见的必要性。成分和配方之间的关系不会改变形式。但是您的应用程序可能需要的信息。编辑noSQL模型往往比编辑SQL表更困难。
这是另一个使用相同模型强调我有目的设计观点的人为例子。假设您的新网站位于着名厨师而不是食谱数据库中:
Person = {
_id: c001,
firstName: "Paula",
lastName: "Deen",
recipeCount: 15,
commonIngredients: [
{
_id: b001,
name: "Butter",
count: 15
},
{
_id: b002,
name: "Salted Butter",
count: 15
}
],
favoriteRecipes: [
{
_id: a001,
name: "Fried Butter",
calories: "3000"
}
]
};
Recipe = {
_id: a001,
name: "Fried Butter",
ingredients: [
{
_id: b001,
name: "Butter"
}
],
directions: "Fry butter. Eat.",
calories: "3000",
rating: 99,
createdBy: {
_id: c001,
firstName: "Paula",
lastName: "Deen"
}
};
Ingredient = {
_id: b001,
name: "Butter",
brand: "Butterfields",
shelfLife: "1 month"
};
这两种设计都使用相同的信息,但它们是根据您收集信息的特定原因建模的。现在,您拥有厨师列表页面和典型排序/过滤的必要信息。您可以从那里导航到配方页面并提供该信息。
设计用例,而不是模型关系。