mongodb -- sqlserver數據轉移到mongodb

現在有一個2000萬級別的數據量的數據庫,數據存在sqlserver 20008中。想要將此數據轉移到mongdb中。網上有看說有個工具可以將mysql的數據直接轉移到mongodb中,但是又要將sqlserver 2008數據先轉移到mysql中,各種折騰後,各種試驗,楞是沒能成功,一怒之下,自己動手寫程序來做這個數據遷移。

之前有講到mongodb一次性插入10000數據的效率,確實很快,然後也測試了下,從sqlserver 一次性選擇10000條數據也是在1秒之內,想想,乾脆一不做二不休,寫了一個程序,採取for循環 每次從數據庫取10000條,然後插入mongdo,直到循環完所有數據。2000萬條數據,對於計算機而言,小事啊 爲了這個,特意做了下效率問題,測試了下,一次循環下來,3秒之內能解決,算算,一分鐘就是20萬數據,二個小時就可以完全搞完。(事實也確實如此,一個多小時搞定了,早知道如此,就不要花了那麼多時間去找工具,找各種導出教程,各種糾結,各種安裝);

  數據庫結構很簡單,是一個比較出名的某某hotel的數據,純學術研究。

程序代碼我放在這裏了:有興趣的朋友可以看看。勿噴。如果你有更好的辦法。歡迎留言;

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回收一直沒有收回的原因!

有趣的是程序打印顯示插入10000筆數據用時1秒多,而實際觀測遠遠不止1秒纔打印出來,說明它插入的不是先往文件存儲區域,應該是到內存中,在由mongo程序寫入存儲位置。這打印出來的1秒實際是寫入到內存所用時間。在數據插入到700萬左右,生成了一個2g文件 *****.6 也證實了之前的猜測;

截圖如下。

最後程序大概跑了1個多小時;同樣的一份數據,在sqlserver 2008中。佔用了7.88g空間。而在mongodb中,佔用了13.3G空間。這玩意佔用空間真不小;


完整代碼貼不上來了,這裏在給一個zip壓縮包形式;提供參考:

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章