最近公司正在研发一个医疗行业的数据库,收录医疗创业公司,人,以及投资机构和医疗编辑们的知识,并将它们关联起来,以便后期的数据分析和编辑选题选素材。
在这种需求下,我们选用了Mongodb这种介于nosql和关系型数据库之间的一种数据库,本质上Mongodb不能单纯的归类为非关系型,虽然他是nosql文档型数据库,但并不意味着它不能有关系,纯nosql数据库应该是Redis,memcached这类key-value数据库,Mongodb是一种特殊的nosql,它采用json的方式存储数据,操作和使用都非常灵活,没有关系型数据库严格的类型长度和复杂的查询,我们的需求对于一个字段来说希望他是灵活的,但是也希望它能处理一些关系,所以Mongodb最适合我们。
传统关系型数据库在涉及一对多的情况下,通常会设置外键来关联,在涉及多对多的情况下,会采用中间表的方式。而Mongodb有个黑科技,因为它是以json存储的,所以,字段类型可以是Array,这样,就可以很方便的实现1 to n的情况,n to n也可以很方便的实现。
下面就说一下Mongodb的几种建模方式,网上的帖子大都是以1 to n为例,这里我们就以最复杂的n to n来说
1)内嵌文档
比如每个Person会有多个Address, 同一个Address又会存在不同的Person中。
{ name: 'Kate Monster1',
_id: ObjectId('ABCD'), addresses : [ { street: '123 Sesame St', city: 'Anytown', cc: 'USA' }, { street: '123 Avenue Q', city: 'New York', cc: 'USA' } ] }
{ name: 'Kate Monster2',
_id: ObjectId('ABCE'), addresses : [ { street: '123 Sesame St', city: 'Anytown', cc: 'USA' }, { street: '123 haidian E', city: 'Beijing', cc: 'CHA' } ] }
优点:一条语句就可以得到某个人的所有地址信息,查询效率无疑是最高的。
缺点:无法像操作独立文档那样来操作地址信息。你必须首先操作Person文档后,才有可能继续操作Address,而且对于单条文档的大小会有影响。
使用场景:不需要独立建表的信息,信息比较简单,数量很少,不值得单独做一个表,没有太多独立操作,但是又有n to n的需求(n < 100),n to n需要使用$elementMatch操作符来反向查询含有某条记录的所有记录。
2)内嵌文档id和中间字段
比如产品(Product)和零部件(part),每个产品会有很多个零部件,每个零部件又被用到了多个产品上,同一个零件在不同产品上的花费又是不一样的。
零部件(Part): { _id : ObjectID('AAAA'), name : 'xxx', price: 3.99 }
{ _id : ObjectID('BBBB'), name : 'xxx2', price: 5.99 }
产品(Product):
{
_id : ObjectID('ZZZZ'), name : 'Knife1', parts : [ { part_id: ObjectID('AAAA'), cost: 5 }, { part_id: ObjectID('BBBB'), cost: 7 } ] }
{
_id : ObjectID('YYYY'), name : 'Knife2', parts : [ { part_id: ObjectID('AAAA'), cost: 8 } ] }
优点:部件是作为独立文档存在的,你可以对某一部件进行独立的操作,比如查询或更新,有效减小了单个文档的大小,并且可以实现中间表字段的功能。
缺点:你必须通过两次查询才能找到某一个产品所属的所有部件详细信息,或者反向找到某个零件所属的所有产品。对文档的大小依然有压力。依然要通过产品来查询两种情况,除非你在零件表也建立一个Array,存放产品id,不过在更新关系字段的时候需要同时更新两边。
使用场景:需要独立建表的信息,信息比较复杂,但数量不是太多,有很多独立操作,但是又有n to n的需求(n < 1000),这是一种最常见的用法
3)完全按照关系型数据库的做法,建立外键(1 to n),或者建立中间表(n to n)
这种方式就不再赘述了,如果过度使用这种办法,建议不要使用Mongodb,还是使用关系型数据库更好一些
使用场景:信息关系极度复杂,数量巨大,有很多独立操作,又有n to n的需求(n > 1000)
最后附上一个官方链接:
http://blog.mongodb.org/post/87892923503/6-rules-of-thumb-for-mongodb-schema-design-part-2