NoSQL (от англ. Not Only SQL — «не только SQL») — это термин, обозначающий типы баз данных, отличные от традиционных реляционных СУБД. NoSQL БД предлагают более гибкие модели хранения данных и лучше подходят для масштабируемых распределённых систем.
Подробнее:
NoSQL БД появились как ответ на ограничения реляционных СУБД в условиях:
- горизонтального масштабирования,
- работы с большими объёмами неструктурированных или слабо структурированных данных,
- необходимости высокой доступности и отказоустойчивости.
CAP-теорема (также называемая теоремой Брюера) гласит, что в распределённой системе невозможно одновременно обеспечить:
| Свойство | Описание |
|---|---|
| Consistency (Согласованность) | Все узлы видят одинаковые данные в один и тот же момент. |
| Availability (Доступность) | Система всегда отвечает на запрос (даже если это не последняя версия). |
| Partition Tolerance (Устойчивость к разделению) | Система продолжает работать, даже если между узлами есть сетевые проблемы. |
🧠 Зачем нужна CAP-теорема?
При проектировании распределённых систем (особенно в NoSQL) часто приходится жертвовать чем-то ради надёжности и масштабируемости. Например:
- В случае сетевого разделения можно либо отказать в доступе (жертвуем A),
- Либо отдать устаревшие данные (жертвуем C).
Вывод: система может выбрать максимум два из трёх свойств одновременно.
Примеры:
- 🔸 Cassandra — AP: предпочитает доступность и устойчивость, согласованность достигается позже (eventual consistency).
- 🔸 MongoDB (до 4.0) — CP: жертвует доступностью при проблемах с сетью.
- 🔸 Redis (в кластере) — чаще AP.
Простейшая модель, напоминающая словарь: ключ → значение.
Пример хранения:
{
"user:123": "Alice",
"user:124": "Bob",
"cart:456": {
"item": "Book",
"qty": 2
}
}Где используется:
- Redis в GitHub — как брокер сообщений и кэш состояний пайплайнов.
- DynamoDB в Amazon — хранение корзин и профилей пользователей.
Хранят данные в виде документов (JSON, BSON и т.д.).
Пример хранения:
{
"_id": "user_001",
"name": "Alice",
"email": "alice@example.com",
"orders": [
{"item": "Book", "qty": 2},
{"item": "Pen", "qty": 5}
]
}Где используется:
- MongoDB в eBay — данные пользователей и товаров.
- CouchDB в BBC — автономный режим с синхронизацией.
Колонночные базы данных на первый взгляд похожи на реляционные, но различие — в физической организации хранения данных.
| Реляционные БД (PostgreSQL, MySQL) | Колонночные БД (Cassandra, Bigtable) | |
|---|---|---|
| Единица хранения | строка (row) | столбец (column) или «семейство столбцов» |
| Физическое хранение | строки лежат вместе | значения одного столбца лежат вместе |
| Сценарий оптимизации | запись/чтение строк | аналитика, агрегации по столбцам |
| Гибкость схемы | строго задана | допускаются разные наборы столбцов |
Пример хранения (упрощённо):
RowKey: user1
Name: Alice
Age: 30
City: Prague
RowKey: user2
Name: Bob
Age: 25
Где используется:
- Cassandra в Netflix — логирование, телеметрия.
- Bigtable в YouTube — просмотры, комментарии, рекомендации.
Графовые базы данных хранят данные как узлы (nodes) и связи (edges) между ними.
Пример хранения:
(Alice)-[:FRIEND]->(Bob)
(Alice)-[:LISTENS_TO]->(Song)
(Alice)-[:VISITED]->(Place)
Механизм поиска связей между сущностями используется повсеместно:
- Facebook: "Возможно, вы знаете этого человека" — через общих друзей.
- Spotify: "Похожие исполнители" — через пользователей с похожими интересами.
- Google Maps: построение маршрута — как поиск кратчайшего пути в графе дорог.
Все эти задачи решаются одними и теми же графовыми алгоритмами (DFS, BFS, Dijkstra и т.д.) на одних и тех же структурах — графах.
Где используется:
- Neo4j в eBay — рекомендации и antifraud.
- Amazon Neptune — персонализация и графы предпочтений.
- LinkedIn — поиск и визуализация сетей профессиональных связей.
| Сценарий | Тип NoSQL | Примеры |
|---|---|---|
| Кэш, сессии, временные данные | Key-Value | Redis, Memcached |
| Пользователи, CMS | Document-oriented | MongoDB, CouchDB |
| Аналитика, временные ряды | Column-family | Cassandra, Bigtable |
| Связи, рекомендации, маршруты | Graph | Neo4j, Neptune, OrientDB |
✅ Используй, если:
- структура данных часто меняется или неформализована;
- требуется масштабирование и отказоустойчивость;
- важны скорость доступа и запись в real-time.
❌ Не подходит, если:
- необходима строгая согласованность и транзакции;
- бизнес-логика требует сложных JOIN-операций;
- используется строго табличная модель с контролем схемы.
💬 Комментарий преподавателя:
Redis — универсальный инструмент. Он почти всегда есть в стеке. Даже если не используется на старте, его часто добавляют позже для кэширования, очередей и хранения сессий. Мы с ним ещё поработаем дальше по курсу.
HTTP-протокол не сохраняет состояния. Чтобы "помнить" пользователя, его действия и не делать одни и те же вычисления много раз — используются куки, сессии и кеш.
- HTTP stateless — каждый запрос сам по себе, без истории.
- Cookie — способ сохранять небольшие данные на стороне клиента (браузера).
- Session — способ сохранять пользовательские данные на сервере, привязанные к уникальному
sessionid, передаваемому в Cookie. - Cache — быстрая память для хранения часто используемых данных (не обязательно связанных с пользователем).
Куки — это пары ключ:значение, которые браузер хранит локально и отправляет на сервер с каждым HTTP-запросом к
соответствующему домену.
Примеры применения:
- Сохранение корзины товаров
- Запоминание темы оформления
- Предзаполнение форм
- Авторизация через
sessionid
Куки существуют только на уровне HTTP запроса! Их может запоминать браузер, но прямого отношения к серверу они не имеют!
Сессия — это механизм сохранения информации между запросами одного и того же пользователя. Чаще всего для реализации сессий используется привязка к куки.
Как это работает в Django:
Браузер → POST /login → Сервер:
- создаёт Session в БД
- возвращает Set-Cookie: sessionid=<uuid>
Браузер → GET /profile → Cookie: sessionid → Сервер:
- достаёт данные из request.session
Где хранятся данные:
- По умолчанию — в таблице базы данных
django_session - Также возможны:
- Redis
- Файлы
- Signed cookies
# Работа с сессией в Django
request.session['visited'] = True
# Проверка
if request.session.get('visited'):
...
# Удаление
del request.session['visited']def post_comment(request, comment):
if request.session.get('has_commented', False):
return HttpResponse("You've already commented.")
request.session['has_commented'] = True
return HttpResponse("Thanks!")request.session['last_action'] = timezone.now()from django.contrib.sessions.backends.db import SessionStore
s = SessionStore()
s['foo'] = 'bar'
s.create()
s.session_key # сохранённый ключ- Ключи сериализуются в строки (JSON)
- Данные сохраняются только при изменении
request.sessionкак объекта
request.session['foo'] = 'bar' # сохранится
request.session['foo']['x'] = 1 # ❌ не сохранится✅ Можно настроить:
SESSION_SAVE_EVERY_REQUEST = Truepython manage.py clearsessionsИли вручную:
from django.contrib.sessions.models import Session
Session.objects.filter(...).delete()Кеш — это временное хранилище для ускорения доступа к часто используемым данным.
# Вместо:
Article.objects.filter(published=True).order_by('-date')[:5]
# Лучше:
articles = cache.get('homepage_articles')
if not articles:
articles = Article.objects.filter(...).all()
cache.set('homepage_articles', articles, timeout=3600)| Хранилище | Плюсы | Минусы |
|---|---|---|
| Redis | Быстро, работает в памяти, масштабируется | Требует установки и сервера |
| Memcached | Очень быстрый, простой | Только строковые ключи |
| FileBased | Не требует серверов | Медленный на больших объёмах |
| Database | Ничего не нужно настраивать | Нагрузка на БД |
| DummyCache | Ничего не делает (для dev) | Нет кеша :) |
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient"
}
}
}from django.core.cache import cache
cache.set("key", "value", timeout=60)
cache.get("key") # "value"
cache.delete("key")Массовые операции:
cache.set_many({"a": 1, "b": 2})
cache.get_many(["a", "b"])from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
...Или в urls.py:
path("foo/", cache_page(900)(views.foo_view)){% load cache %}
{% cache 300 sidebar %}
...HTML sidebar...
{% endcache %}cache.clear()from django.views.decorators.cache import never_cache
@never_cache
def dynamic_view(request):
...- Куки — данные на клиенте (браузере).
- Сессии — данные на сервере, привязанные к пользователю.
- Кеш — быстрая память для ускорения работы, не связана напрямую с пользователем.
- Всё это критично для безопасной, быстрой и удобной работы сайта.
- Чем отличаются куки от сессий?
- Почему сессии нельзя использовать для анонимных пользователей везде?
- Где по умолчанию Django хранит сессии?
- Что произойдёт, если модифицировать
request.session['key']['value']? - Как бы вы реализовали кеширование главной страницы?
- Как очистить все сессии, старше 30 дней?




