MariaDB: 入門指南

如何開始使用 MariaDB

👋 歡迎來到 Stackhero 文件!

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

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

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

連接到您的 MariaDB 服務最簡單的方式是使用 MySQL URL 格式,只要您的驅動程式支援即可:

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

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

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

以下是幾個範例,展示如何透過不同的 PHP 擴充套件連接 MariaDB。雖然這些範例都使用 "root" 資料庫,但建議您為應用程式建立專屬的資料庫與使用者,特別是在生產環境中。

<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port     = '<PORT>';
$user     = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // 僅供示範。最佳實踐請於 phpMyAdmin 建立專屬資料庫與使用者,並使用該組帳密。

$mysqli = mysqli_init();
$mysqliConnected = $mysqli->real_connect($hostname, $user, $password, $database, $port, NULL, MYSQLI_CLIENT_SSL);
if (!$mysqliConnected) {
  die('連線錯誤:' . $mysqli->connect_error);
}

echo '連線成功... ' . $mysqli->host_info . "\n";

$mysqli->close();

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port     = '<PORT>';
$user     = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // 僅供示範。最佳實踐請於 phpMyAdmin 建立專屬資料庫與使用者,並使用該組帳密。

$mysqli = mysqli_init();
$mysqliConnected = mysqli_real_connect($mysqli, $hostname, $user, $password, $database, $port, NULL, MYSQLI_CLIENT_SSL);
if (!$mysqliConnected) {
  die('連線錯誤:' . mysqli_connect_error($mysqli));
}

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

mysqli_close($mysqli);

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port     = '<PORT>';
$user     = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // 僅供示範。最佳實踐請於 phpMyAdmin 建立專屬資料庫與使用者,並使用該組帳密。

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

$options = array(
  // 如果遇到 "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed",請確認 /etc/ssl/certs/ 目錄下有 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 '您已連線到版本為 ' . $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 憑證。如果您有系統權限,可以參考以下方式安裝:

  1. 在 Ubuntu 上,執行:

    apt-get install ca-certificates
    
  2. 在 Alpine Linux 上,執行:

    apk 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 屬性常數未定義,這表示您的 PDO 安裝可能沒有 MySQL 支援。

在 Ubuntu/Debian 上

您可以透過以下指令安裝所需的 PHP MySQL 擴充套件:

sudo apt-get install php-mysql
如果您使用 Docker

請在您的 Dockerfile 中加入以下內容以確保 MySQL 支援:

RUN docker-php-ext-install pdo pdo_mysql

### 在 Symfony 與 Doctrine 中使用 MariaDB

首先,請編輯您的 `.env` 檔案,設定 `DATABASE_URL` 變數如下:

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


接著,更新 `config/packages/doctrine.yaml` 檔案,設定驅動與選項:

```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

這通常是因為系統未安裝 CA 憑證。您可以這樣安裝:

  • 在 Ubuntu/Debian 上,執行:

    sudo apt-get install ca-certificates
    
  • 在 Alpine Linux 上,執行:

    apk add ca-certificates
    

如果無法在系統層級安裝 CA 憑證,也可以手動加入:

  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 中設定 MariaDB,請開啟 config/database.php 並將 mysql 設定更新如下:

'mysql' => [
  'driver'   => 'mysql',
  'host'     => env('STACKHERO_MARIADB_HOST'),
  'port'     => env('STACKHERO_MARIADB_PORT'),
  'username' => env('STACKHERO_MARIADB_USER'),
  'password' => env('STACKHERO_MARIADB_PASSWORD'),
  'database' => env('STACKHERO_MARIADB_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 錯誤如 "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed",請參考上方的疑難排解步驟。
      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_MARIADB_HOST'),
  'port'     => getenv('STACKHERO_MARIADB_PORT'),
  'username' => getenv('STACKHERO_MARIADB_USER'),
  'password' => getenv('STACKHERO_MARIADB_PASSWORD'),
  'database' => getenv('STACKHERO_MARIADB_USER'), // 慣例上,資料庫名稱與使用者名稱相同。
  'dbdriver' => 'mysqli',
  'dbprefix' => '',
  'pconnect' => TRUE,
  'char_set' => 'utf8',
  'dbcollat' => 'utf8_general_ci',
  'encrypt'  => array() // 重要:啟用 TLS 加密
);

建議您不要將帳密寫死在程式碼中,而是透過環境變數取得。可參考以下方式:

$hostname = getenv('STACKHERO_MARIADB_HOST');
$port     = getenv('STACKHERO_MARIADB_PORT');
$user     = getenv('STACKHERO_MARIADB_USER');
$password = getenv('STACKHERO_MARIADB_PASSWORD');
$database = getenv('STACKHERO_MARIADB_USER'); // 慣例上,資料庫名稱與使用者名稱相同。

將 WordPress 連接到 Stackhero for MariaDB 非常簡單。請在 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)。如果未啟用,連線將無法運作。

如果您使用 Node.js,可以嘗試 mysql2 套件(支援 Promise)。安裝方式如下:

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');

  // 如果 users 資料表不存在則建立
  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), // 產生 userId
        'User name',                         // name
        'User address',                      // address
        '[email protected]'                     // email
      ]
    ]
  );

  // 計算 users 資料表中的使用者數量
  const [usersCount] = await db.query('SELECT COUNT(*) AS `cpt` FROM `stackherotest`.`users`');
  console.log(`目前 "users" 資料表共有 ${usersCount[0].cpt} 筆資料`);

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

})().catch(error => {
  console.error('');
  console.error('發生錯誤!');
  console.error(error);
  process.exit(1);
});

對於 Node.js、NestJS 或 TypeORM,您可以透過加入 ssl 選項來啟用 SSL:

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

要用 Prisma 連接 MariaDB,只需在連線 URL 加上 sslaccept=strict。例如,若以 "root" 使用者連接 "root" 資料庫:

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

如果尚未安裝,您可以透過下列指令安裝 mysqlclient 模組來讓 Django 連接 MariaDB:

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。這僅適用於測試,生產環境請勿這麼做。

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_MARIADB_HOST'),
    'PORT': env('STACKHERO_MARIADB_PORT'),
    'OPTIONS': {
      'ssl_mode': 'REQUIRED',
    },
    'NAME': 'root',
    'USER': 'root',
    'PASSWORD': env('STACKHERO_MARIADB_ROOT_PASSWORD')
  }
}

接著,建立或更新 .env 檔案(與 settings.py 同目錄):

STACKHERO_MARIADB_HOST=<XXXXXX>.stackhero-network.com
STACKHERO_MARIADB_PORT=<PORT>
STACKHERO_MARIADB_ROOT_PASSWORD=<ROOT_PASSWORD>

最後,為了安全,請將 .env 加入 .gitignore

echo ".env" >> .gitignore

要讓 Spring 應用程式連接 MariaDB,請設定 SPRING_DATASOURCE_URL 環境變數,使用 jdbc: 前綴。例如:

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

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

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

送出後,系統會自動建立新使用者與同名資料庫。

MariaDB 是 MySQL 的獨立分支(fork),由開源社群於 2010 年 Oracle 收購 MySQL 後創建。對於大多數應用情境,MariaDB 與 MySQL 在功能與相容性上都非常接近。