Ti piace andare al cinema? Hai mai considerato come appare il design del database dietro il loro sistema di prenotazione? In questo articolo prepareremo un modello di database di esempio per un cinema.
Ci sono alcune ipotesi che dobbiamo tenere a mente:
- I cinema multisala contemporanei possono avere uno o più auditorium all'interno di un complesso più ampio,
- ogni auditorium può avere un numero di posti diverso,
- i posti sono numerati con il numero di fila e la posizione del posto all'interno di una fila,
- un film può essere proiettato in più proiezioni in momenti diversi oppure può essere proiettato contemporaneamente in un altro auditorium,
- per ogni proiezione un posto può essere prenotato/venduto una sola volta,
- Vogliamo tenere traccia di chi ha inserito ogni prenotazione/vendita nel sistema.
Diamo un'occhiata a un possibile progetto di database per risolvere questo problema (il modello è stato creato con Vertabelo per il database MySQL):
Di seguito vengono fornite brevi descrizioni della struttura delle tabelle:
-
Il
moviela tabella contiene i dati sui film che verranno proiettati in sala. La chiave primaria èid, che è auto_incrementato come tutte le chiavi primarie in tutte le altre tabelle. L'unico dato obbligatorio ètitle.
Tutti i campi hanno un significato in base al loro nome. La colonna
duration_minpuò essere utilizzato per disabilitare l'inserimento di una nuova proiezione o per mostrare un messaggio di avviso nel caso in cui si voglia inserire una proiezione in un auditorium in cui la proiezione precedente è ancora in corso:
previous screening start time + duration_min of it > this screening start time -
L'
auditoriumla tabella identifica tutti gli auditorium del teatro. Tutti i dati sono obbligatori.
Il
seats_noil campo può essere utilizzato per calcolare la percentuale di disponibilità degli auditorium per una proiezione/film/auditorium/intervallo di date selezionato. Questo è un esempio di ridondanza dei dati perché potremmo ottenere il numero di posti per ogni auditorium contandoli nelseattavolo. In questo esempio potrebbe non migliorare significativamente le prestazioni. Lo mostro qui come un'idea che potrebbe aiutare a progettare modelli più complessi. Se impostiamo il database in questo modo, dobbiamo tenere a mente che se cambiamo un dato, dobbiamo modificarne anche altri. Se aggiungiamo o cancelliamo dati dalseattabella dobbiamo regolare i valoriseats_nonell'auditoriumtavolo. -
Lo
screeningla tabella contiene i dati di tutte le proiezioni e tutti i campi sono obbligatori. Una proiezione deve avere un film, un auditorium e un'ora di inizio correlati. Non possiamo fare due proiezioni nello stesso auditorium contemporaneamente. Possiamo definire una chiave univoca composta daauditorium_idescreening_start. Questa configurazione è migliore della definizione di una chiave univoca composta damovie_id,auditorium_idescreening_startperché ciò ci permetterebbe di accedere alle proiezioni di due film diversi contemporaneamente nello stesso auditorium.
Il codice di anteprima SQL di Vertabelo per questa tabella è simile al seguente (notare Screening_ak_1):
-- Tables -- Table screening CREATE TABLE screening ( id int NOT NULL AUTO_INCREMENT, movie_id int NOT NULL , auditorium_id int NOT NULL , screening_start timestamp NOT NULL , UNIQUE INDEX Screening_ak_1 (movie_id,auditorium_id,screening_start), CONSTRAINT Screening_pk PRIMARY KEY (id) );
-
Il
seatla tabella contiene un elenco di tutti i posti che abbiamo negli auditorium con ogni posto assegnato a un solo auditorium. Tutti i campi sono obbligatori.
-
Il
reservation_typetable è un dizionario di tutti i tipi di prenotazione (per telefono, online, di persona). Tutti i campi sono obbligatori.
-
Il
employeetabella elenca tutti i dipendenti che utilizzano il sistema. Tutti i campi sono obbligatori.
Nei sistemi complessi di solito ci sono più ruoli, quindi è necessario disporre di un dizionario dei ruoli e di una connessione dipendente/ruolo utente. Nel nostro esempio abbiamo un solo ruolo:la stessa persona inserisce le prenotazioni e vende i biglietti.
-
La
reservationeseat_reservedle tabelle sono le tabelle principali del nostro sistema. Questo è il motivo per cui li ho elencati per ultimi. Tutte le altre tabelle possono esistere senza tabelle di prenotazione, ma senza le tabelle di prenotazione perderemmo in primo luogo la ragione per progettare l'intero database.
La
reservationla tabella memorizza i dati su una prenotazione e/o vendita di un biglietto. Se abbiamo una prenotazione, l'attributoreservedsarebbe impostato su True, ilreservation_type_idverrebbe impostato in base all'origine della prenotazione e alemployee_reserved_idconterrebbe ilid_employeevalore della persona che ha inserito i dati (sarebbe vuoto se la prenotazione fosse stata effettuata online dal cliente). Allo stesso modo, se i biglietti sono stati venduti, ilemployee_paid_idverrebbe compilato con ilid_employeevalore della persona che ha venduto i biglietti, l'attributo pagato sarebbe impostato su True. L'attributo attivo identifica se un record è ancora valido. Se i biglietti fossero venduti, questo attributo sarebbe sempre True e la prenotazione senza vendite sarebbe attiva fino a 30 minuti prima dell'inizio della proiezione
Il
seat_reservedtable ci consente di effettuare una prenotazione o un pagamento per più posti. Dopo che il dipendente ha controllato alcuni posti liberi sull'interfaccia, un record sarebbe stato aggiunto a questa tabella per ciascuno di essi. Se vogliamo verificare quali posti sono liberi o occupati possiamo verificare i valori in questa tabella unita allareservationtabella dovereservation.active = True.
Vale la pena ricordare:
employee_reserved_idnon è obbligatorio perché la prenotazione di un posto potrebbe non esistere (un biglietto per un posto viene venduto senza una prenotazione precedente) o viene effettuata onlinereservation_type_idè una chiave esterna che fa riferimento all'"id" del tipo di prenotazione. Non è obbligatorio perché una prenotazione potrebbe non esistere (nel caso in cui abbiamo effettuato una vendita senza una prenotazione precedente)reservation_contactè un campo di inserimento testo per la memorizzazione dei dati di una persona che ha effettuato una prenotazione, non è obbligatorio perché una prenotazione potrebbe non esistere (nel caso in cui abbiamo effettuato una vendita senza una prenotazione precedente)employee_paid_idè correlato a un utente che ha effettuato una vendita, non è obbligatorio perché la vendita potrebbe non essere avvenuta (posto riservato, prenotazione annullata automaticamente, posto non venduto)paidè un flag che indica che il pagamento è avvenuto ed è obbligatorio (i valori possono essere Sì/Vero o No/Falso)
Alla fine, tieni presente che a nessuno piace trovare qualcun altro al suo posto: