.

Mapperid: milliseid on ja miks neid ei kasutata?

16.11.2009  |  Gunnar

Saiku blogi kandes Modernne tarkvara loomine IV: Andmete kühveldamine puudutab Marek mapperite teemat. Kande lõpus soovib lugupeetud autor sõjasaagasid ja ma otsustasin ülevaate sõjasaagadest kirjutada siia eraldi postitusena – kommentaari kohta oleks see ehk liiga pikaks kujunenud.

Ma panen siia paari sõnaga kirja omad kogemused erinevate mapperitega ja lisan koos kommentaaridega mõned arvamused ja müüdid, mis mapperite teemal aastatega kõrvu on jäänud. Käesolev kanne püüab olla minupoolne täiendus sellele, mis Marek jäädvustas.

Lühike ülevaade mapperitest

Mapperid, mida ma ise olen torkinud, võib lühidalt kokku võtta järgmiselt:

  • Linq To SQL – tubli ja pisike, ei toeta kõiki päriluste mappimisi, aga kasutamist vähem nõudlikes rakendustes tasub kindlasti kaaluda. Genereeritava SQL-i monitoorimise saab lahendada väga mugavalt.
  • Entity Framework – tänane versioon on praktiliselt kasutamatu:
    • POCO tugi puudub,
    • äriklassid peavad laiendama EF enda klasse, mis suhtlevad andmebaasiga,
    • pole kuigi kindel, kuidas taoliste objektide liigutamine õnnestub läbi kanalite, kus objektid ühes otsas serialiseeritakse ja teises otsas taastatakse,
    • designer, mille abil mudelit hallatakse, on küllaltki kohmakas ja ebastabiilne ja valed liigutused võivad tähendada mudeli loomist alates nullist või siis päris tõsist käsitööd XML-definitsioonides.
  • Entity Framework 4.0 – see saab tõenäoliselt asendajaks eelmisele kahele. POCO tugi on olemas, samuti kõik vajalikud päriluste mappimised. Genereeritava SQL-i ühtne monitoorimine hetkel puudub, kuid äkki lisatakse (annan omalt poolt igal juhul selleks panuse, et see juhtuks, kuid lõppsõna ütleb ikkagi EF arendusega tegelev tiim Microsoftis). Ahjaa, dünaamilised proxyd genereerib EF4.0 ka kenasti valmis ja nende tugi peaks suht-koht hea tulema valmis versioonis.
  • NHibernate – oli parim, on parim ja arvatavasti ka jääb parimaks. Arvestades sellega, et Visual Studio 2010 tuleb välja märtsis, siis pole Entity Framework 4.0 tasemel enam eriti aega jäänud suuremateks revolutsioonideks ja on vähe tõenäoline, et see kuidagi NHibernate positsiooni ohustaks.

Miks mappereid ei kasutata?

Mina olen kokku puutunud terve rivi erinevate põhjustega. Mõni neist ratsionaalne ja valdav osa mitte.

  • NHibernate on väga keerukas. See avaldus paneb üldiselt selge pitseri arendaja kompetentsile ja on selge märk sellest, et inimesel puudub oluline huvi omal alal edasi areneda. Arvestades netis saadaval olevate materjalide hulgaga, ei tohiks NHibernate käima saamine võtta aega esimesel korral üle tunni-paari (arvestan sellega, et tegemist on täieliku võhikuga, kes kogu seda maailma esimest korda näeb).
  • Meie rakendus on selleks liiga lihtne. Nõus täiesti, et mapper ei ole vahend iga konteksti jaoks. Lihtsamates rakendustes läheb näiteks oluliselt kiiremini ADO.NET pakutava kasutamisega. Samuti olen ma viimasel ajal jätnud objektide mappimise teema projektides natukese kaugemasse tulevikku kui täiesti algus, sest kuniks tellija õpib ja süsteem esmast lihvi saab, ei näe ma põhjust ka mingit liigset ballasti kaasas kanda (eraldi teema, millel pikemalt ei peatu, kuid millest saaks eraldi kande kokku kirjutada).
  • Mapperid ei kasuta ressurse optimaalselt. NHibernate kohalt võin öelda, et automaatselt genereeritud SQL on enamasti ikka oluliselt parem, efektiivsem ja optimaalsem sellest, mida üks keskmine programmeerija kokku keevitab. Selle müüdi tagamaa on enamasti see, et inimesed ei viitsi omale asju selgeks teha ja ei viitsi ka väga süveneda sellesse, kuidas mapper töötab.
  • Mapper on poolik lahendus, sest andmete liikumise katab ta vaid osaliselt. Nüüd hakkab minu sees häire tööle ja punane tuli läheb põlema. Antud väite taga peitub rakenduse arhitektuur, mille ümber tuleks kirjutada jutumärgid – parem lahendus oleks CTRL-A + DEL. Kui rakenduse kihid pannakse kõik ühte patta, siis sünnivad kodukootud raamistikud, mis muudavad kogu süsteemi aja jooksul parajaks monoliitseks käkiks, sest ükski kiht ei ole võimeline töötama ilma teisteta. See kõik on halb arhitektuur, mille juures mapperid ei ole milleski süüdi – ei saa teha otsuseid haiges kontekstis millegi sellise üle, mis pole haiges kontekstis kasutamiseks mõeldud.
  • Mapper ei ole piisavalt dünaamiline. Jah, mapper on mõeldud kasutamiseks OLTP rakenduste juures ning raporteerimise jaoks ei ole need enamasti kohe kindlasti mõeldud. Raporteerimise jaoks ma soovitab kasutada ikka vana hea ADO.NET võimalusi või siis viia raporteerimine üle SQL Serveri vastava toe peale. Raporteerimine ei ole mapperitele sobiv kasutuskontekst).
  • Mappingute haldamine on päris suur ajaline kulu. Muidugi on suur ajaline kulu, kui sellega liiga alguses alustada. Loksuta objektmudel paika mõne lihtsa, kuid efektiivse aluspõhja otsas, mis sobib prototüüpimiseks hästi ja mille peal oled võimeline ise kiiresti liikuma. Kui see ots on tehtud, siis võta mapper kasutusele, kirjuta selle jaoks integratsioonitestid (ilma nendeta kasvab vähem kogenud jõnglaste korral tehnilise praagi arv taevani) ja kõik läheb hästi.

Kindlasti saaks siia lisada veel mitmeid põhjuseid, miks mappereid kindlasti mitte kasutada. Mina kaldun arvama, et suur osa neist põhjustest on pseudoprobleemid, mille sünnitab inimeste viitsimatus uute asjadega tutvumiseks ja kindlasti ka muhedad tehnilised linnalegendid, mille sünni eest pole ükski tehnoloogia kaitstud.

Kokkuvõtteks

Saadaval on mitmeid mappereid ja kui netist otsida, siis leiab neid veel terve rivi. Idee poolest peaks iga huviline suutma endale sobiva leida. Igasugused mapperite ümber keerlevad müüdid on enamasti jama, mille põhjuseks on inimfaktori häbematu laiskus. Kes seni on kartnud ja kuulanud õudusjutte – tehke proovi – äkki läheb te elu hoopis senisest lihtsamaks.

