| 382 | | [attachment:console_6.sql console_6.sql] [attachment:console_7.sql console_7.sql] [attachment:console_8.sql console_8.sql] [attachment:console_9.sql console_9.sql] |
| | 382 | [attachment:console_6.sql console_6.sql] [attachment:console_7.sql console_7.sql] [attachment:console_8.sql console_8.sql] [attachment:console_9.sql console_9.sql] |
| | 383 | |
| | 384 | == 3. Креирање на Погледи (Views) и нивна примена == |
| | 385 | |
| | 386 | Погледите (Views) во системот служат како апстракционен слој кој ги прикрива комплексните спојувања (JOIN наредби) помеѓу табелите. Тие овозможуваат побрз развој на апликативниот дел, стандардизиран пристап до аналитичките податоци и оптимизација на најчесто извршуваните логички процеси на платформата. |
| | 387 | |
| | 388 | === Погледи за Аналитика на Содржини и Корисничка Активност === |
| | 389 | |
| | 390 | ==== 1. view_top_rated_content ==== |
| | 391 | Уредно ги сумира сите медиумски содржини, пресметувајќи го нивниот просечен рејтинг и вкупниот број на гласови, додека динамички го одредува типот на содржината (филм или серија). |
| | 392 | |
| | 393 | * '''Каде се користи:''' На почетната страница на стриминг апликацијата (Landing Page) во секциите од типот *"Најдобро оценети"* или *"Топ содржини на денот"*, како и во административниот панел за следење на трендови. |
| | 394 | * '''За што служи:''' Да овозможи брзо филтрирање и прикажување на најпопуларните содржини според корисниците, притоа заокружувајќи ја оцената на две децимали за естетски приказ на интерфејсот. |
| | 395 | |
| | 396 | {{{ |
| | 397 | #!sql |
| | 398 | CREATE OR REPLACE VIEW view_top_rated_content AS |
| | 399 | SELECT |
| | 400 | m.ContentID, |
| | 401 | m.title, |
| | 402 | m.releaseDate, |
| | 403 | m.AgeRating, |
| | 404 | ROUND(AVG(r.RatingValue), 2) AS avg_rating, |
| | 405 | COUNT(r.RatingID) AS total_ratings, |
| | 406 | CASE |
| | 407 | WHEN mo.MovieID IS NOT NULL THEN 'Movie' |
| | 408 | ELSE 'Series' |
| | 409 | END AS content_type |
| | 410 | FROM Media m |
| | 411 | JOIN Rating r ON r.ContentContentID = m.ContentID |
| | 412 | LEFT JOIN Movie mo ON mo.MovieID = m.ContentID |
| | 413 | LEFT JOIN Series se ON se.SeriesID = m.ContentID |
| | 414 | GROUP BY m.ContentID, m.title, m.releaseDate, m.AgeRating, mo.MovieID, se.SeriesID |
| | 415 | ORDER BY avg_rating DESC; |
| | 416 | }}} |
| | 417 | |
| | 418 | ==== 2. view_user_watch_history ==== |
| | 419 | Ги спојува трансакциските записи од историјата на гледање со матичните кориснички податоци и метаподатоците за медиумите и уредите. |
| | 420 | |
| | 421 | * '''Каде се користи:''' Во корисничкиот профил, поточно во секцијата *"Продолжи со гледање"* (Continue Watching) или *"Историја на прегледи"*. |
| | 422 | * '''За што служи:''' Му дава увид на крајниот корисник кога последен пат гледал одредена содржина, до кој процент стигнал (`Progress_percentage`) и преку каков тип на уред пристапил (на пр. Smart TV, Mobile). |
| | 423 | |
| | 424 | {{{ |
| | 425 | #!sql |
| | 426 | CREATE OR REPLACE VIEW view_user_watch_history AS |
| | 427 | SELECT |
| | 428 | u.UserID, |
| | 429 | u.FirstName, |
| | 430 | u.LastName, |
| | 431 | m.title AS content_title, |
| | 432 | CASE |
| | 433 | WHEN mo.MovieID IS NOT NULL THEN 'Movie' |
| | 434 | ELSE 'Series' |
| | 435 | END AS content_type, |
| | 436 | wh.WatchedAt, |
| | 437 | wh.Progress_percentage, |
| | 438 | d.DeviceType |
| | 439 | FROM WatchHistory wh |
| | 440 | JOIN "User" u ON u.UserID = wh.UserUserID |
| | 441 | JOIN Media m ON m.ContentID = wh.ContentContentID |
| | 442 | LEFT JOIN Movie mo ON mo.MovieID = m.ContentID |
| | 443 | LEFT JOIN Series se ON se.SeriesID = m.ContentID |
| | 444 | LEFT JOIN Devices d ON d.DeviceID = wh.DevicesDeviceID; |
| | 445 | }}} |
| | 446 | |
| | 447 | ==== 3. view_content_details ==== |
| | 448 | Ова е најкомплексниот поглед кој врши агрегација на низи (`STRING_AGG`) за да ги спои сите поврзани уметници (глумци/режисери), жанрови и јазици за секој медиум посебно. |
| | 449 | |
| | 450 | * '''Каде се користи:''' На деталната страница на кој било филм или серија (засебното корисничко мени кое се отвора пред да се кликне копчето "Play"). |
| | 451 | * '''За што служи:''' На едно место ги собира сите релевантни метаподатоци за содржината (целосен каст на артисти, јазични опции, жанрови, времетраење или број на сезони) заедно со вкупната оцена, со цел да се избегнат тешки латерални кверија при секое отворање на детали за филм. |
| | 452 | |
| | 453 | {{{ |
| | 454 | #!sql |
| | 455 | CREATE OR REPLACE VIEW view_content_details AS |
| | 456 | SELECT |
| | 457 | m.ContentID, |
| | 458 | m.title, |
| | 459 | m.releaseDate, |
| | 460 | m.AgeRating, |
| | 461 | CASE |
| | 462 | WHEN mo.MovieID IS NOT NULL THEN 'Movie' |
| | 463 | ELSE 'Series' |
| | 464 | END AS content_type, |
| | 465 | mo.Duration AS movie_duration, |
| | 466 | se.TotalSeasons, |
| | 467 | STRING_AGG(DISTINCT g.Name, ', ') AS genres, |
| | 468 | STRING_AGG(DISTINCT l.Name, ', ') AS languages, |
| | 469 | STRING_AGG(DISTINCT (a.FirstName || ' ' || a.LastName), ', ') AS artists, |
| | 470 | ROUND(AVG(r.RatingValue), 2) AS avg_rating, |
| | 471 | COUNT(DISTINCT r.RatingID) AS total_ratings |
| | 472 | FROM Media m |
| | 473 | LEFT JOIN Movie mo ON mo.MovieID = m.ContentID |
| | 474 | LEFT JOIN Series se ON se.SeriesID = m.ContentID |
| | 475 | LEFT JOIN Content_Genre cg ON cg.ContentContentID = m.ContentID |
| | 476 | LEFT JOIN Genre g ON g.GenreID = cg.GenreGenreID |
| | 477 | LEFT JOIN Content_Language cl ON cl.ContentContentID = m.ContentID |
| | 478 | LEFT JOIN Language l ON l.LanguageID = cl.LanguageLanguageID |
| | 479 | LEFT JOIN Content_Artist ca ON ca.ContentContentID = m.ContentID |
| | 480 | LEFT JOIN Artist a ON a.ArtistID = ca.ArtistArtistID |
| | 481 | LEFT JOIN Rating r ON r.ContentContentID = m.ContentID |
| | 482 | GROUP BY m.ContentID, m.title, m.releaseDate, m.AgeRating, mo.MovieID, mo.Duration, se.TotalSeasons; |
| | 483 | }}} |
| | 484 | |
| | 485 | --- |
| | 486 | |
| | 487 | === Погледи за Претплати, Структурирани Серии и Персонализација === |
| | 488 | |
| | 489 | ==== 4. view_active_subscriptions ==== |
| | 490 | Ги филтрира само тековно активните кориснички претплати и врши агрегација на бројот на моментално логирани уреди по претплата. |
| | 491 | |
| | 492 | * '''Каде се користи:''' Кај апликацискиот заштитен механизам (Auth/Security Middleware) и кај сметководствениот/бизнис панелот за менаџмент на платформата. |
| | 493 | * '''За што служи:''' Системот го користи за брза авторизација кога корисникот сака да пушти видео, проверувајќи дали претплатата му е активна, кој пакет го поседува, каква видео сесија му е дозволена и дали бројот на активни уреди ја надминува границата на пакетот (`MaxDevices`). |
| | 494 | |
| | 495 | {{{ |
| | 496 | #!sql |
| | 497 | CREATE OR REPLACE VIEW view_active_subscriptions AS |
| | 498 | SELECT |
| | 499 | u.UserID, |
| | 500 | u.FirstName, |
| | 501 | u.LastName, |
| | 502 | u.Email, |
| | 503 | s.Name AS subscription_plan, |
| | 504 | s.Price, |
| | 505 | s.MaxDevices, |
| | 506 | s.VideoQuality, |
| | 507 | us.Start_date, |
| | 508 | us.End_date, |
| | 509 | us.Status, |
| | 510 | us.Auto_renew, |
| | 511 | COUNT(d.DeviceID) AS active_devices |
| | 512 | FROM User_Subscription us |
| | 513 | JOIN "User" u ON u.UserID = us.UserUserID |
| | 514 | JOIN Subscription s ON s.SubscriptionID = us.SubscriptionSubscriptionID |
| | 515 | LEFT JOIN Devices d ON d.UserSubscriptionID = us.UserSubscriptionID |
| | 516 | WHERE us.Status = 'Active' |
| | 517 | GROUP BY u.UserID, u.FirstName, u.LastName, u.Email, |
| | 518 | s.Name, s.Price, s.MaxDevices, s.VideoQuality, |
| | 519 | us.Start_date, us.End_date, us.Status, us.Auto_renew; |
| | 520 | }}} |
| | 521 | |
| | 522 | ==== 5. view_series_episodes ==== |
| | 523 | Ја мапира целата хиерархиска структура на една серија, почнувајќи од самата серија, преку сезоните, па сè до финалните епизоди подредени по логички редослед. |
| | 524 | |
| | 525 | * '''Каде се користи:''' Се активира кога корисникот ќе избере серија и сака да ја погледне листата на епизоди поделени по соодветни сезони (на пр. паѓачко мени за Сезона 1, Сезона 2 итн.). |
| | 526 | * '''За што служи:''' Овозможува структуриран приказ на насловите на епизодите, нивните редни броеви и нивното времетраење, подредени точно хронолошки за полесна навигација (`ORDER BY m.title, sea.SeasonNumber, e.episodeNumber`). |
| | 527 | |
| | 528 | {{{ |
| | 529 | #!sql |
| | 530 | CREATE OR REPLACE VIEW view_series_episodes AS |
| | 531 | SELECT |
| | 532 | m.ContentID AS series_id, |
| | 533 | m.title AS series_title, |
| | 534 | se.TotalSeasons, |
| | 535 | sea.SeasonID, |
| | 536 | sea.SeasonNumber, |
| | 537 | sea.ReleaseYear, |
| | 538 | e.EpisodeID, |
| | 539 | e.episodeNumber, |
| | 540 | e.Title AS episode_title, |
| | 541 | e.Duration AS episode_duration |
| | 542 | FROM Series se |
| | 543 | JOIN Media m ON m.ContentID = se.SeriesID |
| | 544 | JOIN Season sea ON sea.SeriesSeriesID = se.SeriesID |
| | 545 | JOIN Episode e ON e.SeasonSeasonID = sea.SeasonID |
| | 546 | ORDER BY m.title, sea.SeasonNumber, e.episodeNumber; |
| | 547 | }}} |
| | 548 | |
| | 549 | ==== 6. view_user_watchlist ==== |
| | 550 | Го отсликува персонализираниот избор на содржини за секој корисник поединечно, подредувајќи ги најновите додадени ставки најгоре. |
| | 551 | |
| | 552 | * '''Каде се користи:''' Во корисничкото мени под опцијата *"Моја Листа"* (My Watchlist / Watch Later). |
| | 553 | * '''За што служи:''' Овозможува брз дофат до содржините кои корисникот намерно ги зачувал за да ги гледа подоцна, прикажувајќи ги основните информации како наслов, тип на содржина и возрасна рестрикција, за брза одлука пред гледање. |
| | 554 | |
| | 555 | {{{ |
| | 556 | #!sql |
| | 557 | CREATE OR REPLACE VIEW view_user_watchlist AS |
| | 558 | SELECT |
| | 559 | u.UserID, |
| | 560 | u.FirstName, |
| | 561 | u.LastName, |
| | 562 | m.title AS content_title, |
| | 563 | CASE |
| | 564 | WHEN mo.MovieID IS NOT NULL THEN 'Movie' |
| | 565 | ELSE 'Series' |
| | 566 | END AS content_type, |
| | 567 | m.AgeRating, |
| | 568 | m.releaseDate, |
| | 569 | wl.dateAdded |
| | 570 | FROM Watchlist wl |
| | 571 | JOIN "User" u ON u.UserID = wl.UserUserID |
| | 572 | JOIN Media m ON m.ContentID = wl.ContentContentID |
| | 573 | LEFT JOIN Movie mo ON mo.MovieID = m.ContentID |
| | 574 | LEFT JOIN Series se ON se.SeriesID = m.ContentID |
| | 575 | ORDER BY wl.dateAdded DESC; |
| | 576 | }}} |