Changes between Initial Version and Version 1 of AdvancedTopics


Ignore:
Timestamp:
07/02/26 01:50:09 (4 days ago)
Author:
231123
Comment:

Напредна тема - OLAP

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedTopics

    v1 v1  
     1= Документација — OLAP =
     2
     3----
     4
     5== Преглед на архитектурата ==
     6
     7Напредната тема го проширува постоечкиот OLTP модел (Hotel, Room, Reservation, Customer, Pet, Payment, итн.) со посебен '''OLAP слој''' во форма на '''ѕвезда шема (star schema)''': табели за димензиите  во однос на три факт-табели, кои се користат за аналитички прашања (ROLLUP, CUBE, drill-down, window функции, pivoting, slicing).
     8
     9Причина за постоење на овој слој одделно од OLTP делот: OLTP шемата е оптимизирана за брзи, точни, секојдневни трансакциски прашања (пр. „резервациите на клиент X"). За разлика од OLTP, OLAP слојот е оптимизиран за тешки, аналитички прашања врз милиони редови (пр. „приход по хотел, по квартал, по вид миленче").
     10
     11=== Редослед на создавање на OLAP ===
     12
     13{{{
     141. Dimensions.sql        → димензии
     152. FactReservation.sql   → факт табела: резервации
     163. FactOrderProduct.sql  → факт табела: продажба на производи
     174. FactServiceUsage.sql  → факт табела: користење услуги
     185. OLAP_Queries.sql      → аналитички прашања
     19}}}
     20
     21----
     22
     23== `Dimensions.sql` — Табели со димензии ==
     24
     25=== Цел ===
     26Ги гради '''табелите со димензии''' —  податоци кои подоцна се користат за филтрирање и групирање во факт-табелите. Ова е стандарден чекор при градење на OLAP/dimensional модел врз постоечка OLTP база.
     27
     28=== Содржина ===
     29
     30||= Табела =||= Тип =||= Опис =||
     31|| `DimDate` || Type 1 || Датумска димензија, за периодот 2015–2027. `date_key` е во формат `YYYYMMDD` и служи и како partition key во факт-табелите. Содржи изведени атрибути: ден, месец, квартал, година, сезона, викенд. ||
     32|| `DimHotel` || Type 1 || Хотели, преземени директно од `Hotel`. ||
     33|| `DimRoomType` || Type 1 || Типови соби. ||
     34|| `DimSpecies`, `DimBreed` || Type 1 || Видови и раси на миленчиња. ||
     35|| `DimService` || Type 1 || Услуги, со додадена изведена колона `price_category` (Budget, Standard, Premium). ||
     36|| `DimProduct` || Type 1 || Производи, со изведена `price_range` (Low, Mid, High). ||
     37|| `DimRoom` || Type 2 || Соби — цената и типот можат да се менуваат со тек на време. ||
     38|| `DimPet` || Type 2 || Миленчиња. Содржи изведена колона `age_group`. ||
     39|| `DimCustomer` || Type 2 || Клиенти — адреса/локација. Содржи изведена колона `customer_segment` (New, Regular, VIP). ||
     40|| `DimEmployee` || Type 2 || Вработени. ||
     41
     42 * '''Type 1''' — нема чување историја.
     43 * '''Type 2''' — табелите имаат `valid_from`, `valid_to`, `is_current` колони, наменети за чување историја на промени.
     44
     45----
     46
     47== `FactReservation.sql` — Факт табела за резервации ==
     48
     49=== Цел ===
     50Централна и најголема факт-табела — по еден ред за секоја резервација, со мерки (`total_cost`, `nights_stayed`, `num_services`, `has_delivery`) и референци кон сите релевантни димензии.
     51
     52=== Партиционирање ===
     53Табелата е партиционирана според датум, со по една партиција за секоја година (2015–2027). Ова значи дека прашање филтрирано по конкретна година (пр. `WHERE d.year = 2022`) чита само од таа партиција, наместо да скенира сè.
     54
     55----
     56
     57== `FactOrderProduct.sql` — Факт табела за продажба на производи ==
     58
     59=== Цел ===
     60По еден ред за секој производ во секоја нарачка (mapping на `OrderProduct`), со мерки за количина, единечна цена, вкупна цена, статус на нарачка и статус на достава.
     61
     62=== Партиционирање и индекси ===
     63Табелата е партиционирана според датум (година).
     64
     65----
     66
     67== `FactServiceUsage.sql` — Факт табела за услуги ==
     68
     69=== Цел ===
     70По еден ред за секое закажување услуга, со мерки за цена, времетраење и статус.
     71
     72=== Партиционирање и индекси ===
     73Табелата е партиционирана според датум (година).
     74
     75----
     76
     77== `OLAP_Queries.sql` — Аналитички прашања ==
     78
     79=== Цел ===
     80Прашања кои ги демонстрираат стандардните OLAP операции и техники: '''ROLLUP''', '''CUBE''', '''drill-down''', '''window функции''', '''pivoting''' и '''slicing'''.
     81
     82=== 1. Приходи — ROLLUP по хотел, година, квартал ===
     83Хиерархиско групирање: `GROUP BY ROLLUP(h.hotel_name, d.year, d.quarter)` генерира детален ред за секоја комбинација, плус меѓусуми на секое повисоко ниво (по хотел+година, по хотел, вкупно).
     84
     85=== 2. Occupancy Rate по хотел и сезона — CUBE ===
     86`GROUP BY CUBE(h.hotel_name, d.season)` генерира '''сите можни комбинации''' на групирање, бидејќи хотел и сезона се независни димензии без природна хиерархија меѓу нив.
     87
     88=== 3. Drill Down — Наоѓање каде паѓа приходот ===
     89Постепено навлегување од општо кон конкретно:
     90 1. Открива година со нисок приход (годишните тотали се споредуваат меѓу себе преку self-join — секоја година е споена со редот за претходната година, наместо со `LAG()`).
     91 2. По хотел, во таа година — открива хотел со низок приход.
     92 3. По вид миленче, во тој хотел/година — открива вид кој придонел за приходот.
     93 4. По месец, за тој вид/хотел/година — крајно ниво на детали.
     94
     95Секој чекор го стеснува опсегот со `WHERE`, врз основа на она што е откриено во претходниот чекор.
     96
     97=== 4. Топ услуги по приход — Window Functions ===
     98Рангира услуги одделно во секој хотел. Вгнездена агрегација пресметува процент од вкупниот приход на хотелот.
     99
     100=== 5. Customer Lifetime Value — највредни клиенти ===
     101Два одделни ранга во исто прашање: глобален и по сегмент (партиција).
     102
     103=== 6. Продажба на производи — CUBE по категорија, хотел и ценовен опсег ===
     104`CUBE(dp.category_name, h.hotel_name, dp.price_range)` со три независни димензии генерира 8 можни комбинации на групирање — сите комбинации од: категорија, хотел и ценовен опсег.
     105
     106=== 7. Pivoting — типови соби како колони ===
     107Ги претвора вредностите на димензијата `room_type` во посебни колони (наместо редови), со цел приходот по секој тип соба да се спореди во еден ред по хотел. Реализирано преку условна агрегација (`SUM(CASE WHEN ... THEN ... END)`), бидејќи Postgres нема вградена `PIVOT` синтакса.
     108
     109
     110=== 8. Slicing — фиксирање вредности на димензии ===
     111Slicing значи фиксирање на вредноста на '''една''' димензија. Во аналитичките прашања се фиксира вредноста на хотелот - hotel_name = 'Fur Haven' и се прави преглед на преостанатите димензии. Во аналитичките прашања се прави и ''dicing'' (се фиксираат вредности на '''повеќе''' димензии истовремено): хотел + сезона + вид миленче.
     112
     113