Настройка PostgreSQL
PostgreSQL — мощная объектно-реляционная СУБД с продвинутыми возможностями: JSON, полнотекстовый поиск, расширения.
Настройка переменных окружения
Откройте файл .env и укажите параметры подключения:
# Название подключения из секции connections
# (должно совпадать с ключом в config/database.php)
DB_CONNECTION=my-pgsql
# Хост и порт
DB_HOST=127.0.0.1
DB_PORT=5432
# Имя базы данных
DB_DATABASE=imhotep
# Учётные данные
DB_USERNAME=root
DB_PASSWORD=secret
# Режим SSL (подробнее ниже)
DB_SSLMODE=prefer
# Схема по умолчанию (обычно public)
DB_SCHEMA=public
# Режим пулинга (PgBouncer)
DB_POOLED=false
Конфигурационный файл
В файле config/database.php в массиве connections добавьте или обновите запись:
'my-pgsql' => [
// Драйвер PostgreSQL
'driver' => 'pgsql',
// Хост и порт
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
// Имя базы данных
'database' => env('DB_DATABASE', 'imhotep'),
// Учётные данные
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
// Кодировка (рекомендуется UTF-8)
'charset' => 'utf8',
// Схема (аналог базы данных в MySQL)
'search_path' => env('DB_SCHEMA', 'public'),
// Префикс таблиц (полезно для мультитенантности)
'prefix' => '',
// Добавлять ли префикс к индексам
'prefix_indexes' => true,
// Режим SSL (подробнее ниже)
'sslmode' => env('DB_SSLMODE', 'prefer'),
// Уровень изоляции транзакций (подробнее ниже)
'isolation_level' => env('DB_ISOLATION_LEVEL', 'read committed'),
// Часовой пояс для сессии
'timezone' => env('DB_TIMEZONE', 'UTC'),
// Режим синхронизации COMMIT (для производительности)
'synchronous_commit' => env('DB_SYNC_COMMIT', 'on'),
// Формат даты (по умолчанию ISO 8601)
'date_format' => env('DB_DATE_FORMAT', 'Y-m-d H:i:s'),
// Unix-сокет (приоритетнее host:port, если указан)
'unix_socket' => env('DB_SOCKET', ''),
// Дополнительные PDO-опции
'options' => [
// PDO::ATTR_EMULATE_PREPARES => false,
// PDO::ATTR_PERSISTENT => true,
// PDO::ATTR_TIMEOUT => 5,
],
],
Схема и search_path
Параметр search_path определяет порядок поиска схем при обращении к таблицам без явного указания схемы. Аналог database в MySQL, но более гибкий.
// Одна схема
'search_path' => 'public',
// Несколько схем (поиск по порядку)
'search_path' => 'myapp, public',
// Динамически через .env
'search_path' => env('DB_SCHEMA', 'public'),
Уровень изоляции транзакций
Transaction Isolation Level определяет видимость изменений между параллельными транзакциями. PostgreSQL поддерживает все четыре уровня стандарта SQL, но с особенностями реализации (MVCC без блокировок на чтение).
| Уровень | Проблемы | Когда использовать |
|---|---|---|
read uncommitted |
Грязное чтение (dirty read) | Не рекомендуется - в PostgreSQL работает как read committed |
read committed |
Неповторяемое чтение (non-repeatable read) | По умолчанию - баланс скорости и консистентности для большинства веб-приложений |
repeatable read |
Фантомное чтение (phantom read) - предотвращается | Когда важна стабильность чтения в рамках транзакции (аналитика, отчёты) |
serializable |
Нет (полная изоляция) | Финансовые операции, где точность критична (может вызывать ошибки сериализации) |
В PostgreSQL
repeatable readполностью предотвращает фантомные чтения (в отличие от MySQL).
Разделение чтения и записи
Для высоконагруженных проектов имеет смысл направлять SELECT-запросы на реплики, а INSERT/UPDATE/DELETE — на мастер-сервер. Это повышает пропускную способность и отказоустойчивость.
'my-pgsql' => [
'driver' => 'pgsql',
'read' => [
'host' => [
'192.168.1.1', // Реплика 1
'192.168.1.2', // Реплика 2
],
// Можно переопределить порт/пользователя для чтения
'port' => 5432,
'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', '5432'),
'database' => env('DB_DATABASE', 'imhotep'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'secret'),
'charset' => 'utf8',
'search_path' => 'public',
//...
],
Как работает sticky:
Если sticky = true, то в течение одного HTTP-запроса после любой операции записи все последующие чтения будут направляться на мастер-сервер.
Это гарантирует, что вы сразу увидите свои изменения (избегает репликационной задержки).