Работа с базами данных в JavaScript: PostgreSQL и MongoDB на практике

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Зачем разработчику знать SQL и NoSQL?

Современная веб-разработка на JavaScript (Node.js) редко обходится без взаимодействия с базами данных. Выбор между реляционными (PostgreSQL) и документоориентированными (MongoDB) СУБД — одна из ключевых архитектурных задач. В этой статье мы на практике разберём, как подключаться к обеим базам данных, выполнять CRUD-операции и выбирать подходящий инструмент под конкретную задачу.

Мы будем использовать популярные библиотеки: pg для PostgreSQL и mongoose для MongoDB. Все примеры кода — на Node.js.

1. PostgreSQL в Node.js: реляционный подход

1.1. Подключение и настройка

PostgreSQL — это мощная реляционная СУБД с поддержкой SQL. Для работы с ней в Node.js установите пакет pg:

npm install pg

Пример подключения к локальной базе данных mydb:

const { Pool } = require('pg');

const pool = new Pool({
  user: 'postgres',
  host: 'localhost',
  database: 'mydb',
  password: 'secret',
  port: 5432,
});

// Тестирование соединения
pool.query('SELECT NOW()', (err, res) => {
  if (err) {
    console.error('Ошибка подключения:', err);
  } else {
    console.log('Подключено к PostgreSQL:', res.rows[0].now);
  }
});

1.2. CRUD-операции (создание, чтение, обновление, удаление)

Создадим таблицу users и выполним базовые операции.

Создание таблицы:

const createTable = async () => {
  const query = `
    CREATE TABLE IF NOT EXISTS users (
      id SERIAL PRIMARY KEY,
      name VARCHAR(100) NOT NULL,
      email VARCHAR(100) UNIQUE NOT NULL,
      age INTEGER
    );
  `;
  await pool.query(query);
  console.log('Таблица users создана');
};

createTable();

Вставка данных (INSERT):

const addUser = async (name, email, age) => {
  const query = 'INSERT INTO users (name, email, age) VALUES ($1, $2, $3) RETURNING *';
  const values = [name, email, age];
  const res = await pool.query(query, values);
  console.log('Добавлен пользователь:', res.rows[0]);
};

addUser('Иван Петров', 'ivan@example.com', 30);

Чтение данных (SELECT):

const getUsers = async () => {
  const res = await pool.query('SELECT * FROM users');
  console.log('Все пользователи:', res.rows);
};

getUsers();

Обновление данных (UPDATE):

const updateUserAge = async (id, newAge) => {
  const query = 'UPDATE users SET age = $1 WHERE id = $2 RETURNING *';
  const values = [newAge, id];
  const res = await pool.query(query, values);
  console.log('Обновлён пользователь:', res.rows[0]);
};

updateUserAge(1, 31);

Удаление данных (DELETE):

const deleteUser = async (id) => {
  const query = 'DELETE FROM users WHERE id = $1 RETURNING *';
  const values = [id];
  const res = await pool.query(query, values);
  console.log('Удалён пользователь:', res.rows[0]);
};

deleteUser(1);

Обратите внимание на использование параметризованных запросов ($1, $2). Это защищает от SQL-инъекций.

1.3. Когда выбирать PostgreSQL?

  • Требуется строгая структура данных и поддержка целостности (внешние ключи, транзакции).
  • Необходимы сложные JOIN-запросы и агрегации.
  • Работа с финансовыми или критически важными данными.
  • Проект использует ORM вроде Sequelize или TypeORM.

2. MongoDB в Node.js: гибкость NoSQL

2.1. Подключение через Mongoose

MongoDB — документоориентированная база данных, где данные хранятся в формате JSON-like (BSON). Для работы установите mongoose:

npm install mongoose

Подключение к локальному серверу MongoDB:

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/mydb')
  .then(() => console.log('Подключено к MongoDB'))
  .catch(err => console.error('Ошибка MongoDB:', err));

2.2. Определение схемы и модели

В отличие от PostgreSQL, MongoDB не требует предварительного создания таблиц. Вместо этого мы определяем схему (Schema) и модель (Model):

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  age: { type: Number, min: 0 },
  createdAt: { type: Date, default: Date.now },
});

const User = mongoose.model('User', userSchema);

2.3. CRUD-операции

Создание документа:

const addUser = async (name, email, age) => {
  const user = new User({ name, email, age });
  const savedUser = await user.save();
  console.log('Добавлен пользователь:', savedUser);
};

addUser('Мария Смирнова', 'maria@example.com', 25);

Чтение документов:

const getUsers = async () => {
  const users = await User.find();
  console.log('Все пользователи:', users);
};

getUsers();

Обновление документа:

const updateUserAge = async (id, newAge) => {
  const user = await User.findByIdAndUpdate(
    id,
    { age: newAge },
    { new: true } // возвращает обновлённый документ
  );
  console.log('Обновлён пользователь:', user);
};

updateUserAge('60d5f484f1a2c8b1f8e4e1a2', 26);

Удаление документа:

const deleteUser = async (id) => {
  const user = await User.findByIdAndDelete(id);
  console.log('Удалён пользователь:', user);
};

deleteUser('60d5f484f1a2c8b1f8e4e1a2');

2.4. Когда выбирать MongoDB?

  • Структура данных часто меняется (динамические схемы).
  • Требуется высокая скорость записи и горизонтальное масштабирование.

Блоги

Рекомендаций по книгам