diff --git a/packages/backend/schema.sql b/packages/backend/schema.sql new file mode 100644 index 0000000..8420efe --- /dev/null +++ b/packages/backend/schema.sql @@ -0,0 +1,239 @@ +-- ============================================================================= +-- SCHEMA COMPLETO PER CATALOGO CELEBRITÀ +-- VERSIONE: 4.2 +-- DESCRIZIONE: Schema base con espansione della taglia del reggiseno e +-- aggiunta della cronologia degli interventi estetici. +-- DATABASE: PostgreSQL +-- ============================================================================= + +-- PREPARAZIONE: Elimina vecchie strutture per una creazione pulita +DROP TABLE IF EXISTS + cosmetic_surgeries, + activity_periods, + celebrity_aliases, + tattoos, + video_performers, + videos, + celebrity_studios, + studios, + external_links, + images, + social_media_accounts, + celebrity_professions, + professions, + celebrities CASCADE; + +DROP TYPE IF EXISTS GENDER_TYPE; +DROP TYPE IF EXISTS SHOE_SYSTEM_TYPE; +DROP TYPE IF EXISTS BRA_SYSTEM_TYPE; +DROP TYPE IF EXISTS SURGERY_TYPE; + +-- ============================================================================= +-- DEFINIZIONE DEI TIPI PERSONALIZZATI (ENUMs) +-- ============================================================================= + +CREATE TYPE GENDER_TYPE AS ENUM ('male', 'female', 'other'); +CREATE TYPE SHOE_SYSTEM_TYPE AS ENUM ('EU', 'US', 'UK'); +CREATE TYPE BRA_SYSTEM_TYPE AS ENUM ('US', 'UK', 'EU', 'FR', 'AU', 'IT', 'JP'); +CREATE TYPE SURGERY_TYPE AS ENUM ( + 'breast_reduction', + 'breast_augmentation', + 'breast_lift', + 'rhinoplasty', + 'other' +); + +-- ============================================================================= +-- TABELLE PRINCIPALI +-- ============================================================================= + +-- Tabella centrale che contiene tutte le informazioni anagrafiche e fisiche +-- I dati fisici (es. taglia reggiseno) rappresentano lo STATO ATTUALE della celebrità. +CREATE TABLE celebrities ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL UNIQUE, + gender GENDER_TYPE NOT NULL, + birth_date DATE, + birth_place TEXT, + nationality TEXT, + ethnicity TEXT, + sexuality TEXT, + + -- Dati fisici (Misure standardizzate in unità metriche per coerenza) + hair_color TEXT, + eye_color TEXT, + height_cm INT CHECK (height_cm > 0), + weight_kg INT CHECK (weight_kg > 0), + body_type TEXT, + + -- Misure femminili (in cm). NULL se non applicabile. + bust_cm INT CHECK (bust_cm > 0), + waist_cm INT CHECK (waist_cm > 0), + hips_cm INT CHECK (hips_cm > 0), + + -- Misure maschili (in cm). NULL se non applicabile. + chest_circumference_cm INT CHECK (chest_circumference_cm > 0), + + -- Campi strutturati per la taglia del reggiseno (stato attuale) + bra_band_size INT CHECK (bra_band_size > 0), -- Es: 34 (per US/UK) o 75 (per EU) + bra_cup_size TEXT, -- Es: 'C', 'DD', 'E' + bra_size_system BRA_SYSTEM_TYPE, -- Sistema di riferimento (US, EU, UK, etc.) + + boobs_are_natural BOOLEAN, + shoe_size DECIMAL(4, 1), + shoe_size_system SHOE_SYSTEM_TYPE, + + -- Dati biografici + biography TEXT, + + -- Metadati e relazioni + official_website TEXT, + profile_image_id INT, -- Riferimento all'immagine del profilo (vedi tabella images) + + -- Timestamp per tracciamento + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Tabella per i tatuaggi (Relazione 1-a-Molti con celebrities) +CREATE TABLE tattoos ( + id SERIAL PRIMARY KEY, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + description TEXT NOT NULL, + body_location TEXT +); + +-- Tabella per gli alias (Relazione 1-a-Molti con celebrities) +CREATE TABLE celebrity_aliases ( + id SERIAL PRIMARY KEY, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + alias_name TEXT NOT NULL, + UNIQUE(celebrity_id, alias_name) +); + +-- Tabella per i periodi di attività (Relazione 1-a-Molti con celebrities) +CREATE TABLE activity_periods ( + id SERIAL PRIMARY KEY, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + start_year INT NOT NULL CHECK (start_year > 1900 AND start_year < 2100), + end_year INT CHECK (end_year >= start_year), -- Può essere NULL se ancora in attività per questo periodo + notes TEXT -- Es. "Carriera principale", "Ritorno sulle scene" +); + +-- ============================================================================= +-- TABELLE DI "LOOKUP" E DI COLLEGAMENTO (MOLTI-A-MOLTI) +-- ============================================================================= + +CREATE TABLE professions ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL UNIQUE +); +CREATE TABLE celebrity_professions ( + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + profession_id INT NOT NULL REFERENCES professions(id) ON DELETE CASCADE, + PRIMARY KEY (celebrity_id, profession_id) +); + +CREATE TABLE studios ( + id SERIAL PRIMARY KEY, + name TEXT NOT NULL UNIQUE +); +CREATE TABLE celebrity_studios ( + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + studio_id INT NOT NULL REFERENCES studios(id) ON DELETE CASCADE, + PRIMARY KEY (celebrity_id, studio_id) +); + +CREATE TABLE videos ( + id SERIAL PRIMARY KEY, + title TEXT NOT NULL, + release_date DATE, + studio_id INT REFERENCES studios(id) ON DELETE SET NULL, + description TEXT, + url_preview TEXT +); +CREATE TABLE video_performers ( + video_id INT NOT NULL REFERENCES videos(id) ON DELETE CASCADE, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + PRIMARY KEY (video_id, celebrity_id) +); + +-- ============================================================================= +-- TABELLE SATELLITE (Informazioni aggiuntive) +-- ============================================================================= + +-- Tabella per tracciare la cronologia degli interventi estetici +CREATE TABLE cosmetic_surgeries ( + id SERIAL PRIMARY KEY, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + surgery_type SURGERY_TYPE NOT NULL, + surgery_date DATE, -- Data (anche approssimativa) dell'intervento + + -- Campi specifici per interventi al seno (saranno NULL per altri tipi di intervento) + -- Rappresentano la taglia RISULTANTE dall'intervento + new_bra_band_size INT CHECK (new_bra_band_size > 0), + new_bra_cup_size TEXT, + new_bra_size_system BRA_SYSTEM_TYPE, + + -- Campi generici + notes TEXT, -- Dettagli aggiuntivi (es. nome del medico, clinica, motivo dell'intervento) + + created_at TIMESTAMPTZ DEFAULT NOW() +); + +CREATE TABLE social_media_accounts ( + id SERIAL PRIMARY KEY, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + platform TEXT NOT NULL, + url TEXT NOT NULL UNIQUE, + follower_count BIGINT, + last_checked_date DATE +); + +CREATE TABLE images ( + id SERIAL PRIMARY KEY, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + file_path TEXT NOT NULL, + caption TEXT, + uploaded_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Aggiunta del vincolo di chiave esterna per la foto profilo +-- Deve essere aggiunto dopo la creazione della tabella 'images' +ALTER TABLE celebrities +ADD CONSTRAINT fk_profile_image +FOREIGN KEY (profile_image_id) REFERENCES images(id) ON DELETE SET NULL; + +CREATE TABLE external_links ( + id SERIAL PRIMARY KEY, + celebrity_id INT NOT NULL REFERENCES celebrities(id) ON DELETE CASCADE, + url TEXT NOT NULL, + title TEXT, + source_website TEXT, + publication_date DATE +); + +-- ============================================================================= +-- CREAZIONE DEGLI INDICI PER MIGLIORARE LE PERFORMANCE +-- ============================================================================= + +-- Indici sulla tabella principale +CREATE INDEX idx_celebrities_name ON celebrities(name); +CREATE INDEX idx_celebrities_gender ON celebrities(gender); + +-- Indici sulle chiavi esterne per accelerare i JOIN +CREATE INDEX idx_cosmetic_surgeries_celebrity_id ON cosmetic_surgeries(celebrity_id); +CREATE INDEX idx_tattoos_celebrity_id ON tattoos(celebrity_id); +CREATE INDEX idx_celebrity_aliases_celebrity_id ON celebrity_aliases(celebrity_id); +CREATE INDEX idx_celebrity_aliases_name ON celebrity_aliases(alias_name); -- Utile per cercare un alias +CREATE INDEX idx_activity_periods_celebrity_id ON activity_periods(celebrity_id); +CREATE INDEX idx_celebrity_professions_celebrity_id ON celebrity_professions(celebrity_id); +CREATE INDEX idx_celebrity_studios_celebrity_id ON celebrity_studios(celebrity_id); +CREATE INDEX idx_video_performers_celebrity_id ON video_performers(celebrity_id); +CREATE INDEX idx_social_media_celebrity_id ON social_media_accounts(celebrity_id); +CREATE INDEX idx_images_celebrity_id ON images(celebrity_id); +CREATE INDEX idx_external_links_celebrity_id ON external_links(celebrity_id); + +-- ============================================================================= +-- FINE DELLO SCRIPT +-- ============================================================================= \ No newline at end of file