Agregatno spajanje stringova za PostgreSQL

Sunday, 26.08.2007 – Srdjan

SQL standard propisuje 5 agregatnih funkcija: AVG, COUNT, MAX, MIN i SUM. Uz izuzetak COUNT funkcije, ostale agregatne funkcije rade nad numeričkim vrednostima.

Šta da radimo ako nam je potrebno prosto spajanje (konkatenacija) stringova? Iskoristićemo PostgreSQL-ovu mogućnost CREATE AGGREGATE za kreiranje nove agregatne funkcije.

Uopšte nije teško na internetu naći ovakvu funkciju. Prikazaću jednu koja je napisana upotrebom SQL jezika:

CREATE FUNCTION agg_concat (text, text) 
RETURNS text AS 
$body$ 
SELECT 
  CASE WHEN $1 IS NULL 
       THEN $2 
       ELSE $1 || ', ' || $2 
  END 
$body$ 
LANGUAGE 'sql';    

CREATE AGGREGATE agg_concat ( 
  BASETYPE = TEXT, 
  SFUNC = agg_concat, 
  STYPE = TEXT 
);

Kako se koristi ova nova agregatna funkcija?

Recimo da imamo jednu tabelu i njene podatke:

CREATE TABLE informacije ( 
  datum_informacije DATE NOT NULL, 
  informacija VARCHAR(10) NOT NULL, 
  CONSTRAINT pk_inf 
    PRIMARY KEY (datum_informacije, informacija) 
);    

INSERT INTO informacije 
       (datum_informacije, informacija) 
VALUES ('2007-08-23', 'posao'); 
INSERT INTO informacije 
       (datum_informacije, informacija) 
VALUES ('2007-08-23', 'odmor'); 
INSERT INTO informacije 
       (datum_informacije, informacija) 
VALUES ('2007-08-24', 'posao'); 
INSERT INTO informacije 
       (datum_informacije, informacija) 
VALUES ('2007-08-24', 'kafic'); 
INSERT INTO informacije 
       (datum_informacije, informacija) 
VALUES ('2007-08-24', 'bioskop'); 
COMMIT;

Ako hoćemo da izvršimo grupisanje informacija po danu, izvršimo sledeći upit:

SELECT datum_informacije, 
       agg_concat(informacija) AS informacije 
  FROM informacije 
 GROUP BY datum_informacije 
 ORDER BY datum_informacije;

Dobijamo sledeći rezultat:

datum_informacije   informacije 
=================   =========== 
2007-08-23          posao, odmor 
2007-08-24          posao, kafic, bioskop

Download Oracle 11g (trenutno samo za Linux)

Tuesday, 21.08.2007 – Dejan

Evo, vratio sam se sa odmora, pa da nastavimo u revijalnom tonu…

Nakon najave nove verzije 11g, Oracle je sluzbeno objavio i dostupnost nove verzije (za pocetak samo na Linux platformi): Oracle Announces General Availability of Oracle Database 11g

Neke od novih opcija ce se posebno naplacivati, tako da je potrebno dobro razmisliti o stvarnoj potrebi za tim opcijama i da li se isplati preci na 11g. Mi u firmi ne planiramo prelaz na 11g prije nego sto izadje 11g Release 2.

U svakom slucaju, potvrdjuje se stara izreka – “Koliko para, toliko muzike”. 



Struktura evidencije partnera

Thursday, 16.08.2007 – Srdjan

S vremena na vreme mi je posao da izvršim transfer podataka iz jednog sistema za čuvanje podataka u drugi sistem. Obično se izvorni sistemi sastoje od DBF datoteka. Česti problemi koji nastaju prilikom ovakvih transfera podataka su:
– različite strukture izvornih i ciljnih podataka i
– “prljavi” izvorni podaci (duplirani podaci (a usput različiti), podaci koji nedostaju, podaci koji se nalaze tamo gde im nije mesto,…).

Pre neki dan sam opet imao “čast” da vršim transfer takvih podataka. Od svega što sam zatekao u izvorni DBF datotekama, ovom prilikom ću prodiskutovati evidenciju o poslovnim partnerima.

Evidencija o partnerima se nalazila u jednoj DBF datoteci, sledeće strukture:

Field   Type Size 
------- ---- ---- 
PRED     C    2 
SIFRA    C    6 
NAZIV1   C   30 
NAZIV2   C   30 
ADRESA   C   30 
POSTBR   C    5 
MESTO    C   24 
GRAD     C   30 
ZRACUN   C   25 
ZRACUN2  C   25 
ZRACUN3  C   25 
ZRACUN4  C   25 
ZRACUN5  C   25 
ZRACUN6  C   25 
OPISD    C   40 
TELEFD   C   12 
TEFAXD   C   12 
OPISK    C   40 
TELEFK   C   12 
TEFAXK   C   12 
OPIS     C   40 
TELEF    C   12 
TEFAX    C   12 
GRUP1    C    2 
GRUP2    C    2 
MATBR    C    8 
REGBR    C   11 
SIFDEL   C    6 
TREBA    L    1 
PIB      C    9 
OBVPDV   L    1

Sama struktura mi je otkrila nekoliko stvari:
– naziv partnera je podeljen na dve kolone,
– predviđeno je da se može zapisati do 6 tekućih računa (pojam žiro račun se ne upotrebljava već 2 i po godine) za jednog partnera,
– predviđeno je da se može zapisati do 6 brojeva telefona za jednog partnera.

Pogled na sadržaj tabele je otkrio mnogo više:
– Za neke partnere je bilo upisano i više od 6 brojeva telefona! Za upis dodatnih brojeva su korišćene kolone ‘opisd’, ‘opisk’ ili ‘opis’.
– Gore spomenute kolone su služile i za upisivanje e-mail adresa (ipak smo u 21-vom veku 🙂 ) ili adrese istovarnog mesta.
– Vrednosti u koloni grad su izvedene od vrednosti kolone ‘postbr’ i ‘mesto’.
Prilično sam se namučio dok nisam podatke prebacio u ciljnu bazu. Posebno su problematične bile kolone opisa, koje su kako sam već rekao korišćene u razne svrhe. Iz ovoga i proizilazi zaključak da korišćena struktura podataka nije odgovarala potrebama za vođenje podataka o partnerima i kontaktima.

Hteo sam malo da se poigram sa postojećom strukturom i postavio sam pitanje: Kakva bi to struktura bila kvalitetnija od postojeće?

Kvalitetnija struktura mora da obezbedi:
1. unos više od 6 tekućih računa (koliko god to ludo zvučalo),
2. unos više od 6 brojeva telefona,
3. unos adresa poslovnica
4. unos e-mail adresa.

Pored gornje liste poboljšanja (koja bi se i još mogla proširiti), kvalitetnija struktura mora obezbediti kvalitetnija imena kolonama (da niko ne mora da razmišlja šta znači ‘grup1’, a šta ‘grup2’).

Ostvarenje prvog cilja

Izdvojio sam sve što se tiče tekućeg računa u novu tabelu kao što je prikazano na donjem dijagramu.

Slika 1

Ostvarenje drugog cilja

Izdvojio sam podatke o kontaktima (osobama, odeljenjima, službama) u posebnu tabelu kao što je prikazano na donjem dijagramu.

Slika 2
Svaki kontakt može imati više brojeva telefona (mobilni, kućni, direktan u firmi, lokal preko centrale). Takođe broj faks nije ništa drugo do još jedne vrste broja telefona. Izdvojio sam brojeve telefona iz tabele kontakata i oformio sam novu tabelu, kao na donjem dijagramu.

Slika 3

Ostvarenje trećeg cilja

Izdvojio sam podatke o adresi (ulica, broj, pošta i mesto) u posebnu tabelu i dodao sam svakoj adresi opis, kao što je prikazano u donjem dijagramu.

Slika 4

Ostvarenje četvrtog cilja

Za ovu potrebu sam jednostavno dodao novu tabelu u koju se zapisuju e-mailovi kontakata. Slično telefonu i adresi, i e-mail ima svoj (jedinstveni) opis.

Slika 5
Evo me na kraju zacrtanih ciljeva. Ova struktura je daleko fleksibilnija od polazne strukture.

Ova struktura ne odgovara samo programerima GUI-a, jer ju je daleko teže prikazati od prvobitne strukture, koja je i bila napravljena sa idejom što lakšeg pisanja programa. Programeri često zaborave da podaci jedne firme često nadžive njihove programe.

Mentalna napomena: Ako se u nekoj koloni očekuje unos imena (osobe, službe) koje se sastoji isključivo od slova, treba zabraniti unos cifara, pluseva, crtica i ostalih ne slovnih znakova. Ako se to ne uradi, naći će se neki korisnik koji će u tu kolonu uneti cifre ili nešto neočekivano.


Spajanje neprekidnih datumskih intervala

Tuesday, 07.08.2007 – Srdjan

Pre neki dan je Dado (kolega s posla) naišao na interesantan problem. Originalni problem se tiče generisanja M4 obrazca za zaposlene i treženja neprekidnog intervala u kome je osoba bila zaposlena.

Postavka problema

Problem se može abstrahovati na sledeći način:

Neka imamo skup datumskih intervala . Interval ’I’ je određen početnim i krajnjim datumima I = [pocetak, kraj).

Intervali se ne preklapaju. Smatramo da se dva intervala I1=[pocetak1, kraj1) i I2=[pocetak2, kraj2) neposredno nastavljaju ako je kraj1 = pocetak2.

Treba spojiti sve intervale koji se neposredno nastavljaju. Dakle ako imamo dva intervala I1 i I2 i ako je kraj1 = pocetak2 onda nam je traženi rezultat interval I3=[pocetak1, kraj2).

Intervali su nam dati u tabeli

CREATE TABLE intervali ( 
  pocetak DATE NOT NULL, 
  kraj DATE NOT NULL, 
  CHECK (pocetak <> kraj) 
);

I imamo nekoliko test podataka:

INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-01-01', '2007-01-15'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-01-15', '2007-01-21'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-01-21', '2007-01-31'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-02-02', '2007-02-15'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-02-17', '2007-02-22'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-02-22', '2007-02-25'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-03-01', '2007-03-10'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-03-10', '2007-03-15'); 
INSERT INTO intervali (pocetak, kraj) 
  VALUES ('2007-03-20', '2007-03-31');

Od ovih podataka očekujemo rezultat:

pocetak kraj 
---------- ---------- 
2007-01-01 2007-01-31 
2007-02-02 2007-02-15 
2007-02-17 2007-02-25 
2007-03-01 2007-03-15 
2007-03-20 2007-03-31

Prvi pokušaji

I Dado i ja smo imali istu ideju: grupišemo neprekidne periode, a onda za svaku grupu uzmemo MIN(pocetak) i MAX(kraj). Ostao nam je još samo problem da nađemo kriterijum grupisanja.

Nezavisno jedan od drugoga, Dado i ja smo došli do dva rešenja.

Dadino rešenje

-- Dadin upit 
SELECT MIN(pocetak), MAX(kraj) 
  FROM (SELECT pocetak, kraj, 
               (SELECT MIN(pocetak) 
                  FROM intervali 
                 WHERE pocetak > 
                       (SELECT MAX(kraj) 
                          FROM intervali AS pr_d 
                         WHERE curr.kraj > pr_d.kraj 
                           AND NOT EXISTS 
                               (SELECT pocetak 
                                  FROM intervali 
                                 WHERE pocetak = pr_d.kraj 
                               ) 
                       ) 
               ) AS min_kraj 
          FROM intervali AS curr 
       ) AS tmp 
 GROUP BY min_kraj 
 ORDER BY 1;

Moje rešenje

Setio sam se da je pre nekoliko meseci na forumu baza podataka EliteSecurity-ja bila interesantna SQL mozgalica u kojoj se radilo o vremenskim intervalima. Modifikovao sam rešenje te mozgalice i došao sam do rešenja našeg problema:

CREATE VIEW bitni_datumi (datum, brojac) 
AS 
SELECT bd2.datum, SUM(bd1.brojac) AS brojac 
  FROM (SELECT pocetak AS datum, 1 AS brojac 
          FROM intervali 
         UNION ALL 
        SELECT kraj + 1, -1 
          FROM intervali 
       ) AS bd1 
       INNER JOIN 
       (SELECT pocetak AS datum 
          FROM intervali 
         UNION ALL 
        SELECT kraj + 1 
          FROM intervali 
       ) AS bd2 
         ON bd2.datum >= bd1.datum 
 GROUP BY bd2.datum 
