Changes between Version 8 and Version 9 of RelationalModel


Ignore:
Timestamp:
04/25/26 19:49:57 (7 days ago)
Author:
231138
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • RelationalModel

    v8 v9  
    1 = Релационен модел
     1# Релационен модел
    22
    3 == ЕР Дијаграм
     3## ЕР дијаграм
    44
    5 [[Image(RelationalModel-drive-net.svg,1400px)]]
    6 == Дополнителен Опис
     5![Релационен модел DriveNet](RelationalModel-drive-net.svg)
    76
    8 - Табелите `users`, `drivers` и `passengers` се моделирани со заедничка база. Централната табела `users` ги чува општите податоци за сите корисници, додека `drivers` и `passengers` се проширувања со специфични атрибути за секоја улога. Еден корисник може да биде и возач и патник истовремено.
     7## Архитектура и главни концепти
    98
    10 - Табелата `vehicles` е поврзана со `vehicle_models` и `manufacturers` со цел нормализација на податоците за возилата и спречување на дупликати. Врската помеѓу возачите и возилата е моделирана преку `vehicle_ownership`, каде историјата на сопственост се зачувува — при промена на сопственик се додава нов запис наместо да се брише стариот.
     9### Користачи и нивни улоги
    1110
    12 - Табелата `routes` претставува шаблон за рута (дефинирана патека помеѓу две локации), додека `rides` претставува конкретно возење на таа рута со определен возач, возило, датум и час. Меѓустаниците се чуваат во `route_stops` со редоследен број, што овозможува дефинирање на рути со произволен број на застанувања. Истата локација може да се повтори на рутата (пр. round trip).
     11Табелите `users`, `drivers` и `passengers` функционираат по принцип на инхеритација. Базната табела `users` содржи основни информации за сите во системот, додека `drivers` и `passengers` се специјализирани и содржат само релевантни атрибути за та улога. Јавно еден кориснички профил може да има и две улоги истовремено — да е и возач и патник.
    1312
    14 - Табелите `route_segments` и `passenger_segments` служат за прецизна пресметка на трошоците. `route_segments` ги дели возењата на сегменти помеѓу два последователни стопа, додека `passenger_segments` чува колку патници биле присутни на секој сегмент и колку треба да плати секој патник за него. Финалниот износ за секоја резервација се чува во `booking_final_fare`.
     13### Возила и нивна класификација
    1514
    16 - Во повеќе табели имаме подмножества на foreign keys коишто се nullable, но нивното значење зависи од контекстот. На пример:
    17    - `bookings(pickup_stop_id, dropoff_stop_id)` — дефинираат сегментот кој го резервира патникот; ако патникот патува на целата рута, стоповите се почетниот и крајниот стоп
    18    - `rides(recurrence_days, recurrence_end_date)` — се пополнуваат само доколку `is_recurring = TRUE`; за еднократни возења овие полиња се NULL
     15Возилата се организирани во три нивоа: `manufacturers` (производител), `vehicle_models` (модел) и `vehicles` (конкретно возило). Овој пристап спречува дупликување на податоци. Врската помеѓу возачите и возилата е моделирана преку табелата `vehicle_ownership`, која чува целосна историја на сопственост. Кога некој во возачот промени возило, новиот запис се додава, а старите се задржуваат — никогаш не бришеме историја.
    1916
    20 - Табелите `toll_points`, `ride_tolls` и `toll_passenger_split` го моделираат системот за патарини. `toll_points` ги чува наплатните рампи со цени по тип на возило, `ride_tolls` евидентира кои рампи се поминати во конкретно возење, а `toll_passenger_split` ја дели патарината рамномерно меѓу патниците кои биле присутни на тој сегмент.
     17### Рути и возења
    2118
    22 - Бидејќи апликацијата работи исклучиво со готовинско плаќање, не постои табела за онлајн трансакции. Наместо тоа, `fare_splits` и `booking_final_fare` служат само како референтни алатки за возачот да знае колку да наплати од секој патник.
     19Табелата `routes` е шаблон — претставува дефинирана патека со нејзиниот редослед на застанувања. Табелата `rides` пак претставува конкретно возење кое возачот го организира врз база на таа рута — сакај определен датум, час и возило.
    2320
    24 - Оценувањето е моделирано преку табелата `ratings` со CHECK constraint кој осигурува дека корисникот не може да се оцени самиот себеси (`reviewer_user_id != reviewee_user_id`). Оцената на возачот/патникот не се чува директно како атрибут туку се пресметува динамички преку views (`driver_ratings`, `passenger_ratings`) за да се избегне inconsistency.
     21Застанувањата на рутата се чувуваат во `route_stops` со редоследен број, што значи рутата може да има колку сакаш застанувања. Истата локација може да се појави повеќе пати (на пример, круговна рута).
    2522
    26 - Табелата `ride_status_history` и `booking_status_history` ги чуваат сите промени на статусот со временска марка, со цел да се овозможи целосна следливост на животниот циклус на возењето и резервацијата.
     23### Сегментирање на возења и наплата
    2724
    28 - За зачувување на статистиките и евиденцијата дури и по бришење на корисници, сите foreign keys кон `users` користат `ON DELETE SET DEFAULT` со резервиран корисник `id=0` ("избришан корисник"). Foreign keys кон структурни табели (`rides`, `routes`, `bookings`) користат `ON DELETE RESTRICT` за да спречат случајно губење на поврзани податоци.
     25За прецизна пресметка на цена, возењата се делат на сегменти:
    2926
     27- **`route_segments`** — ја дели рутата на делови помеѓу два последователни застанувања
     28- **`passenger_segments`** — чува колку патници биле на секој сегмент и колку треба да плати секој од нив
     29
     30Финалната сума за секоја резервација се чува во `booking_final_fare`.
     31
     32### Условни полиња (nullable foreign keys)
     33
     34Неколку табели имаат nullable foreign keys, а нивното значење зависи од контекст:
     35
     36- **`bookings.pickup_stop_id` и `bookings.dropoff_stop_id`** — го дефинираат сегментот што го резервира патникот. Ако патникот патува на целата рута, тие се почетниот и крајниот стоп.
     37- **`rides.recurrence_days` и `rides.recurrence_end_date`** — се пополнуваат само кога `is_recurring = TRUE`. За еднократни возења, овие полиња се NULL.
     38
     39### Система за патарини
     40
     41Три табели работат заедно за управување со патаринските рампи:
     42
     43- **`toll_points`** — наплатни рампи со цена по тип возило
     44- **`ride_tolls`** — евидентира кои рампи се поминати во одредено возење
     45- **`toll_passenger_split`** — ја дели цената рамномерно меѓу патниците кои биле присутни на тој делот
     46
     47### Готовинско плаќање
     48
     49Апликацијата работи исклучиво со готовина, така што **нема табела за онлајн трансакции**. Табелите `fare_splits` и `booking_final_fare` служат како референцијални алатки — возачот ги користи за да знае колку да собере од секој патник, исё.
     50
     51### Оценување (Рејтинги)
     52
     53Оценувањето функционира преку табелата `ratings` со CHECK constraint кој спречува самооценување. Оценката на возач/патник не се чува како просто поле, туку се пресметува динамички преку `driver_ratings` и `passenger_ratings` views за да останува во синхрона.
     54
     55### Историја и следливост
     56
     57Две табели чуваат целосна историја на промени:
     58
     59- **`ride_status_history`** — сите промени на статусот на возење
     60- **`booking_status_history`** — сите промени на статусот на резервација
     61
     62Секоја промена има временска марка, што овозможува целосна следливост.
     63
     64### Бришење на податоци
     65
     66За да се задржи статистика и обврски дури и кога кориснички профили се избришат, сите foreign keys кон `users` користат `ON DELETE SET NULL` или се поврзуваат со резервиран корисник со `id = 0` ("избришан кориснік"). Foreign keys кон критични табели (`rides`, `routes`, `bookings`) користат `ON DELETE RESTRICT` — не смее ништо да се избрише ако е поврзано.
     67
     68---
    3069
    3170## Прегледи (Views)
    3271
    33 Базата на податоци содржи девет прегледи кои ги покриваат најчестите случаи на употреба на апликацијата. Секој преглед е дизајниран да го замени повторувачкиот `JOIN` код во апликацискиот слој и да обезбеди конзистентен приказ на податоците.
     72Базата содржи девет прегледи кои го поедностављуваат најчестиот код во апликацијата.
    3473
    35 ### v_available_rides
     74### `v_available_rides`
    3675
    37 Го прикажува списокот на сите возења со статус `scheduled` кои се достапни за резервација. За секое возење ги обединува податоците за возачот, возилото, марката и моделот, рутата, почетниот и крајниот град, и пресметува проценет вкупен трошок врз основа на должината на рутата и цената по километар. Просечната оцена на возачот е агрегирана директно во прегледот преку `LEFT JOIN` со `ratings`. Овој преглед го користи екранот за пребарување на возења — кога патникот внесува дестинација, апликацијата едноставно додава `WHERE origin_city = ...` или `WHERE departure_time >= ...` на овој преглед.
     76Ги прикажува сите возења со статус `scheduled` кои се отворени за резервирање. За секое возење ја обединува информацијата за возачот, возилото, марката, моделот, рутата и градовите, плус пресметана проценета цена врз база на должина на рута и цена по км. Просечната оцена на возачот е веќе вклучена.
    3877
    39 ### v_driver_profile
     78Апликацијата го користи при пребарување — просто добива WHERE за град на почеток, час, итн.
    4079
    41 Обединет приказ на профилот на возачот — лични податоци, информации за возачката дозвола, примарното активно возило (ако има повеќе, се зема она со најмал `vehicle_id`), бројот на вкупни, завршени и откажани возења, како и агрегираната оцена. Дизајниран е за страницата на профилот на возачот, но истиот преглед го користи и патникот кога сака да провери со кого патува пред да резервира место.
     80### `v_driver_profile`
    4281
    43 ### v_passenger_trip_history
     82Комплетна слика на возачкиот профил — лични податоци, возачка дозвола, примарното возило, укупно/завршено/откажано возења и просечна оцена. Koristi ga возачот при ажурирање на своја страна и патникот при проверка со кого се сокува пред резервирање.
    4483
    45 Целосна историја на патувања за секој патник — резервации со статус, имиња на возачот, почетен и краен град, потврди за качување и слегување, финалната сума и оценката што патникот ја дал. Редовите не се групирани — секоја резервација е посебен ред, па апликацијата може лесно да ги пагинира или филтрира по статус. Ги заменува сложените вгнездени упити кои инаку би биле потребни за приказот „Моите патувања“.
     84### `v_passenger_trip_history`
    4685
    47 ### v_ride_manifest
     86Целосна историја на патувања за секој патник — резервации со статус, име на возач, почеток/крај, потврди за качување/слегување, финална цена и оценка. Секоја резервација е редок (не групиран), што го едностави филтерирањето и пагинирањето во апликацијата.
    4887
    49 Листа на сите потврдени, активни и завршени патници за секое возење, со нивните имиња, телефонски броеви, места на качување и слегување и финалната сума. Возачот го користи овој преглед пред поаѓање за да знае кого чека, каде да застане и колку да наплати. Прикажува само резервации со статус `confirmed`, `picked_up` или `completed` — откажаните резервации намерно се исклучени за да не го збунат возачот.
     88### `v_ride_manifest`
    5089
    51 ### v_driver_earnings
     90Список на сите потврдени, активни и завршени патници за одредено возење — имиња, телефони, места на качување/слегување, финална цена. Возачот го гледа пред поаѓање за да знае кого чека, каде да застане и колку да наплати.
    5291
    53 Месечен преглед на приходите по возач, пресметан врз основа на завршените резервации и нивните финални суми. За секој месец ги прикажува бројот на возења, бројот на наплатени резервации, вкупниот приход, просечниот, максималниот и минималниот износ по резервација. Корисен е и за возачот (личен финансиски преглед) и за администраторот (следење на активноста на платформата по период).
     92### `v_driver_earnings`
    5493
    55 ### v_route_popularity
     94Месечен преглед на приходите по возач. За секој месец прикажува број возења, број наплатени резервации, вкупен приход, просек и min/max по резервација. Корисно е и за возачот (лична финансиска контрола) и за администраторот (анализа на активност).
    5695
    57 Ги рангира сите рути според вкупниот број на резервации. Покрај бројките, прикажува и просечна цена по резервација и просечна цена по километар за секоја рута. Целта е двојна: прво, на почетниот екран да се прикажат најбараните рути како предлози; второ, да служи за аналитика — ако одредена рута има многу возења, но мал број на резервации, тоа е сигнал дека цената е превисока или дека постои проблем со достапноста.
     96### `v_route_popularity`
    5897
    59 ### v_booking_details
     98Ги рангира рутите по број на резервации. Прикажува просечна цена по резервација и просечна цена по км. Служи за препораки на почетниот екран и за анализа — ако рута има многу возења но малку резервации, сигнал е дека нешто не е окај (премногу скапо, лоша достапност).
    6099
    61 Комплетен детален запис за една резервација — сè на едно место: патник, возач, возило со регистарски таблички, места на качување и слегување со имиња на локациите и градовите, времето на поаѓање, статусот и финалниот износ. Наменет е за екранот со потврда на резервација и за генерирање на потврда/сметка. Поради тоа што содржи многу `JOIN`-ови, апликацијата секогаш го повикува со `WHERE booking_id = ?` — никогаш без филтер.
     100### `v_booking_details`
    62101
    63 ### v_unread_notifications
     102Целосна слика на една резервација — патник, возач, возило со регистарски табички, места (со имиња на локации и градови), време поаѓање, статус, финална цена. Користи се при потврда и при генерирање на сметка. Апликацијата секогаш го вика со `WHERE booking_id = ?` — никогаш без филтер.
    64103
    65 Ги враќа само непрочитаните нотификации (каде `read_at IS NULL`), збогатени со името на корисникот и пресметаната „старост во минути“ (`age_mins`), за да може апликацијата да прикаже „пред 5 минути“ без дополнителна логика. Прегледот е наменет за ѕвончето за нотификации во мобилната апликација и секогаш се повикува со `WHERE user_id = ?` за конкретниот најавен корисник.
     104### `v_unread_notifications`
    66105
    67 ### v_incident_summary
     106Само непрочитаните нотификации (каде `read_at IS NULL`), збогатени со име на корисник и „старост во минути" за лесна приказ (нпр. „пред 5 минути"). Апликацијата го вика со `WHERE user_id = ?` за конкретниот логиран корисник.
    68107
    69 Административен преглед на сите пријавени инциденти со целосен контекст — тип и опис на инцидентот, времето на пријавување, личните податоци на пријавувачот и возачот (вклучувајќи го бројот на возачката дозвола) и рутата на возењето. Дизајниран е исклучиво за администраторскиот панел за безбедност и не е изложен кон патничкиот или возачкиот интерфејс. Прикажува инциденти за сите возења без разлика на нивниот статус, бидејќи инцидент може да биде пријавен и по завршено возење.
     108### `v_incident_summary`
     109
     110Административен преглед на пријавени инциденти со целосен контекст — тип, опис, време пријава, лични податоци на пријавувач и возач (вклучувајќи возачка дозвола) и рутата. Наменет исклучиво за администраторот. Прикажува инциденти без оглед на статус на возење, бидејќи инцидент може да се пријави и по завршено возење.