# 📊 Справка по структуре БД отелей ## 🔑 Основные таблицы и их ключевые поля ### 1. `hotel_main` - Основная таблица отелей **Первичный ключ:** `id` (UUID) ⚠️ **НЕ `hotel_id`!** **Основные колонки:** - `id` - UUID отеля (PRIMARY KEY) - `full_name` - Полное название - `short_name` - Краткое название - `website_address` - ⚠️ **НЕ `website`!** Адрес сайта - `phone` - Телефон - `email` - Email - `owner_full_name` - ФИО владельца - `owner_ogrn` - ОГРН - `owner_inn` - ИНН - `region_id`, `region_name` - Регион - `category_id`, `category_name` - Категория (звёзды) - `hotel_type_id`, `hotel_type_name` - Тип отеля - `status_id`, `status_name` - Статус - `website_status` - Статус сайта - `rkn_registry_status`, `rkn_registry_number`, `rkn_registry_date` - РКН - `created_at`, `updated_at` - Даты создания/обновления ### 2. `hotel_website_raw` - Сырые данные с сайтов **Связь:** `hotel_id` → `hotel_main.id` **Основные колонки:** - `id` - ID записи - `hotel_id` - UUID отеля (FK к hotel_main.id) - `url` - URL страницы - `html` - ⚠️ **НЕ `raw_html`!** HTML контент - `status_code` - ⚠️ **НЕ `http_status`!** HTTP код - `crawled_at` - Дата краулинга - `content_hash` - Хеш контента - `response_time` - Время ответа **Уникальный индекс:** `(hotel_id, url)` ### 3. `hotel_website_processed` - Обработанные данные **Связь:** `hotel_id` → `hotel_main.id`, `raw_page_id` → `hotel_website_raw.id` **Основные колонки:** - `id` - ID записи - `raw_page_id` - FK к hotel_website_raw.id - `hotel_id` - UUID отеля (FK к hotel_main.id) - `url` - URL страницы - `cleaned_text` - Очищенный текст - `text_length` - Длина текста - `extracted_data` - Извлечённые данные (JSON) - `has_forms` - Наличие форм - `has_booking` - Наличие бронирования - `processed_at` - ⚠️ **НЕ `created_at`!** Дата обработки **Уникальный индекс:** `(hotel_id, url)` ### 4. `hotel_website_chunks` - Чанки для векторного поиска **Основные колонки:** - `id` - ID записи - `hotel_id` - UUID отеля - `text` - Текст чанка - `metadata` - Метаданные (JSON): `hotel_id`, `hotel_name`, `region_name`, `url` - `embedding` - Вектор эмбеддинга (vector(1024)) ### 5. `hotel_website_meta` - Метаданные сайтов **Основные колонки:** - `id` - ID записи - `hotel_id` - UUID отеля - `total_pages` - Всего страниц - `crawled_pages` - Скраулено страниц - `last_crawl_date` - Дата последнего краулинга - `crawl_status` - Статус краулинга - `ssl_valid` - Валидность SSL - `technologies` - Используемые технологии (JSON) ### 6. `hotel_audit_results` - Результаты аудита **Основные колонки:** - `id` - ID записи - `hotel_id` - UUID отеля - `audit_date` - Дата аудита - `criterion_id` - ID критерия - `criterion_name` - Название критерия - `status` - Статус проверки - `score` - Оценка - `details` - Детали (JSON) - `evidence_urls` - URL доказательств - `evidence_quotes` - Цитаты доказательств ### 7. `hotel_additional_info` - Дополнительная информация ### 8. `hotel_rooms` - Номера отелей ### 9. `hotel_services` - Услуги отелей ### 10. `hotel_sanatorium` - Санатории ### 11. `hotel_raw_json` - Сырые JSON данные ### 12. `hotel_parsing_progress` - Прогресс парсинга --- ## ⚠️ ЧАСТЫЕ ОШИБКИ И ИСПРАВЛЕНИЯ ### 1. Неправильные названия колонок: ```python # ❌ НЕПРАВИЛЬНО: JOIN hotel_main m ON p.hotel_id = m.hotel_id SELECT website FROM hotel_main SELECT raw_html FROM hotel_website_raw SELECT http_status FROM hotel_website_raw WHERE created_at > ... # для hotel_website_processed # ✅ ПРАВИЛЬНО: JOIN hotel_main m ON p.hotel_id = m.id SELECT website_address FROM hotel_main SELECT html FROM hotel_website_raw SELECT status_code FROM hotel_website_raw WHERE processed_at > ... # для hotel_website_processed ``` ### 2. Уникальные индексы: ```sql -- hotel_website_raw ON CONFLICT (hotel_id, url) DO UPDATE ... -- hotel_website_processed ON CONFLICT (hotel_id, url) DO UPDATE ... ``` ### 3. Связи таблиц: ``` hotel_main.id (UUID) ↓ hotel_website_raw.hotel_id → hotel_website_raw.id ↓ ↓ hotel_website_processed.hotel_id + raw_page_id ↓ hotel_website_chunks.hotel_id ``` --- ## 📝 Примеры запросов ### Получить отели с сайтами: ```sql SELECT m.id, m.full_name, m.website_address, COUNT(p.*) as pages_count FROM hotel_main m LEFT JOIN hotel_website_processed p ON p.hotel_id = m.id WHERE m.website_address IS NOT NULL GROUP BY m.id, m.full_name, m.website_address ``` ### Найти отели с N страницами: ```sql SELECT hotel_id, COUNT(*) as page_count FROM hotel_website_processed GROUP BY hotel_id HAVING COUNT(*) = 10 -- ровно 10 страниц ``` ### Статистика по краулингу: ```sql SELECT COUNT(DISTINCT hotel_id) as total_hotels, COUNT(*) as total_pages, AVG(text_length) as avg_text_length FROM hotel_website_processed WHERE processed_at > NOW() - INTERVAL '24 hours' ``` --- ## 🔍 Полная схема См. файл `db_schema_hotels.json` для детальной информации обо всех колонках. --- **Дата создания:** 2025-10-14 **Автор:** Фёдор + AI Assistant