MODUL 1 - LEKCIJA 4

Osiguravanje Integriteta Podataka

Duboki uvid u mehanizme baze koji garantuju istinitost podataka bez greške

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

📖 Integritet kao temelj povjerenja

Aplikacije dolaze i odlaze, ali podaci ostaju. Vaša baza mora biti u stanju da se odbrani od loše napisanog koda koji pokušava unijeti nevalidne podatke (npr. negativnu cijenu ili "siroče" narudžbu bez kupca). SQL Server integritet postiže kroz kaskadu provjera koje se izvršavaju unutar transakcionog loga.

🔑 Identiteti i Ključevi: Više od brojeva

Svaka tabela treba Primary Key, ali kako ga generisati?

1. IDENTITY Property

Najčešći alat (npr. ID INT IDENTITY(1,1)). Međutim, postoje zamke:

2. GUID (UNIQUEIDENTIFIER)

🚫 Performance Warning: Random GUIDs

Standardni NEWID() generiše nasumične ključeve. Ovo uzrokuje užasnu fragmentaciju indeksa i spor upis na disk. Uvijek koristite NEWSEQUENTIALID() u SQL Serveru za primarne ključeve jer generiše sortirane Guid-ove.

✅ Constraints: Čuvari Poslovnih Pravila

Trusted vs Untrusted Constraints

Ovo je koncept koji razlikuje amatere od eksperata. Kada dodajete CHECK ili FOREIGN KEY na tabelu koja već ima podatke, možete koristiti WITH NOCHECK da preskočite provjeru postojećih podataka.

⚠️ Optimizer Impact

Ako koristite WITH NOCHECK, Query Optimizer označi constraint kao not trusted. To znači da optimizer više neće koristiti to ograničenje da ubrza upite, jer ne vjeruje podacima!

⚡ Kako popraviti "Untrusted" Constraint
-- Ponovna provjera i vraćanje povjerenja optimizera
ALTER TABLE Stats.ReportData 
WITH CHECK CHECK CONSTRAINT FK_ReportData_Reports;
GO

🌊 Referential Integrity & Cascading Actions

Referencijalni integritet garantuje da su veze između tabela validne. Ako Report referencira Department, odjeljenje se ne može obrisati dok ima izvještaje.

🛠️ Napredna Konfiguracija Veza
CREATE TABLE Stats.Reports (
    ReportID INT PRIMARY KEY,
    DepartmentID INT,
    CONSTRAINT FK_Reports_Departments FOREIGN KEY (DepartmentID) 
    REFERENCES Stats.Departments (DepartmentID)
    ON DELETE CASCADE  -- Briše podatke izvještaja ako se obriše izvještaj
    ON UPDATE NO ACTION -- Ne dozvoljava promjenu DepartmentID-a ako izvještaj postoji
);

🎯 Praktična Vježba: Izgradnja Neprobojnog Sistema

Zadatak: Bankarski Core Sistem

Moramo osigurati da se transakcije ne mogu kreirati za zatvorene račune i da iznos ne smije biti nula.

Zadatak 1: Kreirajte tabelu Accounts sa statusom (Active, Closed).

Zadatak 2: Kreirajte Transactions sa FK koji ima ON DELETE NO ACTION (nikada ne brišemo historiju novca!).

Zadatak 3: Dodajte Check constraint koji provjerava iznos, ali ga dodajte kao TRUSTED.

💡 Rješenje i Objašnjenje
-- 1. Accounts
CREATE TABLE Banking.Accounts (
    AccountNumber CHAR(10) PRIMARY KEY,
    OwnerName NVARCHAR(100) NOT NULL,
    Status VARCHAR(10) DEFAULT 'Active' CHECK (Status IN ('Active', 'Closed'))
);

-- 2. Transactions
CREATE TABLE Banking.Transactions (
    TransID BIGINT IDENTITY(1,1) PRIMARY KEY,
    FromAccount CHAR(10),
    ToAccount CHAR(10),
    Amount DECIMAL(18,4) NOT NULL,
    TransDate DATETIME2 DEFAULT SYSDATETIME(),
    -- FK sa strogim integritetom
    CONSTRAINT FK_From FOREIGN KEY (FromAccount) REFERENCES Banking.Accounts(AccountNumber),
    CONSTRAINT FK_To FOREIGN KEY (ToAccount) REFERENCES Banking.Accounts(AccountNumber)
);

-- 3. Dodavanje trusted constraint-a na iznos
ALTER TABLE Banking.Transactions 
WITH CHECK ADD CONSTRAINT CHK_Amount_Positive 
CHECK (Amount <> 0);
GO

🔍 Debugging Integrity Violations

Kada dobijete čuvenu grešku 547 (Constraint Violation), SQL Server vam kaže ID ograničenja. Možete koristiti ovaj upit da saznate o čemu se tačno radi:

🕵️ Istraživanje Grešaka
SELECT 
    name AS ConstraintName,
    type_desc AS ConstraintType,
    OBJECT_NAME(parent_object_id) AS TableName,
    is_not_trusted -- AKO JE 1, OPTIMIZER VAS IGNORIŠE!
FROM sys.check_constraints;

✅ Zaključak Modula 1

Završili smo arhitektonski temelj. Sada posjedujete znanje senior dev-a:

📚 Sljedeći Modul: Performansi

U Modulu 2 ulazimo u svijet Indeksa. Naučićete zašto INDEX SEEK rješava sve probleme i kako SSMS čita vaš kod prije nego ga izvrši.