# Databázové schéma — fotky_buzalkovi PostgreSQL 192.168.1.76:5432, databáze `fotky_buzalkovi`. --- ## Skupina 1: Zpracované fotky Tyto tabulky obsahují naparsované informace o fotkách — EXIF, hashe, metadata, tagy. Jsou základem pro veškerou další práci (vyhledávání, deduplikace, organizace). ### photos (85 833 záznamů) Hlavní tabulka. Každý řádek = jedna unikátní fotka identifikovaná hashem `sha256_file`. | Sloupec | Typ | Nullable | Default | Popis | |---------|-----|----------|---------|-------| | **id** | BIGSERIAL | NO | autoincrement | PK | | **sha256_file** | CHAR(64) | NO | — | SHA-256 celého souboru (UNIQUE) | | sha256_pixels | CHAR(64) | YES | — | SHA-256 pixelových dat (odhalí změnu jen v metadatech) | | phash | BIGINT | YES | — | Perceptuální hash (vizuální podobnost) | | dhash | BIGINT | YES | — | Difference hash (vizuální podobnost) | | **file_path** | VARCHAR(2000) | NO | — | Absolutní cesta k souboru | | file_path_relative | VARCHAR(2000) | YES | — | Relativní cesta | | **file_name** | VARCHAR(500) | NO | — | Název souboru | | file_stem | VARCHAR(500) | YES | — | Název bez přípony | | file_ext | VARCHAR(20) | YES | — | Přípona (.jpg, .png, …) | | file_size | BIGINT | YES | — | Velikost v bajtech | | mime_type | VARCHAR(50) | YES | — | MIME typ (image/jpeg, …) | | format | VARCHAR(20) | YES | — | Formát obrázku (JPEG, PNG, …) | | mode | VARCHAR(20) | YES | — | Barevný mód (RGB, L, RGBA, …) | | width | INT | YES | — | Šířka v pixelech | | height | INT | YES | — | Výška v pixelech | | megapixels | NUMERIC | YES | — | Rozlišení v megapixelech | | has_transparency | BOOLEAN | YES | false | Má alfa kanál | | icc_profile | BOOLEAN | YES | false | Obsahuje ICC profil | | embedded_thumbnail | BOOLEAN | YES | false | Obsahuje vložený náhled | | taken_at | TIMESTAMPTZ | YES | — | Datum pořízení fotky | | taken_at_source | VARCHAR(20) | YES | — | Zdroj datumu (exif / mtime / …) | | mtime | TIMESTAMPTZ | YES | — | Datum poslední modifikace souboru | | collected_at | TIMESTAMPTZ | YES | — | Datum sběru/importu do pipeline | | camera_make | VARCHAR(100) | YES | — | Výrobce fotoaparátu | | camera_model | VARCHAR(255) | YES | — | Model fotoaparátu | | lens_model | VARCHAR(255) | YES | — | Model objektivu | | iso | INT | YES | — | ISO citlivost | | aperture | NUMERIC | YES | — | Clona (f/2.8, …) | | exposure_time | VARCHAR(30) | YES | — | Expoziční čas (1/250, …) | | focal_length_mm | NUMERIC | YES | — | Ohnisková vzdálenost v mm | | gps_lat | NUMERIC | YES | — | GPS šířka | | gps_lon | NUMERIC | YES | — | GPS délka | | gps_altitude | NUMERIC | YES | — | GPS nadmořská výška | | is_screenshot | BOOLEAN | YES | false | Detekováno jako screenshot | | face_count | INT | YES | — | Počet detekovaných obličejů | | exif_raw | JSONB | YES | — | Kompletní surová EXIF data | | iptc_raw | JSONB | YES | — | Kompletní surová IPTC data | | xmp_raw | JSONB | YES | — | Kompletní surová XMP data | | imported_at | TIMESTAMPTZ | YES | now() | Kdy byl záznam vložen do DB | | processing_status | VARCHAR(50) | YES | 'pending' | Stav zpracování | **Indexy:** - `photos_pkey` — PK (id) - `photos_sha256_file_key` — UNIQUE (sha256_file) - `idx_photos_sha256_pixels` — (sha256_pixels) - `idx_photos_phash` — (phash) - `idx_photos_taken_at` — (taken_at) - `idx_photos_camera_model` — (camera_model) - `idx_photos_file_name` — (file_name) - `idx_photos_file_ext` — (file_ext) - `idx_photos_exif_gin` — GIN (exif_raw) --- ### tags Hierarchická tabulka tagů. Podporuje stromovou strukturu přes `parent_tag_id`. | Sloupec | Typ | Nullable | Default | Popis | |---------|-----|----------|---------|-------| | **id** | SERIAL | NO | autoincrement | PK | | **name** | VARCHAR(100) | NO | — | Název tagu | | parent_tag_id | INT | YES | — | Rodičovský tag (FK → tags.id) | **Constrainty:** - PK (id) - UNIQUE (name, parent_tag_id) — stejný název může existovat pod různými rodiči - FK parent_tag_id → tags(id) --- ### photo_tags Vazební tabulka M:N mezi `photos` a `tags`. | Sloupec | Typ | Nullable | Default | Popis | |---------|-----|----------|---------|-------| | **photo_id** | BIGINT | NO | — | FK → photos(id) ON DELETE CASCADE | | **tag_id** | INT | NO | — | FK → tags(id) ON DELETE CASCADE | | source | VARCHAR(20) | YES | — | Zdroj tagu (manual / auto / …) | | created_at | TIMESTAMPTZ | YES | now() | Kdy byl tag přiřazen | **Constrainty:** - PK (photo_id, tag_id) - FK photo_id → photos(id) ON DELETE CASCADE - FK tag_id → tags(id) ON DELETE CASCADE --- ## Skupina 2: Sběr a záloha fotek Tyto tabulky slouží **výhradně** pro proces sběru fotek ze všech počítačů na jedno centrální úložiště (Tower1). Neobsahují žádné informace o obsahu fotek — jen evidenci, odkud byly soubory sebrány a kam byly zálohovány. S dalším zpracováním (EXIF, tagy, organizace) nemají nic společného. Skript: `00 PictureCollector/collect_pictures.py` (Linux) / `collect_pictures_windows.py` (Windows) ### zaloha_obrazku (39 961 záznamů) Každý řádek = jeden unikátní soubor fyzicky uložený v záloze (identifikovaný BLAKE3 hashem). | Sloupec | Typ | Nullable | Default | Popis | |---------|-----|----------|---------|-------| | **id** | SERIAL | NO | autoincrement | PK | | **blake3_hash** | VARCHAR(64) | NO | — | BLAKE3 hash souboru (UNIQUE) | | **cesta_zalohy** | TEXT | NO | — | Cesta k záloze na Tower1 | | **nazev_souboru** | VARCHAR(512) | NO | — | Název souboru | | velikost | BIGINT | YES | — | Velikost v bajtech | | datum_kopirovani | TIMESTAMP | YES | now() | Kdy byl soubor zkopírován | **Indexy:** - `zaloha_obrazku_pkey` — PK (id) - `zaloha_obrazku_blake3_hash_key` — UNIQUE (blake3_hash) - `idx_zaloha_hash` — (blake3_hash) --- ### zdrojove_soubory (45 090 záznamů) Každý řádek = jeden nalezený zdrojový soubor na nějakém počítači. Stejný soubor (stejný BLAKE3 hash) může mít více záznamů, pokud existuje na různých místech/počítačích. | Sloupec | Typ | Nullable | Default | Popis | |---------|-----|----------|---------|-------| | **id** | SERIAL | NO | autoincrement | PK | | **hostname** | VARCHAR(255) | NO | — | Název počítače, kde byl soubor nalezen | | **cesta_zdroje** | TEXT | NO | — | Původní cesta k souboru | | **nazev_souboru** | VARCHAR(512) | NO | — | Název souboru | | velikost | BIGINT | YES | — | Velikost v bajtech | | datum_nalezeni | TIMESTAMP | YES | now() | Kdy byl soubor nalezen | | **blake3_hash** | VARCHAR(64) | NO | — | BLAKE3 hash souboru | | zaloha_id | INT | YES | — | FK → zaloha_obrazku(id) | **Constrainty:** - PK (id) - UNIQUE (hostname, cesta_zdroje) — každý soubor z každého PC jen jednou - FK zaloha_id → zaloha_obrazku(id) **Indexy:** - `idx_zdroj_hash` — (blake3_hash) - `idx_zdroj_zaloha` — (zaloha_id) - `idx_zdroj_host` — (hostname) --- ## Poznámky - Počty záznamů jsou k datu 2026-05-24. - Tabulka `cameras` z původního `create_schema.py` v DB neexistuje — informace o kameře jsou přímo ve sloupcích `camera_make` / `camera_model` v tabulce `photos`. - EXIF parser: ExifRead (Pillow má bug v GPS). - Tabulky skupiny 1 a skupiny 2 zatím nejsou propojené (žádný FK mezi `photos` a `zaloha_obrazku`).