Найти в Дзене
Блог IT разработчика

Мой топ‑5 решений при разработке качественной IT‑системы

Создание надёжной, быстрой и удобной IT‑системы требует продуманного подхода к архитектуре, оптимизации и безопасности. Ниже — подборка ключевых решений, которые помогают добиться высокого качества продукта. Суть. Денормализация — это сознательное введение избыточности в реляционную базу данных (уже прошедшую нормализацию) ради роста производительности чтения. Цели: Как это работает. Вместо множества быстрых запросов к нормализованным таблицам мы создаём материализованные представления или дублируем данные, чтобы получать нужные сведения за один запрос. Пример. Представление, объединяющее данные из трёх таблиц: sql CREATE OR REPLACE VIEW core.newview AS
SELECT
cmd.cmdid,
cmd.cmdtype,
cmd.cmdexecstate,
cmd.data,
ctl.fname,
ctl.block,
gud.f_name,
cmd.errdecx,
cmd.stime,
cmd.etime,
cmd.ins_time,
gud.swver,
gud.swname,
ctl.block / ctl.blksize * 100 / ctl.fsize AS percent
FROM rmmt_srv.m_term_cmd cmd
LEFT JOIN rmmt_srv.m_term_ctl ctl O
Оглавление

Создание надёжной, быстрой и удобной IT‑системы требует продуманного подхода к архитектуре, оптимизации и безопасности. Ниже — подборка ключевых решений, которые помогают добиться высокого качества продукта.

1. Денормализация базы данных для ускорения чтения

Суть. Денормализация — это сознательное введение избыточности в реляционную базу данных (уже прошедшую нормализацию) ради роста производительности чтения.

Цели:

  • сократить число операций соединения (JOIN);
  • снизить нагрузку на СУБД;
  • повысить отзывчивость приложения;
  • оптимизировать работу с OLAP‑нагрузкой.

Как это работает. Вместо множества быстрых запросов к нормализованным таблицам мы создаём материализованные представления или дублируем данные, чтобы получать нужные сведения за один запрос.

Пример. Представление, объединяющее данные из трёх таблиц:

sql

CREATE OR REPLACE VIEW core.newview AS
SELECT
cmd.cmdid,
cmd.cmdtype,
cmd.cmdexecstate,
cmd.data,
ctl.fname,
ctl.block,
gud.f_name,
cmd.errdecx,
cmd.stime,
cmd.etime,
cmd.ins_time,
gud.swver,
gud.swname,
ctl.block / ctl.blksize * 100 / ctl.fsize AS percent
FROM rmmt_srv.m_term_cmd cmd
LEFT JOIN rmmt_srv.m_term_ctl ctl ON cmd.tid::text = ctl.tid::text
LEFT JOIN LATERAL (
SELECT
gud_1.id,
gud_1.f_name,
gud_1.oid_tp,
gud_1.f_sign,
gud_1.hwid,
gud_1.swname,
gud_1.swver,
gud_1.descx,
gud_1.crdate,
gud_1.sdate,
gud_1.edate,
gud_1.grp
FROM rmmt_srv.g_update_def gud_1
WHERE cmd.cmdtype::text = 'setUpdate'::text
AND to_number(NULLIF("substring"(cmd.data::text, 2), ''::text), '9999999999'::text) = gud_1.id
) gud ON true;

Когда применять. В системах с частым чтением и редким обновлением данных, в аналитических приложениях, дашбордах.

2. Балансировка нагрузки через Nginx

Суть. Распределение запросов между несколькими серверами‑бэкендами для повышения отказоустойчивости и производительности.

Ключевые настройки:

  • upstream — список серверов‑бэкендов;
  • weight — вес сервера (приоритет);
  • max_fails — число ошибок подряд до исключения из пула;
  • fail_timeout — время исключения;
  • backup — резервный сервер;
  • keepalive — количество соединений в пуле.

Пример конфигурации:

nginx

upstream backend {
server 192.168.1.1:30 weight=3;
server 192.168.1.2:30;
server 192.168.1.13:30 max_fails=3 fail_timeout=3s;
server 192.168.1.14:30 backup;
}

server {
location /api {
proxy_pass http://backend;
proxy_set_header Host $host;
keepalive 32;
}
}

