MODUL 3 - LEKCIJA 1

Dizajniranje i Implementacija Pogleda

Views: Od apstrakcije podataka do materijalizovanih performansi

⏱️ Trajanje: ~3 časa 📚 Nivo: Srednji do Napredni 🎯 Praktični primjeri: 5

📖 Virtuelne Tabele

View (Pogled) je uskladišteni SELECT upit koji se u bazi tretira kao virtuelna tabela. Views ne čuvaju podatke (osim u specifičnom slučaju Indexed Views), ali služe kao moćan sloj apstrakcije koji odvaja bazu od aplikacije.

🎯 Zašto koristiti Views?

⛓️ Schema Binding: Sigurnosno zaključavanje

Čest problem je kada neko promijeni strukturu osnovne tabele (npr. obriše kolonu), a pogled prestane raditi. Rješenje je WITH SCHEMABINDING.

🚫 Rigidnost je vrlina

Kada kreirate pogled sa SCHEMABINDING, SQL Server vam neće dozvoliti da modifikujete osnovne tabele na način koji bi "polomio" taj pogled. Također, kolone u upitu moraju koristiti dvodijelna imena (npr. dbo.Table).

🛠️ Kreiranje Sigurnog Pogleda
CREATE VIEW Stats.v_EmployeeSummary
WITH SCHEMABINDING
AS
SELECT 
    e.EmployeeID, 
    e.FirstName + ' ' + e.LastName AS EmployeeName, 
    ISNULL(COUNT(r.ReportID), 0) as TotalReports,
    ISNULL(SUM(p.Budget), 0) as TotalProjectBudget
FROM Stats.Employees e
LEFT JOIN Stats.Reports r ON e.EmployeeID = r.CreatedBy
LEFT JOIN Stats.Projects p ON e.DepartmentID = p.DepartmentID
GROUP BY e.EmployeeID, e.FirstName, e.LastName;
GO

🔄 Updatable Views: Izmjena kroz filter

Možete li izvršiti UPDATE nad pogledom? Da, ali uz stroga pravila:

🚀 Indexed Views (Materialized Views)

Ovo je vrhunac performansi. Kod običnog pogleda, on se izvršava svaki put kad ga pozovete. Kod Indexed View, rezultati se fizički zapisuju na disk (u B-Tree strukturu).

💎 Kada koristiti?

Kada imate upit koji radi tešku agregaciju (SUM, COUNT) nad milionima redova, a podaci se ne mijenjaju svake sekunde. Prvi indeks na pogledu mora biti Unique Clustered Index.

⚡ Materijalizacija Pogleda
-- 1. View mora biti sa SCHEMABINDING
CREATE VIEW Stats.v_MonthlyReportStats
WITH SCHEMABINDING
AS
SELECT 
    ReportYear = YEAR(CreatedDate),
    ReportMonth = MONTH(CreatedDate),
    TotalReports = COUNT_BIG(*), -- COUNT_BIG je obavezan za indexed views
    DepartmentCount = COUNT_BIG(DISTINCT DepartmentID)
FROM Stats.Reports
GROUP BY YEAR(CreatedDate), MONTH(CreatedDate);
GO

-- 2. Materijalizacija (fizički upis na disk)
CREATE UNIQUE CLUSTERED INDEX IX_MonthlyReportStats 
ON Stats.v_MonthlyReportStats (ReportYear, ReportMonth);
GO

🎯 Praktična Vježba: Sigurnosna Apstrakcija

Zadatak: Implementacija Multi-Tenant Sigurnosti

Imate tabelu Internal.Employees. Želite napraviti pogled Public.Staff koji je dostupan svima, ali sakriva kolonu Salary i JMBG.

Zadatak 1: Kreirajte pogled sa SCHEMABINDING.

Zadatak 2: Onemogućite da korisnici vide kolone kojih nema u pogledu čak i ako imaju pristup bazi (putem DENY komande na tabeli).

💡 Rješenje
-- Kreiranje pogleda
CREATE VIEW HR.v_StaffList
WITH SCHEMABINDING
AS
SELECT Name, Department, OfficeLocation
FROM HR.Employees;
GO

-- Sigurnosna konfiguracija
GRANT SELECT ON HR.v_StaffList TO PublicUser;
DENY SELECT ON HR.Employees TO PublicUser; -- Ne može vidjeti platu direktno u tabeli!

✅ Zaključak

Views su temelj profesionalne arhitekture:

📚 Sljedeća Lekcija

U Lekciji 3.2 idemo korak dalje i pišemo Stored Procedure. Naučićete kako enkapsulirati cijele poslovne procese, rukovati greškama i optimizovati parametre.