Введение: Зачем разработчику знать 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?
- Структура данных часто меняется (динамические схемы).
- Требуется высокая скорость записи и горизонтальное масштабирование.