Зачем NoSQL, если есть PostgreSQL
Чему научишься
- объяснять, что такое база данных и почему таблица — не единственный способ хранить данные;
- узнавать по задаче пять видов хранилищ, которые работают рядом с обычной базой;
- выполнить первую команду Redis и увидеть, как запись исчезает сама.
Глава 1 — «Не всё должно быть таблицей»
Ты — курсант-архивист на станции, которая хранит архивы старой Земли. Мимо этой секции курсанты ходят каждый день: тёмное стекло, за ним ряды погасших хранилищ. Сегодня внутри горит дежурный свет. Инженеры впервые дали питание в Тёмную галерею.
Здесь стоят хранилища «Котомаркета» — интернет-магазина, чью основную базу станция сохранила целиком: покупатели, товары, заказы. Только одной базой магазин не обходился. Рядом работали быстрая память для корзин, хранилище карточек товаров, серверы службы доставки, поиск по витрине. Все они погасли в последний вечер магазина, 24 февраля 2025 года.
У входа тебя встречает комендант галереи: «Заказы, товары и покупатели и так лежали в основной базе. Зачем магазину понадобилось ещё столько хранилищ? Разберись — и скажи, что из этого можно спасти».
С тобой идёт КВЕРИ — ИИ-наставник станции, старый архивный интеллект с повадками кота. Он будет подсказывать по дороге.

