wiki:RelationalModel

Version 10 (modified by 231138, 7 days ago) ( diff )

--

Релационен модел

ЕР дијаграм

Архитектура и главни концепти

Користачи и нивни улоги

Основна е поделбата меѓу users (сите во системот), drivers (возачи) и passengers (патници). Табелата users е како "мајка" — содржи основни информации (име, телефон, емајл). Потоа drivers и passengers додаваат своите специфични полиња. Една иста личност може да биде и возач и патник — нема никаква забрана за тоа.

Возила и производители

Возилата имаат три нивоа организирање. Прво manufacturers (Volkswagen, Mercedes, итн.), потоа vehicle_models (Golf, C-Class), потоа самите vehicles (твоја лична кола). Вакво расчленување спречува да пишувале "Volkswagen" стоди пати во базата.

Возачот има много возила, возило мора да припаѓа на возач. За тоа го имаме vehicle_ownership — табела која чува каде возачот имал кола. Кога возачот купи ново возило, едноставно ј додаваме нов ред во vehicle_ownership. Старото возило останува во историјата, не го бришеме. Вака видиме точно кој возач кога имал кола.

Рути и возења

Routes е шаблон — замисли рута "Скопје → Куманово → Пријепа" дефинирана веќе во системот. Rides е конкретно возење: „Во понеделник во 08:00 возачот Марко ја возеше оваа рута со Volkswagen Golf".

Застанувањата на рутата се во route_stops со редоследни броеви (1, 2, 3...). Рутата може да има 2 застанувања или 10 застанувања. Исто така, на иста рута можеш да направиш и круг (почеток и крај иста локација).

Сегменти — како се делат возењата

Возењето од Скопје до Пријепа преку Куманово не е "целина" во пресметките. Поделено е на сегменти:

  • Скопје → Куманово
  • Куманово → Пријепа

Патниците не мора да патуваат целата рута. Еден патник можеш да влезе во Куманово и да излезе во Пријепа. За тоа route_segments дели рутата на делови меѓу два стопа, а passenger_segments чува колку патници беа на секој сегмент. Вака точно можеме да изразунаме колку требало да плати секој патник според каде вле и каде слезе.

Патарини

Не можеме едноставно да кажеме "возење чини X денари". Некои возења минуваат наплатни рампи. За тоа имаме:

  • toll_points — каде се наплатните рампи и колку чинат по тип возило
  • ride_tolls — евидентира дека возењето Х минало низ рампата Y
  • toll_passenger_split — раздела на патарината меѓу патниците кои беа присутни

Готовина, не картички

Апликацијата е готовина-само. Нема онлајн плаќања, нема дигитални портфели. Возачот собира готовина од патниците. Табелите fare_splits и booking_final_fare служат само да покажат возачу колку собира од кого — ништо повеќе.

Оценувања

Патниците оценуваат возачи, возачи оценуваат патници. Табелата ratings чува сите оценувања. Има CHECK constraint кој вели: "Човек не може да го оцени самиот себеси". За просечната оцена не пишуваме avg_rating поле директно. Наместо тоа, правиме view-и driver_ratings и passenger_ratings кои пресметуваат просек на лету. Вака ако додадеш нова оценка, просекот се ажурира веднаш без дополнителна логика.

История и следливост

Кога возење промени статус (scheduled → in_progress → completed), промената оди во ride_status_history со временска марка. Исто и резервациите во booking_status_history. Вака администраторот има целосна историја — кога точно се случи што.

Бришење на податоци

Претпоставка: администраторот избрише користачки профил. Но возачот има 50 завршени возења! Ние не ги бришеме поврзаните возења — користиме ON DELETE RESTRICT. За статистика, користиме резервиран корисник со id = 0 наречен "избришан корисник". Вака можеме да видиме "некој возач" направил возење, дури и кога профилот е избришан.

Прегледи (Views)

Сите овие табели се напалени со JOIN-ови. Наместо апликацијата да пишува SELECT ... FROM rides JOIN drivers JOIN vehicles ... низ целиот код, ми направивме 9 views. Секој view е спремена SQL "забелешка" која делува како табела.

v_available_rides — Возења отворени за резервирање

Ова е она што патникот вижи кога пребарува возење. Показува:

  • Кога поаѓа возењето
  • Каде почнува, каде завршува
  • Име на возач
  • Марка и модел на возило
  • Проценета цена
  • Просечна оцена на возачот

VIEW вика JOIN меѓу rides, drivers, vehicles, vehicle_models, manufacturers, routes, route_stops, ratings и пресметува просечна оцена на лету. Филтрира само возења со статус scheduled.

Апликацијата го користи вака: SELECT * FROM v_available_rides WHERE origin_city = 'Скопје' AND departure_time >= NOW(). Едноставно!

v_driver_profile — Профилот на возачот

Возачот кога си ажурира профилот, вижи ова. Исто и патникот пред да резервира место ако сака да види со кого ќе возеше.

Содржи:

  • Лични податоци (име, телефон)
  • Информации за возачка дозвола (број, датум на издавање)
  • Примарното возило на возачот (ако има повеќе, земаме оно со најмал ID)
  • Статистика: вкупно возења, завршени, откажани
  • Просечна оцена

VIEW прави JOIN меѓу drivers, users, driver_licenses, vehicles, vehicle_ownership, rides и ratings. Пресметува број на возења по статус и просек на оценувања.

v_passenger_trip_history — Моја патна историја

Патникот кога кликне на "Мои патувања" вижи:

  • Кога беше возењето
  • Каде почнало, каде завршило
  • Име на возач
  • Потврда дека је качен (pickup_confirmed_at)
  • Потврда дека је слезен (dropoff_confirmed_at)
  • Колку платил
  • Неговата оценка за возачот (ако ја дал)

Секоја резервација е редок во view-ot. Апликацијата може лесно да филтрира по статус (completed, canceled) или да го пагинира.

v_ride_manifest — Список на патници за возење

Возачот одлучи да поаѓа во 08:00. Пред да ја запали машината, отворува ја оваа листа за да вижи:

  • Кои патници се качуваат
  • Имиња и телефонски броеви
  • Каде секој вле (punkt_A_stop)
  • Каде секој слезе (punkt_B_stop)
  • Колку собира од секој

Прикажува само резервации со статус confirmed, picked_up или completed. Откажаните резервации не се прикажуваат — нема смисла да ги вижи.

v_booking_details — Целосен детај на резервација

Патникот кликна на една резервација. Вижи "сё на едно место":

  • Кој е возачот (име, телефон, оцена)
  • Какво возило (марка, модел, регистарски табички)
  • Точна локација за качување (Централна станица, Скопје)
  • Точна локација за слегување (Куманово центар)
  • Точен час на поаѓање
  • Финална цена
  • Статус на резервација

Содржи толку многу JOIN-ови што апликацијата СЕКОГАШ го вика со филтер: WHERE booking_id = 123. Никогаш не го вика без филтер — би ја спалил базата од JOIN-ови!

v_unread_notifications — Мои нови нотификации

Патникот или возачот отворува го "звончето". Вижи само непрочитаните нотификации:

  • Каде е написано нотификацијата (текст)
  • Од кого (некој возач, администратор, итн.)
  • Кога (точна време или "пред 5 минути")

VIEW-ot пресметува "старост во минути" за да покаже "пред 5 мин" без дополнителна логика во апликацијата. Апликацијата го вика со WHERE user_id = 42 AND read_at IS NULL.

v_driver_earnings — Мои приходи во месец

Возачот кликне "Финансиски извештај". Вижи:

  • За секој месец колку возења направил
  • Колку резервации наплатил (можеби некој отказал во последниот момент)
  • Вкупен приход
  • Просечен приход по резервација
  • Максимален приход
  • Минимален приход

Администраторот го користи и за анализа — ако возачот нема приход три месеца, веројатно е неактивен.

Пресметува на основа на bookings со статус completed (само завршени) и нивните финални суми.

v_route_popularity — Кои рути се најпопуларни

Апликацијата на почетниот екран прикажува популарни рути за да го вдахновува патникот. Ова view-ot ги рангира:

  • По број на вкупни резервации
  • Просечна цена по резервација
  • Просечна цена по километар

Служи и како сигнал за возачите. Ако рутата Скопје↔Куманово има 50 резервации месечно, но возачот направил 10 возења и не продал ништо — сигнал е дека нешто не е окај. Можеби е превиско скапо, или нема добро рекламирано возење.

v_incident_summary — Безбедносни инциденти

Само администраторот видува ова. Прикажува:

  • Тип на инцидент (невежливост, несреќа, кршење на правила)
  • Опис на инцидентот
  • Кога е пријавен
  • Лични податоци на пријавувачот (патник или возач)
  • Лични податоци на другата страна
  • Возачка дозвола број
  • Рутата на возењето

Инцидентите могат да будат пријавени дури и после завршено возење, така да view-ot не филтрира по статус на возење.

Важно: NULL вредности со логика

Неколку полиња се NULL базирано на логика:

  • rides.recurrence_days и rides.recurrence_end_date — се пополнуваат САМО ако is_recurring = TRUE. За еднократни возења се NULL.
  • bookings.pickup_stop_id и bookings.dropoff_stop_id — ако патникот резервира целата рута, стоповите се почеток и крај. Ако резервира дел, се полнат конкретни стопови.

Апликацијата треба да проверува ова пред да користи вредностите.

Attachments (3)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.