`
huangz
  • 浏览: 322093 次
  • 性别: Icon_minigender_1
  • 来自: 广东-清远
社区版块
存档分类
最新评论

MongoDB数据库关系表示和设计:(1)嵌套文档和引用链接

 
阅读更多

使用数据的时候,一个数据项常常和另外的一个或多个数据项产生关系,比如一个“人”对象,有一个名字,可能有多个电话号码,以及多个子女,等等。

 

在传统的SQL数据库中,关系被分为一个个表(table),在表中,每个数据项以主键(primary key)标识,而一个表的主键又作为另一个表的外键(reference key),在两个表之间引用。当遇上多对多关系的时候,还需要一个额外的关联表(reference table),将多对多关系转化成两个一对多关系。

 

而在MongoDB中,表示关系有两种办法:

 

一种是嵌套(embedded),既是将一个文档包裹一个子文档;

 

而另一种是引用链接(reference link),使用MongoDB的DBRef对象建立文档和文档之间的关系。

 

除此之外,MongoDB的关系比起传统的SQL表关系更丰富一些,可以有 1对1 , 1对N , N对1 和 N对N 几种关系。

 

本文的目的就是探讨MongoDB表示关系的方法。

 

首先,让我们来看看MongoDB表示数据关系的两种方式:嵌套和引用链接。

 

嵌套

 

每个MongoDB文档都由BSON文档组成,有类似JSON格式一样的数据类型,其中String、Int、Float称为基本类型(或常量),而Hash和Array称之为复合类型。

 

所谓的嵌套,就是说文档中,利用复合类型,包裹一个多或多个其他类型的值,这些值称之为子文档。

 

文档嵌套的数量和深度没有限制,但MongoDB目前版本限制一个文档最大为16MB。

 

下面是一个典型的个人档案文档(profile),其中有一个 name 常量域,还嵌套了一个朋友(firends)子数组,数组里面每个项是一个字典。

 

>>> huangz
{'friends': [{'name': 'peter'}, {'name': 'john'}, {'name': 'marry'}], 'name': 'huangz'}

 

嵌套的好处是显而易见的:嵌套文档维持了数据逻辑上的完整性,可以将一整项数据作为一个整体来操纵。

 

对比在关系式的数据库中, 为了设计出符合范式的表,我们常常要将多个数据项分拆为几个表,然后通过外键获取数据。

 

当你阅读一个单独的表的数据时,你通常只看到了其中一部分数据,而其他的都是外键id,就像这样:

 

['name': 'huangz', 'friends_reference_id': [12, 26, 30]]

 

这种数据给人的感觉就像打开了一本电话簿,却发现里面只有电话号码,没有联系人姓名,真是太糟糕了阿。

 

 

引用链接

 

比起嵌套,引用链接更接近传统意义上的(也就是,关系型数据库术语中的)“引用”,它是两个文档之间的一种关系。

 

引用链接通过DBRef对象建立,DBRef对象储存了如何找到目标文档的信息,就像现实世界中的门牌号码一样(也类似关系型数据库中的外键)。

 

如果在一个文档A中,有一个DBRef对象,而这个DBRef对象储存了关于如何找到文档B的信息,那么文档A就可以通过解释这个DBRef对象(称之为解引用)来获取文档B的数据。

 

下面是建立一个文档的引用,以及解引用的过程,这次我们同样表示一个一对多的朋友关系,但这次,我们用链接来建立关系。

 

>>> # 数据
>>> peter = {'name':'peter'}
>>> marry = {'name':'marry'}
>>> john = {'name':'john'}
>>>
>>> # 插入数据
>>> c.test.people.insert([peter, john, marry])
[ObjectId('4e98075224b7d408dc000004'), ObjectId('4e98075224b7d408dc000005'), ObjectId('4e98075224b7d408dc000006')]
>>>
>>> # 建立huangz文档,以及指向各个朋友的链接
>>> huangz = {'name': 'huangz',
...     'friends': [ DBRef('people', peter['_id']),
...                  DBRef('people', john['_id']),
...                  DBRef('people', marry['_id']) ]}
>>>
>>> c.test.people.insert(huangz)
ObjectId('4e9807d924b7d408dc000007')
>>>
>>> # 查看huangz文档
>>> huangz
{'_id': ObjectId('4e9807d924b7d408dc000007'), 'friends': [DBRef('people', ObjectId('4e98075224b7d408dc000004')), DBRef('people', ObjectId('4e98075224b7d408dc000005')), DBRef('people', ObjectId('4e98075224b7d408dc000006'))], 'name': 'huangz'}
>>>
>>> # 对friends中的所有域进行解引用
>>> [ c.test.dereference(friend) for friend in huangz['friends'] ]
[{u'_id': ObjectId('4e98075224b7d408dc000004'), u'name': u'peter'}, {u'_id': ObjectId('4e98075224b7d408dc000005'), u'name': u'john'}, {u'_id': ObjectId('4e98075224b7d408dc000006'), u'name': u'marry'}]
  

OK,虽然有点复杂,但相信聪明的你还是可以看出,我建立了三个字典(Dict,或者说,Hash?)文档,将它们插入people集合。

 

然后使用 BDRef 函数,将集合名和字典的 id 作为参数,对每个字典生成一个 DBRef 对象,然后将三个DBRef对象保存到 friends 域当中。

 

在最后,我遍历 huangz 文档中的 friends 域,将所有 DBRef 对象解引用,获取了三个相应的子文档。

 

-----

 

附录

 

引用和解引用的API:

 

http://api.mongodb.org/python/current/api/pymongo/database.html?highlight=dereference#pymongo.database.Database.dereference

 

http://api.mongodb.org/python/current/api/bson/dbref.html#bson.dbref.DBRef

 

关于DBRef的官方文档:

 

http://www.mongodb.org/display/DOCS/Database+References

 

 

自动解引用

 

目前为止,我们看过了嵌套和引用链接两种使用子文档的方式,但是,慢着,嵌套和引用链接的区别是什么?

 

它们最大的区别似乎在于麻烦程度——嵌套文档可以直接使用子文档中的数据,而引用链接则要先解引用,然后才能获取子文档的数据。

 

如果你也觉得解引用相当麻烦的话,那我有一个好消息要告诉你:pymongo有一个超方便的特性,称之为“自动解引用”,就是每当 pymongo 在你文档中的数据域中发现包含有 DBRef 对象,你忠实的好朋友 pymongo 就会自动帮你进行解引用,你一个手指头都不用动!

 

看看使用自动解引用情况下,之前的 friends 例子:

 

>>> from pymongo.connection import Connection
>>> # 自动解引用所需的函数
>>> from pymongo.son_manipulator import AutoReference, NamespaceInjector
>>>
>>> # 连接数据库,并选择 test 数据库作为储存
>>> c = Connection()
>>> db = c.test
>>>
>>> # 魔法发生的地方。。。
>>> db.add_son_manipulator(NamespaceInjector())
>>> db.add_son_manipulator(AutoReference(db))
>>> 
>>> # 数据
>>> peter = {'name': 'peter'}
>>> john = {'name': 'john'}
>>> marry = {'name': 'marry'}
>>>
>>> # 将数据插入数据库
>>> db.people.insert([peter, john, marry])
[ObjectId('4e980fe824b7d41f52000000'), ObjectId('4e980fe824b7d41f52000001'), ObjectId('4e980fe824b7d41f52000002')]
>>>
>>> # huangz 文档
>>> huangz = {'name': 'huangz', 
...           'friends': [peter, john, marry]}
>>> db.people.insert(huangz)
ObjectId('4e98104324b7d41f52000003')
>>>
>>> # 看一看,文档里多了一些奇怪的东西。。。嗯。。。
>>> huangz
{'_ns': u'people', '_id': ObjectId('4e98104324b7d41f52000003'), 'friends': [{'_ns': u'people', '_id': ObjectId('4e980fe824b7d41f52000000'), 'name': 'peter'}, {'_ns': u'people', '_id': ObjectId('4e980fe824b7d41f52000001'), 'name': 'john'}, {'_ns': u'people', '_id': ObjectId('4e980fe824b7d41f52000002'), 'name': 'marry'}], 'name': 'huangz'}
>>> 
>>> # 试试提取 friends 域中的数据(注意这里我们没有手动进行解引用)
>>> huangz['friends'][0]
{'_ns': u'people', '_id': ObjectId('4e980fe824b7d41f52000000'), 'name': 'peter'}
>>>
>>> # wow,解引用自动完成了!再试试
>>> huangz['friends'][0]['name']
'peter'
>>>
>>> # 这里你可能会疑惑,我们是不是使用嵌套将数据放进了huangz文档里面,而实际上没有使用引用?
>>> # 答案是,不是的,我们使用了引用,看看 peter 文档,它有一个id
>>> # 证明 peter 文档是一个独立文档,而不是一个嵌入文档:
>>> peter
{'_ns': u'people', '_id': ObjectId('4e980fe824b7d41f52000000'), 'name': 'peter'}
>>>
>>> # 如果你还是不信,我们可以试试修改 peter 文档,然后再保存
>>> # 看看 huangz 文档里面的 peter,是否会变化
>>> peter['name'] = 'peter Liu'
>>> db.people.save(peter)
ObjectId('4e980fe824b7d41f52000000')
>>>
>>> # 哈,huangz 文档里面的 peter 也发生了变化,证明我们使用的
>>> # 是引用而不是嵌套,嘿,我可是童叟无欺、信誉良好的阿。
>>> huangz['friends'][0]['name']
'peter Liu'
 

在上面的代码中,我们增加了两个函数,为 db 绑定了两个构造器,从那之后,解引用就魔术般自动完成了。

 

好,这样一来,使用嵌套文档和使用引用链接似乎就没有什么不同了。

 

嘿嘿,现在我要问你一个严肃的问题了:使用嵌套文档和链接文档,究竟有什么不同?

 

请你尽可能地独立思考一下,然后再继续阅读下一节。

 

-----

 

附录

 

自动解引用的例子:

 

https://github.com/mongodb/mongo-python-driver/blob/cd47b2475c5fe567e98696e6bc5af3c402891d12/examples/auto_reference.py

 

 

嵌套 v.s. 引用链接

 

终于来到了谜底揭开的时刻了!如果答案你自己没想出来,也不用心灰意冷,毕竟我就是来告诉你这个的,如果你自己把答案想出来了,这反而没有意思了不是么?

 

关于嵌套和引用链接的真正区别是——它们的名字是不同的!

 

好吧,你一定已经知道这个了,其实,关于嵌套和引用链接的真正却别是——它们的英文名字是不同的!

 

好吧,你一定也已经知道了这个,那我们来说点严肃的。

 

嵌套和引用链接的区别在于,它们对待其他文档(子文档)的方式不同,于是它们获取获取子文档数据的方式也不同。

 

先来看嵌套,当我们将一个子文档,比如 friends 数组(它本身也是一个单独的文档)嵌套于 huangz 文档时, friends 文档其实和 huangz 文档是一体的,其实它们是一个文档,它们的数据储存在一起。

 

而对于引用链接,当你取出一个包含引用链接的文档时,文档里面的 DBRef 对象不会被解开,你取出的是一个包含 DBRef对象的子文档。而那些 DBRef 对象所指向的文档,它们是独立的一个个文档,从某个角度来看,和这个文档没有任何关系。(你对自动解引用感到疑惑么,我马上就会说到这个,请稍等。)

 

因此,每次,当你对DBRef执行解引用的时候,你需要一次额外的查询。

 

啊哈,这就是嵌套和引用链接之间的区别了!

 

我们用两个文档,一个嵌套,一个引用链接,解释查找它们的过程,来说明它们之间的区别。

 

先说嵌套文档,这个文档如下(跟我们之前看的一样):

 

>>> peter = {'name': 'peter'}
>>> john = {'name': 'john'}
>>> marry = {'name': 'marry'}
>>>
>>> huangz = {'name': 'huangz', 'friends': [peter, john, marry]}
>>>
>>> people.insert(huangz)
ObjectId('4e98e30b24b7d40a53000002')
>>>
>>> huangz
{'_id': ObjectId('4e98e30b24b7d40a53000002'), 'friends': [{'name': 'peter'}, {'name': 'john'}, {'name': 'marry'}], 'name': 'huangz'}

 

我们可以用 huangz 文档的 id 作为条件,查找 huangz 文档:

 

>>> people.find_one({'_id': huangz['_id']})
{u'_id': ObjectId('4e98e30b24b7d40a53000002'), u'friends': [{u'name': u'peter'}, {u'name': u'john'}, {u'name': u'marry'}], u'name': u'huangz'}

 

当执行上面的语句时,MongoDB会根据 id ,查找文档,它在数据库内部苦苦找寻,然后,终于找到了你所需的文档。

 

于是MongoDB就将文档返回给你,因为整个 huangz 文档——包括 name 数据域和 friends 数据域都放在一起,所以,执行这个文档只需要一次数据库查询,嗯,就是这样。

 

接着再来看看带有引用链接的文档是怎么处理的:

 

>>> peter = {'name': 'peter'}
>>> john = {'name': 'john'}
>>> marry = {'name': 'marry'}
>>>
>>> people.insert([peter, john, marry])
[ObjectId('4e98e41b24b7d40a53000003'), ObjectId('4e98e41b24b7d40a53000004'), ObjectId('4e98e41b24b7d40a53000005')]
>>>
>>> huangz = {'name': 'huangz',
...           'friends': [ DBRef('people', peter['_id']),
...                        DBRef('people', john['_id']),
...                        DBRef('people', marry['_id']) ] }
>>> people.insert(huangz)
ObjectId('4e98e4da24b7d40a53000006')

 

当我查找 huangz 文档时,会发生些什么?

 

>>> people.find_one({'_id': huangz['_id']})
{u'_id': ObjectId('4e98e4da24b7d40a53000006'), u'friends': [DBRef(u'people', ObjectId('4e98e41b24b7d40a53000003')), DBRef(u'people', ObjectId('4e98e41b24b7d40a53000004')), DBRef(u'people', ObjectId('4e98e41b24b7d40a53000005'))], u'name': u'huangz'}

 

你的老朋友MongoDB(现在你们应该很熟悉了)接到你的查询任务,然后开始在数据库再次苦苦寻找,然后,终于找到你需要的文档,于是,MongoDB返回这个文档。

 

寻找这个文档也只需要一次数据库查询(暂时和嵌套文件一样),但是,请注意,这个文档和之前的嵌套文档不同,它包含的不是你所需要的数据,而是 DBRef 对象,三个 DBRef 对象分别储存了如何去找到 peter、jhon 和 marry 文档的信息,但它们本身还不是你所找的数据(还记得那个只有号码没有姓名的电话簿吗?)。

 

“嘿,我们有 dereference 函数,可以用它进行解引用”,我猜你在这么想——你说得对,我们可以对 huangz 文档里的 friends 数据域中的三个 DBRef 文档进行解引用:

 

>>> for friend in huangz['friends']:
...     db.dereference(friend)
... 
{u'_id': ObjectId('4e98e41b24b7d40a53000003'), u'name': u'peter'}
{u'_id': ObjectId('4e98e41b24b7d40a53000004'), u'name': u'john'}
{u'_id': ObjectId('4e98e41b24b7d40a53000005'), u'name': u'marry'}

 

然后,慢着,在解引用的过程中,发生了什么呢?

 

首先,MongoDB接到第一个 DBRef 文件,上面指名我们所找的文档的 id 和 集合,于是乎,MongoDB就根据这个地址,去帮我们搜索 id 为 '4e98e41b24b7d40a53000003' 的文档,它苦苦找寻,终于发现了 peter 文档,于是,它将 peter 文档返回给你,这个过程需要一个数据库查询。

 

然后,MongoDB 接到第二个 DBRef 文件,上面又有一个新地址,于是 MongoDB 根据这个地址又开始查找,一阵搜索之后,它找到了 john 文档,并返回给你,这个过程又需要一个数据库查询。

 

再次,MongoDB 接到第三个 DBRef 文件,上面又有一个新地址,不辞劳苦的 MongoDB 再一次开始工作,这次,它找到并将 marry 文档返回给你,这个过程又需要一个数据库查询。

 

最终,你使用引用链接的文档获得了和嵌套文档一样的数据,但引用链接的文档使用了 4 次数据库查询(一次 huangz 文档,peter、john 和 marry各一次),而嵌套文档只使用 1 次数据库查询。

 

噢噢噢,你有种忽然明白了一些什么的感觉,是吗?

 

 

结论

 

OK,这时候,我们差不多该下结论说,为了最大效率地使用数据库,你应该尽可能地使用嵌套而不是引用链接来设计你的MongoDB文档,因为每次解引用都会带来一次额外的搜索,它的速度比使用嵌套的文档慢的多(取决于解引用的次数)。

 

但是还有几个微妙的问题,在下结论之前,需要好好地解释一下:

 

1. 自动解引用和手动解引用的效率是否不同?

 

答案是,自动解引用和手动解引用的效率是一样的,它们使用相同的数据库查询次数,

 

当你启用了自动解引用之后,pymongo每次发现你取出的文档里面带有 DBRef 对象时,它就帮你调用 deference 函数,获得 DBRef 所指向的文档的数据,但是,它不会也不可能将 4 次数据库查询换成 1 次数据库查询。

 

2. 使用引用链接,对效率的影响有多大?

 

答:一个包含引用链接文档所需的数据库查询次数正比于解引用的次数 + 1(获取这个文档本身),而所需的查询次数越多,就越慢。

 

像上面 huangz 文档的例子,引用链接版本理论上需要的时间就是嵌套版本的 3 倍。

 

3. 似乎嵌套文档真不错,但如果我有一个 weibo 文档(一个微博文档),它包括 name 和 message,两个数据域。


message 就是储存微博的数据域,而 name 则是用户名字,message 数据域肯定会比 name 数据域大很多,那么,这个 weibo 文档取出的速度,会受到 message 数据域的大小影响吗,name 数据域呢?

 

答:这的确是使用嵌套文档需要小心的地方,因为整个文档可能很大,如果你不小心使用查询语句,确保只取出必须的数据的话,你可能会浪费一些时间读取不必要的字段。

 

比如,以微薄为例子,假如你使用下面这个查询语句,所有属于 huangz 的微薄都会被取出来,这可能不是你想要的结果(比如文档里有 10万 条数据,但你只想取出前 100 条,那样的话,其他 9900 条数据都被浪费了)。

 

data = weibo.find_one({'name': 'huangz'})

 

而换成以下数据,你可以只取出最新100条数据,不浪费任何资源:

 

data = weibo.find_one({'name': 'huangz'}, {'message': {'$slice': -100}})

 

(你可能发现这个查询语句还是有一些问题,嗯,的确是这样,因为它取出来的数据是倒转过来的,也即是,最新发的微薄在最低下,我们以后再来解决这个问题。)

 

如果你在看别人的微薄,那时候你一条信息都不需要取出来,你只需要其他个人信息,比如 name,所以,你应该使用以下语句:

 

data = weibo.find_one({'name': 'huangz'}, {'message: 0})

 

实际上,使用引用连接的文档也有这个问题,而且比嵌套文档的情况更严重(因为它更慢)。

 

所以,无论什么情况下,请确保你使用了正确的查询语句,确保只取出所需的数据。

 

4.如果我先用一个查询取出一个嵌套文档的某一部分,再用另一个查询取出这个嵌套文档的另一部分,这比使用一个引用链接的文档快吗?

 

答:不,因为它们都需要两次数据库查询,效果相差无几。

 

---

 

附录

 

子域查询的语法 http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields

 

 

时间关系。。。

 

好了,这时候,你应该对“使用嵌套文档加上合理的查询,可以获得最高效率”这一结论深信不疑了。

 

嘿嘿,但我有个坏消息要告诉你,就是并不是所有文档关系都能使用嵌套文档来设计,有时候,必须用到引用链接。

 

不过,因为时间关系,以及为了点击量的可持续发展,我决定把这个问题和剩下的内容(1对1、1对N等关系设计和示例)留到下一篇博客再写。

 

嗯,就这样,我们下篇博文再见,bye bye。

 

---

 

附录

 

MongoDB schema design  http://www.mongodb.org/display/DOCS/Schema+Design#SchemaDesign-EmbeddingandLinking

 

 

 

 

分享到:
评论
9 楼 duolaimifa 2014-06-29  
嵌套好像会造成大量数据冗余吧?
8 楼 eimsteim 2014-02-22  
请教一下:如果使用嵌套方式,如果我在被引用的Collection中插入了新的数据,会被同步更新到引用它的Collection中去吗?
7 楼 ls5231 2013-06-09  
>>> # 哈,huangz 文档里面的 peter 也发生了变化,证明我们使用的 
>>> # 是引用而不是嵌套,嘿,我可是童叟无欺、信誉良好的阿。 
>>> huangz['friends'][0]['name'] 

huangz引用了peter那个对象,而peter对象的name发生变化了,huangz['friends'][0]['name'] 当然会变了。而是应该从数据库重新获取huangz来看是不是发生变化了
6 楼 xiao_yaya_happy 2012-10-26  
有幽默感,写的不错。适合新手学习。
5 楼 lisengl 2012-08-13  
4 楼 huangz 2012-04-06  
jzaileen 写道
autoreference 这个是pymongo的特性,不是mongodb的特性,mongodb只有DBRef,需要自己去做单笔查询。


的确是这样,写的时候把 mongodb 和 pymongo 搞混了,谢谢提醒。
3 楼 jzaileen 2012-04-06  
autoreference 这个是pymongo的特性,不是mongodb的特性,mongodb只有DBRef,需要自己去做单笔查询。
2 楼 huangz 2011-11-24  
@austincao

hi,关于你说的问题,我没有遇到过,不过我有一些疑问,如果你能提供更详细的信息的话,我也很有兴趣进行进一步的讨论:

1. 你的文档多出来的 20% 是从那里来?

2. 你说你的应用 insert 操作只有 40%, 既然是读多写少的情况,为什么还会频繁引起 move chunk ?

嗯,直觉给我的感觉是你的每个文档都“非常大”,所以才会出现这样的问题。

如果真的是那样的话,或许你应该考虑对你的数据库设计进行改进,比如说, mongodb 提供了 database , collection 和 document 三个级别的储存单位,你可以通过将 document 无关的部分分离到别的 collection ,将无关的 collection 分离到其他 database ,然后通过 reference link 关联,等等。

有时候引入一些 reference link 取代嵌套也未尝不可,毕竟在代码级别上用起来是一样的(有自动解引用),如果嵌套确实引起了效率问题,尽管把它分离出去就是了。

至于分多细,怎么分,就要看个人情况了和测试数据了,没有 one size fit all 的办法。

:)
1 楼 austincao 2011-11-24  
使用嵌套文档, 我的doc平均大小会增大20%,这种以空间换时间的策略是否就是最好的呢? 占用磁盘空间大了也会带来很多问题,比如加速了chunk分裂和移动,查询也会受影响。

我之所以这么说, 是因为我现在正碰到一个问题:由于move chunk, 我的mongodb集群的写性能下降很厉害, 通过mongostat观察, 60%的情况下insert都是0. 我这还没敢用Replica set, 都是一个mongod作为一个shard。

如有可能,希望和您继续深入讨论

相关推荐

    MongoDB数据库应用.docx

    1. 学习曲线陡峭:MongoDB 的查询语法和数据模型不同于传统的关系型数据库,对于初学者来说可能存在一定的学习成本。 2. 不支持事务:MongoDB 不支持事务操作,对于需要事务支持的应用场景不太适合。 Windows 下 ...

    mongodb数据库以及可视化客户端软件

    1. **文档型数据库**:MongoDB使用JSON-like的BSON格式存储数据,这种格式易于理解和处理,同时支持嵌套的数据结构,适合存储复杂的数据模型。 2. **分布式架构**:MongoDB支持分布式部署,可以跨多个服务器、数据...

    MongoDB数据库

    1. **文档型数据模型**:MongoDB以BSON(Binary JSON)格式存储数据,这种格式是JSON的二进制形式,支持丰富的数据类型,如字符串、数字、日期、数组和嵌套文档。 2. **弹性伸缩**:MongoDB支持水平扩展,通过添加...

    mongodb数据库第一阶段:基础

    深入了解MongoDB的文档模型、数据类型、查询语法以及管理功能,是掌握MongoDB数据库的第一步。在后续的进阶和实战学习中,会涉及更复杂的查询优化、备份恢复、安全性以及分布式部署等高级主题。

    Mongodb数据库和可视化工具robo3t-1.3.1安装包

    MongoDB是一种流行的开源、分布式文档型数据库,广泛应用于大数据存储、实时分析以及现代Web和移动应用。MongoDB以其灵活性、高性能和易于扩展性而著称,尤其适合处理半结构化的数据。它采用NoSQL数据库模式,不同于...

    mongodb数据库

    相比于传统的关系型数据库,MongoDB避免了复杂的多表关联,可以在单一文档中存储完整的业务数据,如电影、影评和影评回复,大大减少了数据模型设计的复杂性。 MongoDB的安装过程相对简单,主要步骤包括下载最新稳定...

    mongodb数据库-4.0.9版本.rar

    MongoDB是一款开源、分布式、文档型的数据库系统,以其高性能、高可用性、易扩展性和丰富的功能在IT行业中广受欢迎。4.0.9版本是MongoDB的...通过提供的安装包,用户可以轻松在Windows环境中部署和管理MongoDB数据库。

    koa 分别 连接 mysql、mongodb数据库操作.zip

    在MongoDB中,数据是以文档的形式存储的,文档是一个键值对的集合,并且文档支持嵌套和数组。MongoDB中的一个文档相当于关系型数据库中的一行,多个文档构成了集合(collection),集合类似于关系型数据库中的表。 ...

    mongodb数据库idea测试.zip

    在MongoDB中,数据是以文档的形式存储的,文档是一个键值对的集合,并且文档支持嵌套和数组。MongoDB中的一个文档相当于关系型数据库中的一行,多个文档构成了集合(collection),集合类似于关系型数据库中的表。 ...

    MongoDB数据库:MongoDB与微服务架构集成

    - **文档存储模型**:MongoDB使用BSON(Binary JSON)格式存储数据,允许存储复杂的数据结构,如嵌套文档和数组。 - **灵活的查询语言**:提供了丰富的查询语言,支持复杂的查询操作,包括聚合、排序、过滤等。 - **...

    Spring boot连接mongoDB数据库.zip

    在MongoDB中,数据是以文档的形式存储的,文档是一个键值对的集合,并且文档支持嵌套和数组。MongoDB中的一个文档相当于关系型数据库中的一行,多个文档构成了集合(collection),集合类似于关系型数据库中的表。 ...

    里面node以及mongodb数据库学习的一些笔记和练习.zip

    在MongoDB中,数据是以文档的形式存储的,文档是一个键值对的集合,并且文档支持嵌套和数组。MongoDB中的一个文档相当于关系型数据库中的一行,多个文档构成了集合(collection),集合类似于关系型数据库中的表。 ...

    腾讯 APIJSON 的 MongoDB 数据库插件.zip

    在MongoDB中,数据是以文档的形式存储的,文档是一个键值对的集合,并且文档支持嵌套和数组。MongoDB中的一个文档相当于关系型数据库中的一行,多个文档构成了集合(collection),集合类似于关系型数据库中的表。 ...

    mongoDB数据库,解压直接使用

    标题中的“mongoDB数据库,解压直接使用”意味着你将收到一个包含MongoDB软件的压缩文件,解压后可以直接启动数据库服务。在提供的描述中提到,解压后的MongoDB文件夹中,"bin"目录包含了一组可执行文件,其中...

    MongoDB数据库、图形界面、应用jar包、文档

    MongoDB是一种流行的开源、分布式文档型数据库,设计用于处理大量数据并提供高可用性和高性能。在本文中,我们将深入探讨MongoDB的四个关键方面:数据库本身、图形界面工具、应用程序jar包以及官方文档。 首先,让...

    Python操作MongoDB数据库的基本一些操作 .zip

    在MongoDB中,数据是以文档的形式存储的,文档是一个键值对的集合,并且文档支持嵌套和数组。MongoDB中的一个文档相当于关系型数据库中的一行,多个文档构成了集合(collection),集合类似于关系型数据库中的表。 ...

    php+mvc+mongodb数据库基本操作

    3. **灵活的数据模型**:支持嵌套数据结构,易于表示复杂关系。 4. **强大的查询能力**:支持丰富的查询表达式和聚合框架,可以方便地进行数据分析。 5. **文档数据库**:每个文档都是自包含的,无需预先定义模式,...

    MongoDb 数据库介绍、安装、使用1

    使用 MongoDB 包括启动数据库服务、连接数据库、创建集合(等同于关系数据库中的表)、插入文档、查询数据、更新和删除记录等操作。例如,使用 `mongod` 命令启动服务,然后通过 `mongo` 命令进入 MongoDB shell ...

    腾讯云-mongodb数据库, 项目部署.zip

    在MongoDB中,数据是以文档的形式存储的,文档是一个键值对的集合,并且文档支持嵌套和数组。MongoDB中的一个文档相当于关系型数据库中的一行,多个文档构成了集合(collection),集合类似于关系型数据库中的表。 ...

    Mongodb数据库介绍ppt

    ### MongoDB数据库介绍 #### MongoDB简介 MongoDB是一种非关系型(NoSQL)的文档数据库,以其灵活的数据模型、高性能和可扩展性而闻名。它采用C++语言编写,支持多种操作系统,包括Windows、Linux和Mac OS。作为一...

Global site tag (gtag.js) - Google Analytics