Сначала — что такое база данных
Программе магазина нужно помнить, что происходит: какие товары остались на складе, кто что заказал, сколько это стоило. Место, где программа хранит эти сведения и откуда потом их достаёт, называют базой данных.
Часто данные в базе лежат таблицами — почти как в электронной таблице: каждая строка хранит одну запись, например товар или заказ, а каждый столбец — одно свойство, например название или цену. Чтобы получить данные из таблицы, программа отправляет базе запрос на языке SQL. Основная база «Котомаркета» работает на PostgreSQL — это программа, которая хранит таблицы и отвечает на такие запросы.
Ниже настоящий запрос к ней: он просит пять самых дорогих товаров. Подробно SQL разбирает отдельный курс, а этот запрос можно прочитать по строкам:
SELECT name, price— покажи название и цену;FROM products— возьми их из таблицы товаров;ORDER BY price DESC— расставь от самой высокой цены к самой низкой;LIMIT 5— оставь первые пять строк.
Нажми «Запустить» и посмотри, что вернёт база.
После запуска база возвращает результат, который снова выглядит как маленькая таблица. Каждая строка в нём — найденный товар, а столбцы показывают его название и цену.
Команда попросила сначала поставить товары с большей ценой, а затем оставить первые пять строк. PostgreSQL ничего не переставляет в самой таблице навсегда: такой порядок существует только в ответе на этот запрос.
Это важная опора для всей главы. Таблица и SQL отлично работают там, где данные удобно спрашивать строками и столбцами. Дальше встретятся задачи, где удобнее другой способ хранения или поиска.
Где таблице неудобно
Таблица хорошо подходит, когда у всех записей одни и те же свойства: у каждого заказа есть покупатель и сумма, у каждого товара — название и цена. Но у интернет-магазина хватает задач, где такая форма начинает мешать.
- Корзина гостя. Пока человек ходит по сайту, магазин помнит, что лежит у него в корзине. Если он ушёл и полчаса не возвращается, корзину можно забыть. В таблице пришлось бы отдельно следить за временем и удалять старые строки.
- Счётчик просмотров. Открыли страницу товара — к счётчику прибавилась единица. Таких событий могут быть тысячи в минуту, пока основная база занята заказами. Гонять туда каждую такую мелкую запись не всегда разумно.
- Карточка товара. У наушников есть время работы от батареи, у джинсов — размеры, у книги — число страниц. Если завести под каждое свойство отдельный столбец, у многих товаров эти клетки останутся пустыми. Такой таблицей неудобно пользоваться, хотя у основной базы есть и другие способы хранить разные характеристики — к ним вернёмся в конце главы.
Получается странная мастерская: для заказов удобны аккуратные строки и столбцы, корзине хочется самой исчезнуть через полчаса, карточкам товаров нужны разные свойства, а поиску вообще приходит вопрос словами покупателя. Заставлять все эти задачи жить по одному устройству можно, но приходится писать лишнюю логику и подгонять данные под форму, которая им не подходит.
Здесь полезен образ большого склада с разными зонами. В одной вещи лежат по строгим ячейкам, в другой их выдают по номерку, в третьей карточки могут отличаться друг от друга, а ещё одна зона устроена так, чтобы быстро отвечать на вопросы о связях. У всех зон одна цель — хранить и находить данные, но внутри они организованы по-разному.
Общее название таких подходов — , «не только SQL». Это не одна особая база с единым устройством. Под этим названием собрали разные способы хранения, которые выбирают под задачу и часто ставят рядом с PostgreSQL, а не вместо него.
Пять подходов — по задаче
Хранилищ без привычных таблиц много, но несколько форм встречаются особенно часто. Названия пока можно не запоминать. Сначала смотри на неудобство, которое нужно убрать. И помни, что подходы сочетаются: документы, например, тоже раскладывают по нескольким серверам.
Когда запись нужно достать по известному имени
Для корзины или сессии программа уже знает, какую запись ищет. Ей не нужно просматривать остальные данные: достаточно назвать имя записи и получить то, что под ним лежит.
Ключ → значение (Redis) похоже на гардероб с номерками. Отдаёшь номерок — его называют ключом — и получаешь вещь, то есть значение. Перебирать соседние записи не нужно.
Такое хранилище часто используют как кэш — быструю память рядом с основной базой. В кэше держат то, что часто спрашивают и что при потере можно снова взять из базы.
Чуть ниже такую запись получится положить в Redis через redis-cli.
Когда у товаров разные свойства
Попытка сделать одну широкую таблицу для книги, джинсов и наушников быстро оставляет много пустых клеток. Можно заводить дополнительные таблицы и правила, но для простой карточки товара это уже лишняя работа.
В документном хранилище каждая запись похожа на отдельную карточку. Так работает MongoDB. Саму карточку называют документом: у наушников в ней можно хранить время работы от батареи, у джинсов — размер, у книги — число страниц. Карточки лежат рядом, хотя набор свойств у них отличается.
Это похоже на папку с анкетами, где первая страница у всех одинаковая, а дальше каждый заполняет только подходящие ему пункты. С такими данными удобно работать, когда записи относятся к одной теме, но не обязаны иметь одинаковый набор свойств. Руками документы MongoDB часто смотрят в MongoDB Compass.
Когда один сервер становится тесным
Служба доставки постоянно получает новые события о посылках. Если весь поток отправлять в одно место, один сервер должен принять и сохранить всё. По мере роста потока эта точка получает всё больше работы.
Cassandra устроена для задач, где записи распределяют между несколькими серверами. Каждый сервер хранит свою часть, поэтому весь поток не обязан проходить через одно место. Здесь полезно думать о сортировочном центре: прибывающие коробки расходятся по нескольким линиям, и каждая линия разбирает свою долю работы.
Такой подход нужен там, где долго идёт большой поток однотипных записей: например, события доставки или технические события программы. Cassandra можно встретить как отдельное хранилище или в облачном сервисе DataStax Astra DB.
Когда покупатель пишет словами, а не ключом
С ключом всё просто, пока программа заранее знает точное имя записи. Покупатель в строке поиска ведёт себя иначе: он не знает ключ товара и пишет обычные слова. Причём его слова могут не совпасть с названием карточки один в один.
Для такой задачи используют поисковое хранилище. Elasticsearch получает текстовый запрос и ищет подходящие записи по словам. Поэтому запрос «тёплый плед» может привести к товару с названием «Плед флисовый», хотя покупатель не вводил точное название.
Такой механизм стоит за поиском по каталогу товаров, статьям, документам и журналам программы. С Elasticsearch результаты и запросы часто смотрят через Kibana.
Когда главный вопрос звучит «что с чем связано?»
Обычная запись хорошо отвечает на вопрос «что известно об этом товаре?». Но у рекомендации другой вопрос: какие товары связаны с выбранным, что часто берут вместе, как одна запись ведёт к другой. Если таких переходов много, сами связи становятся важной частью данных.
Здесь используют граф. В Neo4j записи можно мысленно представить кружками, а связи между ними — линиями. Это похоже на схему знакомств: карточки людей важны, но вопрос «кто с кем знаком?» решается по линиям между карточками.
В магазине такими линиями можно связать товары, которые покупают вместе. Тогда от выбранного товара можно перейти к связанным и использовать это в рекомендациях. Граф Neo4j можно рассматривать и запрашивать в Neo4j Browser.
КВЕРИ: У этих хранилищ разные привычки. Redis быстро находит запись по ключу, MongoDB спокойно живёт с разными карточками, а графу подавай связи. Будем знакомиться по одному.
Первая команда
Ближе всех к выходу из галереи стоит кэш «Котомаркета» — хранилище «ключ → значение», Redis. Станция уже подала питание, так что можно сразу проверить его в работе.
С Redis разговаривают двумя путями. Человек набирает команды в консоли: пишет команду и тут же видит ответ. У Redis такая консоль называется redis-cli. Программа магазина отправляет те же команды из своего кода — так курс будет делать со второй главы.
В ячейке ниже вместо консоли работает cli('…') — учебная функция курса, которая изображает redis-cli. За ней работает учебная модель Redis прямо в браузере. Сама cli есть только здесь, а команда внутри одинарных кавычек настоящая: её можно набрать в любом redis-cli. Название товара внутри команды взято ещё и в двойные кавычки: так консоль понимает, что «Пазл 1000 деталей» — одно значение, а не три слова.
В выводе строка, которая начинается с redis и знака «больше», повторяет отправленную команду. Так курс рисует приглашение консоли, а настоящий redis-cli пишет на этом месте адрес сервера. Под командой стоит ответ хранилища. Нажми «Выполнить» — что значит каждый ответ, разберём сразу после ячейки. Каждая ячейка начинает с архива в исходном виде: что бы ни поменяла одна ячейка, следующая начнёт с того же места.
Python, которого хватит на весь курс
Код в ячейках курса написан на Python, но заранее учить язык не нужно. В первых главах тебе встретятся только несколько вещей:
- текст в кавычках Python называет строкой:
"Пазл 1000 деталей". Это просто текст, а не строка таблицы; - имя со скобками — вызов функции, то есть готового действия; в скобках стоят данные для него;
cli("…")— учебная консоль курса: отправляет команду хранилищу и печатает ответ, как redis-cli;- после знака
#идёт пояснение для человека, Python его пропускает; clock.advance(60)передвигает учебные часы галереи на минуту вперёд: точка выбирает действие часов. У настоящего Redis таких часов нет.
Когда встретится что-то новое, курс сначала покажет это на примере.
Здесь произошло три действия.
- SET кладёт значение под ключ. Ключ здесь —
session:42. Это имя придумано самим магазином: двоеточие просто отделяет слово session от номера покупателя, особого смысла для Redis у него нет. Сессия — это одно посещение сайта: пока покупатель 42 ходит по страницам, программа магазина записала сюда, что он смотрит пазл. Сам Redis за покупателями не следит. - EX 1800 задаёт срок жизни записи в секундах: полчаса. По-английски такой срок называют TTL.
- GET достаёт значение по ключу, TTL показывает, сколько секунд записи осталось жить.
Теперь свяжем команды с ответами по порядку. После сохранения Redis отвечает «OK»: запись принята. Следующий запрос возвращает строку в кавычках — то самое значение, которое лежит под ключом. Последний ответ содержит число 1800, потому что сразу после сохранения весь срок жизни ещё впереди.
Пометка «(integer)» перед числом говорит только о том, что ответ — целое число. Redis не показывает здесь товар, покупателя или отдельную строку таблицы: программа назвала ключ и получила связанное с ним значение. Именно ради такого короткого пути и выбирают форму «ключ → значение».
Запись, которая забывается сама
Теперь проверим свойство, ради которого такие записи удобно держать в Redis. В следующей ячейке запись сначала сохраняется заново — отсчёт получаса начинается с нуля. Потом строка с clock.advance(1801) передвигает учебные часы галереи на 1801 секунду: полчаса и ещё одну. После этого снова спрашиваем про сессию покупателя 42.
Ответ «(nil)» означает: по такому ключу записи больше нет. Никто не запускал отдельное удаление — срок вышел, и Redis сам забыл запись. С таблицей пришлось бы писать программу, которая, например, раз в минуту ищет старые строки и стирает их.
КВЕРИ: Часы галереи стояли на 18:00 — в ту минуту, когда кэш погас. Теперь они снова идут, и сроки записей истекают. Настоящий Redis помнит срок как момент на обычных часах: пока сервер выключен, время идёт, и после запуска просроченную запись уже не прочитать.
🧪 Модель: в настоящей системе иначе
Передвигать время одной строкой умеет только учебный Redis курса. Так можно сразу увидеть, что случится через полчаса, вместо того чтобы ждать. Настоящий Redis смотрит на обычные часы сервера.
cart:17, значение — Мягкая игрушка кот, срок жизни — 10 минут.ТерминыЧто значат новые слова
| слово | обычными словами |
|---|---|
| база данных | место, где программа хранит сведения и откуда их достаёт |
| таблица | данные строками и столбцами: строка — запись, столбец — свойство |
| запрос, SQL | просьба к базе и язык, на котором такие просьбы пишут для таблиц |
| хранилища, которые не ограничиваются привычными таблицами и SQL | |
| ключ и значение | имя записи и то, что под этим именем лежит |
| кэш | быстрая память рядом с основной базой: то, что часто спрашивают и что можно снова взять из базы |
| документ | запись-карточка со своим набором полей |
| граф | хранилище связей между записями |
| сервер | отдельный компьютер, на котором работает хранилище |
| сессия | одно посещение сайта покупателем и запись о нём, пока он на сайте |
| срок жизни | сколько секунд запись проживёт, прежде чем хранилище само её забудет |
Главное из урока
- База данных хранит сведения, которые нужны программе. Часто данные лежат в таблицах, а запросы к ним пишут на SQL.
- — общее название разных способов хранения, а не одна замена PostgreSQL. Их ставят рядом с основной базой, когда конкретной задаче удобнее другое устройство данных.
- Мы встретили пять подходов: ключ → значение для доступа по известному имени, документы для записей с разными свойствами, распределение записей между серверами для большого потока, отдельный поиск по словам и граф для связей.
- Redis хранит пары «ключ → значение» и умеет сам удалять запись, когда заканчивается её срок жизни.
Комендант спрашивал, зачем магазину столько хранилищ. Теперь ответ уже виден: у корзины, поиска, доставки и заказов разные требования к данным. В следующем уроке начнём разбирать эти требования по одному.