MySQL: Comenzando

Cómo empezar con MySQL

👋 ¡Bienvenido a la documentación de Stackhero!

Stackhero ofrece una solución MySQL cloud lista para usar que proporciona una serie de beneficios, incluyendo:

  • Conexiones y transferencias ilimitadas.
  • Interfaz web phpMyAdmin incluida.
  • Actualizaciones sin esfuerzo con solo un clic.
  • Rendimiento óptimo y seguridad robusta gracias a una VM privada y dedicada.

Ahorre tiempo y simplifique su vida: ¡solo toma 5 minutos probar la solución de MySQL cloud hosting de Stackhero!

La forma más sencilla de conectarse a su servicio MySQL es usar el formato de URL de MySQL si su controlador lo admite:

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

Para los usuarios de Ruby, el formato de URL de MySQL es ligeramente diferente:

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'; // No recomendamos usar la base de datos "root". Este ejemplo se proporciona solo con fines de demostración. La mejor práctica es crear una base de datos y un usuario dedicados en phpMyAdmin y usarlos aquí.

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

echo 'Conexión exitosa... ' . $mysqli->host_info . "\n";

$mysqli->close();

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // No recomendamos usar la base de datos "root". Este ejemplo es solo para fines de demostración. Es mejor práctica crear una base de datos y un usuario dedicados en phpMyAdmin y usarlos aquí.

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

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

mysqli_close($mysqli);

?>
<?php

$hostname = '<XXXXXX>.stackhero-network.com';
$port = '<PORT>';
$user = 'root';
$password = '<ROOT_PASSWORD>';
$database = 'root'; // No recomendamos usar la base de datos "root". Esto es solo para fines de demostración. La mejor práctica es crear una base de datos y un usuario dedicados en phpMyAdmin y usarlos aquí.

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

$options = array(
  // Si encuentra un error como "Uncaught PDOException: PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed",
  // asegúrese de que el directorio /etc/ssl/certs/ contenga certificados CA.
  // Vea a continuación para más información.
  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 "Está conectado a una base de datos que ejecuta la versión " . $version[0] . "\n";

?>

Si encuentra el error:

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

esto probablemente se deba a que el directorio /etc/ssl/certs/ no contiene certificados CA.

Si tiene acceso al sistema que ejecuta su código PHP, puede instalar estos certificados de la siguiente manera:

  1. En Ubuntu/Debian, ejecute sudo apt-get install ca-certificates
  2. En Alpine Linux, ejecute apk add ca-certificates

Si no tiene acceso directo al sistema que ejecuta su código PHP, puede instalar el certificado manualmente:

  1. Descargue el certificado a su ordenador: https://letsencrypt.org/certs/isrgrootx1.pem
  2. Agregue el archivo isrgrootx1.pem a sus archivos de proyecto PHP.
  3. Comente la línea PDO::MYSQL_ATTR_SSL_CAPATH => '/etc/ssl/certs/'
  4. Descomente la línea PDO::MYSQL_ATTR_SSL_CA => 'isrgrootx1.pem'

Si encuentra el error:

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

o un mensaje similar como:

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

esto indica que PDO se instaló sin soporte MySQL.

Solución para Ubuntu/Debian

Para resolver esto en sistemas basados en Ubuntu o Debian, instale la extensión PHP MySQL requerida ejecutando el siguiente comando:

sudo apt-get install php-mysql
Solución para Docker

Si está utilizando Docker, asegúrese de que el soporte MySQL esté incluido durante el proceso de construcción. Agregue la siguiente línea a su Dockerfile:

RUN docker-php-ext-install pdo pdo_mysql

Edite el archivo .env y defina la variable DATABASE_URL de la siguiente manera:

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

Luego, edite el archivo config/packages/doctrine.yaml y configure el controlador y las opciones de la siguiente manera:

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 recibe el error:

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

esto probablemente se deba a que el directorio /etc/ssl/certs/ no contiene certificados CA.

Si tiene acceso al sistema que ejecuta su código PHP, puede instalar estos certificados de la siguiente manera:

  1. En Ubuntu/Debian, ejecute sudo apt-get install ca-certificates
  2. En Alpine Linux, ejecute apk add ca-certificates

Si no tiene acceso directo al sistema, puede instalar el certificado manualmente:

  1. Descargue el certificado a su ordenador: https://letsencrypt.org/certs/isrgrootx1.pem
  2. Agregue el archivo isrgrootx1.pem a su proyecto Symfony.
  3. Edite el archivo config/packages/doctrine.yaml y configure el controlador y las opciones de la siguiente manera:
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

Edite el archivo config/database.php y reemplace la configuración de mysql con los siguientes ajustes:

'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 encuentra un error como "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,
    ])
    : [],
],

En el archivo database.php, agregue la siguiente configuración:

$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'), // Por convención, la base de datos tiene el mismo nombre que el usuario.
  'dbdriver' => 'mysqli',
  'dbprefix' => '',
  'pconnect' => true,
  'char_set' => 'utf8',
  'dbcollat' => 'utf8_general_ci',
  'encrypt'  => array() // Importante: activar el cifrado TLS
);

Es una buena práctica no almacenar sus credenciales en su código fuente, sino usar variables de entorno.

A continuación se muestra un ejemplo para recuperar estas credenciales:

$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'); // Por convención, la base de datos tiene el mismo nombre que el usuario.

Conectar WordPress a Stackhero para MySQL es sencillo. Simplemente edite el archivo wp-config.php y configure la base de datos de la siguiente manera:

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

// Usar cifrado TLS (también conocido como SSL)
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);

La parte importante aquí es la activación del cifrado TLS (también conocido como SSL). Sin él, la conexión no funcionará.

En este ejemplo, usamos el paquete oficial xdevapi para aprovechar el protocolo MySQL X. Para instalarlo, ejecute:

npm install @mysql/xdevapi

A continuación se muestra un ejemplo completo que utiliza xdevapi:

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

(async () => {
  // Conéctese a MySQL usando el Protocolo MySQL X
  const session = await mysqlx.getSession({
    host: '<XXXXXX>.stackhero-network.com',
    port: '<PORT>',
    user: 'root',
    password: '<ROOT_PASSWORD>'
  });

  // Cree un esquema (base de datos) si no existe
  const schemaExists = await session.getSchema('stackherotest').existsInDatabase();
  if (!schemaExists) {
    await session.createSchema('stackherotest');
  }

  // Cree la tabla 'users' si no existe
  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();
  }

  // Inserte un usuario ficticio
  await session
    .getSchema('stackherotest') // Nombre de la base de datos
    .getTable('users') // Nombre de la tabla
    .insert('userId', 'name', 'address', 'email') // Nombres de las columnas
    .values(
      Math.round(Math.random() * 100000), // Generar un userId ficticio
      'Nombre del usuario', // columna 'name'
      'Dirección del usuario', // columna 'address'
      'user@email.com' // columna 'email'
    )
    .execute();

  // Cuente el número de filas en la tabla 'users'
  const usersCount = await session
    .getSchema('stackherotest') // Nombre de la base de datos
    .getTable('users')
    .count();

  console.log(`Ahora hay ${usersCount} entradas en la tabla "users"`);

  // Cierre la conexión a MySQL
  await session.close();

})().catch(error => {
  console.error('');
  console.error('🐞 ¡Ocurrió un error!');
  console.error(error);
  process.exit(1);
});

En este ejemplo, usamos el paquete mysql2 con soporte de promesas. Para instalarlo, ejecute:

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

  // Cree la base de datos 'stackherotest' si no existe aún
  await db.query('CREATE DATABASE IF NOT EXISTS stackherotest');

  // Cree la tabla 'users' si no existe aún
  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;');

  // Inserte un usuario ficticio
  await db.query(
    'INSERT INTO `stackherotest`.`users` (`userId`, `name`, `address`, `email`) VALUES ?',
    [
      [
        Math.round(Math.random() * 100000), // Generar un userId ficticio
        'Nombre del usuario', // columna 'name'
        'Dirección del usuario', // columna 'address'
        'user@email.com' // columna 'email'
      ]
    ]
  );

  // Cuente el número de filas en la tabla 'users'
  const [ usersCount ] = await db.query('SELECT COUNT(*) AS `cpt` FROM `stackherotest`.`users`');
  console.log(`Ahora hay ${usersCount[0].cpt} entradas en la tabla "users"`);

  // Cierre la conexión a MySQL
  await db.end();

})().catch(error => {
  console.error('');
  console.error('🐞 ¡Ocurrió un error!');
  console.error(error);
  process.exit(1);
});

