Using MySQL with Go - Golang's Database/SQL Driver

30
Building Apps with Go & MySQL 1 VividCortex Webinar - Baron Schwartz - November 11, 2014

description

Google’s Go language is increasingly popular for systems programming. It’s efficient and fun to program in Go, and it produces high-performance programs. Go is well suited for working with SQL databases, and has excellent MySQL drivers. In this talk Baron will show how to use Go’s database/sql package with MySQL. He’ll discuss idiomatic database/sql code, available drivers for MySQL, and show tips and tricks that will save you time and frustration.

Transcript of Using MySQL with Go - Golang's Database/SQL Driver

Page 1: Using MySQL with Go - Golang's Database/SQL Driver

æ

Building Apps with Go & MySQL

1

VividCortex Webinar - Baron Schwartz - November 11, 2014

Page 2: Using MySQL with Go - Golang's Database/SQL Driver

å

About BaronFounder of @VividCortex

Author of High Performance MySQL

@xaprb on Twitter

[email protected]

http://www.linkedin.com/in/xaprb

Optimization, Backups, Replication, and more

Baron Schwartz, Peter Zaitsev &

Vadim Tkachenko

High PerformanceMySQL

3rd Edition

Covers Version 5.5

2

Page 3: Using MySQL with Go - Golang's Database/SQL Driver

æ

VividCortex - MySQL Performance Management

3

Page 4: Using MySQL with Go - Golang's Database/SQL Driver

å

What’s Nice About Go?

4

Interfaces

Concurrency primitives

Syntax

Performance

Static Linking

Tools

Page 5: Using MySQL with Go - Golang's Database/SQL Driver

å

What’s Not As Nice?Hard to Google it (use “golang”)

Package versioning (use github.com/VividCortex/johnny-deps/)

Doesn’t have generics (not a big deal)

5

Page 6: Using MySQL with Go - Golang's Database/SQL Driver

æ

Go Database Design Patterns

6

Page 7: Using MySQL with Go - Golang's Database/SQL Driver

å

Things To KnowWhat is database/sql?

Where is the documentation?

How do I create a database connection?

How do I query a connection?

How do I retrieve results from a query?

What are the common operations?

7

Page 8: Using MySQL with Go - Golang's Database/SQL Driver

å

Overview of database/sqlA generic, minimal interface for SQL-like databases

Verbs and nouns: Open, Prepare, Exec, Query, QueryRow, Scan, Close

DB, Stmt, Value, Row, Rows, Result

Tx, Begin, Commit, Rollback

Docs: http://golang.org/pkg/database/sql/

Tutorial: http://go-database-sql.org/

8

Page 9: Using MySQL with Go - Golang's Database/SQL Driver

æ9package  main  

import  (     _  "github.com/go-­‐sql-­‐driver/mysql"  

  "database/sql"     "log"  )  

func  main()  {     db,  err  :=  sql.Open("mysql",       "user:password@tcp(127.0.0.1:3306)/test")     if  err  !=  nil  {       log.Println(err)     }     defer  db.Close()  

     //  Do  something  useful  here.  }  

Page 10: Using MySQL with Go - Golang's Database/SQL Driver

åOne-Shot Query

10

  var  str  string     err  =  db.QueryRow(  

"select  hello  from  hello.world  where  id  =  1").Scan(&str)     if  err  !=  nil  &&  err  !=  sql.ErrNoRows  {       log.Println(err)     }     log.Println(str)

Page 11: Using MySQL with Go - Golang's Database/SQL Driver

åQuery...

11

  var  id  int     var  str  string     q  :=  "select  id,  hello  from  hello.world  where  id  =  ?"  

  rows,  err  :=  db.Query(q,  1)     if  err  !=  nil  {       log.Fatal(err)     }        defer  rows.Close()

Page 12: Using MySQL with Go - Golang's Database/SQL Driver

å... Then Fetch Rows

12

  for  rows.Next()  {       err  =  rows.Scan(&id,  &str)       if  err  !=  nil  {         log.Fatal(err)       }       //  Use  the  variables  scanned  from  the  row     }     if  err  =  rows.Err();  err  !=  nil  {       log.Fatal(err)     }  

Page 13: Using MySQL with Go - Golang's Database/SQL Driver

åPrepare...

13

  stmt,  err  :=  db.Prepare(       "select  id,  hello  from  hello.world                where  id  =  ?")     if  err  !=  nil  {       log.Fatal(err)     }        defer  stmt.Close()

Page 14: Using MySQL with Go - Golang's Database/SQL Driver

å... Then Execute & Fetch

14

  rows,  err  :=  stmt.Query(1)     if  err  !=  nil  {       log.Fatal(err)     }        defer  rows.Close()  

  for  rows.Next()  {       //  ...     }  

Page 15: Using MySQL with Go - Golang's Database/SQL Driver

åInsert...

15

  stmt,  err  :=  db.Prepare(       "insert  into  hello.world(hello)  values(?)")     if  err  !=  nil  {       log.Fatal(err)     }        defer  stmt.Close()  

  res,  err  :=  stmt.Exec("hello,  Dolly")     if  err  !=  nil  {       log.Fatal(err)     }

Page 16: Using MySQL with Go - Golang's Database/SQL Driver

å... And Check Results

16

  lastId,  err  :=  res.LastInsertId()     if  err  !=  nil  {       log.Fatal(err)     }     rowCnt,  err  :=  res.RowsAffected()     if  err  !=  nil  {       log.Fatal(err)     }

Page 17: Using MySQL with Go - Golang's Database/SQL Driver

æ

Docs: “Pleasantly Lightweight!”

17

Page 18: Using MySQL with Go - Golang's Database/SQL Driver

æ

Connection Pooling

18

Page 19: Using MySQL with Go - Golang's Database/SQL Driver

æ

Big Unsigned Integers

19

Page 20: Using MySQL with Go - Golang's Database/SQL Driver

æ

Unexpected Connections

20

Page 21: Using MySQL with Go - Golang's Database/SQL Driver

åResource Exhaustion

21

//  Don’t  do  this!  for  i  :=  0;  i  <  50;  i++  {     _,  err  :=  db.Query("DELETE  FROM  hello.world")  }  

//  Use  this  instead!  for  i  :=  0;  i  <  50;  i++  {     _,  err  :=  db.Exec("DELETE  FROM  hello.world")  }  

Page 22: Using MySQL with Go - Golang's Database/SQL Driver

æ

Retry. Retry. Retry. Retry. Retry. Retry. Retry. Retry. Retry. Retry.

22

Page 23: Using MySQL with Go - Golang's Database/SQL Driver

æ

Handling NULLs

23

Page 24: Using MySQL with Go - Golang's Database/SQL Driver

åWorking with NULL

24

var  s  sql.NullString  err  :=  db.QueryRow(        "SELECT  name  FROM  foo  WHERE  id=?",        id).Scan(&s)  

if  s.Valid  {        //  use  s.String  }  else  {        //  NULL  value  }  

//  If  you  don’t  care  to  check  whether  it  was  NULL,  //  Just  use  s.String  without  checking,  it’ll  be  ""

Page 25: Using MySQL with Go - Golang's Database/SQL Driver

å

Boilerplate code everywhere

There’s no sql.NullUint64

Nullability is tricky, not future-proof

It’s not very Go-ish (no useful default zero-value)

25

NULL Makes Code Ugly

Page 26: Using MySQL with Go - Golang's Database/SQL Driver

æ

ORMs - Not Really Suited for Go

26

Page 27: Using MySQL with Go - Golang's Database/SQL Driver

æ

Interfaces - Learn Them, Love Them

27

e.g. https://vividcortex.com/blog/2014/11/11/encrypting-data-in-mysql-with-go/

Page 28: Using MySQL with Go - Golang's Database/SQL Driver

å

Resources

28

http://golang.org/pkg/database/sql/

http://go-database-sql.org/

https://github.com/go-sql-driver/mysql

http://jmoiron.net/blog/

http://twitter.com/VividCortex/ <--- lots of Go tips

Page 29: Using MySQL with Go - Golang's Database/SQL Driver

æ

[email protected] @xaprb • linkedin.com/in/xaprb

Page 30: Using MySQL with Go - Golang's Database/SQL Driver

å

Image Creditshttp://www.flickr.com/photos/simens/6306917636/ http://www.flickr.com/photos/dexxus/5794905716/ http://www.flickr.com/photos/sebastian_bergmann/202396633/ http://www.flickr.com/photos/doug88888/4794114114/ http://www.flickr.com/photos/oatsy40/6443878013/ http://www.sxc.hu/photo/1160562/ Google Maps (screenshot) http://www.flickr.com/photos/estherase/13553883/ http://www.flickr.com/photos/paperpariah/4150220583/ http://www.flickr.com/photos/zooboing/4743616313/ http://www.flickr.com/photos/dseneste/5912382808/ http://www.flickr.com/photos/clickykbd/66165381/sizes/l/ http://www.flickr.com/photos/mamnaimie/5576980406/ https://www.flickr.com/photos/zachstern/87431231

30