之前写了一篇文章《使用PHP脚本把Mysql中的数据导入MongoDB》,这回再补上GO语言版的导入功能实现。
先回顾一下导入操作的核心逻辑:
1)先找出Mysql数据表中最大ID
2)根据当前ID与最大ID判断是否继续执行3) 4)
3)从mysql中读取数据并处理,更新当前ID
4)数据批量导入MongoDB
从mysql中读数据
这一块是最容易出现性能瓶颈的地方。我本地测试环境单表是130W行数据,需要以分段的方式(分页),把数据导出。如果使用如下的sql语句获取数据,读到越后边的行,就会越慢。select * from w_log limit x,y
改良后的sql如下,理论上,读到上亿条数据都不会变慢。有兴趣可以看一下我之前写的的《MariaDB数据库优化,实现百万级数据环境快速翻页》。select * from w_log where id > $id order by id asc limit $leng
go语言循环读取mysql数据的核心代码如下:package main
import (
"database/sql"
_ "github.com/Go-SQL-Driver/MySQL"
"strconv"
)
func main() {
db, err := sql.Open("mysql", "root:root@/weixin_monitor?charset=utf8")
row := db.QueryRow("select id from weixin_log order by id desc limit 1")
var maxId int//weixin_log表中最大的ID
row.Scan(&maxId)
leng := 5000//一次读取mysql的数据量
id := 0//当前ID
for id
sql := "select id from weixin_log where id > " + strconv.Itoa(id) + " order by id asc limit " + strconv.Itoa(leng)
rows, err := db.Query(sql)
for rows.Next() {
//mysql数据处理操作...
rows.Scan(&id)
}
//导入MongoDB操作...
}
}
处理json字符串,转换成MongoDB驱动需要的类型。单条数据插入、多条数据批量插入MongoDB。
package main
import (
"fmt"
"github.com/bitly/go-simplejson"
"gopkg.in/mgo.v2"
)
func main() {
str := `{"list" :[{"date":"2015-08-25"},{"date":"2015-08-26"}]}`
json, _ := simplejson.NewJson([]byte(str))
fmt.Println(json)
//打印&{map[list:[map[date:2015-08-25] map[date:2015-08-26]]]}
json.Set("title", "磨途歌")
fmt.Println(json)
//打印&{map[list:[map[date:2015-08-25] map[date:2015-08-26]] title:磨途歌]}
doc, _ := json.Map() //转换后的数据
fmt.Println(doc)
//打印map[list:[map[date:2015-08-25] map[date:2015-08-26]] title:磨途歌]
session, _ := mgo.Dial("127.0.0.1")
defer session.Close()
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic, true)
c := session.DB("test_db").C("log")
c.Insert(doc) //插入单条数据
var docs []interface{}
docs = append(docs, doc)
docs = append(docs, doc)
c.Insert(docs...) //批量插入多条数据
}
这里我们用到了两个开源包:
github.com/bitly/go-simplejson:在处理json功能方面,比官方提供的encoding/json好用多了,官方的包要求json字符串必须为首字母大写格式,才能正常转换,小写开头的会被忽略掉:str := `{"List" :[{"Date":"2015-08-25"},{"Date":"2015-08-26"}]}`
我估计很多数据库中保存的都是小写开头的json字符串,所以github.com/bitly/go-simplejson提供了最大程度的兼容。
gopkg.in/mgo.v2:是第三方go语言的MongoDB驱动包,比较受欢迎,很有可能被官方采纳