HAVING 2 > SUM(bd1.brojac);          

SELECT bd1.datum, (SELECT MIN(bd2.datum) 
                     FROM bitni_datumi AS bd2 
                    WHERE bd2.datum > bd1.datum) 
  FROM bitni_datumi AS bd1 
 WHERE bd1.brojac = 1 
 ORDER BY 1;

Oba upita su ispravna, ali kako se snalaze sa većim skupom podataka? Testirao sam upite na skupu od 500 intervala. Dadin upit se izvršio za 15 sekundi, a moj za 26. Upiti su sporo, ali se to može rešiti sa indeksima.

CREATE INDEX in_int_pocetak ON intervali (pocetak); 
CREATE INDEX in_int_kraj ON intervali (kraj);

Ponovo sam startovao upite… i nastalo je veliko razočarenje: Dadin upit nije mogao da se izvrši (planer se pobunio), a moj nije imao koristi od indeksa.

Instant rešenje

Uopšte nisam bio zadovoljan brzinom izvršavanja upita. U potrazi za rešenjem problema, setio sam se knjige SQL Cookbook od Anthony Molinaro-a, prelistao je i u poglavlju 10 našao rešenje za naš problem 🙂 Pustio sam upit na 500 intervala i dobio rešenje ispod u vremenu ispod 2 sekunde!

Naravno, ovaj upit je imao koristi od postavljenih indeka.

Nov pokušaj

Zar je moguće da ne mogu doći do dovoljno brzog ’domaćeg’ rešenja? Neću odustati dok ne napravim jedno.

Da razmislim. Šta je bitno u celoj priči? Počeci i krajevi intervala… Počeci i krajevi. Ok, nađem sve početke i sve krajeve intervala, numerišem ih po starosti (ili mladosti?) i onda uparim početak sa krajem koji ima istu numeraciju.

CREATE VIEW poceci (pocetak) 
AS 
SELECT i1.pocetak 
  FROM intervali AS i1 
 WHERE NOT EXISTS 
       (SELECT i2.pocetak 
          FROM intervali AS i2 
         WHERE i1.pocetak = i2.kraj);          

CREATE VIEW krajevi (kraj) 
AS 
SELECT i1.kraj 
  FROM intervali AS i1 
 WHERE NOT EXISTS 
      (SELECT i2.kraj 
         FROM intervali AS i2 
        WHERE i2.pocetak = i1.kraj);          

-- moj upit br. 2 
SELECT MIN(p.pocetak), MAX(k.kraj) 
  FROM -- numerisanje pocetaka 
       (SELECT p1.pocetak, 
               COUNT(p2.pocetak) AS redosled 
          FROM poceci AS p1 
               INNER JOIN 
               poceci AS p2 
                 ON p1.pocetak >= p2.pocetak 
         GROUP BY p1.pocetak) AS p 
       INNER JOIN 
       -- numerisanje krajeva 
       (SELECT k1.kraj, 
               COUNT(k2.kraj) AS redosled 
          FROM krajevi AS k1 
               INNER JOIN 
               krajevi AS k2 
                 ON k1.kraj >= k2.kraj 
         GROUP BY k1.kraj) AS k 
       -- uparivanje pocetaka i krajeva 
         ON p.redosled = k.redosled 
 ORDER BY p.redosled;

Testirao sam moj drugi upit na 500 intervala i dobio sam rezultat za 50 milisekundi! E to je brzina izvršavanja s kojom sam zadovoljan. Upit je definitivno koristio postavljene indekse.

Bilo je vreme da se izvrši testiranje nad skupom od recimo 15000 intervala (ovo je broj podataka koji je veći od broja podataka kojih će biti u produkcionoj bazi). Moj prvi upit je van konkurencije i nisam ga ni testirao. Pustio sam upit iz knjige i čekao… čekao… čekao… i nakon 10 minuta i 30 sekundi se upit uspešno završio.

