すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB RDS:Go-MySQL-Driver を使用した MySQL データベースへの接続

最終更新日:May 13, 2026

お使いのアプリケーションが Go を使用しており、短期間の接続などのシナリオでデータベース接続を頻繁に作成する場合、または接続数が多く、ApsaraDB RDS for MySQL インスタンスの接続制限を超えている場合は、このチュートリアルを使用して Go-MySQL-Driver で接続できます。このドライバーは、接続の頻度を減らし、データベースのオーバーヘッドを最小限に抑えます。このトピックでは、接続後にデータベース操作を実行する方法についても説明します。

説明

Go-MySQL-Driver は、MySQL および MariaDB データベースへの接続をサポートする Go 用のサードパーティデータベースドライバーです。詳細については、「Go-MySQL-Driver」をご参照ください。

制限事項

このガイドは、MySQL 5.7、8.0、または 8.4 を実行する ApsaraDB RDS for MySQL インスタンスに適用されます。

前提条件

  • Go 環境をダウンロードしてインストール済みであること。Go 1.20 以降を推奨します。

  • クライアントの IP アドレスを ApsaraDB RDS for MySQL インスタンスの IP ホワイトリストに追加してください。詳細については、「IP ホワイトリストの設定」をご参照ください。

    説明

    お使いのアプリケーションが、ApsaraDB RDS for MySQL インスタンスと同じリージョンおよび仮想プライベートクラウド (VPC) 内にある Elastic Compute Service (ECS) インスタンスにデプロイされている場合は、IP ホワイトリストを設定する必要はありません。

Go-MySQL-Driver を使用したデータベースへの接続

ステップ1:依存関係の追加

  1. Go プロジェクトの go.mod ファイルに、go-sql-driver 依存関係を追加します。

    require (
        github.com/go-sql-driver/mysql v1.8.1
    )
  2. .go ファイルに、次のパッケージをインポートしてください。

    import (
        // 汎用的なSQLインターフェースを提供します。
        "database/sql"
        // フォーマットされたI/Oを実装します。
        "fmt"
        // Go で MySQL データベースに接続して操作するためのドライバーです。
        "github.com/go-sql-driver/mysql"
        // 時間の測定と表示機能を提供します。
        "time"
    )

ステップ2:接続プールの初期化

.go ファイルの main 関数で、接続プールを初期化し、次のパラメーターを設定してください。以下にコード例を示します。

// データベース接続を作成します。
cfg := mysql.NewConfig()
cfg.User = "****"       // 実際のデータベースのユーザー名に置き換えてください。
cfg.Passwd = "****"     // 実際のデータベースのパスワードに置き換えてください。
cfg.Net = "tcp"         // 接続タイプはTCPです。デフォルト値のままにしてください。
cfg.Addr = "rm-2zefwjx1s8156******.mysql.rds.aliyuncs.com:3306" // MySQL データベースの実際のエンドポイントとポートに置き換えてください。
cfg.DBName = "****"     // 実際のデータベース名に置き換えてください。

conn, err := mysql.NewConnector(cfg)
if err != nil {
    panic(err.Error())
}

db := sql.OpenDB(conn)
defer func(db *sql.DB) {
    err := db.Close()
    if err != nil {
        fmt.Printf("データベース接続のクローズ中にエラーが発生しました: %v\n", err)
    }
}(db)
// 接続プールのパラメーターを設定します。
db.SetMaxOpenConns(20)                 // 接続プール内のオープン接続の最大数を設定します。必要に応じてこの値を調整してください。
db.SetMaxIdleConns(2)                  // 接続プール内のアイドル接続の最大数を設定します。必要に応じてこの値を調整してください。
db.SetConnMaxIdleTime(10 * time.Second) // プール内の接続の最大アイドル時間を設定します。必要に応じてこの値を調整してください。
db.SetConnMaxLifetime(80 * time.Second) // 接続の最大生存期間を設定します。必要に応じてこの値を調整してください。
説明

ApsaraDB RDS for MySQL インスタンスのエンドポイントとポートを確認するには、「インスタンスのエンドポイントとポートの表示と管理」をご参照ください。

主要な接続プールパラメーター

重要
  • 推奨設定 はデータベースの安定性を向上させ、運用リスクを低減します。任意設定 はパフォーマンスを向上させることができます。

  • 本番環境で新しいパラメーター値を適用する前に、包括的な機能テストとパフォーマンステストを実行して、システムの安定性を確認してください。

推奨

パラメーター

説明

デフォルト

推奨

説明

maxIdleTime

接続がアイドル状態でいられる最大時間。

0

10~30分

  • デフォルト値の 0 は、タイムアウトがないことを示します。

  • アプリケーションの実際の要件に基づいてこのパラメーターを設定することを推奨します。このパラメーターは SetConnMaxIdleTime メソッドを使用して設定できます。

maxLifetime

接続を使用できる最大時間。

0

1~8時間

  • デフォルト値の 0 は、接続の生存期間が無制限であることを示します。

  • 接続が長時間保持されてリソースを消費するのを防ぐために、このパラメーターを設定することを推奨します。このパラメーターは SetConnMaxLifetime メソッドを使用して設定できます。

maxOpenConns

データベースへのオープン接続の最大数。

0

100

  • デフォルト値の 0 は、制限がないことを示します。

  • MaxIdleConns が 0 より大きく、新しい MaxOpenConnsMaxIdleConns より小さい場合、MaxIdleConns は新しい MaxOpenConns の制限に合わせて減少します。

  • アプリケーションの実際の要件に基づいてこのパラメーターを設定することを推奨します。このパラメーターは SetMaxOpenConns メソッドを使用して設定できます。

maxIdleConns

プールに保持するアイドル接続の最大数。

2

20

  • このパラメーターを適切な値に設定して、特定の数の接続を予約することで、データベースリクエストの急増を迅速に処理できます。

  • この値が MaxOpenConns より高く設定されている場合、自動的に MaxOpenConns の制限まで引き下げられます。

  • このパラメーターは SetMaxIdleConns メソッドを使用して設定できます。

  • 0 または負の数に設定した場合、アイドル接続は保持されません。

readTimeout

I/O 読み取りタイムアウト。

0

10000 ms~60000 ms

  • デフォルト値の 0 はタイムアウト制限がないことを示します。デフォルト値を維持することを推奨します。この値を変更する必要がある場合は、ビジネス要件に基づいて調整してください。

  • time.Duration 型を使用してください (例: cfg.ReadTimeout = 30 * time.Second)。'30s' のような文字列形式は使用しないでください。

writeTimeout

I/O 書き込みタイムアウト。

0

10000 ms~60000 ms

  • デフォルト値の 0 はタイムアウト制限がないことを示します。デフォルト値を維持することを推奨します。この値を変更する必要がある場合は、ビジネス要件に基づいて調整してください。

  • time.Duration 型を使用してください (例: cfg.WriteTimeout = 30 * time.Second)。'30s' のような文字列形式は使用しないでください。

任意

パラメーター

説明

デフォルト

推奨

説明

timeout

接続を確立するためのタイムアウト。

デフォルト値はオペレーティングシステムによって決定されます。

3000 ms

  • time.Duration 型を使用してください (例: cfg.Timeout = 30 * time.Second)。'30s' のような文字列形式は使用しないでください。

  • ネットワークの遅延に応じて、1~10 秒のタイムアウトを設定してください。

データベース操作の実行

テーブルの作成

この例では、userinfo という名前のテーブルを作成する方法を説明します。

_, err = db.Exec("CREATE TABLE IF NOT EXISTS userinfo(uid INT AUTO_INCREMENT, username VARCHAR(20) NOT NULL DEFAULT '', departname VARCHAR(20) NOT NULL DEFAULT '', created VARCHAR(10) NOT NULL DEFAULT '', PRIMARY KEY(uid));")
if err != nil {
    fmt.Println("create table error: ", err)
    return
}

データの挿入

この例では、userinfo テーブルにデータを挿入する方法を説明します。

方法1: db.Prepare の使用

stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
res, err := stmt.Exec("田中一郎", "研究", "2016-06-17")
id, err := res.LastInsertId()
if err != nil {
    panic(err)
}
fmt.Println(id)

方法2: db.Exec の使用

result, err := db.Exec("INSERT INTO userinfo (username, departname, created) VALUES (?, ?, ?)", "鈴木花子", "テスト", "2016-06-21")
if err != nil {
    panic(err)
}
ids, err := result.LastInsertId()
fmt.Println(ids)

データの更新

この例では、userinfo テーブルのデータを更新する方法を説明します。

stmtUpdate, err := db.Prepare("UPDATE userinfo SET username=?, departname=?, created=? WHERE username=?")
if err != nil {
    fmt.Println("Prepare update statement error:", err)
    return
}
resUpdate, err := stmtUpdate.Exec("佐藤健太", "営業", "2024-09-23", "鈴木花子")
if err != nil {
    fmt.Println(err)
}
rowCnt, _ := resUpdate.RowsAffected()
fmt.Println(rowCnt)

データのクエリ

この例では、userinfo テーブルから username='佐藤健太' のデータをクエリする方法を説明します。

方法1: db.Query の使用

rows, err := db.Query("SELECT username,departname,created FROM userinfo WHERE username=?", "佐藤健太")
if err != nil {
    panic(err)
}
for rows.Next() {
 var username, departname, created string
 if err := rows.Scan(&username, &departname, &created); err != nil {
     fmt.Println(err)
 }
 fmt.Println("username:", username, "departname:", departname, " created:", created)
}
defer func(rows *sql.Rows) {
 err := rows.Close()
 if err != nil {
     fmt.Println(err)
 }
}(rows)

方法2: db.Prepare の使用

stmtQuery, err := db.Prepare("SELECT username,departname,created FROM userinfo WHERE username=?")
if err != nil {
    fmt.Println("prepare error", err)
    return
}
rowData, err := stmtQuery.Query("佐藤健太")
if err != nil {
    fmt.Println("query data error", err)
    return
}
for rowData.Next() {
 var username, departname, created string
 if err := rowData.Scan(&username, &departname, &created); err != nil {
     fmt.Println(err)
 }
 fmt.Println("username:", username, "departname:", departname, "created:", created)
}
defer func(rows *sql.Rows) {
 err := rows.Close()
 if err != nil {
     fmt.Println(err)
 }
}(rowData)

データの削除

この例では、userinfo テーブルから username='田中一郎' のデータを削除する方法を説明します。

delStmt, _ := db.Prepare("DELETE FROM userinfo WHERE username=?")
resultDel, err := delStmt.Exec("田中一郎")
if err != nil {
    panic(err)
}
rowAffect, _ := resultDel.RowsAffected()
fmt.Println("データの削除が完了しました。", rowAffect)

完全な例

package main

import (
    // 汎用的なSQLインターフェースを提供します。
    "database/sql"
    // フォーマットされたI/Oを実装します。
    "fmt"
    // Go で MySQL データベースに接続して操作するためのドライバーです。
    "github.com/go-sql-driver/mysql"
    // 時間の測定と表示機能を提供します。
    "time"
)

func main() {
    // データベース接続を作成します。
    cfg := mysql.NewConfig()
    cfg.User = "****"                                                   // ユーザー名
    cfg.Passwd = "****"                                                 // パスワード
    cfg.Net = "tcp"                                                     // 接続タイプ
    cfg.Addr = "rm-2ze1vw17v542q6b****.mysql.pre.rds.aliyuncs.com:3306" // エンドポイント
    cfg.DBName = "****"                                                 // データベース名
    cfg.Timeout = 3 * time.Second                                       // 接続を確立するためのタイムアウト。
    cfg.ReadTimeout = 60 * time.Second                                  // I/O 読み取りタイムアウト。
    cfg.WriteTimeout = 60 * time.Second                                 // I/O 書き込みタイムアウト。

    conn, err := mysql.NewConnector(cfg)
    if err != nil {
        panic(err.Error())
    }

    db := sql.OpenDB(conn)
    defer func(db *sql.DB) {
        err := db.Close()
        if err != nil {
            fmt.Printf("データベース接続のクローズ中にエラーが発生しました: %v\n", err)
        }
    }(db)

    // 接続プールのパラメーターを設定します。
    db.SetMaxOpenConns(100)                 // オープン接続の最大数。
    db.SetMaxIdleConns(20)                  // アイドル接続の最大数。
    db.SetConnMaxIdleTime(10 * time.Minute) // 接続の最大アイドル時間。
    db.SetConnMaxLifetime(8 * time.Hour)    // 接続の最大生存期間。

    // userinfo という名前のテーブルを作成します。
    _, err = db.Exec("CREATE TABLE IF NOT EXISTS userinfo(uid INT AUTO_INCREMENT, username VARCHAR(20) NOT NULL DEFAULT '', departname VARCHAR(20) NOT NULL DEFAULT '', created VARCHAR(10) NOT NULL DEFAULT '', PRIMARY KEY(uid));")
    if err != nil {
        fmt.Println("create table error: ", err)
        return
    }

    // プリペアドステートメントでデータを挿入します。
    stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
    res, err := stmt.Exec("田中一郎", "研究", "2016-06-17")
    id, err := res.LastInsertId()
    if err != nil {
        panic(err)
    }
    fmt.Println(id)

    // 直接実行でデータを挿入します。
    result, err := db.Exec("INSERT INTO userinfo (username, departname, created) VALUES (?, ?, ?)", "鈴木花子", "テスト", "2016-06-21")
    if err != nil {
        panic(err)
    }
    ids, err := result.LastInsertId()
    fmt.Println(ids)

    // データを更新します。
    stmtUpdate, err := db.Prepare("UPDATE userinfo SET username=?, departname=?, created=? WHERE username=?")
    if err != nil {
        fmt.Println("Prepare update statement error:", err)
        return
    }
    resUpdate, err := stmtUpdate.Exec("佐藤健太", "営業", "2024-09-23", "鈴木花子")
    if err != nil {
        fmt.Println(err)
    }
    rowCnt, _ := resUpdate.RowsAffected()
    fmt.Println(rowCnt)

    // データを直接クエリします。
    rows, err := db.Query("SELECT username,departname,created FROM userinfo WHERE username=?", "佐藤健太")
    if err != nil {
        panic(err)
    }
    for rows.Next() {
        var username, departname, created string
        if err := rows.Scan(&username, &departname, &created); err != nil {
            fmt.Println(err)
        }
        fmt.Println("username:", username, "departname:", departname, "created:", created)
    }
    defer func(rows *sql.Rows) {
        err := rows.Close()
        if err != nil {
            fmt.Println(err)
        }
    }(rows)

    // プリペアドステートメントでデータをクエリします。
    stmtQuery, err := db.Prepare("SELECT username,departname,created FROM userinfo WHERE username=?")
    if err != nil {
        fmt.Println("prepare error", err)
        return
    }
    rowData, err := stmtQuery.Query("佐藤健太")
    if err != nil {
        fmt.Println("query data error", err)
        return
    }
    for rowData.Next() {
        var username, departname, created string
        if err := rowData.Scan(&username, &departname, &created); err != nil {
            fmt.Println(err)
        }
        fmt.Println("username:", username, "departname:", departname, "created:", created)
    }
    defer func(rows *sql.Rows) {
        err := rows.Close()
        if err != nil {
            fmt.Println(err)
        }
    }(rowData)

    // データを削除します。
    delStmt, _ := db.Prepare("DELETE FROM userinfo WHERE username=?")
    resultDel, err := delStmt.Exec("田中一郎")
    if err != nil {
        panic(err)
    }
    rowAffect, _ := resultDel.RowsAffected()
    fmt.Println("データの削除が完了しました。", rowAffect)
}

関連ドキュメント