mongodb -- sqlserver数据转移到mongodb

现在有一个2000万级别的数据量的数据库,数据存在sqlserver 20008中。想要将此数据转移到mongdb中。网上有看说有个工具可以将mysql的数据直接转移到mongodb中,但是又要将sqlserver 2008数据先转移到mysql中,各种折腾后,各种试验,楞是没能成功,一怒之下,自己动手写程序来做这个数据迁移。

之前有讲到mongodb一次性插入10000数据的效率,确实很快,然后也测试了下,从sqlserver 一次性选择10000条数据也是在1秒之内,想想,干脆一不做二不休,写了一个程序,采取for循环 每次从数据库取10000条,然后插入mongdo,直到循环完所有数据。2000万条数据,对于计算机而言,小事啊 为了这个,特意做了下效率问题,测试了下,一次循环下来,3秒之内能解决,算算,一分钟就是20万数据,二个小时就可以完全搞完。(事实也确实如此,一个多小时搞定了,早知道如此,就不要花了那么多时间去找工具,找各种导出教程,各种纠结,各种安装);

  数据库结构很简单,是一个比较出名的某某hotel的数据,纯学术研究。

mongodb -- sqlserver数据转移到mongodb_第1张图片

程序代码我放在这里了:有兴趣的朋友可以看看。勿喷。如果你有更好的办法。欢迎留言;

CSDN git 仓库地址:

[email protected]:chenqiangdage/sqltomongo.git

项目地址:

https://code.csdn.net/chenqiangdage/sqltomongo/tree/master


程序每次从sqlserver 中取10000条数据。之所以这样,因为改表主键id是连续而且从1开始。所以每次循序取10000条,这样就能保证取到所以的数据了。

  public static DataSet SelectData(DataSet dt,string query)
       {           
           cmd = new SqlCommand(query, sqlconnection);
           SqlDataAdapter sda = new SqlDataAdapter(cmd);
           sda.Fill(dt);
           return dt;
       }

不考虑什么安全,就使用最简单的字符串拼接。采用一个for循序,遍历所有数据,拼凑代码如下:

  string querystr = @"SELECT id,[Name] ,[CardNo],[CtfTp],[CtfId] ,[Gender] ,[Birthday] ,[Address] ,[Zip] ,[District2] ,[District3] ,[District4],[Mobile],[Tel],[Fax],[EMail],[Version] 
                                FROM [testdb].[dbo].[cdsgus] ";       
            Stopwatch sw1 = new Stopwatch();
            Stopwatch sw2 = new Stopwatch();
           
            for (int i = 0; i <= 20050154; i = i + 10000)
            {
                DataSet dt = new DataSet();
                sw1.Start();
                string tempquery = "";
                tempquery = querystr + " where id between " + (i + 1) + " and " + (i + 10000);
                dt = SqlServerHelp.SelectData(dt,tempquery);
                dus = ConstructMongoDocuments(dt);
                Console.WriteLine("from " + (i + 1) + "  to " + (i + 10000)+" is ready! ");
                MongoHelp.Insert10000Documents(dus);
                sw1.Stop();
                TimeSpan ts1 = sw1.Elapsed;
                Console.WriteLine("Done!  cost time : "+ts1.TotalMilliseconds);
                sw1.Reset();
                System.Threading.Thread.Sleep(10);
                System.GC.Collect();
            }
其中ConstructMogoDocuments方法是凑成mongodb插入多数据所需的文档集合;

解释下,这里在不断调用gc.collect()是因为程序占用内存太多了,按照回收机制,程序里面的dataset在一次for循环完了后,这个小程序里面已经没有引用指向这块内存,但是gc.collect()好像并不回收这块内存。可能的原因Mongodb非常占用内存,插入试验中,有不断对程序申请的内存做主动回收处理,可发现,尽管调用回收,可内存依旧没有降下去,说明程序中占用的内存还有引用指向了这块数据内存,而且监控发现,从100万数据到500万数据这个过程中,db所在的文件夹所占用的5个数据文件大小就没变过,于是我在想,有必要去看看源代码了,大胆猜测它是先开辟一块2g的存储空间,然后不断的往这块空间里填数据,而这些数据一直在内存里!这是gc回收一直没有收回的原因!

mongodb -- sqlserver数据转移到mongodb_第2张图片

有趣的是程序打印显示插入10000笔数据用时1秒多,而实际观测远远不止1秒才打印出来,说明它插入的不是先往文件存储区域,应该是到内存中,在由mongo程序写入存储位置。这打印出来的1秒实际是写入到内存所用时间。在数据插入到700万左右,生成了一个2g文件 *****.6 也证实了之前的猜测;

截图如下。

mongodb -- sqlserver数据转移到mongodb_第3张图片

最后程序大概跑了1个多小时;同样的一份数据,在sqlserver 2008中。占用了7.88g空间。而在mongodb中,占用了13.3G空间。这玩意占用空间真不小;


完整代码贴不上来了,这里在给一个zip压缩包形式;提供参考:

http://download.csdn.net/detail/chenqiangdage/9313687


你可能感兴趣的:(sql,mongodb,数据库,server,C#,迁移)