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"啊~~