📖 Izvan osnovnog skladištenja
U savremenom razvoju softvera, podaci nisu statični. Zahtjevi za auditom (ko je šta promijenio i kada) i
upravljanje tabelama sa stotinama miliona redova zahtijevaju tehnologije koje prevazilaze standardni
CREATE TABLE. SQL Server 2022 nudi Temporal Tables za automatsko
verziranje
i Partitioning za inteligentno podjelu podataka.
⏱️ Temporal Tables (System-Versioned Internals)
Temporalna tabela je zapravo par tabela: trenutna tabela (koju koristite za rad) i historijska tabela (koju engine koristi za čuvanje starih verzija redova).
Kako to radi "ispod haube"?
- INSERT: Postavlja
ValidFromna trenutno sistemsko vrijeme, aValidTona9999-12-31. - UPDATE: Trenutni red se kopira u historijsku tabelu, njegov
ValidTose postavlja na vrijeme izmjene. Novi red u glavnoj tabeli dobija novoValidFrom. - DELETE: Red se briše iz glavne tabele i prebacuje u historijsku sa postavljenim
ValidTo.
-- Preporuka: Uvijek koristite PAGE kompresiju na historijskoj tabeli jer se rijetko mijenja
CREATE TABLE Procurement.Vendors (
VendorID INT PRIMARY KEY IDENTITY(1,1),
VendorName NVARCHAR(200) NOT NULL,
DiscountPct DECIMAL(5,2) NOT NULL,
-- Period kolone su obavezne
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON (
HISTORY_TABLE = Procurement.Vendors_History,
DATA_CONSISTENCY_CHECK = ON
));
GO
🎯 Zašto HIDDEN kolone?
Koristimo ključnu riječ HIDDEN kako bi SELECT * upiti ostali čisti i ne bi
prikazivali
tehničke kolone validnosti osim ako ih specifično ne tražimo.
🗜️ Data Compression: Page-Level Deep Dive
Dok Row kompresija štedi bajtove unutar reda, Page Compression radi na nivou cijele 8KB stranice koristeći dva procesa:
- Prefix Compression: Ako kolona u više redova na jednoj stranici počinje istim karakterima (npr. 'Sarajevo, 'Sarajevo 1'), SQL Server čuva prefiks samo jednom.
- Dictionary Compression: Traži identične vrijednosti bilo gdje na stranici i mijenja ih kratkim tokenima.
⚠️ CPU vs I/O Tradeoff
Kompresija zahtijeva CPU cikluse za otpakivanje podataka u RAM-u. Međutim, pošto je I/O (čitanje sa diska) skoro uvijek usko grlo, kompresija obično poboljšava ukupne performanse sistema.
🧩 Table Partitioning: Strategija "Divide and Conquer"
Particionisanje nije samo za prostor. To je alat za Data Lifecycle Management (DLM).
Komponente Particionisanja:
- Partition Function: Definiše granice (npr. svaka godina je nova particija).
- Partition Scheme: Mapira particije na Filegroups (različite diskove).
- Partition Key: Kolona po kojoj se vrši podjela (uvijek uključena u indekse).
-- Zamislite da imamo milione redova u tabeli 'Logs' za 2023. godinu.
-- Umjesto sporog 'DELETE FROM Logs WHERE Year = 2023', radimo SWITCH:
-- 1. Napravimo identičnu praznu tabelu 'Logs_Archive_2023'
-- 2. "Prebacimo" particiju (to je samo metadata promjena u engine-u)
ALTER TABLE Logs SWITCH PARTITION 1 TO Logs_Archive_2023;
-- Trajanje: ~10ms bez obzira na broj redova (100 miliona ili 100 redova).
🎯 Praktična Vježba: Totalna Optimizacija
Zadatak: Dizajniranje "Big Data" Tabele za Transakcije
Aplikacija bilježi 10 miliona transakcija mjesečno. Moramo osigurati da sistem ostane brz i da možemo lako arhivirati stare podatke.
Zadatak 1: Kreirajte Partition Function po mjesecima za 2025. godinu.
Zadatak 2: Kreirajte tabelunad tom shemom sa uključenom PAGE kompresijom.
Zadatak 3: Omogućite System Versioning za audit promjena statusa transakcija.
-- 1. Funkcija
CREATE PARTITION FUNCTION pf_Monthly (DATE)
AS RANGE RIGHT FOR VALUES ('2025-02-01', '2025-03-01', '2025-04-01');
GO
-- 2. Shema (Mapiramo sve na PRIMARY radi jednostavnosti vježbe)
CREATE PARTITION SCHEME ps_Monthly AS PARTITION pf_Monthly ALL TO ([PRIMARY]);
GO
-- 3. Tabela sa svim "naprednim" začinima
CREATE TABLE Financial.Transactions (
TransID BIGINT IDENTITY(1,1),
Amount DECIMAL(18,2) NOT NULL,
TransDate DATE NOT NULL,
Status NVARCHAR(20),
ValidFrom DATETIME2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL,
ValidTo DATETIME2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL,
PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo),
CONSTRAINT PK_Transactions PRIMARY KEY (TransID, TransDate) -- PK mora sadržavati partition key
)
ON ps_Monthly (TransDate)
WITH (
SYSTEM_VERSIONING = ON (HISTORY_TABLE = Financial.Transactions_History),
DATA_COMPRESSION = PAGE
);
GO
✅ Zaključak
Napredni dizajn tabela transformiše vašu bazu iz pasivnog spremišta u inteligentan sistem:
- ✅ Temporalne tabele eliminišu potrebu za kompleksnim "audit triggerima".
- ✅ Page kompresija omogućava rad sa više podataka u istoj količini RAM-a.
- ✅ Particionisanje čini operacije održavanja (Maintenance) trenutnim procesima.
📚 Sljedeća Lekcija
U Lekciji 1.4 zaključujemo Modul 1 fokusirajući se na Integritet Podataka i kako mehanizmi baze garantuju da nikada ne dobijete "siroče" u podacima.