如何將MongoDB數據庫的數據遷移到MySQL數據庫中


  FAQ v2.0終於上線了,斷斷續續忙了有2個多月。這個項目是我實踐的第一個全棧的項目,從需求(后期有產品經理介入)到架構,再到設計(有征詢設計師的意見)、構建(前端、后台、數據庫、服務器部署),也是第一次獨立負責一個項目,所以意義很不一般,后面還會寫一篇總結的文章。閑言少敘,進入正題:

  其中有一個自動定時發訪問記錄列表和反饋問題列表的郵件的功能,本來打算自己寫的,不過后來了解到團隊有現成的平台可以做這個事,所以就用現成的嘍。但有一個問題,該平台配置的數據源必須是MySQL數據庫,而FAQ平台用的是MongoDB數據庫。有兩個辦法:一是把現有的MongoDB數據庫換成MySQL,這樣的話要改動比較大;二是把MongoDB里的數據遷移到MySQL數據庫。我采用的是第二種方法,可是怎么遷移呢?不能直接遷移,在網上搜了下,有一個辦法是先把MongoDB里的數據導出到csv文件或者txt文件中,再把csv/txt文件中的數據導入到MySQL數據庫中,感覺挺靠譜的。

  分兩步走:

  PS:昨天用windows自帶的畫圖工具畫的那個圖有點丑,今天一個設計師朋友用sketch給我畫了個好看點的圖,附上。(2016.10.26更新)

  第一步:將MongoDB里的數據導出到csv文件,有一個mongo自帶的工具mongoexport就可以實現。

/usr/local/mongodb/bin/mongoexport -h ip(192.168.0.102) -u mongo數據庫登錄帳號 -p mongo數據庫登錄密碼 -d mongo數據庫名稱 -c mongo數據庫集合名 -f _id,字段1,字段2 --type=csv -o 保存路徑(/data/kagol/records.csv)

   導出的csv文件格式是一條mongo記錄占一行,字段之間用逗號(,)分割。

  第二步:將csv文件導入到MySQL數據庫中,可以用MySQL的load命令。

  SQL語句如下(load_csv_data.sql):

1 load data local infile '/data/kagol/records.csv'
2 into table `records` character set utf8
3 fields terminated by ',' optionally enclosed by '"'
4 lines terminated by '\n'
5 ignore 1 lines;

  寫成shell腳本(load_csv_data.sh):

mysql -hip(192.168.0.105) -umysql登錄用戶名 -pmysql登錄密碼 mysql數據庫名 --default-character-set=utf8 --local-infile=1 < /data/kagol/load_csv_data.sql

  要注意的是:

  (1)-h和ip之間不需要空格(-u,-p同理);

  (2)MySQL數據庫的格式必須和csv格式一致(字段數、順序等)。

  這樣就順利地完成了MongoDB數據庫到MySQL數據庫的遷移,but!!這個方法導出來的數據中文是亂碼的!!花了那么多時間居然是亂碼,此刻我的內心是奔潰的!(此處不配圖,自己腦補畫面)

  

  於是,有了現在的方案,寫代碼(Node)遷移。

 1 //mongo對象
 2 var Record     = require('./record');
 3 
 4 //mysql對象
 5 var mysql      = require('mysql');
 6 var connection = mysql.createConnection({
 7     host     : '192.168.0.104',//mysql服務器ip
 8     user     : 'XXX',//mysql登錄名
 9     password : 'XXX',//mysql登錄密碼
10     database : 'XXX'//mysql數據庫名
11 });
12 
13 connection.query('set names latin1');//這句很關鍵,確保中文不亂碼
14 
15 var addZero = function(num){
16     return num < 10 ? '0' + num : num;
17 }
18 
19 var getYesterday = function(){
20     var now = new Date();
21     var year = now.getFullYear();
22     var month = now.getMonth() + 1;
23     now.setTime(now.getTime() - 1000*60*60*24);
24     var day = now.getDate();
25     var result = year + '-' + addZero(month) + '-' + addZero(day);
26     return result;
27 }
28 
29 var yesterday = getYesterday();
30 
31 //導入昨天的數據
32 Record.find({time:{'$gt':yesterday + ' 00:00:00','$lt':yesterday + ' 23:59:59'}},function(err, docs){
33     if(err){
34         console.log('error');
35     }else{
36         for(var i=0;i<docs.length;i++){
37                 var 字段1 = docs[i].字段1;
38                 var 字段2 = docs[i].字段2;
39                 var sql = 'insert into faq_records (字段1, 字段2) values("'+字段1+'","'+字段2+');';
40                 connection.query(sql, function(err, rows) {
41                     return;
42                 });
43         }
44         console.log('succeed!');
45     }
46 })

  record.js文件是封裝了對mongo數據庫的操作:

1 var mongoose = require('mongoose');
2 var connectionRecord = mongoose.createConnection('mongodb://mongo登錄帳號:mongo登錄密碼@ip:mongo服務端口(默認是27017)/數據庫名');
3 var Schema = mongoose.Schema;
4 var recordSchema = new Schema({
5         字段1: String,
6         字段2: String
7 });
8 var Record = connectionRecord.model('Record', recordSchema);
9 module.exports = Record;

  

  這個方案完美地解決了中文亂碼問題!

  大家有別的方法可以一起討論哈~~

  PS:一直沒搞明白為什么第一種方案會亂碼,mongo里的數據確實是沒有亂碼的,csv文件里的數據也沒有亂碼,就是到了MySQL里就是亂碼,懷疑是load data那一步有問題,但是我加了"character set utf8"和"--default-character-set=utf8"啊~~

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM