Встречается на 20% собеседований по JavaScript

Расскажи про опыт работы с PostgreSQL

PostgreSQL — это мощная реляционная СУБД с расширенными возможностями, которую я активно использовал в Node.js-проектах. В работе я применял как нативный драйвер pg, так и ORM (Sequelize, TypeORM) в зависимости от задачи. Ключевые аспекты: эффективное управление подключениями через пул, использование транзакций для целостности данных, работа с JSONB для гибкого хранения и подготовленные выражения для безопасности.

Как это работает

В Node.js основным способом взаимодействия с PostgreSQL является драйвер pg. Он предоставляет два основных API: Client для одиночных подключений и Pool для управления пулом соединений. Пул особенно важен в веб-приложениях, так как создание нового подключения — дорогая операция. Пример настройки пула:

javascript
const { Pool } = require('pg');
const pool = new Pool({
  user: 'dbuser',
  host: 'localhost',
  database: 'mydb',
  password: 'secret',
  port: 5432,
  max: 10, // максимальное число соединений в пуле
  idleTimeoutMillis: 30000,
});

async function getUsers() {
const res = await pool.query('SELECT * FROM users WHERE active = $1', [true]);
return res.rows;
}

text

Здесь `$1` — это параметризованный запрос, который защищает от SQL-инъекций. Драйвер автоматически использует prepared statements для повторяющихся запросов, что повышает производительность.

## Транзакции и продвинутые возможности

Транзакции обеспечивают атомарность операций. В `pg` их можно реализовать через `BEGIN`/`COMMIT`/`ROLLBACK`, но удобнее использовать клиент из пула:

```javascript
const client = await pool.connect();
try {
  await client.query('BEGIN');
  await client.query('UPDATE accounts SET balance = balance - 100 WHERE id = $1', [1]);
  await client.query('UPDATE accounts SET balance = balance + 100 WHERE id = $1', [2]);
  await client.query('COMMIT');
} catch (err) {
  await client.query('ROLLBACK');
  throw err;
} finally {
  client.release();
}

PostgreSQL также поддерживает тип JSONB, который позволяет хранить документы и эффективно индексировать их содержимое. Это удобно для гибких схем данных. Для сложных выборок я использовал CTE (WITH-запросы) и оконные функции (ROW_NUMBER(), SUM() OVER), что упрощает аналитические запросы.

Подводные камни

  • Утечка соединений: если не вызывать client.release() или не закрывать Pool, соединения исчерпаются. Всегда используйте try/finally или async-менеджеры.
  • N+1 запросов: при использовании ORM легко попасть в ловушку множественных запросов. Решается через JOIN или eager loading.
  • Миграции: без системы миграций (например, node-pg-migrate) сложно поддерживать схему БД в команде.
  • Производительность: для массовых операций лучше использовать COPY или батч-вставки, а не циклы с отдельными INSERT.

Когда использовать

PostgreSQL — отличный выбор для проектов, требующих надёжности, сложных запросов и гибкости данных. В Node.js он хорошо сочетается с Express/NestJS. ORM (Sequelize, TypeORM) ускоряет разработку, но для высоконагруженных систем лучше использовать нативный pg с ручной оптимизацией запросов.

Коротко

  • Основной драйвер — pg, используйте Pool для управления соединениями.
  • Всегда применяйте параметризованные запросы для защиты от SQL-инъекций.
  • Транзакции обязательны для операций, изменяющих несколько таблиц.
  • Используйте JSONB, CTE и оконные функции для сложных сценариев.
  • Следите за утечками соединений и избегайте N+1 запросов в ORM.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы