MySQL: Erste Schritte

Wie man mit MySQL beginnt

👋 Willkommen in der Stackhero-Dokumentation!

Stackhero bietet eine einsatzbereite MySQL-Cloud-Lösung, die zahlreiche Vorteile bietet, darunter:

  • Unbegrenzte Verbindungen und Übertragungen.
  • phpMyAdmin Web-UI inklusive.
  • Mühelose Updates mit nur einem Klick.
  • Optimale Performance und robuste Sicherheit durch eine private und dedizierte VM.

Sparen Sie Zeit und vereinfachen Sie Ihr Leben: Es dauert nur 5 Minuten, um die MySQL-Cloud-Hosting-Lösung von Stackhero auszuprobieren!

Der einfachste Weg, sich mit Ihrem MySQL-Dienst zu verbinden, ist die Verwendung des MySQL-URL-Formats, wenn Ihr Treiber dies unterstützt:

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

Für Ruby-Nutzer ist das MySQL-URL-Format leicht anders:

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

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Wir empfehlen nicht, die "root"-Datenbank zu verwenden. Dieses Beispiel dient nur zu Demonstrationszwecken. Die beste Praxis ist es, eine dedizierte Datenbank und einen Benutzer in phpMyAdmin zu erstellen und diese hier zu verwenden.

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

echo 'Verbindung erfolgreich... ' . $mysqli->host_info . "\n";

$mysqli->close();

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Wir empfehlen nicht, die "root"-Datenbank zu verwenden. Dieses Beispiel dient nur zu Demonstrationszwecken. Es ist am besten, eine dedizierte Datenbank und einen Benutzer in phpMyAdmin zu erstellen und diese hier zu verwenden.

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

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

mysqli_close($mysqli);

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Wir empfehlen nicht, die "root"-Datenbank zu verwenden. Dies dient nur zu Demonstrationszwecken. Die beste Praxis ist es, eine dedizierte Datenbank und einen Benutzer in phpMyAdmin zu erstellen und diese hier zu verwenden.

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

$options = array(
  // Wenn Sie auf einen Fehler wie "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed" stoßen,
  // stellen Sie sicher, dass das Verzeichnis /etc/ssl/certs/ CA-Zertifikate enthält.
  // Siehe unten für weitere Informationen.
  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 "Sie sind mit einer Datenbank verbunden, die Version " . $version[0] . "\n" ausführt;

?>

Wenn Sie den Fehler erhalten:

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

liegt das wahrscheinlich daran, dass das Verzeichnis /etc/ssl/certs/ keine CA-Zertifikate enthält.

Wenn Sie Zugriff auf das System haben, das Ihren PHP-Code ausführt, können Sie diese Zertifikate wie folgt installieren:

  1. Auf Ubuntu/Debian führen Sie sudo apt-get install ca-certificates aus
  2. Auf Alpine Linux führen Sie apk add ca-certificates aus

Wenn Sie keinen direkten Zugriff auf das System haben, das Ihren PHP-Code ausführt, können Sie das Zertifikat manuell installieren:

  1. Laden Sie das Zertifikat auf Ihren Computer herunter: https://letsencrypt.org/certs/isrgrootx1.pem
  2. Fügen Sie die Datei isrgrootx1.pem zu Ihren PHP-Projektdateien hinzu.
  3. Kommentieren Sie die Zeile PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/' aus
  4. Kommentieren Sie die Zeile PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem' ein

Wenn Sie den Fehler erhalten:

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

oder eine ähnliche Meldung wie:

Fatal error: Uncaught Error: Undefined constant PDO::MYSQL_*

zeigt das an, dass PDO ohne MySQL-Unterstützung installiert wurde.

Lösung für Ubuntu/Debian

Um dies auf Ubuntu- oder Debian-basierten Systemen zu beheben, installieren Sie die erforderliche PHP-MySQL-Erweiterung, indem Sie den folgenden Befehl ausführen:

sudo apt-get install php-mysql
Lösung für Docker

Wenn Sie Docker verwenden, stellen Sie sicher, dass die MySQL-Unterstützung während des Build-Prozesses enthalten ist. Fügen Sie die folgende Zeile zu Ihrer Dockerfile hinzu:

RUN docker-php-ext-install pdo pdo_mysql

Bearbeiten Sie die .env-Datei und definieren Sie die Variable DATABASE_URL wie folgt:

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

Bearbeiten Sie dann die Datei config/packages/doctrine.yaml und setzen Sie den Treiber und die Optionen wie folgt:

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

Wenn Sie den Fehler erhalten:

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

liegt das wahrscheinlich daran, dass das Verzeichnis /etc/ssl/certs/ keine CA-Zertifikate enthält.

Wenn Sie Zugriff auf das System haben, das Ihren PHP-Code ausführt, können Sie diese Zertifikate wie folgt installieren:

  1. Auf Ubuntu/Debian führen Sie sudo apt-get install ca-certificates aus
  2. Auf Alpine Linux führen Sie apk add ca-certificates aus

Wenn Sie keinen direkten Zugriff auf das System haben, können Sie das Zertifikat manuell installieren:

  1. Laden Sie das Zertifikat auf Ihren Computer herunter: https://letsencrypt.org/certs/isrgrootx1.pem
  2. Fügen Sie die Datei isrgrootx1.pem zu Ihrem Symfony-Projekt hinzu.
  3. Bearbeiten Sie die Datei config/packages/doctrine.yaml und setzen Sie den Treiber und die Optionen wie folgt:
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

Bearbeiten Sie die Datei config/database.php und ersetzen Sie die MySQL-Konfiguration durch die folgenden Einstellungen:

'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([
      // Wenn Sie auf einen Fehler wie "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed" stoßen,
      PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/',
      // PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem',
      PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
    ])
    : [],
],

Fügen Sie in der Datei database.php die folgende Konfiguration hinzu:

$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'), // Üblicherweise hat die Datenbank denselben Namen wie der Benutzer.
  'dbdriver' => 'mysqli',
  'dbprefix' => '',
  'pconnect' => true,
  'char_set' => 'utf8',
  'dbcollat' => 'utf8_general_ci',
  'encrypt'  => array() // Wichtig: TLS-Verschlüsselung aktivieren
);

Es ist eine bewährte Praxis, Ihre Anmeldedaten nicht im Quellcode zu speichern, sondern stattdessen Umgebungsvariablen zu verwenden.

Hier ist ein Beispiel, um diese Anmeldedaten abzurufen:

$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'); // Üblicherweise hat die Datenbank denselben Namen wie der Benutzer.

Die Verbindung von WordPress mit Stackhero für MySQL ist einfach. Bearbeiten Sie einfach die Datei wp-config.php und konfigurieren Sie die Datenbank wie folgt:

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

// TLS-Verschlüsselung verwenden (auch bekannt als SSL)
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

Der wichtige Teil hier ist die Aktivierung der TLS-Verschlüsselung (auch bekannt als SSL). Ohne sie wird die Verbindung nicht funktionieren.

In diesem Beispiel verwenden wir das offizielle xdevapi-Paket, um das MySQL X-Protokoll zu nutzen. Um es zu installieren, führen Sie aus:

npm install @mysql/xdevapi

Hier ist ein vollständiges Beispiel, das xdevapi verwendet:

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

(async () => {
  // Verbinden Sie sich mit MySQL unter Verwendung des MySQL X-Protokolls
  const session = await mysqlx.getSession({
    host: '<XXXXXX>.stackhero-network.com',
    port: '<PORT>',
    user: 'root',
    password: '<ROOT_PASSWORD>'
  });

  // Erstellen Sie ein Schema (Datenbank), wenn es nicht existiert
  const schemaExists = await session.getSchema('stackherotest').existsInDatabase();
  if (!schemaExists) {
    await session.createSchema('stackherotest');
  }

  // Erstellen Sie die Tabelle 'users', wenn sie nicht existiert
  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();
  }

  // Fügen Sie einen fiktiven Benutzer ein
  await session
    .getSchema('stackherotest') // Datenbankname
    .getTable('users') // Tabellenname
    .insert('userId', 'name', 'address', 'email') // Spaltennamen
    .values(
      Math.round(Math.random() * 100000), // Generieren Sie eine fiktive userId
      'Benutzername', // Spalte 'name'
      'Benutzeradresse', // Spalte 'address'
      'user@email.com' // Spalte 'email'
    )
    .execute();

  // Zählen Sie die Anzahl der Zeilen in der Tabelle 'users'
  const usersCount = await session
    .getSchema('stackherotest') // Datenbankname
    .getTable('users')
    .count();

  console.log(`Es gibt jetzt ${usersCount} Einträge in der Tabelle "users"`);

  // Schließen Sie die Verbindung zu MySQL
  await session.close();

})().catch(error => {
  console.error('');
  console.error('🐞 Ein Fehler ist aufgetreten!');
  console.error(error);
  process.exit(1);
});

In diesem Beispiel verwenden wir das mysql2-Paket mit Unterstützung für Promises. Um es zu installieren, führen Sie aus:

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

  // Erstellen Sie die Datenbank 'stackherotest', wenn sie noch nicht existiert
  await db.query('CREATE DATABASE IF NOT EXISTS stackherotest');

  // Erstellen Sie die Tabelle 'users', wenn sie noch nicht existiert
  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;');

  // Fügen Sie einen fiktiven Benutzer ein
  await db.query(
    'INSERT INTO `stackherotest`.`users` (`userId`, `name`, `address`, `email`) VALUES ?',
    [
      [
        Math.round(Math.random() * 100000), // Generieren Sie eine fiktive userId
        'Benutzername', // Spalte 'name'
        'Benutzeradresse', // Spalte 'address'
        'user@email.com' // Spalte 'email'
      ]
    ]
  );

  // Zählen Sie die Anzahl der Zeilen in der Tabelle 'users'
  const [ usersCount ] = await db.query('SELECT COUNT(*) AS `cpt` FROM `stackherotest`.`users`');
  console.log(`Es gibt jetzt ${usersCount[0].cpt} Einträge in der Tabelle "users"`);

  // Schließen Sie die Verbindung zu MySQL
  await db.end();

})().catch(error => {
  console.error('');
  console.error('🐞 Ein Fehler ist aufgetreten!');
  console.error(error);
  process.exit(1);
});

Um sich von Node.js, NestJS oder TypeORM zu verbinden, fügen Sie die ssl-Option wie in diesem Beispiel gezeigt hinzu:

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

Um sich mit Prisma zu verbinden, fügen Sie die Option sslaccept=strict hinzu, um sicherzustellen, dass die SSL-Verschlüsselung aktiviert ist. Hier ist ein Beispiel mit dem Benutzer "root" und der Verbindung zur Datenbank "root":

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

Wenn das Modul mysqlclient noch nicht installiert ist, installieren Sie es, da es zur Verbindung mit MySQL verwendet wird:

pip install mysqlclient

Wenn Sie den Fehler Exception: Can not find valid pkg-config name bei der Installation von mysqlclient erhalten, installieren Sie das Paket libmysqlclient. Auf Ubuntu/Debian können Sie ausführen: apt-get update && apt-get install --no-install-recommends -y libmysqlclient-dev

In diesem ersten Schritt wird das Passwort direkt in der Datei settings.py gespeichert, nur zu Testzwecken. Es wird empfohlen, eine sicherere Methode zu verwenden, wie weiter in dieser Dokumentation beschrieben.

Öffnen Sie die Datei settings.py und fügen Sie Folgendes hinzu:

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>'
  }
}

Achtung Dieses Beispiel wird nicht für die Produktion empfohlen und ist nur für Testzwecke gedacht!

Sobald die Verbindung erfolgreich ist, können Sie die empfohlene Methode verwenden, um Anmeldedaten sicher zu speichern. In diesem Beispiel wird django-environ verwendet, um Umgebungsvariablen zu verwalten.

Installieren Sie zuerst django-environ mit dem Befehl:

pip install django-environ

Öffnen Sie dann die Datei settings.py und fügen Sie Folgendes hinzu:

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

Öffnen oder erstellen Sie dann die Datei .env im selben Verzeichnis wie settings.py und fügen Sie Folgendes hinzu:

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

Fügen Sie schließlich .env zu Ihrer .gitignore-Datei hinzu, um sicherzustellen, dass Ihre Anmeldedaten nicht in Ihr Git-Repository übernommen werden:

echo ".env" >> .gitignore

Um Ihre Spring-Anwendung zu verbinden, setzen Sie die Umgebungsvariable SPRING_DATASOURCE_URL mit Ihrer Datenbank-URL, die mit jdbc: beginnt:

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

Das folgende Beispiel zeigt, wie Sie Ihre Grails-Anwendung mit MySQL verbinden:

dataSource {
  pooled = true
  driverClassName = "com.mysql.cj.jdbc.Driver"
  dialect = org.hibernate.dialect.MySQL8Dialect
  // SSL-spezifische Eigenschaften
  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" // Ersetzen Sie "/root" durch die Datenbank, mit der Sie sich verbinden möchten.
      username = "root" // Es ist ratsam, einen dedizierten Benutzer zu erstellen, anstatt die "root"-Anmeldedaten zu verwenden.
      password = System.env.STACKHERO_MYSQL_ROOT_PASSWORD // Es ist ratsam, einen dedizierten Benutzer zu erstellen, anstatt die "root"-Anmeldedaten zu verwenden.
      properties {
        maxActive = 50
        minEvictableIdleTimeMillis = 1800000
        timeBetweenEvictionRunsMillis = 1800000
        numTestsPerEvictionRun = 3
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = false
        validationQuery = "SELECT 1"
      }
    }
  }
}

Eine bewährte Praxis ist es, einen dedizierten Benutzer für Ihre Anwendung zu erstellen, anstatt den "root"-Benutzer zu verwenden.

Der einfachste Weg, dies zu tun, ist über phpMyAdmin.

  1. Klicken Sie in phpMyAdmin oben auf Benutzerkonten.

  2. Klicken Sie auf Benutzerkonto hinzufügen.

  3. Füllen Sie das Benutzererstellungsformular aus:

    1. Wählen Sie einen Kontonamen (normalerweise den Namen Ihrer Anwendung)
    2. Klicken Sie auf Passwort generieren, um ein sicheres Passwort zu erstellen (kopieren Sie es in Ihre Zwischenablage)
    3. Aktivieren Sie die Option Datenbank mit demselben Namen erstellen und alle Privilegien gewähren

Sobald Sie das Formular bestätigen, wird der neue Benutzer erstellt, zusammen mit einer entsprechenden Datenbank, die denselben Namen wie der Benutzername trägt.