[ laden @ 23.02.2010. 17:03 ] @
Preturajuci po postovima sa foruma saznao sam da je skakljiva tema i da treba biti oprezan pri denormalizaciji ali posto je akademski rad ne moze biti velika steta:) Zahtev je da se odradi denormalizacija unutar baze nabavke. Imam jednu ideju ali mi je potrebna pomoc da je realizujem. Tabele koje bi ucestvovale u denormalizaciji su:

NabavniNalog ( SifraNaloga #, Datum, ZatvorenNalog, SifraSektora #, JMBG #, JMBG` #)
StavkaNabavnogNaloga (SifraNaloga #, Rb #, SifraPro #, TrebovanaKolicina, RokNabavke, ZatvorenaStavka)

Narudzbenica (SifraNarudzbenice #, DatumPrometaDobara, DatumValute, DatumIzdavanja, SifraDob #, SifraPonude #, JMBG#)
StavkaNarudzbenice (SifraNarudzbenice #, Rb #, NarucenaKolicina, SifraPro #)

Prijemnica (SifraPrijemnice #, Datum, Ukupno, JMBG #, SifraOtpremnice #)
StavkaPrijemnice (SifraPrijemnice #, Rb #, PrimljenaKolicina, Cena, IznosPDV, Iznos, SifraPro #)

Proizvod (SifraPro #, Naziv, JedMere, KolicinaUSkladistu, Opis)

Na osnovu njih ja bih napravio jednu tabelu izvestavanja npr. Promet proizvoda koja bi davala kumulativne vrednosti iz ovih gore tabela po proizvodima:

PrometProizvoda (SifraPP#, SifraPro#, Naziv, TrebovanaKolicina, NarucenaKolicina, PrimljenaKolicina)

Znaci svaki put kada se kreira neki od dokumenata NabavniNalog, Narudzbenica, Prijemnica da se to upisuje u novoformiranu tabelu. Da li sam na dobrom putu i da li je moguce realizovati ideju? I kako ispovezivati tabele? Preko SifraPro# ili? Takodje je dobrodosao svaki savet i ideja o denormalizaciji u ovom primeru. Mozda u novu tabelu uvesti polje datum.
Podvuceni su PK, dok su FK oznaceni sa #.



[ Zidar @ 23.02.2010. 17:58 ] @
Imas srece ovaj put. Tvoje tabele vec izgledaju dovolno denormalizovane, tako da nemas sta da radis.

Ovako:

A)
Citat:
StavkaPrijemnice (SifraPrijemnice #, Rb #, PrimljenaKolicina, Cena, IznosPDV, Iznos, SifraPro #)

Verovatno vazi
Iznos = PrimljenaKolicina * Cena + IznosPDV
Zanci da je Iznos racunata kolona i ne bi trebalo da bude u normalizovanoj tabeli. Znaci, ova tabela je denormalizovana dodavanjem kolone koja nije nazavisna nego se racuna.

B)
Citat:
Proizvod (SifraPro #, Naziv, JedMere, KolicinaUSkladistu, Opis)

I ova tabela je denormalizovana. Kolona KolicinaUSkladistu teorijski ne bi trebala da postoji. Kolicina u skladistu se racuna kao razlika ukupnog ulaza i izlaza. Prema tome, i ovo je zavisna kolona - zavisi od svih ostalih redova u nekim drugim tabelama.

Da su ti tabele normalizovane, ovo pod B) bi doslo u ozbzir ka nekakva 'razumna' denormalizacija. Kad god roba udje u mgacin, neki triger poveca KolicinaUSkladistu u tabeli proizvod. Kad god roba izadje iz magacina, onda neki triger smanji kolicinu u tabeli Proizvod. Zasto? zato sto se KolicinaNaSkladistu racuna kao zbir svih ualza u nekoj tabeli koja prati ulaz minus szbir svih izlaza u nekoj tabeli koja prati izlaz. I tako za sve proizvode. I programeri koji su radili u COBOLu znaju da je to spora operacija i plase se toga. U SQL bazama to nije spora operacija i ne treba raditi, ali neki to po navici rade. Niko ne razmislaj da je sporije pozivati triger na dve tabekle da bi se yuraduio UPDATE na trecoj tabeli, ali sta da radis, stare navike i stari strahovi ne umiru lako.

Ono pod A), Iznos = Kolicina*cena se ne radi jer je absolutno nepotrebno, uvek se moze dobiti u kveriju i kveri prakticno ne bi bio nista sporiji.

Posto si unapred normalizovao bazu, sada treba da vodis racuna da se ove izracunate vrednosti azuriraju svaki put kad se nesto promeni na izvoru podatka. A to znaci pisanje trigera. A to je strasno zabavno, pa zasto da ne.









[ laden @ 23.02.2010. 19:00 ] @
Hvala na brzom odgovoru, Zidar. Citajuci postove razmisljao sam da bi bilo lepo videti tvoj post na temi:)

Znao sam da su izvedeni rezultati denormalizacija ali pretpostavljao sam da mogu uraditi nesto malo sire. U nekim radovima sam naisao na primer u kom se denormalizuje baza pravljenjem ovih tabela za izvestavanje a takodje i vertikalnom i horizontalnom podelom tabele, pa sam pomislio da ne bi bilo lose pokusati tako nesto. A sto se tice att KolicinaUSkladistu mislis da bi ga trebalo brisati? Ja parkticno izlaze i nemam, jer gledamo samo proces vezan za dobavljaca, nema izdavanja materijala sa skladista. Ako uspem do veceras da uradim kompletan MOV u visio-u okacicu ga ovde, sada ga imam samo iz delova. Dobro mi doslo par saveta za poboljsanje, jer na faksu naucis jedan nacin i onda te guraju da to radis copy-paste. A trigeri su svejedno obavezni da se urade tako da se nadam da cu uzivati sa njima:)
[ Zidar @ 23.02.2010. 21:49 ] @
[QUOTE]U nekim radovima sam naisao na primer u kom se denormalizuje baza pravljenjem ovih tabela za izvestavanje a takodje i vertikalnom i horizontalnom podelom tabele, pa sam pomislio da ne bi bilo lose pokusati tako nesto.[/QUOTE]

Seti se da normalizacija vodi do manje vise jedinstvenog resenja. Denormalizacija je otvoren proces i ima beskonacno mnogo resenja. kao sistem jednacina sa pet nepoznatih i samo 3 jednacine. Za dve nepoznate mozes da pretpostavis sta god hoces. Teorijski, svaki upit koji korisniku moze da zatreba, moze se pretvoriti u flat tabelu. Medjutim, to se tada ne zove vise denormalizacija, nego gradjene neceg sto se zove Data Warehouse. A to nije tvoj zadatak.

Predlazem da nista vise ne denormalizujes. Ostavi KolicinaUSkladistu, to ce ti neko kad tad traziti u praksi, pa zasto da ne probas. Ostavi dakle da se kolicina u skladistu menja kad god se unese ili promeni neki red u tabeli StavkaPrijemnice. Trebace ti triger na StavkaPrijemnice koji pri unosu ili promeni kolone Kolicina azurira tabelu Proizvodi. Ti nemas nikakvu tabelu koja bi vodila ulaz, ali ne mari, princip je isti. Bice ti veoma zabavno da pises triger koji treba da radi sa vise od jednim rekordom u jednoj transakciji.

Ono Iznos = Kolicina*Cena definitivno izbaci jer je besmisleno. To ti niko nece traziti ni u praksi, za razliku od kolicine u skladistu.

Ako bas hoces, uradi vertikalnu podelu, recimo hoces da vodis tabelu Prijemnica i StavkePrijemnice posebno za svaku godinu. Tako ces imati Prijemnica_2010, StavkePrijemnice_2010, pa sledece godine novi par tabela Prijemnica_2011, StavkePrijemnice_2011 i tako dalje svake godine. Tabela Proizvod ostaje ista. Sada ces morati da onaj triger koji azurira tabelu Proizvod pravis nanovo, kad god kreiras novu tabelu StavkePrijemnice_2011. Plus, kad ti bud etrebao neki visegodisnji pregled, moraces da radis UNION izmedju razlicitih tabela. Da bude gore, taj kveri ce morati da se manja kad god dodas novi par tabela. I sve ovo radis jednom godisnje, taman dovoljno da zaboravis sta si radio prosle godine.

Kako rekoh, denormalizacija je otvoreno pitanje i ima beskonacno odgovora, ni jedan ne valja, ali s eu izvesnim situacijam u praksi moze prihvatiti. Sve zavisi od situacije.

[ laden @ 23.02.2010. 23:37 ] @
Izbacen ce biti taj iznos, a samim tim bih izbacio i Ukupno sa Prijemnice, jer to je sum iznosa po stavkama?

Sad, cini mi se da ce ovo sa prijemnicama da mi zada glavobolje pa bih pre radio vertikalnu podelu npr nove tabele Dobavljac (SifraDob#, NazivDob, Adresa, Telefon, Mail, Pib, TekuciRacun, Delatnost) i to na Dobavljac1(SifraDob#, NazivDob) --- sadrzi najcesce koriscen podatak o dobavljacu
Dobavljac2(SifraDob#, NazivDob, Adresa, Telefon, Mail, Pib, TekuciRacun, Delatnost)

Da li bi to znacilo da obe ove tabele moram da vezujem sa svim drugim tabelama u modelu? Npr imam tabelu Katalog(SifraKat#, Datum, SifraDob#) i posto je ovde SifraDob FK morao bih vezati tabelu i sa Dobavljac1 i sa Dobavljac2?

Vezano za tbl Proizvod, meni je ta tabela povezana sa StavkaReklamacije preko SifraPro, veza je tbl Proizvod 0,m---1,1 tbl StavkaReklamacije. Kojom od tehnika denormalizacije bi se smatralo ubacivanje att KolicinaUSkladistu? Mozda Pre-joining Tables?

[Ovu poruku je menjao laden dana 24.02.2010. u 02:56 GMT+1]
[ Zidar @ 24.02.2010. 14:14 ] @
Nemoj da izbacujes UkupnoNaSkaldistu. Jeste denormalizovano, ali se cesto trazi i radi u praksi i jeste ono sto hoces da demonstriras.

Ako razbijes tabelu Dobavljaci na dve, koje ce biti u vezi 1:1, to je OK. Za sve ostale atbeel treba da vezes samo
Dobavljac1(DobID, ImeDobavljaca).
Onu sa dresom vezujes samo za Dobavljac1.

Primeti da u Dobavljac2 imas ImeDobavljaca. To ti je denormalizacija, ponovio si kolonu koja nije PK na dva mesta. Razbijanje tabele na dve koje su u vezi 1:1 tehnicki jeste denormalizacija ali je najbezazlenija od svih (pogotovo ako osim PK nemas zajednickih kolona). To s eu praksi takodje radi i korisno jaj znati akko se to radi.

Primer za Pre-joining bi bila na primer tabela PregledDugovanjaDobavljacu (DobavlajcID,VrednostIsporuceneRobe, KolikoSmoPlatili)

Kad god dobavljac isporuci robu (stavke prijemnice) dodas ukupnu vrednost iz te prijemnice na kolonu VrednostIsporuceneRobe.
Kad god nesto platimo dobavljacu, dodas taj iznos koloni KolikoSmoPlatili. Tako onaj ko hoce da vidi kome sta dugujemo u svakom momentu, moze da otvori tabelu PregledDugovanjaDobavljacu i vidi sve odmh, bez potrebe da se izvrsava kveri koji bi vratio iste rezultate.

Citat:
Kojom od tehnika denormalizacije bi se smatralo ubacivanje att KolicinaUSkladistu

Ne znam, nisam teorijski mnogo potkovan. Denormalizacija nije zasnovana na teoriji pa u principu ne postoje 'tehnike'. Mozda je pre-joinig, ali sa agregacijom - jer ti treba i JOIN i GROUP BY SUM() u kveriju koji racuna KolicinuUSkladistu.

Generalno, koji god metod denormalizacije su ti opisali i zadali, uvek mozes da napravis kveri koji vraca zahtevane rezultate. Sad zamisli da je taj kveri tabela koju treba da popunjavas kad se nesto desi u drugim tabelama. Denormalizacija jednostavno materijalizuje kverije. A kverija moze biti beskonacno mnogo. Koji ce se izabrati, zavisi od konkretnih uslova. Ti sebi zamisli neke uslove i pusi masti na volju.

Sto vise problema budes imao da napravis denormalizovano resenje, tim bolje, naucices da izbegavas takva resenja u praksi.
[ laden @ 24.02.2010. 14:49 ] @
Veoma mi koristi ova diskusija i polako shvatam bazicne ideje. Tako su nam siromasno govorili o ovome na faksu a sada traze da se uradi. Trigere cak nisu ni predavali a ja cu sada morati u radu da odradim i specifikaciju i implementaciju istih:( Hvala jos jednom na velikoj pomoci, Zidar. Trudicu se da u daljoj diskusiji iznosim konkretne predloge. Kad zavrsim sa tri ili cetiri primera denormalizacije i specifikaciju trigera za njih javljam se i pokusacu da ih okacim u temi.
[ Zidar @ 24.02.2010. 17:14 ] @
Pomoci cu sa zadovoljstvom. Samo budi oprezan da te ne odvucem od teme ili zadatka. Sta se desava u praksi je jedna stvar, a sta ti traze da uradis je nesto sasvim drugo.

Ja sam u ovom poslu manje vise samouk i moras dobro da pazis sta ces da prihvatis od mene, da se ne uvalis u nevolju. Radi sta ti profesor kaze, a ja ti mogu pomoci ako negde nesto zapne oko tehnickih detalja. Ne samo ja, imas gomilu ljudi na forumu koji znaju isto ili vise, a zavrsili su istu ili slicnu skolu koju ti sad ucis.

Srecan rad.
[ laden @ 24.02.2010. 22:42 ] @
Evo ga prvi primer denormalizacije i specifikacija trigera. Nadam se da je dobro:)

Okacio sam i ostale primere.

[Ovu poruku je menjao laden dana 25.02.2010. u 02:02 GMT+1]
[ Zidar @ 25.02.2010. 18:04 ] @
Meni izgleda OK, ali proveri sa profesorom da li je to sto si uradio u stvari ono sto se trazi. Ne bih da padnes na ispitu pa posle ja budem kriv. Sve sto si napisao deluje OK, ali vidi sa profsorima da li je to ono sto su oni zamislili.

Srecno
[ laden @ 01.03.2010. 17:17 ] @
Po shvatanjima profesora samo je primer sa tranzitivnoscu denormalizacija, na ostalo gledaju kao na optimizaciju. Mogli su nam to bar i reci:( No dobro, imam novi termin da to popravim i da napisem trigere, tako da se nadam da cu naici na ovako dobru vasu pomoc i kad krenem to da radim.
[ chachka @ 02.03.2010. 12:11 ] @
Denormalizacija je obrnuto od normalizacija. Ništa novo, ali je ključ za rešenje :)

Normalizaciju radimo tako da šemu baze redom prebacujemo iz 1nf u 2nf pa u 3nf.

Denormalizacija je obrnuto iz 3nf pa u 2nf pa u 1nf.

Primer na delu polazne šeme koja je u 3NF:

Narudzbenica (SifraNarudzbenice #, DatumPrometaDobara, DatumValute, DatumIzdavanja, SifraDob #, SifraPonude #, JMBG#)
StavkaNarudzbenice (SifraNarudzbenice #, Rb #, NarucenaKolicina, SifraPro #)
Proizvod (SifraPro #, Naziv, JedMere, KolicinaUSkladistu, Opis)

Prebacimo je u 2NF:

Narudzbenica (SifraNarudzbenice #, DatumPrometaDobara, DatumValute, DatumIzdavanja, SifraDob #, SifraPonude #, JMBG#)
StavkaNarudzbenice (SifraNarudzbenice #, Rb #, NarucenaKolicina, SifraPro #, Naziv, JedMere, KolicinaUSkladistu, Opis)

Sad ovo prebacimo u 1NF:

Narudzbenica (SifraNarudzbenice #, DatumPrometaDobara, DatumValute, DatumIzdavanja, SifraDob #, SifraPonude #, JMBG#, Rb #, NarucenaKolicina, SifraPro #, Naziv, JedMere, KolicinaUSkladistu, Opis)

[ Zidar @ 02.03.2010. 15:51 ] @
Uvek znam da je nesto briljantno kad vidim resenje i kazem "Tako jednostavno, pa zasto se ja nisam ovoga setio?"

:-)
[ Fitopatolog @ 03.03.2010. 16:37 ] @
Korisnički programi koji komuniciraju sa nekom bazom podataka mogu se podeliti u dve grupe:

1. Programi kojima se vrši obuhvat i memorisanje podataka u bazu (interaktivno ili u BATCHu). Ovo su tzv "Analizatori podataka", kojima se ulazni podaci raščlanjuju i memorišu u tabele baze podataka.

2. Programi kojima se se vrši izveštavanje. Ovo su tzv. "Sintetizatori podataka" koji na osnovu podataka iz baze generišu izveštaje.

Normalizacijom se omogućuje da programi prvog tipa funkcionišu na najbolji način. Postupak normalizacije je nezavisan od vrste podataka i dokumenata koje treba "analizirati" (dokumenata sa kojih se unose podaci). Nažalost, normalizovana baza ne omogućuje bezuslovno dobre performanse za programe drugog tipa (za izveštavanje). Štaviše, normalizovana baza je skoro uvek uzrok slabijih performansi programa drugog tipa. Zbog toga se na kontrolisan način uvode izvedeni objekti u bazu - baza se denormalizuje. Kako će se vršiti denormalizacija baze veoma zavisi od izlaznih (sintetizovanih) dokumenata - izveštaja pa se postupak denormalizacije ne može dati generalno. U prilogu se nalazi dokumenat u kome je pokušano da se ipak napravi gruba sistematizacija postupaka denormalizacije.

Da prokomentarišem i:

Citat:
laden: Po shvatanjima profesora samo je primer sa tranzitivnoscu denormalizacija, na ostalo gledaju kao na optimizaciju. Mogli su nam to bar i reci:( No dobro, imam novi termin da to popravim i da napisem trigere, tako da se nadam da cu naici na ovako dobru vasu pomoc i kad krenem to da radim.


Ako je npr. izvedeni atribut IZNOS jednak proizvodu KOLIČINE i CENE, tada ipak tranzitivno zavisi od ključa relacije kojoj pripada pa je i baza koja ga sadrži denormalizovana.



[Ovu poruku je menjao Fitopatolog dana 03.03.2010. u 18:07 GMT+1]
[ chachka @ 03.03.2010. 20:53 ] @
Ovde treba postaviti i pitanje - U kojoj to normalnoj formi treba da bude šema baze da bi je profesor smatrao denormalizovanom? Da li je to 1nf, 2nf ili 3nf?

Ili obrnuto pitanje - Koju to normalnu formu treba da zadovoljava šema da bi je profesor proglasio normalizovanom? Onda je, naravno, sve ispod toga denormalizovano.
[ laden @ 04.03.2010. 16:52 ] @
Normalizacija je radjena do trece normalne forme. Ali to je sada ok, problem je nastao jer ja nisam znao sta oni pod denormalizacijom smatraju pa sam tako uradio neke stvari koje su po njima optimizacija, mada je svuda u literaturi na netu do koje sam ja dosao to denorm.
[ miki1205 @ 05.03.2010. 13:51 ] @
Druže,
Sigurno je u pitanju FON, predmet Baze podataka 2 i profesor Marijanović? Jesam li u pravu?

Imam isti problem kao i ti, tačnije, prošao sam kod profe isto kao i ti. Sve što sam uradio su svrstali u optimizaciju a ne u denormalizaciju!

Hoću sad sa tobom da vidim da li sam dobro razumeo šta treba da se uradi pod denormalizacijom.

NPR:

Student (Br_Ind #, Ime i prezime, Adresa, telefon.....)
Predmet(ID_PRED#, Naziv_Predmeta, Profesor)
Položio(Br_Ind #, ID_PRED#, Ocena )

Denormalizacija:

Položio(Br_Ind #, ID_PRED#, Naziv_Predmeta, Ocena )

Ubacili smo Naziv predmeta u tabelu Položio, time narušili 3NF, ali smo, kao, dobili na performansama jer sad kad izlačimo izveštaj o položenim ispitima za nekog studenta, ne moramo da povezujemo tabele Položio i Predmet već to sve čitamo iz tabela Položio. Možda je primer glup ali mislim da si shvatio poentu. Znači, ne ubacuješ neku novu izvedenu vrednost (to je optimizacija) već povlačiš neki atribut iz druge tabele kako bi dobio na performansama.

A drugi primer, odnosno narušavanje 2nf, bi bilo kad bi umesto nekog neljučnog atributa (u ovom primeru ime i prezime) povukao neki spoljni ključ i tako poboljšao povezivanje tabela. Odnosno, umesto da povežeš tri tabele da dođeš do nekog podatka, uradiš denormalizaciju, ubaciš spoljni ključ u jednu od tabela i onda povežeš samo dve tabele i tako poboljšaš performance. :)

Jesam li dobro shvatio priču oko denormalizacije ili ne?

I posle uspešne denormalizacije, treba da uradiš triggere koji bi se odnosili samo na ove denormalizacije.
NPR. Promena Br_indeka u tabeli Položio treba da aktivira trigger koji će ažurirati Ime studenta u tabeli položio.
[ laden @ 05.03.2010. 16:13 ] @
Ja mislim da je ovo sto si ti opisao resenje naseg problema. Jesu BP2 na FON-u :) Ja cu tako i uraditi, s tim sto su sada za trigere izbacili semu na sajtu koja ne sadrzi deo za proveru PK jer je to odradjeno preko ref. integriteta.
[ yeki @ 06.03.2010. 20:41 ] @
Da vam se i ja pridruzim :)
Pitanje za denormalizaciju:da bih narusila III NF ako npr. imam:
DepoKarton (IDDepoKartona#, ..., BrojRačuna#), pa ovo denormalizujem kao DepoKarton (IDDepoKartona#, ..., BrojRačuna#, BrojModela, PozivNaBroj) posto je Račun(BrojRačuna#, BrojModela, PozivNaBroj, Suma...).
Prvo pitanje: stavljam samo neke atribute, ne moram sve?

Zatim, da bih narusila II NF iz:
DepoKarton(IDDepoKartona#, DostavaIzvoda, DatumDK)
StavkeDepoKartona(IDDepoKartona#, RBStavkeDK#, Samostalno, ....)
dobijam:
DepoKarton(IDDepoKartona#, DostavaIzvoda, DatumDK, {RBStavkeDK#, Samostalno, ...})
Zanima me je li ovo ok?

Zatim, kod trigera, moze li neko da napise primer pseudo-koda... Meni je nekako glupo da pisem: "ako postoje stavke depo kartona, zabranjuje se brisanje depo kartona, u suprotnom... bla bla"
[ laden @ 06.03.2010. 22:46 ] @
III NF ti je dobra i bas tako nesto sam i ja uradio, a naravno da ne moras da stavljas sve atribute, samo one koje mislis da bi bili korisni gledano sa aspekta poslovne logike.
Ovo razbijanje II NF ja nisam radio, to mi je bas previse da strpam sve te stavke u jednu tabelu:( Ja sam odradio iz jednog od mojih prethodnih postova denormalizaciju i trigere 1 pa pogledaj. A za pseudo kod mislim da ti je bolje da se drzis ovih njihovih primera sa sajta, jer svako svoje dete voli najvise na svetu:)

E sad, ja imam problema sa implementacijom trigera, u ms sql serveru 2000 sam ih pokusao uraditi. Ako neko moze da pomogne, sta je potrebno izmeniti da bi ovaj kod proradio
Code:
CREATE TRIGGER update_jedmere_u_proizvodu ON Proizvod
FOR UPDATE
AS
declare @newName varchar(10)
if not update (JedMere)
begin
return
end
select @newName=(select JedMere from Inserted)
update StavkaPrijemnice
set JedMere=@newName
where StavkaPrijemnice.SifraPro=Proizvod.SifraPro


Triger inace treba da kad se azurira naziv JedMere u tabeli Proizvod to azuriranje odradi i u tabeli StavkaPrijemnice, za odgovarajuci proizvod(po SifraPro).

Tabele su:
StavkaPrijemnice (SifraPrijemnice#,Rb#, PrimljenaKolicina, Cena, SifraPro#, Naziv, JedMere)
Proizvod(SifraPro#, Naziv, JedMere, Opis)

RESENO, evo triger, nadam se da je to to. Radi ali ako neko ima zamerke neka ih slobodno iznese
Code:
CREATE TRIGGER update_jedmere_u_proizvodu ON Proizvod 
FOR UPDATE
AS
UPDATE StavkaPrijemnice
SET JedMere=Proizvod.JedMere
FROM Proizvod, StavkaPrijemnice
WHERE Proizvod.SifraPro=StavkaPrijemnice.SifraPro


[Ovu poruku je menjao laden dana 07.03.2010. u 00:35 GMT+1]

[Ovu poruku je menjao laden dana 07.03.2010. u 00:41 GMT+1]
[ Raaaa @ 07.03.2010. 11:17 ] @
Pozdrav drugari vidim da svi imamo isti problem kod prof. Marjanovića :)

Mene interesuje sledeća stvar ako neko može da mi pomogne naime imam sledeću situaciju

Klijent(#ŠifraKlijenta, Adresa, Telefon,#PoštanskiBroj)
FizičkoLice(#ŠifraKlijenta, JMBG, Ime, Prezime, BrojLičneKarte)
PravnoLice(#ŠifraKlijenta, PIB, MatičniBroj, Naziv, Račun)
Saobraćajna(#BrojSaobraćajne, DatumIzdavanja, Napomena, DatumIstekaVaženja, Sup, RegistarskiBroj, #ŠifraKlijenta, #ŠifraVozila)

Klijent mi ima specijalizaciju na Fizičko i Pravno lice da li je moguće sad prebaciti Ime i Prezime sa Fizičkog i PIB i Naziv sa Pravnog u Saobraćajnu u time zadovoljiti denormalizaciju?

Tako da to izgleda ovako

Saobraćajna(#BrojSaobraćajne,....., #ŠifraKlijenta, #ŠifraVozila, Ime, Prezime, PIB, Naziv)

Ovo mi je prva denormalizacjia a druga mi izgleda ovako

Zastupnik(#JMBGZastupnika, Ime, Prezime, Adresa, BrojLičneKarte, #PoštanskiBroj)
Ugovor(#BrojUgovora, DatumUgovora, CenaVozila, #BrojSaobraćajne, #ŠifraKlijentakupuje, #ŠifraKlijentaprodaje, #JMBGZastupnika)

Pa sam na ugovor prebacio ime i prezime zastupnika

Ugovor(#BrojUgovora, DatumUgovora, CenaVozila, #BrojSaobraćajne, #ŠifraKlijentakupuje, #ŠifraKlijentaprodaje, #JMBGZastupnika, Ime, Prezime)

Šta mislite da li je ovo ok?

Pozdrav
[ laden @ 07.03.2010. 22:24 ] @
Mislim da je ovo sto si napisao ok, u oba slucaja je razbijanje III NF. A zar niko nije radio trigere? :( Dajte malo pomoci i komentara oko toga.
[ yeki @ 08.03.2010. 10:03 ] @
Treba li uopste da se razbija II NF? Ili je dovoljno samo III NF?
A trigere pravimo za koliko tabela? Posto izgleda nije dovoljno samo za 2 tabele...
[ miki1205 @ 08.03.2010. 14:15 ] @
Potrebno je uraditi 2 denormalizacije i odgovarajuće trigere za te denormalizacije.
Denormalizaciju 2NF i denormalizaciju 3NF. Da li to ima smisla i kako to izvesti, to ne znam. I ja imam problem sa tim. Uradim ja te denormalizacije ali ni jedna niti je logična niti zadovoljava poslovnu logiku ovog mog mini inf. sistema. :)

Što se tiče triggera, ja imam iskustva u PL/SQL-u, nisam nikad radio na SQL serverima 2000, My sql i slično ali sve je to "isto sra.e drugo pakovanje".

Ladene, ono što sam primetio da ti nedostaje u tvom primeru jeste na koju kolonu se odnosi update. To je važno u ovom slučaju sa denormalizacijama, jer bi triger trebao da se okida samo kad se određena kolona promeni a ne ceo red. Kod tebe se triger okida kad god se izvrši update tabele proizvod bilo da mu menjaš naziv proizvoda ili jedinicu mere.

I kod koji si ti napisao više liči na proceduru a manje na update trigger. Kod trigera se najčešće koristi karakteristika :new i :old. Gde :new.JedMere pretstavlja novu vrednost jedinice mere određenog proizvoda u tabeli Proizvod a :old.JedMere staru vrednost, odn vrednost koja se menja. Nema potrebe da u SQL upitu povezuješ tabelu proizvod i stavkuPrijemnice kad već raspolažeš sa podacima iz tabele Proizvod u trenutku okidanja triggera jer se triger izvršava nad tom tabelom.

Code:

CREATE OR REPLACE TRIGGER update_jedmere_u_proizvodu
 BEFORE
 UPDATE OF JedMere
 ON Proizvod
 FOR EACH ROW
DECLARE
 
BEGIN

UPDATE StavkaPrijemnice
SET JedMere=:new.JedMere
WHERE StavkaPrijemnice.SifraPro = :new.SifraPro;

END;



Nego, zna li neko nešto vezano za ove Korisnički definisane tipove podataka. Tu mi ništa nije jasno šta treba uraditi. Nisam baš pazio na tom času :)
[ Zidar @ 08.03.2010. 15:07 ] @
RESENO, evo triger, nadam se da je to to. Radi ali ako neko ima zamerke neka ih slobodno iznese

[Code]
CREATE TRIGGER update_jedmere_u_proizvodu ON Proizvod
FOR UPDATE
AS
UPDATE StavkaPrijemnice
SET JedMere=Proizvod.JedMere
FROM Proizvod, StavkaPrijemnice
WHERE Proizvod.SifraPro=StavkaPrijemnice.SifraPro
[/code]

Dati triger ima najmanje dva problema, jedan logicki i drugi tehnicki.

Sta radi ovaj triger:
- kad god se promeni bilo sta u tabeli Proizvod => odradi se UPDATE nad tabelom StavkaPrijemnice
- UPDATE StavkaPrijemnice jednostavno prepise sve jedinice mere u SVIM stvakama prijemnice onim sto se nalazi u tabeli Proizvodi za SVE proizvode.

Znaci, promeni se recimo opis za 'Jabuke' u 'Jabike Delises' i ovo izazove UPADTE cele tabele StavkePrijemnice u koloni JedMere, koja se nije promenila uopste u tabeli Proizvod. Ovo je strasno jer se rade nepotrebne operacije, cak i denormalizacija ne zahteva da se radi UPDATE jedinica mere kad se promeni opis proizvoda. Ovo je tehnicki problem, jer se bespotrebno radi UPDATE nad potencijalno velikom tabelom.

Tezi od dva problema je logicki: Jos strasnije je sto se ovo uopste radi. Recimo da je proizvod "Jabuke" bio meren u "kg" jedno vreme. Onda udjemo u EU i sad se jabuke mere u "LB". Sad ce triger da promeni jedinicu mere u svim prijemnicama koje psotoje od ranije u "LB". Posto je LB = 0.454 Kg, jednim potezom si napravio haos u knjigovodstvu. Dobro, EU ne koristi LB, ali s emoze promeniti sa Kg u Tone recimo, i onda opet nastaje haos u knjigovodstvu.

Triger ne sme da dira stare rekorde, ni pod kojim uslovima. Postavlja se pitanje - kako da triger zna koji rekordi u tabeli proizvod su promenjeni, da bi mozda promenio samo te rekorde u nekoj drugoj tabeli.

U sustini, primer je jako lose izabran, a onda je triger lose napisan. I onaj za ORACLE niej bolji u tom pogledu. Konstrukcije tipa 'FOR EACH ROW" su generalno opasne, jer one to i rade - nesto rade za SVAKI red. Gde smoz aboravili WHERE?

[ Zidar @ 08.03.2010. 15:44 ] @
Cini mi se da je triger trebalo da resi ovu situaciju:

"Kad se rekord unese u StavkePrijemnice, prepisati Jedmere iz tabele Proizvodi"

Ovo zato sto smo procesom denormalizacije uveli nepotrebnu kolonu JedMere u tabelu StavkePrijemnice.

Triger treba da bude ne tabeli StavkePrijemnice, na ON INSERT i treba da za upravo uneti rekord (to jest grupu rekorda) kopira JedMere iz tabele Proizvod. Otprilike ovako (kod pisem iz glave, sigurno negde ima neka sintaksna greska,):

Code:

CRAETE TRIGER trgSTavkePrijemnice_CopyJedMere_from_Proizvod ON dbo.StavkePrijemnice
FOR INSERT AS

UPDATE dbo.StavkePrijemnice
SET JedMere = P.JedMere
FROM StavkePrijemnice AS S
JOIN Inseretd AS I ON I.proizvodID = S.proizvodID
;

GO


Primetite da je upotrebljena SQL Serverova interna tabele "Inserted". Inserted izgleda isto kao tabela koja se modifikuje i sadrzi rekorde koji ce biti uneti ovom transakcijom. Tabela Inseretd je enprazna u slucaju da imamo UPDATE ili INSERT. Postoji i tabele "Deleted" koja se javlja u slucaju DELETE ili UPDATE. Inserted i Deleted imaju strukturu identicnu tabeli koja se menja i koriste se u trigerima da se dejstvo trigera ogranic samo na rekorde koji su se stvarno promenili. O ovome su morali da vas uce u skoli.

Dakle, nas triger cita iz tabele rekorde koji ce upravo biti uneseni u tabelu StavkePrijemnice (FROM Stavkeprijemnice JOIN Inserted) Onda svakom rekordu dodeli verenost JedMere koja mu odgovara (JOIN ON I.proizvodID = S.ProizvodID)

Da se ovo razume, potrebno je razumeti UPDATE komandu koja radi ne sa JOINovanim tabelama.

U praksi, veom je cesto da se ovako prepisuje Cena iz tabele Proizvod u tabelu StavkeRacuna na primer...


[ laden @ 08.03.2010. 20:43 ] @
Hvala Zidar, da si samo znao koliko cesto sam ovih dana prizeljkivao tvoj post:) Ono gore mi je prvi napisan triger ikada tako da sam bio srecan samo kad sam video da radi radnju:) a pretpostavljao sam da ce biti gresaka. Trudim se da ne ocekujem ovde gotova resenja, nego da ponudim bar nesto za diskusiju, ma koliko bilo pogresno. Hvala jos jednom.
[ Zidar @ 08.03.2010. 21:18 ] @
Samo uzivaj i srecan rad

[ yeki @ 09.03.2010. 12:15 ] @
Citat:

DepoKarton (IDDepoKartona#, IDKlijenta#,DatumDK, ..., BrojRačuna#)
Račun(BrojRačuna#, BrojModela, PozivNaBroj, Suma...)
StavkeDepoKartona(IDDepoKartona#, IDKlijenta#, RBStavkeDK#, Samostalno, ....)
OvlascenoLice(IDOvlLice#, ImePrezime...)

Ja se i dalje zezam sa denormalizacijom. Moze li neko da napise primer razbijanja II nf za denormalizaciju?
Ne verujem da ce dati da se preda primer sa 2x razbijenom III nf.
Zanima me takodje da li mogu da uradim sledece: posto mi je veza StavkeDepoKartona i OvlascenoLice 1,M i 0,M, tj. u relacionom modelu je pravljena nova tabela Relacija3(IDDepoKartona#, IDKlijenta#, RBStavkeDK#,IDOvlLice#);
Da li mogu umesto pravljena te nove tabele samo da spustim FK IDOvlLice u tabelu StavkeDepoKartona i da dobijem => StavkeDepoKartona(IDDepoKartona#, IDKlijenta#, RBStavkeDK#, Samostalno, ....... IDOvlLice#) i da tako izvrsim denormalizaciju (tako cu umesto spajanja 3 tabele, imati spajanje samo 2 tabele)?

Znam da su rekli da moraju po jedan insert, update, delete trigger da se napise. Ja nisam sigurna da cu imati insert trigger...

I jos nesto za korisnicke definisane tipove - u ms sql serveru: CREATE TYPE nekiTip FROM varchar(11) NOT NULL ; i sl.
Nije valjda da na ovo misle?

[ chachka @ 09.03.2010. 16:45 ] @
Citat:
yeki: Moze li neko da napise primer razbijanja II nf za denormalizaciju?

primer
[ yeki @ 09.03.2010. 17:04 ] @
^Procitala sam ovu temu, ali mi to nije pomoglo... (videces i moj post da sam isto tako uradila, ali poprilicno sam sigurna da ce da nas vrate kad onako uradimo)
Moze li neko da okaci primer razbijanja II NF koja je prosla kod profesora?
[ laden @ 09.03.2010. 17:53 ] @
@yeki
Nemoj siriti ovu temu tako sto pitas neke stvari vezane za faks, to sve mozes postovati na fonforum. Ovde bi bilo bolje da razradimo neku opstu pricu na temu denormalizacije, trigera itd, a to sto prof. trazi nema bas mnogo veze sa realnoscu i stvarnim zahtevima u nekom poslovnom sistemu. Btw, ja necu raditi nesto sto je mnoooooogo nelogicno, a mislim da je razbijanje II NF bas takva stvar.
[ Zidar @ 09.03.2010. 18:21 ] @
Nikako mi nije jasno da se trosi toliko vremena na nesto sto ne treba raditi. Da bi nesto denormalizovao, treba da je prvo normalizovano. A u prirodi ne psotoje normalizovani podaci. Normalizacijom mukotrpno popravljamo ono sto u prirodnom obliku ne valja. Znaci, denormalizoacijom kvarimo nesto do cega se doslo mukom i znojem. Pa jos se sporimo oko toga koji je pravi nacin da pokvarimo ono sto smo napravili dobro...

Koji je pravilan nacin da se sa 2NF vratimo na 1NF? Da li je bolje napiti se od piva, vina ili meke rakije, pitanje je sad...

Ne mogu da verujem da neko maltretira studente ovakvim glupostima.

U realnom zivotu postoje dva - tri primera gde se moze dopustiti pod odredjenim (sve redjim) uslovim nedovoljna normalizacija, i to je sve:

- Banke ne racunaju stanje na tekucem racunu kverijima, stanje na racunu se azurira (UPDATE) posle svake transakcije. Tako banke rade. Tacka. Nema normalizacije u tom delu. Tako banke hoce, jer su navikle, nekad je glavni jezik bio COBOL. Tacka.

- Cena se prepisuje iz tabele Proizvodi u tabelu StavkeNaRecunu. Adresa se prepisuje iz tabele Kupci u tabelu Otpremnice, da bi se zapamtilo na koju je adresu roba otisla u slucaju da kupac promeni adresu kasnije. Ovo mozda i nije denormalizacija, jer postoji TrenutnaCena i CenaPoKojoj smo prodali robu na odredjeni dan. Isto i za adresu, tekuca adresa i adresa na koju smo isporucili robu, mogu da budu iste, ali i ne moraju. Nema duplikacije, pa nema ni denormalizacije, iako izgleda kao da ima.

- Datum stupanja na posao i datum prekida rada se cuvaju u istom redu, iako to krsi neko tamo pravilo koje kaze da svaki atribut sme da zavisi samo i samo od PK. Datum prekida rada zavisi od PK, ali zavisi i od Datuma pocetka rada, znaci prekrseno pravilo. Ne znam da je neko ovo razresio daljom normalizacijom, iako je svakako moguce.

To su neki primeri nedovoljno normalizovanih struktura. Mozda ima jos, ali mi tesko pada na pamet. Da sam ja profesor, pokusao bih da objasnim deci bar neke od ovih situacija, jer ce se sa time sresti u praksi. A ne da ih maltretiram trazenjem "pravilnog" nacina da se denormalizuje skup tabela. To je isto kao prihvatiti deljenje sa nulom. Jednom kad prihvatis da se sme deliti nulom, sve je moguce i nema kraja mogucnostima. Mogu da dokazem da je 1=2, na primer:

X2-X2 = X2-X2

to moze da se napise kao:

(X-X)(X+X) = X(X-X)

podelimo obe strane sa (X-X) i dobijemo

X+X = X => 1=2

Ako dakle prihvatim glupost za ispravan korak u postupku, dobicu glupost kao rezultat. A onda pomnozim obe strane sa 7, pa dobijem 7 = 14. Onda to nazovem 'optimizacijom', a deljenje sa (X-X) ostaje 'denormalizacija'

Tako je isto i sa denormalizacijom. Cuj, 'optimizacija'. Jedan doktor me izleci od gripa, a onda mi drugi prebije nogu, jer me prvi izlecio previse. I to je optimizacija. Da mi je izbio oko, bila bi denormalizacija.

Bez namere da uvredim ikoga, ali pitam se ko je ovde 'denormalan'?

:-)
[ Zidar @ 09.03.2010. 18:33 ] @
@yeki: Ne mogu ti pomoci jer ne vidim tvoje tabele niti znam sta radis. Chachka je dao generalno resenje - ides unazad. Ili zamisli da nije normalizovana baza, pa kreni ponovo korak po korak. Kad stignes do 2NF, ti stani i izgledace kao da si se vratila sa 3NF.

Najbolje ej da pitas profesore, oni valjda naju sta se hoce ovom vezbom i kako to izvesti.

Moj poslednji post se ne odnosi na studente, vi ste zrtve u ovoj guzvi, a mi vam ne mozemo pomoci. Samo sam se iskukao, kao kad se zale ljudi na zagadjene vazdha i unistavanje okoline.

Mozda ti budem mogao pomoci su ti kad se bude pisao triger koji ce morati da obezbedi ono sto je bilo obezbedjeno referencijalnim integritetom, a mi smo ga pokvarili (optimizovali?) denormalizacijom.

Mene su u skoli ucili da 'optimal' znaci 'najbolji'. Optimizacija dakle ne znaci 'poboljsanje performansi' nego znaci 'pronalazenje najboljeg resenja'. Nikako mi ta rec 'optimizacija' ne pasuje ovde
[ yeki @ 09.03.2010. 18:50 ] @
Ok, hvala ti. Znam ja normalizaciju, samo me buni do koje tacke se treba denormalizvoati, a da se ne pretera...
[ Fitopatolog @ 09.03.2010. 20:26 ] @
Evo još jednom:

Normalizacijom se dobija set tabela u kojima ne postoji redundansa podataka (nema čuvenih problema sa duplim ili višestrukim ažuriranjem podataka itd...). Njome smo rešili problem UNOSA i skladištenja podataka. Postupak normalizacije NE ZAVISI od prirode ulaznih podataka.

Ako je normalizovana baza dobra i sa stanovišta izveštavanja (izveštavanje troši prihvatljivu količinu vremena i drugih resursa) posao je gotov, ne treba nam denormalizacija.

Ako su performanse izveštajnih programa loše, tada se uvode IZVEDENI objekti (radi se denormalizacija baze) ali samo za one situacije za koje želimo popraviti performanse. Zato ne postoji opšti recept KAKO se radi denormalizacije. Ona se radi samo za deo kome se žele popraviti performanse.
Pedagoški bi bilo da profesor zada zadatak u kome će studenti moći da vide kako se nekom denormalizacijom nešto popravilo. Ovako ostaje suvoparan primer "denormalizacije radi denormalizacije".
[ Zidar @ 10.03.2010. 16:34 ] @
Citat:
...samo me buni do koje tacke se treba denormalizvoati, a da se ne pretera...

To samo profesor moze da ti odgovori. Nama je lako da ovde pricamo kako profesori maltretiraju studente, medjutim profesori nisu bas blesavi. SIgurno postoji razlog zasto ovo traze od vas i najverovatnije da profesor(i) zna(ju) i dokle treba da idete sa denormalizacijom. Najprostije resenje - posalji e-mail profesoru, ili trk pred kabinet pa cekaj red za konsultacije. A i asistenti na vezbama mora da imaju neku ideju i mogu pomoci.

Ovo su nezgodna pitanja, u sivoj zoni, pa saveti koje delimo po forumu mogu vise da odmognu nego da pomognu. Ovde niko ne moze da odgovori dokle treba ici sa denormalizacijom 'a da se ne pretera', pa nem svrhe to ni pitati.

[ sandrava @ 16.01.2013. 08:39 ] @
Pozdrav,
Da ne otvaram novu temu pisacu ovde jer naslov mi skroz odgovara :-),posto nije odavno pisano nadam se da ce neko ugledati moj post :-)
opet mi treba podrska da li sam na dobrom putu? :-)
Uradila sam denormalizaciju 2NF izgleda kao u prilozenim stavkama,interesuje me da li ovo ima logike i jesam li dobro predstavila.Hvala unapred!