Плюсы:

  • равномерное распределение нагрузки;
  • автоматическое отключение упавших серверов;
  • поддержка резервных узлов;
  • экономия ресурсов за счёт keepalive.

3. Кэширование с Redis

Суть. Хранение часто запрашиваемых данных в оперативной памяти (Redis) для сокращения времени ответа и нагрузки на БД.

Алгоритм:

  1. Формируем уникальный ключ кэша на основе параметров запроса.
  2. Проверяем наличие данных в Redis.
  3. Если кэш есть — отдаём его.
  4. Если нет — выполняем запрос к БД, сохраняем результат в Redis, возвращаем клиенту.

Пример кода (Node.js):

javascript

const where = { link, ...require('../../../function/helper').getWhereRowFilter(req.query) };
const cacheKey = `articles:link:${link}:${JSON.stringify(where)}`;

const cached = await require('../../../redis/redis').getCache(cacheKey);
if (cached) return res.status(200).json(cached.data);

// Если кэша нет — выполняем запрос к БД и сохраняем результат
const data = await Article.findAll({ where });
await require('../../../redis/redis').setCache(cacheKey, { data });
res.json(data);

Плюсы:

  • снижение времени ответа до миллисекунд;
  • уменьшение нагрузки на БД;
  • масштабируемость при росте числа запросов.

4. Валидация данных через Joi

Суть. Проверка входных данных на соответствие схеме до их обработки бизнес‑логикой.

Почему Joi:

  • декларативный синтаксис;
  • богатая система правил (обязательность, типы, регулярные выражения, длины и т. д.);
  • интеграция с Express/Koa.

Пример схемы для статьи:

javascript

const Joi = require('joi');

const articleSchema = Joi.object({
link: Joi.string().required().trim().lowercase().regex(/^[a-z0-9-]+$/),
linktext: Joi.string().required().trim(),
title: Joi.string().max(255).required(),
description: Joi.string().allow('', null),
text: Joi.string().allow('', null),
ins_datetime: Joi.date().optional().default(Date.now),
upd_datetime: Joi.date().optional()
});

module.exports = { articleSchema };

Плюсы:

  • предотвращение ошибок на раннем этапе;
  • единообразие данных;
  • упрощение отладки (чёткие сообщения об ошибках).

5. Универсальный CRUD‑контроллер

Суть. Абстракция над типовыми операциями с данными (Create, Read, Update, Delete) для сокращения дублирования кода.

Преимущества:

  • единообразный API для разных моделей;
  • встроенная поддержка кэширования;
  • гибкость через параметры конфигурации.

Пример сигнатуры:

javascript

const createCrudController = (options) => {
const {
model, // Sequelize‑модель
cachePrefix, // Префикс для ключей Redis
attributes = null, // Какие поля возвращать
byLinkText = false, // Разрешить поиск по linktext
transformQuery = (where) => where // Модификация условия WHERE
} = options;

// ... реализация методов GET, POST, PUT, DELETE
};

Как использовать:

javascript

const articleController = createCrudController({
model: Article,
cachePrefix: 'articles',
attributes: ['id', 'link', 'title'],
byLinkText: true
});

Плюсы:

  • сокращение объёма кода;
  • стандартизация API;
  • лёгкая интеграция кэширования и фильтрации.

Дополнительные приёмы (кратко)

  1. Деструктуризация объектов
    Упрощает работу с параметрами запроса:

javascript

let { offset, limit, order } = req.query;

  1. Заголовок Content-Range
    Позволяет клиенту знать общее число записей и размер выборки:

javascript

const range = `${count}/${data.length}`;
res.set('Content-Range', range);

Итог

Эти решения формируют фундамент качественной IT‑системы:

  • денормализация — скорость чтения;
  • балансировка — отказоустойчивость;
  • кэширование — отзывчивость;
  • валидация — целостность данных;
  • универсальный CRUD — поддерживаемость кода.

Комбинируя их, вы получаете систему, которая:

  • быстро отвечает на запросы;
  • выдерживает высокую нагрузку;
  • легко масштабируется;
  • проста в поддержке и развитии.

Подписаться | Канал в дзене | Наш сайт | ВК | YouTube