使用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驱动包,比较受欢迎,很有可能被官方采纳


评论:

  1. 暂无评论...
  2. 我来说两句:

      切换  

    磨途歌检测发现,您当前使用的浏览器版本过低,要想使用画板模式,请先更新浏览器

      切换  

    磨途歌随机验证码