in

mscommunity.net

Interactive mscommunity.net online activities

data.hr

rujan 2007 - Posts

  • Myths&legends

    Mitovi i legende (o SQL Serveru, ne o kralju Arturu) su izgleda popularna tema ovih dana. Na privatnoj MVP news grupi je nedavno bio jedan prilično opsežan thread o njima. Maciej Pilecki je upravo danas popodne radio Myths&legends workshop ovdje u Cavtatu. Marko Čulo radi predavanje u subotu na codecampu na tu temu.

    Što se misli kad se kaže "mitovi i legende"? Uglavnom se ima na umu neke manje-više netočne tvrdnje koje kruže community-jem, a koje su zbog same svoje dugovječnosti i upornosti dobile status neslužbenih "istina". Neke od njih su zabavne, neke prilično opasne, ali niti jedna od njih nije istinita.

    Nemam namjeru nabrajati ovdje te mitove. Pojavite se u subotu na codecampu, odslušajte Markovo predavanje, i čut ćete. Ali, danas mi je palo na pamet nešto što još do sada nigdje nisam čuo ni pročitao - a legenda je, po definiciji.

    Naime, kad govorimo o transakcijama, obično imamo na umu onu kraticu ACID - atomicity, consistency, isolation, durability. Consistency se obično definira kao svojstvo transakcije da iza sebe (commit ili rollback, svejedno) ostavi bazu u logički konzistentnom stanju. I to se onda obično ilustrira primjerom da kao neka banka prebacuje neki iznos novaca s jednog računa na drugi, i to se realizira kroz dva odvojena INSERTa: jedan kojim skidamo novac s računa A i drugi kojim stavljamo taj isti iznos na račun B. A transakcija ovdje znači da će oba INSERTa, ako ih "zatvorimo" u transakciju i odradimo barem nekakav osnovni error checking, proći kao jedan, ili pasti kao jedan, dakle "all or nothing".

    To je jasno, i u čemu je problem? Problem je u tome tko definira što je tu logička konzistentnost podataka. U ovom slučaju, to definira aplikacija. Aplikacija isto tako može (pogrešno) reći da želi s računa A skinuti 1000, a na račun B staviti 2000. Ili recimo izvršiti samo jedan INSERT. Da li je i tom slučaju baza podataka ostavljena u logički konzistentnom stanju? Možda, iako bi se moglo reći da nije :) Da li baza zna da li je u konzistentnom stanju ili nije? Nema pojma. Zašto nema pojma? Zato što ovo poslovno pravilo, koje kaže da iznos novca koji se skida s jednog računa mora biti identičen iznosu koji se stavlja na drugi račun, nije izraženo deklarativno, nego je (ako je) realizirano samo programski.

    Dakle, transakcija sama po sebi ne jamči ništa, barem u ovakvom slučaju kad je poslovno pravilo realizirano na ne-deklarativan način. Transakcija je ovdje samo mehanizam koji je na raspolaganju programeru da osigura da se nekoliko (ne)ovisnih upita izvršava kao jedna logička jedinica, i ne puno više od toga.

    Pozdrav, čujemo se.

    Dean

    Posted ruj 25 2007, 06:17 by dvitner with 3 comment(s)
    Filed under:
  • Kriza identiteta

    Je, znam da sam rekao kako ću ovdje pričati o Katmai-ju i uzbudljivim još-uvijek-novim stvarima u Yukon-u.. Budem. Idući put :) Danas, nešto što mi se mota po glavi zadnjih par dana. Stara i otrcana tema, možda, ali nažalost izgleda još uvijek aktualna.

    Prije nekog vremena, na Mobility Day (koji je BTW po meni sasvim uspio kao konfa, svaka čast organizatorima i predavačima!) sjedio sam na predavanju na kojem je predavač, pored još nekih "bisera" koje sad neću spominjati, ničim izazvan ustvrdio kako je ustvari dobra ideja postaviti GUID kao primary key ako se tablica ima namjeru koristiti u replikaciji. Hm..

    Pukom slučajnošću, dan-dva iza toga, na hr.comp.programiranje.baze -- prilično divlje zna biti tamo ponekad, ali moj samaritanski duh se hrani pomažući ljudima gdje god -- u jednom odgovoru sam onako u prolazu savjetovao OP-u da ne koristi IDENTITY za primary key. I u tren oka par ljudi je skočilo s pitanjem "pa zašto sad to?". Hmm..

    Da stvar bude još gora, jedan učesnik u threadu je, valjda iz želje da pojasni stvari, postao link na članak Kimberly Tripp o clustered indeksima. Hmmm..

    OK, čemu dakle taj hm-hmm-hmmm od mene? Zaista, zašto ne koristiti autogenerated vrijednosti (kao što su IDENTITY i GUID) za primary key na tablici? Odakle pomutnja? Pokušat ću jednostavnim jezikom, i uglavnom o IDENTITY-ju, njega se puno više zloupotrebljava.

    Prvi i osnovni razlog je taj što ključevi (primarni, sekundarni, kandidati, kojigod) stvar logičkog dizajna baze podataka, i tiču se samo integriteta podataka. Osnovna zadaća ključeva je da se pomoću njih može jednoznačno identificirati neki red. IDENTITY i GUID su implementacijski detalj u SQL Serveru -- oni ne postoje u realnom svijetu, nisu dio poslovne domene, nemaju ama baš nikakve veze s podacima, njihova vrijednost nije poznata do trenutka nakon što su podaci već upisani, korisniku ne znače ništa i ne može ih koristiti u upitima, GUID pored toga i nije nešto što želite ukucati preko tipkovnice, etc. Očito je da oni ne ispunjavaju onu maloprijespomenutu osnovnu zadaću - da identificiraju red u tablici.

    Tu se javlja i par sasvim praktičnih problema. Prvi je taj da, kako sam već rekao, vrijednost IDENTITY kolone nije poznata prije nego što smo podatke upisali u bazu. Uzmimo za primjer onaj čuveni sa SalesOrderHeader i SalesOrderDetail tablicama iz AdventureWorks sample baze (usputbudirečeno, ta baza je više primjer kako NE dizajnirati bazu, nego obrnuto.. no dobro). Imamo SalesOrderID kolonu s dignutim IDENTITY property-jem kao PK na SalesOrderHeader tablici, i postavljen FK constraint sa SalesOrderDetail na SalesOrderHeader preko SalesOrderID kolone. Što radimo kad želimo upisati novi order, i header i details? Nešto ovakvo:

    INSERT Sales.SalesOrderHeader (<columns>) VALES (<values>);
    SET @SalesOrderID = SCOPE_IDENTITY();
    INSERT Sales.SalesOrderDetail (SalesOrderID, <other_columns>) VALUES (@ID, <other_values>);
    INSERT Sales.SalesOrderDetail (SalesOrderID, <other_columns>) VALUES (@ID, <other_values>);


    Sve pet ako je samo jedan order u pitanju. A što ako želimo odjednom upisati nekoliko ordera? Npr:

    INSERT Sales.SalesOrderHeader (<columns>) SELECT (<columns>) FROM OverseasSales.SalesOrderHeader WHERE <filter>;
    INSERT Sales.SalesOrderDetail (SalesOrderID, <other_columns>) SELECT ???


    Ako i uspijete saznati novogenerirane vrijednosti za SalesOrderID (hint: OUTPUT), kako ćete ih logički povezati s onim izvornima? OK, mi smo kreativni ljudi i smislit ćemo već nešto..

    Nadalje, IDENTITY ne mora nužno biti unique (IDENTITY_INSERT, recimo). Bad.

    Za identične podatke -- ako ih upisujemo u dva navrata -- možemo dobiti (ne samo da možemo, nego ćemo i dobiti) dvije različite vrijednosti u IDENTITY koloni. Isto je i ako upisujemo identične podatke u dvije različite baze. Pa onda poslije imamo problema s konsolidacijom (i trošimo novce na skupa MDM rješenja).

    Vrijednost IDENTITY-ja se generira neovisno o transakciji. Npr:

    SET NOCOUNT ON;
    GO

    USE tempdb;
    GO

    CREATE TABLE tbl (c1 int IDENTITY(1,1), c2 varchar(10));
    GO

    INSERT tbl VALUES ('qwerty');

    BEGIN TRAN;

    INSERT tbl VALUES ('asdfgh');

    SELECT * FROM tbl;

    ROLLBACK;

    INSERT tbl VALUES ('asdfgh');

    SELECT * FROM tbl;

    DROP TABLE tbl;

     

    c1          c2
    ----------- ----------
    1           qwerty
    2           asdfgh

    c1          c2
    ----------- ----------
    1           qwerty
    3           asdfgh


    Za drugi red ('asdfgh') smo prvo dobili vrijednost c1 kolone 2, a nakon ROLLBACK-a pri ponovnom upisu smo dobili 3. Plus toga, imamo i gap (hrvatski: rupu) u redoslijedu, što može i ne mora biti bitno.

    A GUID.. Ajd, sad barem imamo NEWSEQUENTIALID(). I da, istina, morate imati uniqueidentifier kolonu da biste replicirali tablicu. Svejedno, ni to nije razlog da je proglasite za primary key :)

    A što nam je htio reći onaj kolega s početka priče, kad nas je naputio da pročitamo članak o clustered indeksima s bloga Kimberly Tripp? To je jedan od onih "mitova i legendi" o kojima će, pretpostavljam, pričati Marko na bootcampu ovaj mjesec. Radi se naime o tome da su primary key i unique constrainti u SQL Serveru podržani preko (unique) indeksa. Što je sasvim OK. Ono što nije OK je to da će, ako eksplicitno ne kažete drugačije, SQL Server primary key podržati s clustered indeksom. A to nije OK iz najmanje dva razloga. Prvo, to stvara konfuziju kod ljudi, i prečesto se te dvije stvari poistovjećuju, iako se ustvari radi o dvije različite stvari -- jedno je integrity constraint, a drugo implementacija, tj kako je taj constraint realiziran -- pa se onda često priča o jednom, a misli se na drugo. Zatim, clustered indeks je jedna prilično važna alatka iz arsenala perf tuninga. Postavljanjem clustered indeksa na ovoj ili onoj koloni možemo nekad ubrzati određenu vrstu upita, recimo range query-je (ordered scan). Ne, ovime nisam želio reći da ćemo ako želimo ubrzati range upite obavezno postaviti CI na kolonu po kojoj je definiran range. Ovisi. Na koju kolonu ćemo postaviti clustered indeks, ili ga nećemo postaviti uopće, ovisi o podacima i njihovom korištenju, ali želimo li doista odreći se te mogućnosti?


    Nakon svega ovoga -- ipak, IDENTITY uopće nije tako loš, ali važno je znati što nije i koja su ograničenja. Nekad je dapače i koristan -- može se postaviti unique constraint na njega i raditi DRI, pa čak i clustered indeks se može postaviti na njega. Ako imate razloga za to. Sve ovisi :)

    Puno više o svemu ovome ćemo pričati na bootcampu u Varaždinu. Kog zanima, dobrodošao je. Early bird i dodatni popust za community još uvijek se mogu iskoristiti.

    Pozdrav, čujemo se.

    Dean

    Posted ruj 18 2007, 06:23 by dvitner with 3 comment(s)
    Filed under: ,
  • Please allow me..

    Što nam donosi SQL Server 2008 (FKA Katmai)? To je jedna od tema kojima ćemo se baviti ovdje u narednim postovima.  Budite sigurni, nećemo samo nabrajati i ilustrirati nove feature-s -- kao i uvijek od mene, ovdje mozete očekivati i kritičke osvrte i osobna mišljenja.

    Za početak, ustvari i prije početka, jedan generalni stav -- Katmai ne donosi ništa tako revolucionarno novo kao što je donijela 2005-ica. Nema velikih arhitektonskih promjena, kao što su u Yukonu primjerice bili CLRSQL, XML podrška, ili (najvažnija stvar IMHO) copy-on-write i row versioning. Ono što Katmai donosi, to bi se prije moglo reći da su stvari koje nisu uspjele ući u Yukon timeframe (DATE i TIME tipovi, npr, ali "done right this time"), ili se svode na poliranje postojećih funkcionalnosti (kao recimo unaprijeđenja na DB mirroring-u). Naravno, ima i par zgodnih sasvim novih stvari. Ali, o tome ćemo kasnije.

    Yukon je još uvijek, čak i za mnoge MVP-jeve, "nova" verzija sikvela, nešto što se na mnogim mjestima tek uvodi u poslovanje ili se uvođenje tek priprema. Mnoge stvari koje imamo u Yukonu zato su još nedovoljno poznate ili nedovoljno korištene. Te "nove" stvari, njihovo korištenje u praksi, do's and don'ts, best practices i perf implikacije, bit će druga velika tema narednih postova.

    Pored ovog dvoga, koristit ću ovaj prostor i za najavu nekih kako svojih osobnih tako i community akcija.

    Za početak, volio bih vas sve pozvati na Vladanov codecamp 19-og (http://codecamp.mscommunity.net/). Ne znam koliko sad i ovdje smijem reći o samom eventu, jer agenda još nije službeno objavljena, ali već sada je jasno da će to biti najjači skup kvalitetnih i zanimljivih predavača iz (ne samo HR!) MS community-ja okupljenih na jednom mjestu -- ikada.

    Odmah nakon toga, prvi tjedan u listopadu, Marko i ja radimo "second edition" SQL Server botcampa u MSPTC u Varaždinu (http://www.mscommunity.net/Default.aspx?tabid=1103). Ako ne znate što je "bootcamp", samo tri riječi: krv, suze i znoj. Prijavite se, dodjite, nećete požaliti.

    A sredinom listopada, Marko i ja idemo u radni posjet Dejanu i Mihi u Ljubljanu, na sastanak SLO UG. Sunčana strana Alpa :)

    Pozdrav, čujemo se.

     Dean

     

    Posted ruj 08 2007, 07:22 by dvitner with 1 comment(s)
    Filed under: ,
Powered by Community Server (Commercial Edition), by Telligent Systems