Pustio sam svoj upit broj dva. Upit se završio za 6 i po sekundi!

Krajnje rešenje

Bio sam prilično zadovoljan brzinom izvršavanja svog upita i bilo mi je jasno koji upit će se koristit u produkciji, ali… kopkala me je još jedna stvar. Najsporija operacija u izvršavanju upita je numerisanje početaka i numerisanje krajeva. Da li se to može nekako izbeći?

Opet mi se u glavu vratio Dadin upit. On je u svom upitu koristio logiku ’najveći među datumima manjim od’. Primenio sam tu logiku na moj upit broj 2 i kao rezultat sam dobio upit

-- moj upit br. 3 
SELECT (SELECT MAX(p.pocetak) 
          FROM poceci AS p 
         WHERE k.kraj > p.pocetak) AS pocetak, 
       k.kraj 
  FROM krajevi AS k 
 ORDER BY k.kraj;

Testirao sam gorni upit na skupu od 15000 intervala i upit se izvršio za 350 milisekundi! Pored toga što je najbrži, upit je i najjasniji od svih prikazanih upita.

Prešao sam priličan put od prvog upita koji bi sesigurno izvršavao danima da sam ga pokrenuo na skupu od 15000 intervala, do poslednjeg upita koji istu stvar radi za manje od sekunde. Poslednji upit je na stotine hiljada puta brži od prvog upita!

Završne napomene

O Dadinom upitu

Sva testiranja su obavljena na PostgreSQL 8.1.0 serveru kojeg koristimo u produkciji. Pustio sam Dadin upit na PostgreSQL 8.2.4 serveru i upit je uspešno izvršen. Na testu od 15000 intervala se upit pokazao izuzetno uspešan sa vremenom izvršavanja od 800 milisekundi.

O upitu iz knjige SQL Cookbook

Upit iz knjige se nije pokazao efikasan na PostgreSQL-u. U knjizi postoji i specijalno rešenje za Oracle koje koristi analitičke funkcije. Ovo rešenje se na OracleXE 10.2g pokazalo uspešno za brzinom od 250 milisekundi na skupu od 15000 intervala.

Zaključak

1. Znatna ubrzanja u izvršavanju upita su nastala prelaskom sa razmatranja celog skupa podataka, na razmatranje samo interesantnog podskupa (počeci i krajevi). Treba što pre eliminisati nebitne stvari.

2. Ne treba nekritično verovati svemu što se pročita u knjizi (članku, internetu). Uvek treba tražiti način za unapređenje.


Prva normalna forma

Sunday, 29.07.2007 – Srdjan

Definicija: Relacija je u prvoj normalnoj formi (1NF) ako svi njeni atributi imaju samo atomske (nedeljive) vrednosti.

Od kada sam se prvi put susreo s ovom definicijom, delovala mi je neprecizna zbog pominjanju jednog nepreciznog pojma – atomske vrednosti. (Neki autori 1NF definišu nepostojanjem ponavljajućih grupa, što mi je jednako neprecizno.)

Šta je to atomska vrednost? Atomska vrednost je vrednost koja se nemože dalje deliti na prostije činioce. U mom tumačenju – atomska vrednost je vrednost koju nema smisla dalje deliti na prostije činioce.

Da li je datum ’29.07.2007.’ atomska vrednost? Po definiciji, nije! Ovaj datum (kao i bilo koji drugi) mogu da izdelim na dan, mesec i godinu. Koliko puta mi je zatrebala samo godina iz nekog datuma.

Da li je prost string ’Srđan’ koji sadrži moje ime atomska vrednost? Nije. Iz njega mogu da izdvojim prvo slovo ’S’ kao jedno slovo mojih inicijala. Ne samo da se ovo može uraditi, nego ovo ima i smisla.

Ovakvo razmišljanje mi nije pomoglo u shvatanju atomske vrednosti. Atomsku vrednost i njenu vezu sa atributima sam usvojio po intuiciji, onako kako mi zdrava logika nalaže: Jedan atribut u jednoj torci ne može da ima dve (ili više) vrednosti.

