Обичате ли да ходите на кино? Замисляли ли сте се как изглежда дизайнът на базата данни зад тяхната система за резервации? В тази статия ще подготвим примерен модел на база данни за киносалон.
Има няколко предположения, които трябва да имаме предвид:
- съвременните мултиплексни киносалони могат да имат една или повече аудитории в рамките на по-голям комплекс,
- всяка аудитория може да има различен брой места,
- местата са номерирани с номер на ред и позиция на седалката в един ред,
- филмът може да има множество прожекции по различно време или може да бъде прожектиран едновременно в различна аудитория,
- за всяка прожекция място може да бъде запазено/продадено само веднъж,
- искаме да проследим кой е въвел всяка резервация/продажба в системата.
Нека разгледаме един възможен дизайн на база данни за решаване на този проблем (моделът е създаден с Vertabelo за MySQL база данни):
Кратки описания на структурата на таблицата са дадени по-долу:
-
movie
таблицата съдържа данни за филми, които ще се показват в кината. Първичният ключ еid
, който автоматично се увеличава като всички първични ключове във всички други таблици. Единствените задължителни данни саtitle
.Всички полета имат значения според името си. Колоната
duration_min
може да се използва за деактивиране на вмъкването на нова прожекция или за показване на предупредително съобщение, в случай че искаме да влезем в прожекция в аудитория, където предходната прожекция все още е в ход:
previous screening start time + duration_min of it > this screening start time
-
auditorium
таблицата идентифицира всички аудитории в театъра. Всички данни са задължителни.seats_no
полето може да се използва за изчисляване на процента на наличност на аудитории за избрана прожекция/филм/аудитория/период от дати. Това е пример за резервиране на данни защото можем да получим броя на местата за всяка аудитория, като ги преброим вseat
маса. В този пример може да не подобри значително производителността. Показвам го тук като идея, която може да помогне при проектирането на по-сложни модели. Ако настроим базата данни по този начин, трябва да имаме предвид, че ако променим една част от данни, трябва да променим и други. Ако добавим или изтрием данни отseat
таблица трябва да коригираме стойностиseats_no
вauditorium
маса. -
screening
таблицата съдържа данни за всички прожекции и всички полета са задължителни. Прожекцията трябва да има свързан филм, аудитория и начален час. Не можем да имаме две представления в една и съща аудитория по едно и също време. Можем да дефинираме уникален ключ, състоящ се отauditorium_id
иscreening_start
. Тази настройка е по-добра от дефинирането на уникален ключ, състоящ се отmovie_id
,auditorium_id
иscreening_start
защото това би ни позволило да влизаме в прожекциите на два различни филма по едно и също време в една и съща аудитория.Кодът за визуализация на Vertabelo SQL за тази таблица изглежда така (забележете 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) );
-
seat
таблицата съдържа списък на всички места, които имаме в аудиториите, като всяко място е определено за строго една аудитория. Всички полета са задължителни. -
reservation_type
table е речник на всички видове резервации (по телефон, онлайн, лично). Всички полета са задължителни. -
employee
таблицата изброява всички служители, използващи системата. Всички полета са задължителни.В сложните системи обикновено има повече роли, така че трябва да имаме речник на ролите и връзка между служител/потребител. В нашия пример имаме само една роля:едно и също лице вмъква резервации и продава билети.
-
reservation
иseat_reserved
таблиците са основните таблици на нашата система. Ето защо ги изброих последно. Всички други таблици могат да съществуват без таблици за резервации, но без таблиците за резервации бихме загубили причината за проектиране на цялата база данни на първо място.reservation
таблицата съхранява данни за резервация и/или продажба на билет. Ако имаме резервация, атрибутътreserved
ще бъде зададен на True,reservation_type_id
ще бъде зададен според произхода на резервацията иemployee_reserved_id
ще съдържаid_employee
стойност на лицето, което е въвело данни (би било празно, ако резервацията беше направена онлайн от клиента). По същия начин, ако билетите са били продадени,employee_paid_id
ще бъде попълнено сid_employee
стойност на лицето, продало билети, атрибутът платен ще бъде зададен на True. Активният атрибут идентифицира дали записът все още е валиден. Ако билетите бяха продадени, този атрибут винаги щеше да е True и резервацията без продажби ще бъде активна до 30 минути преди началото на прожекциятаseat_reserved
таблица ни позволява да направим резервация или едно плащане за няколко места. След като служителят провери няколко свободни места в интерфейса, към тази таблица ще бъде добавен по един запис за всяко от тях. Ако искаме да проверим кои места са свободни или заети, можем да проверим стойностите в тази таблица, присъединена къмreservation
таблица, къдетоreservation.active = True
.
Струва си да се спомене:
employee_reserved_id
не е задължително, тъй като може да не съществува резервация за място (билет за място се продава без предходна резервация) или се прави онлайнreservation_type_id
е външен ключ, препращащ „id“ на типа резервация. Не е задължително, тъй като може да не съществува резервация (в случай, че сме направили продажба без предишна резервация)reservation_contact
е поле за въвеждане на текст за съхраняване на данни на лице, което е направило резервация, не е задължително, тъй като резервация може да не съществува (в случай, че сме направили продажба без предходна резервация)employee_paid_id
е свързан с потребител, извършил продажба, не е задължителен, тъй като продажбата може да не се е случила (местото е запазено, резервацията е анулирана автоматично, мястото не е продадено)paid
е флаг, който показва, че плащането е извършено и е задължително (стойностите могат да бъдат Yes/True или No/False)
В крайна сметка, имайте предвид, че никой не обича да намира някой друг на мястото си: