Changes between Version 2 and Version 3 of AdvancedApplicationDesign


Ignore:
Timestamp:
08/20/24 19:28:38 (3 months ago)
Author:
216049
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AdvancedApplicationDesign

    v2 v3  
    2222[https://develop.finki.ukim.mk/projects/BusNGo/wiki/AdvancedApplicationDesign/ruta Стартување на рута на автобус]
    2323
     24== Материјализирани views
     25
     26Напредните извештаи од минатите фази се искористени за да се направат materialized views. Материјализираните views значително го намалуваат времето на извршување на квери поради тоа што го чуваат и резултатот. Ова е соодветно поради тоа што ваквите статистики нема потреба да бидат up to date во секој момент, доволно е да се рефрешираат на одреден период (на пример 12 часа).
     27
     28Во продолжение се прикажани материјалиизираните views (за некои од нив има и графици кои може да се погледнат во амин панелот).
     29
     30==== Средна разлика на простигнување на инстанците од постојка А до постојка Б
     31
     32Идејата е да може да се има естимација на време за кое автобусот би стигнал на одредена постојка.
     33
     34{{{#!div
     35{{{#!sql
     36
     37CREATE MATERIALIZED VIEW avg_time_diffs AS
     38WITH ordered_instanca AS (SELECT ilpl.instanca_na_linija_id,
     39                                 ilpl.postojka_na_linija_id,
     40                                 pnl.reden_broj,
     41                                 ilpl.timestamp
     42                          FROM instanca_na_linija_postojka_na_linija ilpl
     43                                   JOIN
     44                               postojka_na_linija pnl ON ilpl.postojka_na_linija_id = pnl.id
     45                          ORDER BY ilpl.instanca_na_linija_id,
     46                                   pnl.reden_broj),
     47     time_differences AS (SELECT o1.instanca_na_linija_id,
     48                                 o1.postojka_na_linija_id                          AS start_station_id,
     49                                 o1.timestamp                                      AS start_time,
     50                                 o2.postojka_na_linija_id                          AS end_station_id,
     51                                 o2.timestamp                                      AS end_time,
     52                                 EXTRACT(EPOCH FROM (o2.timestamp - o1.timestamp)) AS time_diff
     53                          FROM ordered_instanca o1
     54                                   JOIN
     55                               ordered_instanca o2 ON o1.instanca_na_linija_id = o2.instanca_na_linija_id
     56                          WHERE o1.reden_broj + 1 = o2.reden_broj)
     57SELECT
     58    row_number() over () as id,
     59    start_station_id,
     60       end_station_id,
     61       AVG(time_diff)::double precision AS avg_time_diff_seconds
     62FROM time_differences
     63GROUP BY start_station_id,
     64         end_station_id
     65ORDER BY start_station_id,
     66         end_station_id;
     67
     68create unique index avg_time_diffs_index on avg_time_diffs (id);
     69
     70
     71}}}
     72}}}
     73
     74==== Број на казни според линија
     75
     76{{{#!div
     77{{{#!sql
     78
     79create materialized view kazna_po_linija as
     80select row_number() over () as id, l.id as line_id, count(l.id)
     81from linija l
     82         left join instanca_na_linija inl on l.id = inl.linija_id
     83         left join kontrola k on inl.id = k.instanca_na_linija_id
     84         left join kazna kaz on k.id = kaz.kontrola_id
     85where extract(year from kaz.date_created) = extract(year from now())
     86group by l.id
     87order by count(l.id) desc;
     88
     89create unique index index_kazna_po_linija on kazna_po_linija(id);
     90
     91}}}
     92}}}
     93
     94
     95==== Зафатеност на линиите по интервали од 1 час
     96
     97{{{#!div
     98{{{#!sql
     99
     100create materialized view most_busy_part_of_the_day as
     101select row_number() over () as id, id as linija_id, interval_1h, count(id || '-' || interval_1h) broj_pati
     102from (select li.id,
     103             (to_char(extract(hour from v.start_date), '00') || ':00 -' || to_char(extract(hour from (v.start_date
     104                 + '1 hours'::interval))::int, '00') || ':00') as interval_1h
     105      from linija li
     106               left join instanca_na_linija inl on li.id = inl.linija_id
     107               left join vozenje v on inl.id = v.instanca_na_linija_id
     108      where v.start_date between (make_date(extract(year from (now()))::int, 1, 1)) and (make_date(extract(year from (now()))::int, 12, 31))) as hours
     109group by id, interval_1h
     110order by interval_1h desc;
     111
     112create unique index index_most_busy_part_of_the_day on most_busy_part_of_the_day(id);
     113
     114}}}
     115}}}
     116
     117==== Commutes per line
     118
     119{{{#!sql
     120create materialized view commutes_by_line as
     121select row_number() over () as id, l.id as linija_id, count(v.id)
     122from linija l
     123         left join instanca_na_linija inl on l.id = inl.linija_id
     124         left join vozenje v on inl.id = v.instanca_na_linija_id
     125where v.start_date between date_trunc('year', now()) and date_trunc('month', date_trunc('year', now())+ interval '7 months')
     126group by l.id;
     127}}}
     128
     129==== Number of passengers per line and station
     130
     131{{#!sql
     132create materialized view number_passengers_per_line_and_station as
     133select row_number() over () as id, p.id as station_id, l.id as line_id, count(p.id)
     134from postojka p
     135         join postojka_na_linija pnl on p.id = pnl.postojka_id
     136         join vozenje v on pnl.id = v.postojka_na_linija_start_id
     137         join patnik pat on v.patnik_id = pat.id
     138         join linija l on pnl.linija_id = l.id
     139where v.start_date between (make_date(extract(year from (now() - '1 years'::interval))::int, 4, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 6, 30))
     140group by p.id, l.id
     141order by count(p.id) desc;
     142}}
     143
     144==== Ticket sales
     145
     146{{{#!sql
     147create materialized view ticket_sales as
     148select row_number() over () as id, filtered.tip_id, filtered.interval_1h, filtered.broj_pati
     149from (select filter.tip_id, interval_1h, count(tip_id || '-' || interval_1h) broj_pati
     150      from (select *,
     151                   (to_char(extract(hour from b.datum_kupuvanje), '00') || ':00 -' ||
     152                    to_char(extract(hour from (b.datum_kupuvanje + '1 hours'::interval))::int, '00') ||
     153                    ':00') as interval_1h
     154            from tipbilet t
     155                     left join bilet b on t.id = b.tip_id
     156--     where  b.datum_kupuvanje between (make_date(extract(year from (now() - '1 years'::interval))::int, 1, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 12, 31))
     157
     158           ) as filter
     159      group by filter.tip_id, interval_1h) filtered
     160where broj_pati = (select max(filtered.broj_pati)
     161                   from (select filter.tip_id, interval_1h, count(tip_id || '-' || interval_1h) broj_pati
     162                         from (select *,
     163                                      (to_char(extract(hour from b.datum_kupuvanje), '00') || ':00 -' ||
     164                                       to_char(extract(hour from (b.datum_kupuvanje + '1 hours'::interval))::int,
     165                                               '00') ||
     166                                       ':00') as interval_1h
     167                               from tipbilet t
     168                                        left join bilet b on t.id = b.tip_id
     169--     where  b.datum_kupuvanje between (make_date(extract(year from (now() - '1 years'::interval))::int, 1, 1)) and (make_date(extract(year from (now() - '1 years'::interval))::int, 12, 31))
     170
     171                              ) as filter
     172                         group by filter.tip_id, interval_1h) filtered)
     173  and tip_id in (select id
     174                 from tipbilet
     175                 where ime in ('Hourly', 'Daily'));
     176}}}
     177
     178==== Total income (from ticket sales and fines)
     179
     180{{{#!sql
     181create materialized view total_income as
     182WITH kazna_sum AS (
     183    SELECT
     184        EXTRACT(YEAR FROM k.date_payed) AS year,
     185        SUM(k.iznos) AS sum_kz
     186    FROM
     187        kazna k
     188    WHERE
     189        k.plateno = TRUE
     190    GROUP BY
     191        EXTRACT(YEAR FROM k.date_payed)
     192),
     193     bilet_sum AS (
     194         SELECT
     195             EXTRACT(YEAR FROM b.datum_kupuvanje) AS year,
     196             SUM(tb.cena) AS sum_b
     197         FROM
     198             bilet b
     199                 JOIN tipbilet tb ON tb.id = b.tip_id
     200         GROUP BY
     201             EXTRACT(YEAR FROM b.datum_kupuvanje)
     202     )
     203SELECT
     204    row_number() over () as id,
     205    COALESCE(k.year, b.year)::text AS year,
     206    COALESCE(sum_kz, 0) as fines_income,
     207    COALESCE(sum_b, 0) as ticket_income,
     208    COALESCE(sum_kz, 0) + COALESCE(sum_b, 0) AS total_income
     209FROM
     210    kazna_sum k
     211        FULL OUTER JOIN bilet_sum b ON k.year = b.year
     212ORDER BY
     213    year desc;
     214}}}