This commit is contained in:
Nicola Malizia
2025-10-10 18:12:43 +02:00
parent cda58ec2f9
commit c9a0d557aa

239
packages/backend/schema.sql Normal file
View File

@@ -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
-- =============================================================================