Настройка Mysql / MariaDB

MySQL — одна из самых популярных реляционных СУБД, широко используемая в веб-разработке. Подходит для проектов любого масштаба: от небольших сайтов до высоконагруженных систем.

MariaDB — форк MySQL с расширенной функциональностью, полностью совместим с драйвером mysql, но также может работать под собственным драйвером mariadb.

Настройка переменных окружения

Откройте файл .env и укажите параметры подключения:

# Название подключения из секции connections
# (должно совпадать с ключом в config/database.php)
DB_CONNECTION=my-mysql

# Хост и порт
DB_HOST=127.0.0.1
DB_PORT=3306

# Имя базы данных
DB_DATABASE=imhotep

# Учётные данные
DB_USERNAME=root
DB_PASSWORD=secret

# Дополнительные параметры (опционально)
DB_SOCKET=/var/run/mysqld/mysqld.sock
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
INI

Конфигурационный файл

В файле config/database.php в массиве connections добавьте или обновите запись:

'my-mysql' => [
    // Для MariaDB используйте драйвер: mariadb
    'driver' => 'mysql',
    
    // Подключение через сокет (приоритетнее host:port)
    'unix_socket' => env('DB_SOCKET', ''),
    
    // Хост и порт
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    
    // Имя базы и автоматический выбор после подключения
    'database' => env('DB_DATABASE', 'imhotep'),
    // Отключить автоматический USE database после подключения
    //'use_db_after_connecting' => false,
    
    // Учётные данные
    'username' => env('DB_USERNAME', 'root'),
    'password' => env('DB_PASSWORD', 'secret'),
    
    // Кодировка и сравнение
    'charset' => env('DB_CHARSET', 'utf8mb4'),
    'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
    
    // Префикс таблиц (полезно для мультитенантности)
    'prefix' => '',
    // Добавлять ли префикс к индексам
    'prefix_indexes' => true,
    
    // Режимы работы (подробнее ниже)
    'modes' => null,
    
    // Строгий режим (рекомендуется true)
    'strict' => true,
    
    // Движок таблиц по умолчанию (InnoDB, MyISAM и т.д.)
    'engine' => null,
    
    // Часовой пояс
    'timezone' => null,
    
    // Уровень изоляции, по умолчанию "REPEATABLE READ" (подробнее ниже)
    // 'isolation_level' => 'REPEATABLE READ',
    
    // Дополнительные PDO-опции
    'options' => [
        // PDO::ATTR_EMULATE_PREPARES => false,
        // PDO::ATTR_PERSISTENT => true,
        // PDO::MYSQL_ATTR_SSL_CA => 'ca.crt'
    ]
],
PHP

Уровень изоляции транзакций

Transaction Isolation level (уровень изоляции транзакций) — это механизм, который определяет, насколько изменения одной транзакции видны другим. Это баланс между согласованностью и производительностью.

Уровень Проблемы Блокировки Когда использовать
READ UNCOMMITTED Грязное чтение (dirty read) Почти нет Только для отчётов, где допустима неточность
READ COMMITTED Неповторяемое чтение (non-repeatable read) Строки блокируются только на время запроса Большинство веб-приложений (баланс скорости и консистентности)
REPEATABLE READ Фантомное чтение (phantom read), частично предотвращается gap-блокировками MVCC + снимок данных Когда важна стабильность чтения в рамках транзакции (дефолт MySQL)
SERIALIZABLE Нет Максимальные (shared + exclusive locks) Финансовые операции, где точность важнее скорости

Разделение чтения и записи

Для высоконагруженных проектов имеет смысл направлять SELECT-запросы на реплики, а INSERT/UPDATE/DELETE — на мастер-сервер. Это повышает пропускную способность и отказоустойчивость.

'my-mysql' => [
    'driver' => 'mysql',
    
    'read' => [
        'host' => [
            '192.168.1.1',  // Реплика 1
            '192.168.1.2',  // Реплика 2
        ],
        
        // Можно переопределить порт/пользователя для чтения
        'port' => 3306,
        'username' => 'readonly_user',
        'password' => 'readonly_pass',
    ],
    'write' => [
        'host' => [
            '192.168.1.3', // Мастер 1
            '192.168.1.4', // Мастер 2
        ],  
        // Или если есть только один мастер
        'host' => '192.168.1.3'
    ],
    
    // После записи читать с мастера в течение текущего соединения
    'sticky' => true,
    
    // Общие настройки для всех подключений
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'imhotep'),
    'username' => env('DB_USERNAME', 'root'),
    'password' => env('DB_PASSWORD', 'secret'),
    'charset' => env('DB_CHARSET', 'utf8mb4'),
    'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
    'prefix' => '',
    'strict' => true,
    'engine' => null,
],
PHP

Как работает sticky:

Если sticky = true, то в течение одного HTTP-запроса после любой операции записи все последующие чтения будут направляться на мастер-сервер. Это гарантирует, что вы сразу увидите свои изменения (избегает репликационной задержки).

Режимы SQL (SQL Modes)

Режимы влияют на поведение SQL-запросов и строгость проверок. Если modes не задан, будет использовано значение strict. Во время разработки рекомендуется использовать строгий режим, чтобы отловить все ошибки данных.

// Использовать следующие ограничения
'modes' => [
    'STRICT_TRANS_TABLES',
    'ONLY_FULL_GROUP_BY',
    'NO_ZERO_IN_DATE',
    'NO_ZERO_DATE',
    'ERROR_FOR_DIVISION_BY_ZERO',
    'NO_ENGINE_SUBSTITUTION',
],
PHP

SSL-подключение

Если БД требует защищённого соединения, используйте options:

'options' => [
    PDO::MYSQL_ATTR_SSL_CA   => '/path/to/ca.pem',
    PDO::MYSQL_ATTR_SSL_KEY  => '/path/to/client-key.pem',
    PDO::MYSQL_ATTR_SSL_CERT => '/path/to/client-cert.pem',
],
PHP

Параметр use_db_after_connecting

Опция use_db_after_connecting определяет, будет ли автоматически выполнена команду USE database_name после установки соединения с БД. Используйте этот параметр, в случае крайней необходимости.