wiki:ReportsProcedures

Version 12 (modified by 223075, 3 weeks ago) ( diff )

--

Напредни извештаи од базата (PostgreSQL)


Оваа страна прикажува 3 покомплексни извештаи.

Извршени се SQL надградбите (views, triggers, function, indexes) преку Node:

cd backend
npm run db:apply
"Enhancements applied (views, triggers, function, indexes)."

Потоа внесовме мал демо-сет:

npm run db:seed
Seed done. User IDs: { ana: '12', bojan: '13', ciro: '14', classId: '7' }

1) Топ потрошувачи (пакети + мерч) со рангирање

Цел: По корисник, колку потрошил (сума на пакети + мерч) и кој му е рангот според вкупниот трошок.

Користен поглед: vw_user_spend

SQL:

SELECT user_id, username, email,
       spend_packages, spend_merch, total_spend,
       RANK() OVER (ORDER BY total_spend DESC) AS spend_rank
FROM vw_user_spend
ORDER BY total_spend DESC, user_id;

Релациска алгебра:

Π_{user_id,username,email,spend_packages,spend_merch,total_spend}
 ( User ⟕ (γ_{user_id; SUM(price)→spend_packages}(User_Purchased_Package ⋈ Package))
        ⟕ (γ_{user_id; SUM(price)→spend_merch}(User_Purchased_Merch ⋈ Merch_Items)) )

Извршување:

npm run db:reports

ги создава датотеките:

backend/proofs/top_spenders.json

backend/proofs/class_utilization.json

backend/proofs/training_pop_monthly.json
[
  {
    "user_id": "8",
    "username": "mikiYoga",
    "email": "miki@example.com",
    "spend_packages": "45.00",
    "spend_merch": "12.00",
    "total_spend": "57.00",
    "spend_rank": "1"
  },...
]

2) Исполнетост на часови со дневно рангирање

Цел: За секој час: booked/capacity (во %) и ранг за истиот ден.

Користен поглед: vw_class_utilization

SQL:

SELECT *,
       DENSE_RANK() OVER (PARTITION BY date ORDER BY utilization_pct DESC NULLS LAST) AS daily_rank
FROM vw_class_utilization
ORDER BY date, start_time, class_id;

Релациска алгебра:

γ_{class_id; COUNT(user_id)→booked}(Class ⟕ User_Booked_Class)
+ калкулација utilization_pct = booked / capacity
 [
  {
    "class_id": "5",
    "date": "2025-06-09T22:00:00.000Z",
    "start_time": "08:00:00",
    "end_time": "09:00:00",
    "location": "Studio A",
    "capacity": 20,
    "booked": "1",
    "utilization_pct": "5.00",
    "instructor_id": "5",
    "daily_rank": "2"
  },...
]

3) Популарност на тренинзи по месец

Цел: По месец, броиме уникатни корисници кои резервирале часови што содржат даден тренинг; даваме месечен ранг.

Користен поглед: vw_training_pop_monthly

SQL:

SELECT training_id, training_name, month, num_bookings,
       RANK() OVER (PARTITION BY month ORDER BY num_bookings DESC NULLS LAST) AS rank_in_month
FROM vw_training_pop_monthly
ORDER BY month DESC, rank_in_month, training_name;

Релациска алгебра:

γ_{training_id,month; COUNT(DISTINCT user_id)→num_bookings}
 ( Training ⋈ Class_Includes_Training ⋈ Class ⟕ User_Booked_Class )
[
  {
    "training_id": "7",
    "training_name": "Vinyasa",
    "month": "2025-08-31T22:00:00.000Z",
    "num_bookings": "1",
    "rank_in_month": "1"
  },...
] 

4) EXPLAIN/ANALYZE (доказ за индекси)

Ги генерираме плановите:

npm run db:explain

*Напомена:* Поради мал сет, за демонстрација користевме и „forced“ планови со enable_seqscan=off. Фајлови:

  • backend/proofs/events_explain_forced.json
  • backend/proofs/class_bookings_explain_forced.json

A) Настани по датум/време – составен индекс (date,time)

Фајл: backend/proofs/events_explain_forced.json

Очекуван извадок (Index Scan преку idx_event_date_time): {{{json {

"Node Type": "Index Scan", "Index Name": "idx_event_date_time", "Relation Name": "Event", "Alias": "Event", "Index Cond": "(date >= CURRENT_DATE)"

} }}}

B) Резервации по час – два индекса

Фајл: backend/proofs/class_bookings_explain_forced.json

1) Индекс врз Class за датум: {{{json {

"Node Type": "Index Scan", "Index Name": "idx_class_date_time", "Relation Name": "Class", "Alias": "c", "Index Cond": "(date >= CURRENT_DATE)"

} }}}

2) Индекс врз User_Booked_Class за поврзување по class_id: {{{json {

"Node Type": "Index Scan", "Index Name": "idx_ubc_class", "Relation Name": "User_Booked_Class", "Alias": "ubc", "Index Cond": "(class_id = c.class_id)"

} }}}

Note: See TracWiki for help on using the wiki.