MongoDB与传统数据库的使用区别——批量插入与批量查询
我在百X知道上回答问题时经常遇到类似与这样的问题:MongoDB有没有像MySQL一样的ODBC驱动?MongoDB能不能像MySQL一样获取字段名称或类型。
我的回答是:不行,因为MongoDB不是MySQL。这个回答显得MongoDB太弱了,我的原意是你不能要求一个物理优秀教师帮你辅导数学,也许他能做到基本的教学,但他很难做到优秀数学教师那么全面。
今天讨论的问题是:批量插入和批量查询
昨天在百X知道上有人问起MongoDB的批量插入如何写,这个我还真没用过,一方面MongoDB的速度足够快让我从来没有想过去找这种方法,另一方面MongoDB的官网以及API里也找不到这种方法。
那就带来两个问题。
问题1:这样岂不是没有速度更快的批量插入么?
这个问题毫无技术含量,MongoDB怎么可能会比MySQL慢?这里还是涉及到大家经常用到的传统关系型数据库和NoSQL的本质区别问题,NoSQL的每次操作都非常轻量级,小型化,除了数据的写入外基本没有多余的操作。再举个栗子:MongoDB就是放东西(数据)时把东西扔入相应的柜子(数据库)即可,而MySQL则要保持与送东西人的沟通(双向连接保持),东西的折叠整理分格存储(事务+有模式)。MySQL的批量插入就是减少了沟通以及分格等过程,而MongoDB本身就不存在这些过程,因此MongoDB就不存在批量插入这个概念了。结论就是,MongoDB的普通插入比MySQL的批量插入还要快,或者说MongoDB的普通插入就是批量插入。
问题2:把多个操作放入一个事务里一起执行不就不能实现了?
这个问题更没有技术含量了,MongoDB有事务么?还是那句,不要把NoSQL当关系型数据库用。那岂不是MongoDB的数据完整性和数据安全性会很差?这个,还得再重复一遍,MongoDB的设计是为了处理大规模数据的,所以对数据完整性要求不是那么严格。如果非要较真儿的话,MongoDB也可以处理这种情况,就是getLastError,它会牺牲性能以获取数据操作是否正确,你可以在批量插入一批数据后调用一次这个方法,如果出错,就把这批数据重新操作一遍,一批调用getLastError一次,既可保证性能,又可保证数据安全。
批量查询
再来说一下批量查询,这里的批量对应于官网上的batch select的概念,可以理解为一次查询一批数据。很多人在使用数据库的时候会用:
Statement stmt = a.createStatement();
ResultSet rs = stmt.executeQuery(sql);
for(int i = 1; i < 10000; i++){
//read data from rs
}
这样操作,会把数据库中的数据全部读入内存还是每条数据都去数据库中读一次?实际上两者都不是,MySQL会把部分数据放入内存,如果这部分数据读完了,那么再读入一部分。因为很久没用MySQL了,我记得C++的驱动中确实有一个类是用于把全部数据都读入内存的,不过这种方法很少人使用。
MongoDB的查询是这样的,你用Cursur去查询,如果没有设置batch size这个参数,那么MongoDB默认会返回101条数据,等到这101条数据读完了,也就是说用户想读第102条数据,那么驱动会再次去MongoDB中获取后面的一批数据,这批数据不是以个数记的,而是最大限制4M的大小,将这4M的数据返回供用户继续读,读完再申请4M。当然,你可以通过batch size来改变这一数值,如果设置了,那么每次返回都会返回batch size条数据。
转载请注明出处:http://blog.sina.com.cn/s/blog_56545fd301013zav.html