在SQL数据库中,如果我想访问某种嵌套数据,例如表格中每个项目的标签或类别列表,我必须使用一些不起眼的连接形式,以便发送一次SQL查询,然后只遍历结果游标。
我的问题是,在NoSQL数据库(例如MongoDB)中,可以重复查询数据库,以便我可以按如下方式执行上一个任务:
cursor = query for all items
for each item in cursor do
tags = query for item's tags
我知道我可以将标签存储在项目文档中的数组中,但我假设不可能将所有内容存储在同一文档中。如果是这种情况,重复查询数据库是否很昂贵,或者设计为以这种方式使用?
答案 0 :(得分:2)
不,在Mongo和任何其他数据库中都不应该在循环中查询数据库。其中一个很好的理由是性能:在大多数Web应用程序中,数据库是一个瓶颈,开发人员试图尽可能少地进行数据库调用,而在这里你试图尽可能多地创建。
我mongo你可以在很多方面做你想做的事。其中一些是:
{itemName : 'item', tags : [1, 2, 3]}
db.tags.find({ field: { $in: [<value1>, <value2>, ... <valueN> ] }})
答案 1 :(得分:1)
您应始终尝试使用尽可能少的查询来完成请求。请记住,即使数据库可以完全从缓存中回答每个查询,也需要在应用程序服务器,数据库和返回之间进行网络往返。
即使您假设两台服务器位于同一数据中心且只有几微秒的延迟,当您查询大量文档时,这些延迟时间也会增加。
关系数据库使用JOIN
命令解决了这个问题。但不幸的是,MongoDB不支持连接。因此,您应该尝试以最简单的查询可以由单个文档回答的方式构建文档。这意味着您应该对数据进行非规范化。当您具有1:n关系时,应考虑将引用文档作为数组嵌入主文档中。在MongoDB中,数据库中的冗余通常不像在关系数据库中那样不可接受。
当你仍然有充分的理由将子文档作为单独的文档保存时,你应该使用$in operator的查询一次查询所有文件,正如Salvador Dali在他的回答中所说的那样。