fix: исправлен конфликт имён переменных в loadDraft (claimId -> finalClaimId)
- Исправлена ошибка ReferenceError при загрузке черновиков - Переименована локальная переменная claimId в finalClaimId для избежания конфликта с параметром функции - Обновлена логика извлечения claim_id из разных источников (claim.claim_id, payload.claim_id, body.claim_id, claim.id) - Добавлен fallback на параметр claimId функции для надёжности
This commit is contained in:
198
ticket_form/docs/REDIS_VS_POSTGRESQL_SPEED.md
Normal file
198
ticket_form/docs/REDIS_VS_POSTGRESQL_SPEED.md
Normal file
@@ -0,0 +1,198 @@
|
||||
# Redis vs PostgreSQL: Когда что использовать?
|
||||
|
||||
## Скорость доступа
|
||||
|
||||
### Redis:
|
||||
- ⚡ **0.1-1 мс** (данные в памяти)
|
||||
- Мгновенный доступ
|
||||
- Идеально для частых чтений
|
||||
|
||||
### PostgreSQL:
|
||||
- 🐢 **1-10 мс** (с индексами)
|
||||
- Зависит от нагрузки и индексов
|
||||
- Но всё равно очень быстро
|
||||
|
||||
---
|
||||
|
||||
## Когда Redis имеет смысл
|
||||
|
||||
### ✅ Используй Redis, если:
|
||||
|
||||
1. **Очень частые чтения** (каждый запрос, каждый клик)
|
||||
- Например: счетчики, rate limiting, сессии
|
||||
|
||||
2. **Временные данные** (TTL, автоочистка)
|
||||
- Например: SMS коды, временные токены
|
||||
|
||||
3. **Кеширование результатов запросов**
|
||||
- Например: результаты AI классификации, шаблоны визардов
|
||||
|
||||
4. **Pub/Sub события** (реал-тайм)
|
||||
- Например: `ocr_events:{claim_id}` для SSE
|
||||
|
||||
---
|
||||
|
||||
## Когда PostgreSQL достаточно
|
||||
|
||||
### ✅ Используй только PostgreSQL, если:
|
||||
|
||||
1. **Данные читаются не так часто**
|
||||
- Загрузка страницы, переход между шагами
|
||||
- Пользователь не заметит разницу 1-10 мс
|
||||
|
||||
2. **Важна консистентность**
|
||||
- Нужна гарантия актуальности данных
|
||||
- Нет риска рассинхронизации
|
||||
|
||||
3. **Данные уже в PostgreSQL**
|
||||
- Не нужно дублировать
|
||||
- Проще архитектура
|
||||
|
||||
---
|
||||
|
||||
## Для веб-формы: Анализ использования
|
||||
|
||||
### Когда читаются данные заявки:
|
||||
|
||||
1. **При загрузке страницы** (1 раз)
|
||||
- Пользователь открывает форму
|
||||
- Можно загрузить из PostgreSQL (10 мс) - не критично
|
||||
|
||||
2. **При переходах между шагами** (редко)
|
||||
- Пользователь нажимает "Далее"
|
||||
- Можно загрузить из PostgreSQL (10 мс) - не критично
|
||||
|
||||
3. **При обновлении данных** (редко)
|
||||
- Пользователь заполняет форму
|
||||
- Сохраняется в PostgreSQL
|
||||
|
||||
### Вывод:
|
||||
- ❌ **НЕ критично по скорости** - пользователь не заметит разницу
|
||||
- ✅ **Важнее консистентность** - данные всегда актуальные
|
||||
- ✅ **Проще архитектура** - один источник истины
|
||||
|
||||
---
|
||||
|
||||
## Компромиссное решение
|
||||
|
||||
### Вариант: Кеширование в Redis с инвалидацией
|
||||
|
||||
```python
|
||||
# При чтении данных заявки
|
||||
async def get_claim(claim_id: str):
|
||||
# 1. Пробуем Redis (быстро)
|
||||
cached = await redis.get(f"claim:{claim_id}")
|
||||
if cached:
|
||||
return json.loads(cached)
|
||||
|
||||
# 2. Если нет в кеше - из PostgreSQL
|
||||
claim = await db.get_claim(claim_id)
|
||||
|
||||
# 3. Сохраняем в кеш на 1 час
|
||||
await redis.set(f"claim:{claim_id}", json.dumps(claim), ttl=3600)
|
||||
|
||||
return claim
|
||||
|
||||
# При обновлении данных
|
||||
async def update_claim(claim_id: str, data: dict):
|
||||
# 1. Обновляем PostgreSQL
|
||||
await db.update_claim(claim_id, data)
|
||||
|
||||
# 2. Инвалидируем кеш (удаляем из Redis)
|
||||
await redis.delete(f"claim:{claim_id}")
|
||||
|
||||
# Или обновляем кеш сразу
|
||||
await redis.set(f"claim:{claim_id}", json.dumps(data), ttl=3600)
|
||||
```
|
||||
|
||||
### Плюсы:
|
||||
- ✅ Быстрый доступ (если есть в кеше)
|
||||
- ✅ Актуальные данные (инвалидация при обновлении)
|
||||
- ✅ Fallback на PostgreSQL (если кеш пуст)
|
||||
|
||||
### Минусы:
|
||||
- ❌ Дополнительная сложность
|
||||
- ❌ Нужно инвалидировать кеш при каждом обновлении
|
||||
- ❌ Риск устаревших данных (если забыли инвалидировать)
|
||||
|
||||
---
|
||||
|
||||
## Рекомендация для веб-формы
|
||||
|
||||
### Вариант 1: Только PostgreSQL (рекомендую)
|
||||
|
||||
**Когда использовать:**
|
||||
- Данные читаются не так часто (загрузка страницы, переходы)
|
||||
- Важна консистентность
|
||||
- Простота архитектуры важнее скорости
|
||||
|
||||
**Плюсы:**
|
||||
- ✅ Просто (один источник данных)
|
||||
- ✅ Всегда актуальные данные
|
||||
- ✅ Нет рассинхронизации
|
||||
- ✅ PostgreSQL с индексами всё равно быстро (1-10 мс)
|
||||
|
||||
**Минусы:**
|
||||
- ❌ Чуть медленнее, чем Redis (но не критично)
|
||||
|
||||
---
|
||||
|
||||
### Вариант 2: PostgreSQL + Redis кеш (если нужна скорость)
|
||||
|
||||
**Когда использовать:**
|
||||
- Очень частые чтения (каждый запрос)
|
||||
- Критична скорость (но для веб-формы это не так)
|
||||
|
||||
**Плюсы:**
|
||||
- ✅ Быстрый доступ (0.1-1 мс)
|
||||
- ✅ Меньше нагрузки на PostgreSQL
|
||||
|
||||
**Минусы:**
|
||||
- ❌ Сложнее (нужна инвалидация кеша)
|
||||
- ❌ Риск устаревших данных
|
||||
- ❌ Больше кода для поддержки
|
||||
|
||||
---
|
||||
|
||||
## Итог
|
||||
|
||||
### Для веб-формы:
|
||||
|
||||
**Рекомендую: Только PostgreSQL**
|
||||
|
||||
**Почему:**
|
||||
1. ⚡ PostgreSQL с индексами быстро (1-10 мс) - пользователь не заметит
|
||||
2. ✅ Всегда актуальные данные (нет рассинхронизации)
|
||||
3. ✅ Проще архитектура (один источник истины)
|
||||
4. ✅ Данные читаются не так часто (не каждый запрос)
|
||||
|
||||
**Redis используй только для:**
|
||||
- ✅ Pub/Sub (`ocr_events:{claim_id}`) - события в реальном времени
|
||||
- ✅ Кеширование AI ответов (классификация, визарды) - если нужно
|
||||
- ✅ SMS коды, временные токены - с TTL
|
||||
|
||||
**НЕ используй Redis для:**
|
||||
- ❌ Основных данных заявки (есть в PostgreSQL)
|
||||
- ❌ Документов (есть в PostgreSQL)
|
||||
- ❌ Ответов визарда (есть в PostgreSQL)
|
||||
|
||||
---
|
||||
|
||||
## Если всё-таки нужен Redis кеш
|
||||
|
||||
Можно добавить опциональное кеширование:
|
||||
|
||||
```python
|
||||
# В n8n workflow после claimsave
|
||||
if (channel === 'web_form' && enable_cache === true) {
|
||||
// Опционально: кешируем в Redis на 1 час
|
||||
await redis.set(
|
||||
`claim:${claim_id}`,
|
||||
JSON.stringify(claim_data),
|
||||
ttl=3600
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Но это опционально и не обязательно для веб-формы.
|
||||
|
||||
Reference in New Issue
Block a user