Обичате ли да ходите на кино? Замисляли ли сте се как изглежда дизайнът на базата данни зад тяхната система за резервации? В тази статия ще подготвим примерен модел на база данни за киносалон.
Има няколко предположения, които трябва да имаме предвид:
- съвременните мултиплексни киносалони могат да имат една или повече аудитории в рамките на по-голям комплекс,
- всяка аудитория може да има различен брой места,
- местата са номерирани с номер на ред и позиция на седалката в един ред,
- филмът може да има множество прожекции по различно време или може да бъде прожектиран едновременно в различна аудитория,
- за всяка прожекция място може да бъде запазено/продадено само веднъж,
- искаме да проследим кой е въвел всяка резервация/продажба в системата.
Нека разгледаме един възможен дизайн на база данни за решаване на този проблем (моделът е създаден с 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_typetable е речник на всички видове резервации (по телефон, онлайн, лично). Всички полета са задължителни.
-
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)
В крайна сметка, имайте предвид, че никой не обича да намира някой друг на мястото си: