Як у PDO перейти з MySQL на PostgreSQL

PDO (PHP Data Objects) дозволяє змінити базу даних з MySQL на PostgreSQL без переписування PHP-коду, якщо код написаний правильно. Однак потрібно розуміти, що саме змінюється, а що — ні.


1. Головне правило

PDO прибирає залежність від драйвера БД, але не від SQL-діалекту.

  • ✔ PHP-код зазвичай не змінюється
  • ✔ змінюється DSN підключення
  • ❌ SQL-запити та структура БД можуть потребувати адаптації

2. Заміна DSN (обовʼязково)

Було: MySQL

$pdo = new PDO(
    "mysql:host=localhost;dbname=test_db;charset=utf8mb4",
    "db_user",
    "db_pass",
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    ]
);

Стало: PostgreSQL

$pdo = new PDO(
    "pgsql:host=localhost;port=5432;dbname=test_db",
    "db_user",
    "db_pass",
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    ]
);

Весь інший PHP-код залишається без змін.


3. PDO-код, який працює і в MySQL, і в PostgreSQL

$stmt = $pdo->prepare(
    "SELECT id, name FROM users WHERE active = :active"
);

$stmt->execute([
    'active' => true
]);

$rows = $stmt->fetchAll();

4. Що ламається при переході (і як виправити)

LIMIT offset, count

MySQL:

LIMIT 10, 20

PostgreSQL:

LIMIT 20 OFFSET 10

Універсальний варіант:

LIMIT :limit OFFSET :offset

AUTO_INCREMENT

MySQL:

id INT AUTO_INCREMENT

PostgreSQL:

id SERIAL
-- або
id INT GENERATED ALWAYS AS IDENTITY

PHP-код не змінюється, якщо використовується lastInsertId().


INSERT IGNORE

MySQL:

INSERT IGNORE INTO users (...)

PostgreSQL:

INSERT INTO users (...)
ON CONFLICT DO NOTHING

ON DUPLICATE KEY UPDATE

MySQL:

ON DUPLICATE KEY UPDATE name = VALUES(name)

PostgreSQL:

ON CONFLICT (email)
DO UPDATE SET name = EXCLUDED.name

IF()

MySQL:

IF(active = 1, 'yes', 'no')

PostgreSQL:

CASE WHEN active THEN 'yes' ELSE 'no' END

5. Типи даних, які потрібно змінити

MySQL PostgreSQL
TINYINT(1) BOOLEAN
DATETIME TIMESTAMP
LONGTEXT TEXT
DOUBLE DOUBLE PRECISION

6. JSON — різний синтаксис

MySQL:

JSON_EXTRACT(data, '$.name')

PostgreSQL:

data->>'name'

7. Рекомендовані налаштування PDO

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false
];

8. Коли можна змінити БД без змін PHP

  • ✔ використовується PDO
  • ✔ немає MySQL-специфічного SQL
  • ✔ відсутні FULLTEXT, ENUM, REPLACE INTO

9. Висновок

Перехід з MySQL на PostgreSQL у PDO — це перш за все:

  • 🔹 заміна DSN
  • 🔹 адаптація SQL-запитів
  • 🔹 міграція структури БД

PDO значно спрощує міграцію, але не є повною абстракцією від SQL.

Рекомендація: завжди пишіть портований SQL, щоб у майбутньому легко змінювати СУБД.