9 kommentaari sissekandele “Mapperid: milliseid on ja miks neid ei kasutata?”

  1. Bunter

    Ma olen täheldanud sarnaseid väiteid. Kui inimene on kulutanud tegelikult nädalaid ja kuid oma SQL-i oskuste lihvimiseks sinnajuurde käivate API-dega, siis tundub millegipärast see mõned tunnid kuni päev nhibernatega tohutu koorem. Programmeerijad on loogilised, eks?

    Üks täiendav “ei” faktor on andmemudel, mis pole absoluutselt mäpperisõbralik. Tavaliselt tähendab see 3-ndast normaalkujust räigeid kõrvalekaldumisi, halbu võtmestrateegiaid ning kolekeerulisi seosetabeleid (haakub normaalkuju eiramisega).

  2. Gunnar

    Andmemudelist alustamine tähendab seda, et kogu rakenduse kood kirjutatakse ümber andmebaasist lähtuva loogika ja mängureeglite. Andmebaas ja objektmudel pole enamasti 1:1 kooskõlla kuigi lihtsasti viidavad kui esimene mingit spetsiifikat või nii-saab-mugavamalt-stiilis häkke sisaldab. Kõrvalekaldumine kolmandamast normaalkujust on vaid üks näide.

    Osad karmid mehed kirjutavad rakenduse koodi ja tabelite vahele veel terve spetsiaalse kihi protseduure, mis omakorda maailma paremaks teevad ja väga targad on. Tihti on tegemist wrapperitega kuhu hakkab aja jooksul kuhjuma igasugust töötava koodi mõttes kõrvaltegevust ja kõrvalist loogikat. Tulemuseks jälle see, et koodi tasemel tuleb teha terve rivi mõistusele vastukäivaid häkke, et andmemudel “korrektselt” arvesse saaks võetud.

  3. Leinz

    Mina kasutasin eelnevatel töökohtadel mappereid. Tunnistan ausalt üles, et nende hingeellu polnud aega ega mahti põhjalikult süveneda ning “ise tehtud, hästi tehtud” loogika järgi tegin uues kohas üksi arendades enda andmebaasikihi.
    Ma tõesti ei tea, mis loogika järgi need mappereid suure hunniku uusi objekte salvestavad, aga minul juhtus selline probleem:
    Minu andmebaasikiht salvestas igat objekti eraldi (transaktsioonis ikka olid). Kõik oli tore, kuni tekkis probleem, et andmebaasist füüsiliselt kaugel asuvas arvutis toimus tuhandete uute objektide salvestamine väga aeglaselt (tuhanded eraldi paketid arvuti ja andmebaasivahel läbi keerulise füüsilise võrgu).
    Lahenduseks tegin järgnevat:
    Kulus vist pool päeva ja objektide tuhandete objektide salvestamiseks kulus ainult kümmekond päringut - kõik objektid pandi andmebaasi pärinevuse järgi kolme massiivi (iga tabeli kohta massiiv) (update, delete ja insert massiivid), insert jagati gruppidesse (maksimaalse lubatud andmebaasi päringu parameetrite arvu tõttu) ja andmebaasi poole saadetigi kümmekond hiiglaslikku käsku.

    Minu küsimus ongi, et kuidas mapperid selliseid andmebaasioperatsioone teevad ning kas nendes annab sellist salvestamise viisi määrata? Mina igatahes olin rahul, et sain 5 minutilise salvestamise 10 sekundiliseks tehtud.

    Tean-tean - peaksin kasutama teenuste kihti - tegelen sellega.

  4. Gunnar

    Mapperid üldiselt peaks suutelised olema selleks, et muudatused ühe käsuga teele panna. Ma ei ole väga kindel, et nad 100% optimaalse tulemuse sinu kontekstis genereerivad, kuid flushimine on neil enamasti olemas. Jällegi asi, mida pead lihtsalt proovima ja uurima, et teada saada.

    See, et andmebaas ja klientkeskkonda jooksutav arvuti teineteisest kaugel asuvad, on minu arusaama järgi hetkel-on-lihtsalt-nii juhtum (kõik teavad, et see asi peaks olema kuidagi teisiti, aga tänane lahendus on selline). Sellest, et traffic väiksem oleks, siis võib kaaluda näiteks selliseid asju:

    1. Andmete puhverdamine kliendi poolel (võimalik siis, kui andmeid teises otsas iga minut ei muutu). See võib vähendada päringute mahtu oluliselt ja objektide konstrueerimine läheb ka kiiremini, sest andmed on kohapeal olemas.
    2. Kui on muudatusi, mida tehakse üle suure hulga andmete ja need muudatused on ühised objektidele ja neid muudatusi saab teha andmebaasis, siis võib need muudatused viia ka stored procedure taha peitu. Sellisel juhul on üks pöördumine andmebaasi, mis need muudatused ära teeb.

    Kindlasti tasub kaaluda ka teenustele üleminekut, sest võrgu kirjelduse järgi tundub hajusarhitektuuri kohalt teenuste kasutamine naturaalsem. Kui salvestamise tulemused sind kliendipoolel koheselt ei huvita, siis saad kliendi keskkonna kiiremaks tegemiseks kasutada ka teenuste meetodite asünkroonset kutsumist. Teenuste korral saad paika panna andmevahetuskanalid ja vajadusel määrata neile kompressimise ka, et paketid vähem ruumi võtaks.

    Mis puutub enda kirjutatud andmekihte, siis need on jõudluse osas (kui me räägime juba tõsisest kasutajate arvust või tõsiselt mahukatest operatsioonides) paremad kui see, mis mapperid pakuvad. Vähemasti on need kiiremad mapperitest, mis reflectioni peal elavad. Sellise tulemuse võib saavutada ka nende mapperitega, mis “teisel pool” kompilaatorit midagi ei loo ja ei tekita - leidub selliseid, mis genereerivad kõik vajaliku koodi valmis enne kui projekt kokku kompileeritakse. Enamasti annab neid laiendada ja nende loodut muuta ja optimeerida vajadustele vastavalt. See on ka variant, mida annab kaaluda, kui mapperite kasutamine mõistlik tundub.

  5. Bunter

    Mõnikord tuleb paraku baasist lähtuda, sest rakendust tegema hakates on baas juba olemas ja toodangus. Kuidas kellelgi need rakenduse tegemised kipuvad olema. Samas näiteks pole mul neid stored proccide wrappereid õnnestunud viimased 3-4 aastat õnneks näha. Aga kui neid veel oli, siis eriti mahedaks muutsid asja tavaliselt “parim” meetod äriloogika laiendamiseks, triggerid. Iga operatsioon oli selline pingpongipalli pesumasinasse viskamine.

  6. Gunnar

    Mulle on see triggeritesse igasugu tarkuse paigaldamine jätnud koguaeg selle mulje, et mõni SQL-i tasemel n00b püüab midagi uudset, kaasaegset, tarka ja meisterlikku luua. Kindlasti on asju, mida ongi mõistlik triggeritesse paigutada, kuid et igasugu rakenduse loogika seal istuks… ei-ei-ei.

  7. Kuido

    Kõik need mäpperid muutuvad kasutuks, kui sul on süsteemil mingi keerukam loogika, mis nõuab mitme andmetabeli andmete omavahelist loogilist seostamist ehk objektorienteeritud relatsiooniline andmebaas on surnud rakendus. Niipea, kui andmetöötlus kaldub “Batch Processingust” kõrvale on SQL SERVER surmalaps.

  8. Gunnar

    Enamasti on mapperitel olemas on ka custom päringute tugi, millele saab ise tagastatavad tüübid vajadusel ette öelda. NHibernate’il on lisaks oma päringute keel, mis on SQL-i sarnane ja toimib üle erinevate andmebaaside (võib muidugi leida asju, mis ühes baasis on ja teises mitte). Sellega annab ka suhteliselt palju ära teha.

    Idee poolest saad teha ka read-only objektid, millele vastavad andmed saad kas view või stored procedure abil ette anda.

  9. Bunter

    Kõik rakendused, millega ma töötan on “keerulisema loogikaga” ehk siis vajavad mitme tabeli seostamist. Ei ole märganud mäpperi kasutuks muutumist.

Kommenteeri

sulge
Saada link e-postiga

© DT 2006-2008 | Creative Commons Attribution-Noncommercial 3.0 License | WordPress