Daljim proučavanjem problematike 1NF sam našao, i prihvatio, da ni jedna tabela SQL baziranih sistema za upravljanje bazama podataka ne može da naruši 1NF. Ovo je jednostavno za razumevanje, jer ni jedan presek reda i kolone u SQL tabeli ne može da sadrži dve vrednosti.

Priču sam započeo sa relacionom teorijom podataka, a u predhodnom paragrafu sam neneamerno prešao na SQL (iako su ove dve stvari slične, nikako ih ne treba poistovećivati, ali o tome nekom drugom prilikom). U SQL-u su sve tabele minimalno u 1NF, ali šta se dešava sa 1NF u relacionoj teoriji?

Pre neki dan sam počeo da čitam knjigu ‘Date on Database: Writings 2000-2006’ od C.J. Date-a. Danas sam završio sa čitanjem osmog poglavlja knjige pod nazivom ‘What First Normal Form Really Means’ (‘Šta je pravo značenje prve normalne forme’).

U tom poglavlju se C.J. Date poziva na radove Hugh Darwen-a na polju problematike odnosa prve normalne forme i relacione teorije. C.J. Date priznaje da je dugo godina (30 godina!) bio zbunjen po pitanju prve normalne forme.

Ukratko, C. J. Date kaže da sam pojam atomske vrednosti nema absolutno (nepromenljivo) značenje, već da njegovo značenje zavisi od onoga što želimo da uradimo sa podacima (nekad nam treba ceo datum, a nekad samo godina iz tog datuma). Iz tog razloga pojam atomske vrednosti treba izbaciti iz upotrebe, a samim tim i pojam 1NF, koji gubi smisao bez pojama atomske vrednosti.

C.J. Date (uz Hugh Darwen-a) na kraju tvrdi da svaka relacija po svojoj definiciji zadovoljava 1NF.

Pročitavši osmo poglavlje gore spomenute knjige, napokon sam zatvorio poglavlje svog dugogodišnjeg razmišljanja o značenju prve normalne forme.


Oracle 11g launched

Thursday, 12.07.2007 – Dejan

Juče je marketinški predstavljena nova verzija Oracle baze – Oracle Database 11g.

Sama prezentacija je skoro katastrofalno odrađena –  ne znam samo kako dopustiše onom dedici na početku da se onako blamira…

Red suhoparne priče, red slajdova, red napumpavanja marketinškim podacima (u stilu “Oracle je bolji od SAP“, “Oracle 11g jede malu djecu“, “Oracle je toliko jeftin, da ćete uštedjeti milione – limes TCO-a teži ka nuli” i sličan bullshit), pa tako u krug – možda su i uspjeli impresionirati nekog bizMismena, ali na mene ova prezentacija uopšte nije djelovala.

Ajd što je prezenterski dio haotično odrađen, al’ što sam se namučio gledajući prezentaciju, pa to je bruka. 10-ak puta mi se prenos prezentacije prekidao, tako da sam par dijelova prezentacije nenamjerno propustio.

No, na stranu sa tim marketinškim napumpavanjem.

Ono što me oduševilo su najavljene mogućnosti Oracle 11g baze, ali koliko god da sam optimističan, malo sam i suzdržan, jer je Oracle u zadnje vrijeme počeo toliko da fušeri, da je to nepojmljivo, a iz iskustva znam da prije Oracle 11g Release 2 ne treba ni pomišljati na upgrade.

Oracle 11g još nije dostupan za download, ali po najavama biće ubrzo.


Offtopic: EliteSecurity me razocarao definitivno

Friday, 06.07.2007 – Dejan

Davne 2001. sam se registrovao na EliteSecurity, presao put od newbie-a do SuperModeratora, trudio se uvijek pisati konkretne i konstruktivne poruke, nekad se znao i zakaciti sa pojedincima drzeci do svog principa, stosta naucio od drugih, stosta naucio druge, no nazalost (ili nasrecu) doslo je vrijeme da kazem – “Zbogom EliteSecurity”.

Napustio sam status SuperModeratora (koliko god on nekima znacio), jer se nisam slagao sa stavovima pojedinaca pri vrhu ES piramide. Uradio sam to tiho, bez mnogo pompe. Samo sam rekao da mi skinu status i da se ne dize velika frka oko toga.

Nastavio sam i dalje aktivno da ucestvujem u diskusijama, uglavnom pomazuci manje iskusnim posjetiocima. Cak imam dojam da sam aktivnije pomagao posjetiocima, nego dok sam bio SuperModerator.

U zadnje vrijeme sam vidjao mnogo zalbi na moderatore, SM-ove i administratore, ali nisam primijetio da je u vecini slucajeva uvazena zalba/kritika/prijedlog/sugestija od strane korisnika.

I tako prije nekoliko dana pocne se meni EliteSecurity sajt sporije ucitavati. Umjesto sekund-dva, sajt se ucitavao oko 10-ak sekundi. Postavim ja temu sa pitanjem zasto se sajt sporije ucitava, ali ne dobih odgovor, nego je tema obrisana (hi markom) – i to BEZ OBRAZLOZENJA. Pitao me Gojko putem PP da mu dam vise informacija, kako bi eventualno rijesili taj problem. Ja mu dam.

Ni nakon nekoliko dana, nista se nije promijenilo, pa sam ja opet postavio pitanje u potrazi za objasnjenjem, zasto se sajt sporije ucitava (moja pretpostavka je bila zbog reklama u headeru). Kaze Nebojsa Milanovic:”Nemoj da dramis, vec sam ti rekao da je to do browsera. Problem ti pravi IE, a ne ES.”.
Ne bijah lijen, otvorim Firefox, krenem ucitavati ES, kadli ono – isti efekat. Sajt se ucitava 7-8 sekundi. Uzmem screenshot i okacim u toj temi kao kontraargument Nebojsi (koji se izgleda osjetio pogodjenim u vezi reklama; hint: BM Foto Oprema).
Ne prodje nekoliko minuta, kad tema nestade bez traga. Cak nisam ni obavjestenje o brisanju dobio, sto znaci da je poruka obrisana direktno u bazi. Eto markoma s porukom:”Imas ad bloker za taj problem. Diskusija o reklamama je zabranjena na javnom.”

Mislim… Kuda takvo ponasanje vodi?

Ne smeta meni ako Gojko ili ko vec ima koristi od tih reklama, ali dajte ljudi osposobite sajt da funkcionise kako treba i pokusajte barem rijesiti ukazane probleme.

Sad tek shvatam revolt drugih kolega (bluesman, dinke, towk i dr.), kada naidju na nerazumijevanje i ignorisanje vrhuske po pitaju korisnika.

Zasto ovo pisem ovdje? Zato sto bi mi na ES sigurno obrisali temu, a na drugim forumama takodje ne zelim, da ih ne uplicem u ovo.

Zbogom EliteSecurity.


Oracle 10g (OCP) Certification Preparation

Friday, 29.06.2007 – Dejan

Danas naletih na zanimljivu prezentaciju sa korisnim informacijama za sve one, koje zanimaju Oracle sertifikati. Osim opisa pojedinih sertifikata, ima dosta primjera sa objasnjenjima, a tu su cak i primjeri SelfTestSoftware pitanja.

Preporucujem za citanje.

Link: Oracle 10g (OCP) Certification Preparation



Oracle Security Workshop

Friday, 22.06.2007 – Dejan

Nedavno (13.06.2007. godine) sam bio na jednom Oracle seminaru o sigurnosti, na kojem su prezentovane neke opštepoznate činjenice o sigurnosnim prijetnjama i zatim rješenja, koja nudi Oracle na polju sigurnosti baza podataka.

Neki od statističkih podataka su:
87% upada u bazu se odvija tako što “bad guys” prvo “hackuju” operativni sistem (Windows npr.), pa tek onda bazu
80% svih napada na bazu dolazi od samih zaposlenika firme, tzv. “insajdera
– samo 1% profesionalnih upada u bazu bude otkriven
10% svih hackova bivaju javno objavljeni

Takođe ću navesti neke od rješenja, koja Oracle nudi kao odgovor na potencijalne sigurnosne prijetnje:
Oracle Database Vault
Oracle Audit Vault
Oracle Virtual Private Database (VPD)
Oracle Label Security
Transparent Data Encryption
Oracle Advanced Security
Single-Sign-On
Identity & Access Management

Tokom seminara su na praktičnim primjerima prvo pokazani Oracle Database Vault i Oracle Audit Vault, kada recimo korisnik SYS (da, taj super-extra-turbo-ultra-mega-giga-mighty-DBA-baja je ostao bez jaja) nema pristup zabranjenim podacima (u ovom primjeru se radilo o brojevima kreditnih kartica). Potom je prikazana enkripcija podataka, tako da samo onaj ko ima ključ za dekripciju, može doći do pravih podataka.

Prezentovano je još mnogo toga, a između ostalog SSO (Single-Sign-On), DBMS_CRYPTO, DBMS_OBFUSCATION_TOOLKIT, sigurnosne role u aplikaciji (DVSYS.DBMS_MACSEC_ROLES.SET_ROLE), FGA (Fine Grained Auditing) i td.

Moje subjektivno-objektivno mišljenje je da su od gorenavedenih mnoge stvari korisne i da će naći primjenu kod mnogih korisnika, a Oracle ima prednost pogotovo što nijedan drugi RDBMS ne nudi ove mogućnosti u sklopu samog RDBMS-a.
Međutim, velika mana su plaćanje dodatnih licenci za korištenje tih komponenti, kao i potreba za više RAM-a i više procesora, što je “neslužbeno” potvrdio i jedan od predavača na seminaru. Na sve to dolaze i uvećani troškovi za ljudske resurse (obučavanje, dodatne radne obaveze), pa će biti klasično – koliko para, toliko muzike.

Oracle security workshop - madjionicarNakon silnog tehničkog teoretisanja, organizatori su nas počastili iznenađenjem – mađioničarem.
Prvo smo se svi pogledali onako u smislu “Šta će ovdje mađioničar!?“, ali nas je lik oduševio već nakon par minuta. Izvanredni trikovi sa kartama, novčićima i konopcom (tj. komadom užeta) popraćeni duhovitom pričom, razdragali su i najokorjelije geekove. 🙂 Čak je dobio jači aplauz, nego svi Oracle predavači zajedno.

Za kraj, evo jedna slika na kojoj pijem kafu i jedem izvanredan “brownie” tokom pauze.
Oracle security workshop - Dejan


Oracle: BUG 6141507 & ORA-07445 & query_rewrite_enabled=TRUE

Wednesday, 20.06.2007 – Dejan

Mrzim kada trazim razlog neke greske i kada izgubim prilicno vremena i zivaca, a onda se na kraju ispostavi, da je to Oracle bug.

Naime, prije nekoliko mjeseci smo dobijali gresku ORA-07445: exception encountered: CORE Dump[ACCESS_VIOLATION]  [kkssct+102] [PC:0x93DF2E] [ADDR:0x14] [UNABLE_TO_READ] [], zbog koje sam na savjet Oracle Support strucnjaka morao dodati jedan nedokumentovani init parametar (_fix_control=’3118776:OFF’) i dva init parametra izmijeniti (query_rewrite_enabled=FALSE i cursor_sharing=EXACT).

Nakon toga je neko vrijeme sve radilo kako treba, iako su performanse baze drasticno opale, pa sam morao puno truda uloziti u optimizaciju SQL upita i postojecih materialized views. Posto broj korisnika sve vise raste i posto ima sve vise aplikacija u bazi, opterecenje je proporcionalno tome raslo.

Moj pokusaj da gorespomenuta dva init parametra vratim na prvobitno stanje, kako bih dobio na performansama, sveo se na hrpu gorespomenutih ORA-07445 gresaka i zalbu mnogobrojnih korisnika.

Zbog toga sam putem Metalinka odlucio ponovo pokrenuti pitanje (Service Request) u vezi ove greske. Nakon visednevnog “dopisivanja” i testiranja, ljudi iz Oracle Supporta su zakljucili da je to bug (Bug 6141507 – QUERY_REWRITE_ENABLED=TRUE ORA-07445: [ACCESS_VIOLATION] KSSCT+102]) i da mi ne preostaje nista drugo, nego cekati da se taj bug ispravi.