引用:http://blog.csdn.net/adparking/article/details/38727911
MongoDB的应用场景在网上搜索了下,很少介绍关于传统的信息化应用中如何使用MongoDB数据库方面的内容,比较多的还是介绍日志的采集和存储,小文件的分布式存储,类似互联网微博应用的数据存储等方面的内容。在这里思考下传统企业信息化系统中的应用可行性。
首先对于NoSQL数据库,在数据库建模上需要重点考虑,彻底放弃传统的关系型数据库建模方法,如果将传统的关系型数据库表原封不动的映射到NoSQL数据库,很多NoSQL数据库本身的优点特性反而无用武之地。其中最重要的就是转化为面对对象的思维模式,更加关注领域对象和实体信息。MongoDB数据库的集合本身就是一个可以包罗万象的层次化的文档对象,集合本身还可以包含子集合,形成一个完整意义上的对象。
如果拿一个最简单的企业客户信息管理功能来说,可以看到首先要维护有哪些企业客户,企业客户的常用联系人,每个人的联系方式,企业相关的资料文档,企业的地址信息,企业的账户信息,争取企业的拜访记录等,这里讲的就是一个最简单的企业客户域的对象信息。
按道理来说企业信息就是一个完整的对象,企业附属对象都从属于企业这个对象,企业这个信息没有了其余附属对象信息的生命周期也就结束。如果按这个意义上来说只需要简历一个collection集合就可以管理所有事情。但是我看到企业客户包括了两方面信息,一个是偏静态信息,如企业基本信息,联系人,联系地址信息;一个是偏动态信息,即企业的拜访记录等。考虑了企业拜访记录本身变动频繁是动态信息,可以将企业拜访记录拆分出来单独做为一个文档对象来管理。如果这样的话,要完善以上功能只需要建两个文档对象,一个是企业客户基本信息,一个是拜访记录信息。另外还有一个文件存储功能,直接使用MongoDB的GridFS来完成即可。
在企业客户信息中,企业客户即一个集合,在该集合中联系人信息为子集合,联系人的联系方式(多种联系方式)信息可以有两点考虑,一个是子子集合,也可以直接将多种联系方式归并到联系人对象一层,由于MongoDB的属性字段本身就可以方便的扩展,这样设计可以减少整个集合的层次。(在这里我的考虑就是,对于1对多关系,对于子表本身就只有一个字段的都可以考虑合并到父对象里面减少层次)。这些信息往往在客户基本信息录入的时候就需要完整录入,一个完整的JSON对象格式可以很方便的作为一个整体存入到MongoDB数据库中。
对于客户的拜访记录由于动态经常增加,可以单独设置一个对象,在该对象中增加客户ID,客户名称信息冗余,减少后续查询功能中不必要的对象关联。对于这个对象我们可以看到会经常增加数据,但是实际增加的数据本身变动却很少。在拜访记录中如果还有和本次拜访相关的图片或文档存储,也可以很方面的解决问题。
对于客户文档资料存储,前面已经说过了直接使用GridFS来完成即可。GridFS是MongoDB的一个内置功能,它提供一组文件操作的API以利用MongoDB存储文件。对于刚才的场景可以看到,对于增加一个客户资料的存储首先调用文件存储API完成非结构化文件的存储,存储完成后可以返回文件句柄ID,这个句柄ID可以做为一个子集合直接存储在客户主Collection对象上,也可以单独建立一个客户ID和文件句柄ID的关联表,但是个人认为直接建立在客户主集合对象似乎更好。
基于以上基本思路来分析实际客户信息管理需要的具体功能点。
客户信息新增功能,在新增界面上需要维护客户基本信息,客户的联系人,地址信息,客户的文档资料信息,如果不考虑非结构文档附件,整个页面本身就是一个完整的JSON对象,可以只调用一次即完成整个层次化集合对象的存储,而且相当简单。考虑到附件信息,即操作分为两个步骤,首先上传存储附件获取附件句柄ID,然后再存储结构化客户基本对象信息。对于客户拜访记录信息,录入客户拜访记录首先肯定是要选择到具体的客户,选择到具体客户后,客户的ID信息,客户的名称信息即已经可以获取到。新增加一条拜访记录也是相当简单的操作即可以完成。
再来看查询功能,首先看客户信息查询可能是一个模糊查询功能,而MongoDB对模糊查询性能是比较弱的,因此尽可能的减少不必要模糊查询字段,对于必须的查询字段可以在MongoDB对象中增加相应的索引信息。最重要的就是基于MongoDB数据库对Join操作的支持很弱,应该在数据模型设计和查询设计上尽可能的减少不必要的对象关联操作。当查询到某一个具体的客户信息后,需要查看该客户具体的拜访记录就相当简单的,只是对拜访记录表最简单的根据客户ID的一个类where操作即可完成。对于客户具体的附件列表信息可以做相似的设计,即点击链接后再进入到具体的客户附件文档查看界面。
对于更新功能,基本对象的更新也相当简单,剩下的就是对于联系人信息的更新,联系人信息是一个子集合对象,在这里暂时还没有看到是需要对这个子集合对象全部更新掉,还是可以做到只更新操作子集合对象中的一条记录。对于更新操作,仍然需要定位到具体的ID值再进行更新。对于批量更新现在MongoDB本身也提供了相应的操作,类似批量更新客户状态操作还是很容易实现的。
以上只是一个最简单的分析,基于这种分析,以后对于类似主数据管理系统的应用完全可以迁移到MongoDB数据库来支撑。另外对于记录更新不频繁,对象直接相互关联和影响小的场景也适合迁移到MongoDB数据库。在NoSQL数据库的使用过程中应该尽量避开类似强一致性要求,表间关系复杂,长周期事务等场景。