3.

MySQL への接続方法完全ガイド — CLI から各言語まで

編集
この記事の要点
  • CLI: mysql -h host -P 3306 -u user -p dbname(パスワードはプロンプトで入力)
  • ローカルは Unix ソケット --socket=/var/run/mysqld/mysqld.sock が高速
  • SSL/TLS は --ssl-mode=REQUIRED で強制、CA 検証は --ssl-ca
  • 言語別: PHP PDO / Python pymysql / Java JDBC / Node.js mysql2 すべて DSN 形式
  • Docker 内 → ホスト MySQL は host.docker.internal(Mac/Win) or --network=host

1. CLI から接続(mysql コマンド)

# 最小: ローカルの自分アカウント
mysql -u root -p
# Enter password: ********

# host / port / DB 指定
mysql -h 192.168.1.100 -P 3306 -u app -p appdb

# パスワードを直接渡す(履歴に残るので非推奨)
mysql -u root -ppassword

# Unix ソケット指定(速い)
mysql --socket=/var/run/mysqld/mysqld.sock -u root -p

# 設定ファイルに保存(推奨)
cat > ~/.my.cnf <<'EOF'
[client]
host = 127.0.0.1
port = 3306
user = app
password = AppPass!
database = appdb
EOF
chmod 600 ~/.my.cnf
mysql  # 引数不要で接続

2. 接続のオプション

オプション意味
-h, --host接続先ホスト
-P, --portポート(デフォルト 3306)
-u, --userユーザー名
-p, --passwordパスワード(プロンプト推奨)
-D, --database初期 DB(位置引数でも可)
--socketUnix ソケットパス
--protocoltcp / socket / pipe / memory
--ssl-modeDISABLED/PREFERRED/REQUIRED/VERIFY_CA/VERIFY_IDENTITY
--ssl-caCA 証明書
--default-character-setutf8mb4 推奨
-eSQL を実行して終了

3. SSL/TLS で安全に接続

# 強制 SSL
mysql -h prod.example.com -u app -p \
    --ssl-mode=REQUIRED

# CA 検証付き
mysql -h prod.example.com -u app -p \
    --ssl-mode=VERIFY_CA \
    --ssl-ca=/etc/mysql/ca.pem

# サーバ側で SSL 必須化
ALTER USER 'app'@'%' REQUIRE SSL;

-- 状態確認
SHOW STATUS LIKE 'Ssl_cipher';
-- Ssl_cipher | TLS_AES_256_GCM_SHA384

4. PHP PDO で接続

$dsn = 'mysql:host=127.0.0.1;port=3306;dbname=appdb;charset=utf8mb4';
$user = 'app';
$pass = 'AppPass!';

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
    PDO::MYSQL_ATTR_SSL_CA       => '/etc/mysql/ca.pem',
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    error_log($e->getMessage());
    http_response_code(500);
    exit('DB connection error');
}

// プリペアドステートメント(必ず使う)
$stmt = $pdo->prepare('SELECT id, name FROM users WHERE active = ?');
$stmt->execute([1]);
foreach ($stmt as $row) {
    echo $row['name'] . "\n";
}

5. Python(pymysql / mysql-connector)

import pymysql

conn = pymysql.connect(
    host='127.0.0.1',
    port=3306,
    user='app',
    password='AppPass!',
    database='appdb',
    charset='utf8mb4',
    cursorclass=pymysql.cursors.DictCursor,
    ssl={'ca': '/etc/mysql/ca.pem'},
)

try:
    with conn.cursor() as cur:
        cur.execute('SELECT id, name FROM users WHERE active = %s', (1,))
        for row in cur.fetchall():
            print(row)
finally:
    conn.close()

# SQLAlchemy の場合
# engine = create_engine('mysql+pymysql://app:AppPass!@127.0.0.1/appdb?charset=utf8mb4')

6. Java JDBC

import java.sql.*;

String url = "jdbc:mysql://127.0.0.1:3306/appdb"
           + "?useSSL=true&serverTimezone=Asia/Tokyo"
           + "&characterEncoding=utf8&useUnicode=true";

try (Connection conn = DriverManager.getConnection(url, "app", "AppPass!");
     PreparedStatement ps = conn.prepareStatement(
         "SELECT id, name FROM users WHERE active = ?")) {
    ps.setInt(1, 1);
    try (ResultSet rs = ps.executeQuery()) {
        while (rs.next()) {
            System.out.println(rs.getInt("id") + " " + rs.getString("name"));
        }
    }
}

7. Node.js(mysql2)

import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  host: '127.0.0.1',
  port: 3306,
  user: 'app',
  password: 'AppPass!',
  database: 'appdb',
  waitForConnections: true,
  connectionLimit: 10,
  ssl: { ca: fs.readFileSync('/etc/mysql/ca.pem') },
});

const [rows] = await pool.execute(
  'SELECT id, name FROM users WHERE active = ?',
  [1]
);
console.log(rows);

8. Docker コンテナから接続

# Docker for Mac / Windows: ホストの MySQL に接続
mysql -h host.docker.internal -P 3306 -u root -p

# Linux で同等のことをするなら --add-host
docker run --add-host=host.docker.internal:host-gateway \
    -it mysql:8 mysql -h host.docker.internal -u root -p

# 別コンテナの MySQL に接続(同一ネットワーク)
docker network create app-net
docker run -d --name db --network app-net \
    -e MYSQL_ROOT_PASSWORD=pass mysql:8
docker run -it --rm --network app-net mysql:8 \
    mysql -h db -u root -ppass

9. SSH トンネル経由で接続

# ローカル 13306 → リモート踏み台 → DB サーバの 3306
ssh -L 13306:db.internal.example.com:3306 -N bastion.example.com

# 別ターミナルから
mysql -h 127.0.0.1 -P 13306 -u app -p appdb

接続エラー早見表

エラー確認 / 対処
ERROR 2003 Can't connect to MySQL server on hostFW / port / bind-address。nc -zv host 3306 で疎通確認
ERROR 2002 Can't connect to local MySQL server through socketサービス停止 or ソケットパス違い。systemctl status mysqld
ERROR 1045 Access deniedパスワード / ユーザー / Host 不一致
ERROR 1130 Host is not allowedユーザーが 'app'@'%' 等を許可していない
SSL connection errorCA 証明書 / 期限 / サーバ証明書 SAN を確認
Public Key Retrieval is not allowedJDBC で allowPublicKeyRetrieval=true

FAQ

Q: ローカルから接続できるが、別ホストからは ERROR 1130
A: MySQL ユーザーが 'app'@'localhost' しか定義されていない。CREATE USER 'app'@'%' IDENTIFIED BY '...' でリモート許可、または特定 IP を許可。

Q: bind-address を 0.0.0.0 にしても外から繋がらない
A: ① FW(iptables / firewalld / Security Group)、② skip-networking 設定、③ netstat -tlnp | grep 3306 で LISTEN 確認。

Q: パスワードに記号を含めると CLI で接続できない
A: シェルの特殊文字エスケープ問題。-p でプロンプトに任せるか、~/.my.cnf 経由で渡す。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. MySQLの起動(Windows)
  2. MySQLの起動、停止、再起動(Linux)
  3. MYSQL への接続
  4. データベース一覧の表示
  5. データベースへの接続
  6. テーブル一覧を表示
  7. テーブル定義を確認
  8. ユーザーおよびパスワード一覧の確認