Para conectarse desde Node.js, NestJS o TypeORM, incluya la opción ssl como se muestra en este ejemplo:

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

Para conectarse usando Prisma, agregue la opción sslaccept=strict para asegurar que el cifrado SSL esté habilitado. Aquí hay un ejemplo usando el usuario "root" y conectándose a la base de datos "root":

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

Si el módulo mysqlclient aún no está instalado, instálelo ya que se usará para conectarse a MySQL:

pip install mysqlclient

Si encuentra el error Exception: Can not find valid pkg-config name al instalar mysqlclient, instale el paquete libmysqlclient. En Ubuntu/Debian, puede ejecutar: apt-get update && apt-get install --no-install-recommends -y libmysqlclient-dev

En este paso inicial, la contraseña se almacena directamente en el archivo settings.py solo con fines de prueba. Se recomienda usar un enfoque más seguro como se describe más adelante en esta documentación.

Abra el archivo settings.py y agregue lo siguiente:

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

Tenga cuidado: este ejemplo no se recomienda para producción y está destinado solo a fines de prueba.

Una vez que la conexión sea exitosa, puede usar el método recomendado para almacenar credenciales de manera segura. En este ejemplo, se utiliza django-environ para gestionar variables de entorno.

Primero, instale django-environ usando el comando:

pip install django-environ

Luego abra el archivo settings.py y agregue lo siguiente:

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

A continuación, abra o cree el archivo .env en el mismo directorio que settings.py y agregue lo siguiente:

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

Finalmente, agregue .env a su archivo .gitignore para asegurarse de que sus credenciales no se comprometan en su repositorio Git:

echo ".env" >> .gitignore

Para conectar su aplicación Spring, configure la variable de entorno SPRING_DATASOURCE_URL con su URL de base de datos, precedida por jdbc::

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

El siguiente ejemplo demuestra cómo conectar su aplicación Grails a MySQL:

dataSource {
  pooled = true
  driverClassName = "com.mysql.cj.jdbc.Driver"
  dialect = org.hibernate.dialect.MySQL8Dialect
  // Propiedades específicas de 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" // Reemplace "/root" con la base de datos a la que desea conectarse.
      username = "root" // Es aconsejable crear un usuario dedicado en lugar de usar las credenciales "root".
      password = System.env.STACKHERO_MYSQL_ROOT_PASSWORD // Es aconsejable crear un usuario dedicado en lugar de usar las credenciales "root".
      properties {
        maxActive = 50
        minEvictableIdleTimeMillis = 1800000
        timeBetweenEvictionRunsMillis = 1800000
        numTestsPerEvictionRun = 3
        testOnBorrow = true
        testWhileIdle = true
        testOnReturn = false
        validationQuery = "SELECT 1"
      }
    }
  }
}

Una buena práctica es crear un usuario dedicado para su aplicación en lugar de usar el usuario "root".

La forma más sencilla de hacerlo es a través de phpMyAdmin.

  1. En phpMyAdmin, haga clic en Cuentas de usuario en la parte superior.

  2. Haga clic en Agregar cuenta de usuario.

  3. Complete el formulario de creación de usuario:

    1. Elija un nombre de cuenta (generalmente el nombre de su aplicación)
    2. Haga clic en Generar contraseña para crear una contraseña segura (cópiela en su portapapeles)
    3. Marque la opción Crear base de datos con el mismo nombre y otorgar todos los privilegios

Una vez que valide el formulario, se creará el nuevo usuario junto con una base de datos correspondiente que comparte el mismo nombre que el nombre de usuario.