PostgreSQL
Что это
PostgreSQL — это зрелая реляционная база данных с открытым исходным кодом, которая хранит данные в типизированных таблицах с сильной поддержкой SQL, транзакций и целостности данных. Она известна корректностью, расширяемостью и богатыми возможностями вроде JSONB, полнотекстового поиска и оконных функций. Это выбор по умолчанию для большинства бэкендов приложений, которым нужны надёжные структурированные данные.
Сильные стороны
- ACID-транзакции и сильная согласованность по умолчанию.
- Мощный SQL: соединения, CTE, оконные функции и агрегаты.
- Гибкие типы, включая
JSONB, массивы, диапазоны и пользовательские типы. - Расширения вроде PostGIS (геопространственные данные) и
pgvector(эмбеддинги). - Сильные ограничения, внешние ключи и проверочные правила обеспечивают качество данных.
Компромиссы
- Вертикальное масштабирование лёгкое; горизонтальный шардинг требует дополнительного инструментария.
- Требует миграций схемы по мере развития модели.
- Тяжелее в эксплуатации, чем однофайловая база данных, для крошечных проектов.
- Модель «соединение на клиента» требует пулера (PgBouncer) при высокой нагрузке.
Когда использовать
Обращайтесь к PostgreSQL как к варианту по умолчанию почти для любого приложения с реляционными данными, транзакциями или потребностями в отчётности: бэкенды SaaS, электронная коммерция, аналитика и всё, что выигрывает от ограничений и соединений.
Соответствие вайб-кодингу
Управляя ИИ, дайте ему сущности и их связи, а затем попросите создать нормализованную схему с первичными ключами, внешними ключами, ограничениями NOT NULL и разумными индексами. Настаивайте на параметризованных запросах (никогда не на SQL, собранном конкатенацией строк), чтобы предотвратить инъекции, и просите ИИ оборачивать многошаговые записи в транзакцию. Хороший совет: скажите ИИ также генерировать обратимый файл миграции и объяснять каждый добавляемый индекс, чтобы вы понимали компромиссы между чтением и записью до применения.
CREATE TABLE users (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE orders (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
total NUMERIC(10,2) NOT NULL CHECK (total >= 0),
status TEXT NOT NULL DEFAULT 'pending'
);
CREATE INDEX idx_orders_user_id ON orders(user_id);
-- Параметризованный запрос (плейсхолдеры, а не конкатенация)
SELECT o.id, o.total
FROM orders o
WHERE o.user_id = $1 AND o.status = $2;