MySQL: Premiers pas

Comment débuter avec MySQL

👋 Bienvenue sur la documentation de Stackhero !

Stackhero propose une solution MySQL cloud prête à l'emploi qui offre de nombreux avantages, notamment :

  • Connexions et transferts illimités.
  • Interface web phpMyAdmin incluse.
  • Mises à jour faciles en un clic.
  • Performance optimale et sécurité robuste grâce à une VM privée et dédiée.

Gagnez du temps et simplifiez-vous la vie : il ne faut que 5 minutes pour essayer la solution MySQL cloud hosting de Stackhero !

La manière la plus simple de se connecter à votre service MySQL est d'utiliser le format URL MySQL si votre driver le supporte :

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

Pour les utilisateurs de Ruby, le format URL MySQL est légèrement différent :

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'; // Nous ne recommandons pas d'utiliser la base de données "root". Cet exemple est fourni à des fins de démonstration uniquement. La meilleure pratique est de créer une base de données et un utilisateur dédiés dans phpMyAdmin et de les utiliser ici.

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

echo 'Connexion réussie... ' . $mysqli->host_info . "\n";

$mysqli->close();

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Nous ne recommandons pas d'utiliser la base de données "root". Cet exemple est à des fins de démonstration uniquement. Il est préférable de créer une base de données et un utilisateur dédiés dans phpMyAdmin et de les utiliser ici.

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

echo 'Succès : ' . mysqli_get_host_info($mysqli) . "\n";

mysqli_close($mysqli);

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // Nous ne recommandons pas d'utiliser la base de données "root". Ceci est à des fins de démonstration uniquement. La meilleure pratique est de créer une base de données et un utilisateur dédiés dans phpMyAdmin et de les utiliser ici.

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

$options = array(
  // Si vous rencontrez une erreur comme "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed",
  // assurez-vous que le répertoire /etc/ssl/certs/ contient des certificats CA.
  // Voir ci-dessous pour plus d'informations.
  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 "Vous êtes connecté à une base de données exécutant la version " . $version[0] . "\n";

?>

Si vous rencontrez l'erreur :

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

cela est probablement dû au fait que le répertoire /etc/ssl/certs/ ne contient pas de certificats CA.

Si vous avez accès au système exécutant votre code PHP, vous pouvez installer ces certificats comme suit :

  1. Sur Ubuntu/Debian, exécutez sudo apt-get install ca-certificates
  2. Sur Alpine Linux, exécutez apk add ca-certificates

Si vous n'avez pas d'accès direct au système exécutant votre code PHP, vous pouvez installer le certificat manuellement :

  1. Téléchargez le certificat sur votre ordinateur : https://letsencrypt.org/certs/isrgrootx1.pem
  2. Ajoutez le fichier isrgrootx1.pem à vos fichiers de projet PHP.
  3. Commentez la ligne PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/'
  4. Décommentez la ligne PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem'

Si vous rencontrez l'erreur :

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

ou un message similaire tel que :

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

cela indique que PDO a été installé sans support MySQL.

Solution pour Ubuntu/Debian

Pour résoudre cela sur les systèmes basés sur Ubuntu ou Debian, installez l'extension PHP MySQL requise en exécutant la commande suivante :

sudo apt-get install php-mysql
Solution pour Docker

Si vous utilisez Docker, assurez-vous que le support MySQL est inclus lors du processus de build. Ajoutez la ligne suivante à votre Dockerfile :

RUN docker-php-ext-install pdo pdo_mysql

Modifiez le fichier .env et définissez la variable DATABASE_URL comme suit :

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

Ensuite, modifiez le fichier config/packages/doctrine.yaml et définissez le driver et les options comme suit :

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

Si vous recevez l'erreur :

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

cela est probablement dû au fait que le répertoire /etc/ssl/certs/ ne contient pas de certificats CA.

Si vous avez accès au système exécutant votre code PHP, vous pouvez installer ces certificats comme suit :

  1. Sur Ubuntu/Debian, exécutez sudo apt-get install ca-certificates
  2. Sur Alpine Linux, exécutez apk add ca-certificates

Si vous n'avez pas d'accès direct au système, vous pouvez installer le certificat manuellement :

  1. Téléchargez le certificat sur votre ordinateur : https://letsencrypt.org/certs/isrgrootx1.pem
  2. Ajoutez le fichier isrgrootx1.pem à votre projet Symfony.
  3. Modifiez le fichier config/packages/doctrine.yaml et définissez le driver et les options comme suit :
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

Modifiez le fichier config/database.php et remplacez la configuration mysql par les paramètres suivants :

'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([
      // Si vous rencontrez une erreur telle que "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,
    ])
    : [],
],

Dans le fichier database.php, ajoutez la configuration suivante :

$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'), // Par convention, la base de données porte le même nom que l'utilisateur.
  'dbdriver' => 'mysqli',
  'dbprefix' => '',
  'pconnect' => true,
  'char_set' => 'utf8',
  'dbcollat' => 'utf8_general_ci',
  'encrypt'  => array() // Important : activer le chiffrement TLS
);

Il est préférable de ne pas stocker vos identifiants dans votre code source mais d'utiliser des variables d'environnement à la place.

Voici un exemple pour récupérer ces identifiants :

$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'); // Par convention, la base de données porte le même nom que l'utilisateur.

Connecter WordPress à Stackhero pour MySQL est simple. Modifiez simplement le fichier wp-config.php et configurez la base de données comme suit :

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

// Utiliser le chiffrement TLS (également connu sous le nom de SSL)
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

La partie importante ici est l'activation du chiffrement TLS (également connu sous le nom de SSL). Sans cela, la connexion ne fonctionnera pas.

Dans cet exemple, nous utilisons le package officiel xdevapi pour tirer parti du protocole MySQL X. Pour l'installer, exécutez :

npm install @mysql/xdevapi

Voici un exemple complet utilisant xdevapi :

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

(async () => {
  // Connectez-vous à MySQL en utilisant le protocole MySQL X
  const session = await mysqlx.getSession({
    host: '<XXXXXX>.stackhero-network.com',
    port: '<PORT>',
    user: 'root',
    password: '<ROOT_PASSWORD>'
  });

  // Créez un schéma (base de données) s'il n'existe pas
  const schemaExists = await session.getSchema('stackherotest').existsInDatabase();
  if (!schemaExists) {
    await session.createSchema('stackherotest');
  }

  // Créez la table 'users' si elle n'existe pas
  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();
  }

  // Insérez un utilisateur fictif
  await session
    .getSchema('stackherotest') // Nom de la base de données
    .getTable('users') // Nom de la table
    .insert('userId', 'name', 'address', 'email') // Noms des colonnes
    .values(
      Math.round(Math.random() * 100000), // Générer un userId fictif
      'Nom de l'utilisateur', // colonne 'name'
      'Adresse de l'utilisateur', // colonne 'address'
      'user@email.com' // colonne 'email'
    )
    .execute();

  // Comptez le nombre de lignes dans la table 'users'
  const usersCount = await session
    .getSchema('stackherotest') // Nom de la base de données
    .getTable('users')
    .count();

  console.log(`Il y a maintenant ${usersCount} entrées dans la table "users"`);

  // Fermez la connexion à MySQL
  await session.close();

})().catch(error => {
  console.error('');
  console.error('🐞 Une erreur est survenue !');
  console.error(error);
  process.exit(1);
});

Dans cet exemple, nous utilisons le package mysql2 avec support des promesses. Pour l'installer, exécutez :

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

  // Créez la base de données 'stackherotest' si elle n'existe pas encore
  await db.query('CREATE DATABASE IF NOT EXISTS stackherotest');

  // Créez la table 'users' si elle n'existe pas encore
  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;');

  // Insérez un utilisateur fictif
  await db.query(
    'INSERT INTO `stackherotest`.`users` (`userId`, `name`, `address`, `email`) VALUES ?',
    [
      [
        Math.round(Math.random() * 100000), // Générer un userId fictif
        'Nom de l'utilisateur', // colonne 'name'
        'Adresse de l'utilisateur', // colonne 'address'
        'user@email.com' // colonne 'email'
      ]
    ]
  );

  // Comptez le nombre de lignes dans la table 'users'
  const [ usersCount ] = await db.query('SELECT COUNT(*) AS `cpt` FROM `stackherotest`.`users`');
  console.log(`Il y a maintenant ${usersCount[0].cpt} entrées dans la table "users"`);

  // Fermez la connexion à MySQL
  await db.end();

})().catch(error => {
  console.error('');
  console.error('🐞 Une erreur est survenue !');
  console.error(error);
  process.exit(1);
});

Pour se connecter depuis Node.js, NestJS ou TypeORM, incluez l'option ssl comme montré dans cet exemple :

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

Pour se connecter en utilisant Prisma, ajoutez l'option sslaccept=strict pour garantir que le chiffrement SSL est activé. Voici un exemple utilisant l'utilisateur "root" et se connectant à la base de données "root" :

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

Si le module mysqlclient n'est pas encore installé, installez-le car il sera utilisé pour se connecter à MySQL :

pip install mysqlclient

Si vous rencontrez l'erreur Exception: Can not find valid pkg-config name lors de l'installation de mysqlclient, installez le package libmysqlclient. Sur Ubuntu/Debian, vous pouvez exécuter : apt-get update && apt-get install --no-install-recommends -y libmysqlclient-dev

Dans cette étape initiale, le mot de passe est stocké directement dans le fichier settings.py à des fins de test uniquement. Il est recommandé d'utiliser une approche plus sécurisée comme décrit plus loin dans cette documentation.

Ouvrez le fichier settings.py et ajoutez ce qui suit :

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

Attention : cet exemple n'est pas recommandé pour la production et est destiné uniquement à des fins de test !

Une fois la connexion réussie, vous pouvez utiliser la méthode recommandée pour stocker les identifiants de manière sécurisée. Dans cet exemple, django-environ est utilisé pour gérer les variables d'environnement.

Tout d'abord, installez django-environ en utilisant la commande :

pip install django-environ

Ensuite, ouvrez le fichier settings.py et ajoutez ce qui suit :

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

Ensuite, ouvrez ou créez le fichier .env dans le même répertoire que settings.py et ajoutez ce qui suit :

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

Enfin, ajoutez .env à votre fichier .gitignore pour vous assurer que vos identifiants ne sont pas commis dans votre dépôt Git :

echo ".env" >> .gitignore

Pour connecter votre application Spring, définissez la variable d'environnement SPRING_DATASOURCE_URL avec votre URL de base de données, préfixée par jdbc: :

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

L'exemple suivant montre comment connecter votre application Grails à MySQL :

dataSource {
  pooled = true
  driverClassName = "com.mysql.cj.jdbc.Driver"
  dialect = org.hibernate.dialect.MySQL8Dialect
  // Propriétés spécifiques 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" // Remplacez "/root" par la base de données à laquelle vous souhaitez vous connecter.
      username = "root" // Il est conseillé de créer un utilisateur dédié plutôt que d'utiliser les identifiants "root".
      password = System.env.STACKHERO_MYSQL_ROOT_PASSWORD // Il est conseillé de créer un utilisateur dédié plutôt que d'utiliser les identifiants "root".
      properties {
        maxActive = 50
        minEvictableIdleTimeMillis = 1800000
        timeBetweenEvictionRunsMillis = 1800000
        numTestsPerEvictionRun = 3
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = false
        validationQuery = "SELECT 1"
      }
    }
  }
}

Une bonne pratique est de créer un utilisateur dédié pour votre application plutôt que d'utiliser l'utilisateur "root".

La manière la plus simple de le faire est via phpMyAdmin.

  1. Dans phpMyAdmin, cliquez sur Comptes utilisateurs en haut.

  2. Cliquez sur Ajouter un compte utilisateur.

  3. Remplissez le formulaire de création d'utilisateur :

    1. Choisissez un nom de compte (généralement le nom de votre application)
    2. Cliquez sur Générer un mot de passe pour créer un mot de passe sécurisé (copiez-le dans votre presse-papiers)
    3. Cochez l'option Créer une base de données portant le même nom et accorder tous les privilèges

Une fois que vous validez le formulaire, le nouvel utilisateur sera créé avec une base de données correspondante partageant le même nom que le nom d'utilisateur.