使用GO语言把Mysql中的数据导入MongoDB
[文章作者:磨延城 转载请注明原文出处: https://mo2g.com/view/148/ ]
之前写了一篇文章《使用PHP脚本把Mysql中的数据导入MongoDB》,这回再补上GO语言版的导入功能实现.先回顾一下导入操作的核心逻辑:1)先找出Mysql数据表中最大ID.2)根据当前ID与最大ID判断是否继续执行3) 4)..3)从mysql中读取数据并处理,更新当前ID.4)数据批量导入MongoDB
之前写了一篇文章《使用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 < maxId { 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驱动包,比较受欢迎,很有可能被官方采纳
我来说两句: