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
movie
la 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_min
può 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'
auditorium
la tabella identifica tutti gli auditorium del teatro. Tutti i dati sono obbligatori.Il
seats_no
il 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 nelseat
tavolo. 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 dalseat
tabella dobbiamo regolare i valoriseats_no
nell'auditorium
tavolo. -
Lo
screening
la 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_id
escreening_start
. Questa configurazione è migliore della definizione di una chiave univoca composta damovie_id
,auditorium_id
escreening_start
perché 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
seat
la 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_type
table è un dizionario di tutti i tipi di prenotazione (per telefono, online, di persona). Tutti i campi sono obbligatori. -
Il
employee
tabella 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
reservation
eseat_reserved
le 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
reservation
la tabella memorizza i dati su una prenotazione e/o vendita di un biglietto. Se abbiamo una prenotazione, l'attributoreserved
sarebbe impostato su True, ilreservation_type_id
verrebbe impostato in base all'origine della prenotazione e alemployee_reserved_id
conterrebbe ilid_employee
valore 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_id
verrebbe compilato con ilid_employee
valore 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 proiezioneIl
seat_reserved
table 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 allareservation
tabella dovereservation.active = True
.
Vale la pena ricordare:
employee_reserved_id
non è 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: