MySQL: 入門指南

如何開始使用 MySQL

👋 歡迎來到 Stackhero 文件!

Stackhero 提供即用型 MySQL cloud 解決方案,帶來多項好處,包括:

  • 無限連接和傳輸。
  • 包含 phpMyAdmin 網頁介面。
  • 只需點擊即可輕鬆進行 更新
  • 專用私有 VM 提供的最佳 效能和強大 安全性

節省時間簡化您的生活:只需 5 分鐘即可嘗試 Stackhero 的 MySQL cloud hosting 解決方案!

如果您想要快速連接到您的 MySQL 服務,並且您的驅動程式支援,您可以考慮使用 MySQL URL 格式:

mysql://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?useSSL=true&requireSSL=true

如果您使用 Ruby,URL 格式會略有不同:

mysql2://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?reconnect=true&useSSL=true&requireSSL=true

以下是使用 PHP 的 MySQLi 擴充套件(物件導向寫法)連接 MySQL 的範例:

<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // 雖然本範例使用 "root" 資料庫,但建議您透過 phpMyAdmin 為您的應用程式建立專屬的資料庫與使用者。

$mysqli = mysqli_init();
$mysqliConnected = $mysqli->real_connect($hostname, $user, $password, $database, $port, NULL, MYSQLI_CLIENT_SSL);
if (!$mysqliConnected) {
  die("Connection Error: " . $mysqli->connect_error);
}

echo 'Connection successful... ' . $mysqli->host_info . "\n";

$mysqli->close();

?>

如果您偏好程序式寫法,以下是使用 MySQLi 程序式方式連接的範例:

<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // 為了最佳安全性,請在 phpMyAdmin 中建立專屬的資料庫與使用者,而非直接使用 "root"。

$mysqli = mysqli_init();
$mysqliConnected = mysqli_real_connect($mysqli, $hostname, $user, $password, $database, $port, NULL, MYSQLI_CLIENT_SSL);
if (!$mysqliConnected) {
  die("Connection error: " . mysqli_connect_error($mysqli));
}

echo 'Success: ' . mysqli_get_host_info($mysqli) . "\n";

mysqli_close($mysqli);

?>

如果您偏好使用 PDO 來存取資料庫,以下是連線設定範例:

<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // 建議為您的應用程式建立專屬的資料庫與使用者。

$dsn = "mysql:host=$hostname;port=$port;dbname=$database";

$options = array(
  // 如果連線時遇到 SSL 相關錯誤,請確認您的系統已安裝正確的 CA 憑證(詳見下方)。
  PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/',
  // PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem',
  PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
);

$pdo = new PDO($dsn, $user, $password, $options);

$stm = $pdo->query("SELECT VERSION()");
$version = $stm->fetch();

echo "You are connected to a database running version " . $version[0] . "\n";

?>

如果您看到如下錯誤:

Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed

這通常表示您的系統在 /etc/ssl/certs/ 目錄下缺少 CA 憑證。

如果您有權限存取執行 PHP 程式的系統,可以這樣安裝憑證:

  1. Ubuntu/Debiansudo apt-get install ca-certificates
  2. Alpine Linuxapk add ca-certificates

如果您無法直接存取系統,也可以手動加入憑證:

  1. 下載憑證:https://letsencrypt.org/certs/isrgrootx1.pem
  2. isrgrootx1.pem 檔案放到您的 PHP 專案中
  3. 註解掉 PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/' 這一行
  4. 取消註解 PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem' 這一行

如果您看到如下錯誤:

Fatal error: Uncaught Error: Undefined constant PDO::MYSQL_ATTR_SSL_CAPATH

或類似訊息,這表示您的 PDO 安裝時未包含 MySQL 支援。

  1. 在 Ubuntu/Debian 上

您可以執行以下指令安裝所需擴充套件:

sudo apt-get install php-mysql
  1. 在 Docker 環境中

如果您使用 Docker,請確保在建置時已包含 MySQL 支援。可在 Dockerfile 中加入:

RUN docker-php-ext-install pdo pdo_mysql

### 在 Symfony 與 Doctrine 中使用 MySQL

如果您使用 Symfony 與 Doctrine,可以這樣設定連線:

1. 編輯 `.env` 檔案,設定 `DATABASE_URL` 變數:

DATABASE_URL="mysql://<USER>:<PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/<DATABASE>"


1. 接著在 `config/packages/doctrine.yaml` 設定 driver 與 options:

```yaml
doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
        driver: 'pdo_mysql'
        options:
            # PDO::MYSQL_ATTR_SSL_CAPATH
            1010: '/etc/ssl/certs'
            # PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT
            1014: true

如果您遇到如下錯誤:

Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed

這通常是因為 /etc/ssl/certs/ 目錄下缺少 CA 憑證。

如果您有系統存取權限,可以這樣安裝:

  1. Ubuntu/Debiansudo apt-get install ca-certificates
  2. Alpine Linuxapk add ca-certificates

如果無法直接存取,也可以手動加入憑證:

  1. 下載:https://letsencrypt.org/certs/isrgrootx1.pem
  2. isrgrootx1.pem 放到您的 Symfony 專案中
  3. 更新 config/packages/doctrine.yaml
doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
        driver: 'pdo_mysql'
        options:
            # PDO::MYSQL_ATTR_SSL_CA
            1009: 'isrgrootx1.pem'
            # PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT
            1014: true

要在 Laravel 設定 MySQL,請開啟 config/database.php 並修改 MySQL 區段:

'mysql' => [
  'driver' => 'mysql',
  'host' => env('STACKHERO_MYSQL_HOST'),
  'port' => env('STACKHERO_MYSQL_PORT'),
  'username' => env('STACKHERO_MYSQL_USER'),
  'password' => env('STACKHERO_MYSQL_PASSWORD'),
  'database' => env('STACKHERO_MYSQL_USER'),
  'charset' => 'utf8mb4',
  'collation' => 'utf8mb4_unicode_ci',
  'prefix' => '',
  'prefix_indexes' => true,
  'strict' => true,
  'engine' => null,
  'sslmode' => 'require',
  'options' => extension_loaded('pdo_mysql')
    ? array_filter([
      // 若遇到 SSL 錯誤,請參考上方疑難排解。
      PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/',
      // PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem',
      PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
    ])
    : [],
],

database.php 設定檔中,您可以加入:

$db['default'] = array(
  'hostname' => getenv('STACKHERO_MYSQL_HOST'),
  'port'     => getenv('STACKHERO_MYSQL_PORT'),
  'username' => getenv('STACKHERO_MYSQL_USER'),
  'password' => getenv('STACKHERO_MYSQL_PASSWORD'),
  'database' => getenv('STACKHERO_MYSQL_USER'), // 慣例上,資料庫名稱與使用者相同。
  'dbdriver' => 'mysqli',
  'dbprefix' => '',
  'pconnect' => true,
  'char_set' => 'utf8',
  'dbcollat' => 'utf8_general_ci',
  'encrypt'  => array() // 重要:啟用 TLS 加密
);

為了安全起見,建議不要將資料庫帳號密碼寫在程式碼中,您可以改用環境變數。以下是取得方式:

$hostname = getenv('STACKHERO_MYSQL_HOST');
$port = getenv('STACKHERO_MYSQL_PORT');
$user = getenv('STACKHERO_MYSQL_USER');
$password = getenv('STACKHERO_MYSQL_PASSWORD');
$database = getenv('STACKHERO_MYSQL_USER'); // 慣例上,資料庫名稱與使用者相同。

將 WordPress 連接到 Stackhero for MySQL 很簡單,只需編輯您的 wp-config.php 檔案如下:

define('DB_HOST', '<XXXXXX>.stackhero-network.com');
define('DB_PORT', '<PORT>');
define('DB_NAME', 'root');
define('DB_USER', 'root');
define('DB_PASSWORD', '<yourPassword>');

// 啟用 TLS 加密(又稱 SSL)
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

關鍵步驟是啟用 TLS(SSL)加密。若未啟用,連線將無法正常運作。

若要使用 MySQL X 協定,請安裝官方 xdevapi 套件:

npm install @mysql/xdevapi

以下為範例程式:

const mysqlx = require('@mysql/xdevapi');

(async () => {
  // 使用 MySQL X 協定連線
  const session = await mysqlx.getSession({
    host: '<XXXXXX>.stackhero-network.com',
    port: '<PORT>',
    user: 'root',
    password: '<ROOT_PASSWORD>'
  });

  // 若 schema(資料庫)不存在則建立
  const schemaExists = await session.getSchema('stackherotest').existsInDatabase();
  if (!schemaExists) {
    await session.createSchema('stackherotest');
  }

  // 若 'users' 資料表不存在則建立
  const tableExists = await session
    .getSchema('stackherotest')
    .getTable('users')
    .existsInDatabase();
  if (!tableExists) {
    await session
      .sql('CREATE TABLE `stackherotest`.`users` '
        + '('
        + '`userId` INT UNSIGNED NOT NULL,'
        + '`name` VARCHAR(128) NOT NULL,'
        + '`address` TEXT NOT NULL,'
        + '`email` VARCHAR(265) NOT NULL'
        + ') '
        + 'ENGINE = InnoDB;')
      .execute();
  }

  // 插入一筆範例使用者資料
  await session
    .getSchema('stackherotest')
    .getTable('users')
    .insert('userId', 'name', 'address', 'email')
    .values(
      Math.round(Math.random() * 100000),
      'User name',
      'User address',
      '[email protected]'
    )
    .execute();

  // 計算使用者數量
  const usersCount = await session
    .getSchema('stackherotest')
    .getTable('users')
    .count();

  console.log(`There are now ${usersCount} entries in the table "users"`);

  // 關閉連線
  await session.close();

})().catch(error => {
  console.error('');
  console.error('An error occurred!');
  console.error(error);
  process.exit(1);
});

如果您偏好傳統協定,可以使用支援 Promise 的 mysql2 套件。安裝方式:

npm install mysql2

範例用法:

const mysql = require('mysql2/promise');

(async () => {
  const db = await mysql.createConnection({
    host: '<XXXXXX>.stackhero-network.com',
    port: '<PORT>',
    user: 'root',
    password: '<ROOT_PASSWORD>'
  });

  // 若資料庫不存在則建立
  await db.query('CREATE DATABASE IF NOT EXISTS stackherotest');

  // 若資料表不存在則建立
  await db.query('CREATE TABLE IF NOT EXISTS `stackherotest`.`users` '
    + '('
    + '`userId` INT UNSIGNED NOT NULL,'
    + '`name` VARCHAR(128) NOT NULL,'
    + '`address` TEXT NOT NULL,'
    + '`email` VARCHAR(265) NOT NULL'
    + ') '
    + 'ENGINE = InnoDB;');

  // 插入一筆範例使用者資料
  await db.query(
    'INSERT INTO `stackherotest`.`users` (`userId`, `name`, `address`, `email`) VALUES ?',
    [
      [
        Math.round(Math.random() * 100000),
        'User name',
        'User address',
        '[email protected]'
      ]
    ]
  );

  // 計算使用者數量
  const [ usersCount ] = await db.query('SELECT COUNT(*) AS `cpt` FROM `stackherotest`.`users`');
  console.log(`There are now ${usersCount[0].cpt} entries in the table "users"`);

  // 關閉連線
  await db.end();

})().catch(error => {
  console.error('');
  console.error('An error occurred!');
  console.error(error);
  process.exit(1);
});

若要從 Node.js、NestJS 或 TypeORM 連線,您可以加入 ssl 選項如下:

TypeOrmModule.forRoot({
  type: 'mysql',
  host: '<XXXXXX>.stackhero-network.com',
  port: <PORT>,
  username: 'root',
  password: '<ROOT_PASSWORD>',
  database: 'root',
  entities: [],
  synchronize: true,
  ssl: {}
});

如果您使用 Prisma,加入 sslaccept=strict 選項可確保連線加密。範例設定如下:

datasource db {
  provider = "mysql"
  url = "mysql://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?sslaccept=strict"
}

如果尚未安裝 mysqlclient 模組,可以這樣安裝:

pip install mysqlclient

如果安裝時遇到 Exception: Can not find valid pkg-config name 錯誤,您可能需要安裝 libmysqlclient 套件。 在 Ubuntu/Debian 上可執行:apt-get update && apt-get install --no-install-recommends -y libmysqlclient-dev

初期測試時,您可以直接將密碼寫在 settings.py。但長期來看,建議改用環境變數(見下方)。

請這樣編輯您的 settings.py

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'HOST': '<XXXXXX>.stackhero-network.com',
    'PORT': '<PORT>',
    'OPTIONS': {
      'ssl_mode': 'REQUIRED',
    },
    'NAME': 'root',
    'USER': 'root',
    'PASSWORD': '<ROOT_PASSWORD>'
  }
}

請注意:此範例僅供測試,不建議用於正式環境!

確認連線無誤後,建議改用 django-environ 管理環境變數以提升安全性。

首先安裝套件:

pip install django-environ

然後更新 settings.py

import environ
env = environ.Env()
environ.Env.read_env()

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'HOST': env('STACKHERO_MYSQL_HOST'),
    'PORT': env('STACKHERO_MYSQL_PORT'),
    'OPTIONS': {
      'ssl_mode': 'REQUIRED',
    },
    'NAME': 'root',
    'USER': 'root',
    'PASSWORD': env('STACKHERO_MYSQL_ROOT_PASSWORD')
  }
}

在與 settings.py 相同目錄下建立或編輯 .env 檔案,內容如下:

STACKHERO_MYSQL_HOST=<XXXXXX>.stackhero-network.com
STACKHERO_MYSQL_PORT=<PORT>
STACKHERO_MYSQL_ROOT_PASSWORD=<ROOT_PASSWORD>

最後,為了保護您的憑證,請將 .env 加入 .gitignore

echo ".env" >> .gitignore

要讓 Spring 應用程式連接 MySQL,您可以設定 SPRING_DATASOURCE_URL 環境變數,並加上 jdbc: 前綴:

SPRING_DATASOURCE_URL=jdbc:mysql://root:<ROOT_PASSWORD>@<XXXXXX>.stackhero-network.com:<PORT>/root?useSSL=true&requireSSL=true

以下為 Grails 應用程式連接 MySQL 的設定範例:

dataSource {
  pooled = true
  driverClassName = "com.mysql.cj.jdbc.Driver"
  dialect = org.hibernate.dialect.MySQL8Dialect
  // SSL 相關屬性
  properties {
    useSSL = true
    requireSSL = true
    verifyServerCertificate = true
    sslMode = "REQUIRED"
  }
}

environments {
  production {
    dataSource {
      dbCreate = "none"
      url = "jdbc:mysql://" + System.env.STACKHERO_MYSQL_HOST + ":" + System.env.STACKHERO_MYSQL_PORT + "/root?useSSL=true&requireSSL=true&verifyServerCertificate=true&sslMode=required" // 您可以將 "/root" 替換為您指定的資料庫名稱。
      username = "root" // 建議為您的應用程式建立專屬使用者。
      password = System.env.STACKHERO_MYSQL_ROOT_PASSWORD
      properties {
        maxActive = 50
        minEvictableIdleTimeMillis = 1800000
        timeBetweenEvictionRunsMillis = 1800000
        numTestsPerEvictionRun = 3
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = false
        validationQuery = "SELECT 1"
      }
    }
  }
}

為了提升安全性,建議您為應用程式建立專屬使用者,而非直接使用 "root"。您可以透過 phpMyAdmin 輕鬆完成:

  1. 在 phpMyAdmin 上方選單選擇 User accounts

  2. 點擊 Add user account

  3. 填寫使用者建立表單:

    • 輸入帳號名稱(通常為您的應用程式名稱)
    • 點擊 Generate password 產生安全密碼並複製
    • 勾選 Create database with same name and grant all privileges

提交表單後,您將擁有一組新使用者及與使用者名稱相同的專屬資料庫。