Artikler om O/R Mappere som NHibernate o.l., databaseteknologier or relaterte tema finner du på denne siden..

.net ninja på DBA-kurs

Monday, January 24th, 2011
Ingen kommentarer

Denne uken skal jeg og en kollega på kurs i SQL Server. Kurset heter Maintaining a Microsoft SQL Server 2008 Database.

Hææ? Skal du bli DBA nå eller?

Jeg kan komme på i alle fall tre gode grunner til at du skulle synes dette er litt merkelig, og jeg føler derfor jeg har et lite forklaringsbehov.

For det første er jeg en hardbarka koder, og er vel egentlig ikke så  opptatt av hva som skjer etter produksjonssetting?! Jeg ville satt mer pris på å lære om kompilatorbygging, domenedrevet design eller et nytt programmeringsspråk.

Dessuten har jeg jobbet med SQL Server i årevis, og burde vel kunne det som trengs nå?!

Og sist men ikke minst har jeg jo assosiert meg sterkt med NoSQL-bevegelsen, og fikk til og med tittelen db4o Valued Professional i 2010 – så disse relasjonsgreiene er vel ganske så avleggs uansett, eller hva?

Jeg har gått litt i meg selv og funnet at jeg har enkelte kunnskapshull jeg ønsker å tette. DBA-kurset skal tette ett av dem. Jeg ønsker å kunne uttale meg med autoritet om temaer som backupstrategier og katastrofeberedskap, og vite hvordan man sett opp SQL Server til å yte optimalt under gitte forutsetninger.

For selv om jeg har brukt SQL Server mye, så vet jeg at det er mye jeg ikke vet. Og selv om mange løsninger hadde blitt bedre med en ikke-relasjonsoritentert databaseløsning, så er realiteten den at vi som oftest fortsatt forholder oss til en eller annen relasjonsdatabase. Jeg har derfor bestemt for å innrømme en av mine svakheter, utfordre meg selv, og en gang for alle bli god på SQL Server.

Litt ADO.NET i IronRuby

Thursday, July 8th, 2010
Ingen kommentarer

For automatisering av driftsrutiner og andre ad-hoc oppgaver er det gull å ha et bra, dynamisk skriptspråk tilgjengelig. Og med IronRuby får du også tilgang til å bruke hele .Net-rammeverket, så da har du i både pose og sekk for å si det sånn. Akkurat nå sitter jeg og lager noen ADO.Net-spørringer mot SQL Server i IronRuby, og tenkte det kunne være greit å vise hvor enkelt det er.

Så uten noe mer fjas og vas, her er et eksempel hvor jeg henter ut noe data og printer det til konsollet:

1 load_assembly System.Data
2 include System::Data::SqlClient
3
4 # Utility method to open a DB connection, read and print
5 # some data based on a SQL command and a hash of field
6 # display names and related ordinals in the recordset.
7 def execute_read connection_string, sql, fields
8   connection = SqlConnection.new connection_string
9   command = SqlCommand.new sql, connection
10   connection.open
11
12   reader = command.execute_reader
13   while reader.read
14     puts fields.inject({}) do |acc, field|
15       #{acc} #{field.first}: #{reader[field.last]} 
16     end
17   end
18   connection.close
19 end
20
21 execute_read(
22   User ID=foo;Password=bar;Data Source=THEBOSS\\SQL2005;Initial Catalog=theDB;,
23   SELECT * from Rule,
24   Id => 0, Name => 1, Active => 3, Transp => 4)

Så lett er det å inkludere et namespace fra .Net-rammeverket og ta det i bruk.

Det eneste som kan være litt vanskelig å tyde her er måten jeg skriver ut rader til konsollet på – jeg har blitt så utrolig glad i inject (aggregate/reduce/fold/whatever) i det siste, og bruker det hele tiden, men det resulterer ikke alltid i den mest lesbare koden i verden for dem som ikke er vandt til slikt ;)

Les også: Slette/tømme MSMQ-køer med IronRuby.

Administrasjonsgrensesnitt for db4o

Sunday, March 22nd, 2009
Ingen kommentarer

Blant spørsmålene jeg fikk da jeg presenterte db4o på NNUG i februar var om det fantes et verktøy for å inspisere databasene. Jeg kunne ikke vise til noe konkret da, men det viser seg at folkene bak db4o har et slikt produkt, og at det ble sluppet som en del av open source lisensen i januar i år:

“Object Manager Enterprise is a plug-in for your development environment (Visual Studio 2005/2008 for .NET users and Eclipse for Java users). OME allows you to browse your db4o database in a graphical interface. With OME you can always check which objects were stored and how the database structure looks like. Additional benefit – you can check the correctness of your queries by comparing the query result with the view in OME.”

Sjekk ut annonseringen her: OME now free for all developers!

Knagger: ,

Contiki bruker Reporting Services

Friday, March 13th, 2009
Ingen kommentarer

Contiki ECMJeg jobber i et software-selskap (eller ISV om du vil) som heter CMA Contiki. Vi lager en enterprise contract management løsning som brukes av kunder over hele verden – av selskaper som Total, Halliburton, ConocoPhillips og Telenor.

Contiki ECM versjon 6, som er det jeg har jobbet med i snart 3 år, har hele tiden vært et veldig fleksibelt produkt som i stor grad kan tilpasses ulike kunder – bl.a. gjennom en egenprodusert workflow-løsning. Rapportering har også vært en sentral del, og vi hadde bygget inn XtraReports fra DevExpress i klienten vår for å kunne gi kundene en fleksibel rapporteringsløsning.

Nå har vi derimot gått bort fra denne løsningen, og i versjon 6.6 vil våre kunder få et produkt som er fullt integrert med SQL Server Reporting Services (SSRS) fra Microsoft. Vi tror både vi og kundene vil tjene på dette, siden SSRS er en mer kjent løsning som mange allerede har erfaring med.

Vi lar selvsagt kundene definere opp og tilgjengeligjøre alle de rapportene de selv ønsker, men vi har også valgt å ta et ekstra steg og bytter nå ut enkelte, sentrale skjermbilder i klienten vår med SSRS rapporter.

Standard contract summary
Contiki ECM: Standard contract summary

I skjermdumpen over ser du Contiki ECM versjon 6.5, hvor jeg har åpnet hovedbildet for en kontrakt. Det inneholder 6 faner (til høyre i bildet) hvor man får tilgang til nøkkeldata om kontrakten. Ulempen er at ulike kunder er interessert i ulike ting, og vi skulle derfor hatt en måte å tilpasse dette skjermbildet på. Derfor jobber vi nå med å bytte ut dette bildet..

Contract summary with SSRS
Contiki ECM: Custom contract summary with SSRS

Skjermdumpen over viser det samme oversiktsbildet for kontrakt, men denne gangen er den en SSRS rapport som lastes. Denne kan enkelt skreddersys til å vise akkurat de dataene kunden er mest opptatt av – de som er viktigst for dem. Takket være vårt konfigurasjonssystem kan man velge å vise ulike skjermbilder (dvs. rapporter) for ulike avdelinger (f.eks. markedsavdelingen kontra innkjøpsavdelingen), eller til og med for enkeltbrukere – CEO kan få sitt helt eget oversiktsbilde for kontrakter.

Som du kanskje ser gjenstår det litt på designet, men det er en smal sak. Vi har lagt mye arbeid ned i integrasjonen, for eksempel for å knytte SSRS mot vårt ACL system, slik at brukerne bare får tilgang til data de skal ha tilgang til.

Standard commercial commitment screen
Contiki ECM: Standard commercial commitment

Her ser du et annet skjermbildet vi ønsker å bytte ut. I bildet over ser du de komersielle dataene for en kontrakt slik det ser ut i versjon 6.5 og tidligere. Her har kundene meget varierende behov, og vi velger derfor å gå for en rapport (bildet nedenfor) som kan tilpasses.

Commercial overview with SSRS
Contiki ECM: Commercial commitment with SSRS

Denne strategien betyr også mere arbeid for våre konsulenter, som vil tilpasse skjermbildene og også lage nye rapporter for kundene. Erfaringen sålangt er bra, og kunsulentene har raskt lært seg å jobbe med SQL Server og Reporting Services. En bi-effekt er muligens at utviklerne ikke har behovet for å forstå kundenes behov i samme detaljgrad, som kanskje også vil kunne øke effektiviteten i utviklingen noe.

For å muligjøre en så tett integrasjon som mulig mellom rapportene og klienten vår har vi også utviklet funksjonalitet får å kunne klikke på linker i rapportene som navigerer til objekter i klienten. Vi har implementert en egen Contiki-protokoll som gjør at vi kan lage linker som f.eks. contiki://open/contract/id/1234 – som vil åpne kontrakten med id 1234. Slik blir rapportene er helt naturlig del av grensesnittet.

Vi bruker selvsagt også SSRS-integrasjonen i webklienten vår, som har vært mitt ansvarsområde. Reporting services kommer med Report-viewer for både WinForms og WebForms.

Jeg mener det har vært et lite genitrekk å knytte rapportene så tett inn i løsningen vår. Etterhvert som vi implementerer rapport-muligheter flere og flere steder i klienten, vil kundene kunne tilpasse produktet mere og mere til akkurat det de trenger, uten at vi behøver å øke kompleksiteten i det vi leverer. Nå gjenstår det bare å gjøre Contiki skriptbart, så kan vi slutte å kode selv også :)

Knagger: Contiki, SQL Server.

Objekt-orienterte databaser (del2): Db4objects

Friday, February 27th, 2009
5 kommentarer

Del 1 i denne serien finner du her.

De første objekt-orienterte databasene kom ut av forskningsmiljøene tidlig på 70-tallet, men begrepet ble ikke tatt i bruk før 1985. På 90-tallet dukket det opp mange, komersielle løsninger, hvor objektdatabaser bl.a. ble integrert i programmeringsspråk for persistering av objekter. C++ var lenge størst på dette området.

Rundt 2004 fikk objektdatabaser en ny vekst gjennom diverse open source-prosjekter. Det finnes i dag et hav av løsninger under diverse lisenser og for diverse programmeringspråk.

Objektdatabasene har hatt liten effekt på mainstream, kommersiell dataprosessering, og mange utviklere vet derfor lite om dem. Men ODBMS er mye brukt innenfor enkelte spesialfelt, som f.eks. telekommunikasjon, fysikk og molekylærbiologi. Det er verdt å merke seg at verdens største database er en objektdatabase: Stanford Linear Accelerator Center’s ODBMS var den første databasen over 1000 terabytes. Objektdatabaser er også attraktive for embedded devices og innefor real-time systemer.

Den objektdatabase-teknologien jeg har valgt å eksperimentere med heter db4o (database for objects). Db4o er en objektdatabase både for Java og .NET, og er gratis for ikke-kommerisell bruk. Produktet fikk prisen Best of Open Source Developer Tools i 2008, og har et stort community. Det finnes allerede et hav av open source sideprosjekter som implementerer støtteverktøy og lignende ting – intergasjon til Castle, Spring.NET og CSLA, støtte for bruk i Ruby, JRuby, Eiffel.NET, Scala og PHP, Ant tasks, Silverlight-støtte, ASP.NET providers osv. Dokumentasjonen er relativt bra, og teknologien er i produksjon mange steder: bl.a. sitter det en db4o-database i hjertet av Spanias nye kontrollsenter for høyhastighetståg.

Databasespørringer i db4o

I del 1 viste jeg hvor enkelt det er å lagre objekter i objektdatabasen. Oppdatering av objekter er like enkelt – man bruker den samme Store() metoden faktisk – den legger inn nye objekter og oppdaterer eksisterende objekter. Når det gjelder å hente ut data har db4o flere muligheter.

For det første kan man bruke QueryByExample (QBE). Dette er noe f.eks. NHibernate også støtter. Man oppretter et nytt objekt av den typen man skal hente ut – ofte kalt en prototype – og setter properties som man er interessert i å matche på. Vil man f.eks. hente ut alle Personer som heter “Torbjørn”, oppretter man en person som heter nettopp Torbjørn og sender det til QBE metoden:

public IEnumerable<Person> FindAllTorbjorns()

{

    using (IObjectContainer db = Db4oFactory.OpenFile(“foo.db”))

    {

        Person prototype = new Person

        {

            GivenName = “Torbjørn”

        };

 

        return db.QueryByExample(prototype).Cast<Person>();

    }

}

QBE kan selvsagt ikke brukes til alt, men det er overraskende kraftig, og godt nok i mange tilfeller.

Den neste muligheten i db4o er det de kaller native queries. Her bruker man elementer i programmeringspåket man jobber i til å gjøre spørringer mot objektene. Man bruker typisk delegater / anonyme metoder til å definere kriterier for hvilke objekter som skal returneres. En variant av native queries i .NET er db4o’s støtte for LINQ. Jeg er veldig glad i LINQ, og synes det er den mest naturlige måten å jobbe med databasen på. Skal jeg f.eks. hente ut alle personer som har enter en shipping-adresse eller en e-post adresse (ja, jeg har utvidet domenemodellene min litt nå), så kan jeg gjøre det slik:

public IList<Person> FindPersonsWeCanContact()

{

    using (IObjectContainer db = Db4oFactory.OpenFile(“foo.db”))

    {

        var query = from Person p in db

                    where p.ShippingAddress != null

                       || p.Email != null

                    select p;

 

        return query.ToList();

    }

}

Gjennom LINQ kan jeg uttrykke akkurat hva jeg er ute etter. Jeg kan jobbe med databasen som om det var en avansert kolleksjon i minnet, og få tilbake mine egne domeneobjekter uten å måtte gjøre noen form for mapping. Å jobbe med persistert data har aldri vært enklere!

Det finnes selvsagt noen detaljer jeg har utelatt. F.eks. vil ikke db4o returnere den komplette objektstrukturen (Person + alle underobjekter) uten at jeg eksplisitt ber den om det. Db4o kan derimot konfigureres til f.eks. å bruke eager fetching / load all levels hver gang jeg henter ut personobjekter – eller jeg kan definere nøyakig hvor mange nivåer som skal lastes. Samme teknikk må man bruke når man oppdaterer og sletter – fortelle db4o hvor mange nivåer som skal påvirkes.

Det finnes også en siste måte å gjøre spørringer, og det er via db4o’s SODA Query API. Dette er den mest kraftige måten å gjøre spørringer på, men også mer low level, og krever at man setter seg inn i API’et. Foreløpig har jeg ikke hatt behov for det – LINQ har gitt meg alt jeg trenger til nå, og er den måten dokumentasjonen anbefaler å bruke – men om du vil lære mer har db4o documentert SODA ganske bra også.

Dette er andre del av en artikkelserie om objekt-orienterte databaser, basert på mitt NNUG-foredrag om samme tema. Fortsettelsen følger..

Knagger: ,

Objekt-orienterte databaser (del 1)

Thursday, February 26th, 2009
1 kommentar

Det finnes en utfordring nesten alle software-prosjekter lever med, og det er den konseptuelle forskjellen mellom objekt-orientering og relasjons-modellen. Koden vår struktureres etter objekt-orienterte prinsipper, og vi forsøker å skape en abstraksjon over vår logikk som best mulig modellerer det domenet/den verden vi skal representere. Men som regel benytter vi også en relasjonsdatabase – og disse to modellene er svært ulike. Vi sier at det eksisterer en impedance mismatch mellom objekt-orierntert kode og data i en relasjonsmodell.

Dette fører til unødvendig kompleksitet. Objektene våre må ofte struktureres på en bestem måte for å kunne persisteres fornuftig i databasen, og vi kan ikke fokusere så mye på domenemodellen som vi skulle ønsket. O/R-mappere som f.eks. NHibernate hjelper oss et stykke på veien, men de kan også føre med seg sine egne problemer, og har et performance overhead. Dessuten er det en ekstra teknologi man da må lære seg.

Men er vi virkelig nødt til å “skvise” objektene våre ned i relasjonsdatabaser? Svaret er NEI, DET ER VI IKKE NØDT TIL!

Første gangen jeg hørte om objektdatabaser (eller ODBMS som man gjerne kaller det) var på Universitetet. Vi lærte om relasjons-databaser, og ble fortalt at det også fantes databaser som lagret objektstrukturer, men at det var noen rare greier som ingen egentlig brukte. Dette var noe vi bare kunne se bort ifra. (Det er uansett slik jeg husker det – mulig det ikke var foreleseren som sa det i det hele tatt).

Nå har jeg derimot lest meg opp på ODBMS, og sett at det er et stort miljø rundt dette, og at det brukes i mange, ulike miljøer. De siste par månedene har jeg begynt å bruke det selv også, og for meg er det en aldri så liten REVOLUSJON. ODBMS’er gir deg både en enkelhet jeg aldri har opplevd med andre verktøy, samtidig med en styrke på enkelte områder som ikke finnes i relasjonsdatabaser.

Men first thing first: Hva er en objektdatabase?

CropperCapture[2].Png

Mens relasjonsdatabaser lagrer data i form av rader i tabeller med relasjoner mellom data representert vha. primær- og fremmednøkler, så lagrer objektdatabasene objekter “slik de er”. I en relasjonsdatabase vil Ordrelinjer ha en fremmednøkkel til en Ordre – i en objektdatabase vil en Ordre ha en liste med Ordrelinjer. Man navigerer i strukturen gjennom pointere eller referanser, som når vi programmerer, i stedet for joins basert på nøkler.

Styrken for oss utviklere er at databasemodellen er definert av objektene våre, ikke av kravene en relasjonsdatabase stiller. Dette gjør at det er mye enklere å kode mot et ODBMS. Ta for eksempel denne mer eller mindre vanlige kodesnutten for å lagre et domeneobjekt til en relasjonsdatabase gjennom ADO.NET:

public void SaveNewPerson(Person personToSave)

{

    using (SqlConnection connection = new SqlConnection(_connectionString))

    {

        connection.Open();

 

        SqlCommand command = connection.CreateCommand();

        command.CommandText =

            “INSERT into TPerson (“ +

            ” FirstName, LastName” +

            “) VALUES (“ +

            “@FirstName, @LastName” +

            “)”;

 

        command.Parameters.Add(“@FirstName”, SqlDbType.NVarChar, 50);

        command.Parameters.Add(“@LastName”, SqlDbType.NVarChar, 50);

 

        command.Parameters["@FirstName"].Value = personToSave.GivenName;

        command.Parameters["@LastName"].Value = personToSave.FamilyName;

 

        command.ExecuteNonQuery();

    }

}

Det eneste jeg har klart å gjøre på disse 23 linjene er å lagre et fornavn og et etternavn til databasen – helt uten transaksjons- og feilhåndtering – samtidig som jeg har introdusert rissiko ved å referere til databaseinformasjon (tabell- og feltnavn samt felt-type og størrelse) uten noen form for kontroll. Kompleksiteten i dette har fått annenhver utvikler til å designe sine egne dataaksess-løsninger som forsøker å gjøre dette enklere, hvor f.eks. kodegenerering var hot for noen år siden, og O/R-mappere er hot akkurat nå.

Skal du gjøre det samme med en O/R-mapper som NHibernate vil koden se omtrent slik ut:

public void SaveNewPerson(Person personToSave)

{

    using (ISession session = _sessionFactory.OpenSession())

    {

        session.Save(personToSave);

    }

}

Mye bedre, ikke sant?! Men det er noe som mangler her. For å få dette til å virke må vi konfigurere NHibernate til å skjønne hva som skal skje. Vi må lage en mapping-fil for Person-classen vår, som i prinsippet vil inneholde mye av det samme som koden i ADO.NET eksempelet. Fluent NHibernate kan gjøre dette enklere, men mappingen mellom databasen og objektene MÅ defineres på en eller annen måte. I tillegg må man lage en NHibernate konfigurasjonsfil for databasen. Jeg har forresten også utelatt opprettelsen av sessionFactory.

Ser vi på den tilsvarende koden for en objektorientert database, ser vi at det ligner svært mye på NHibernate-eksempelet:

public void SaveNewPerson(Person personToSave)

{

    using (IObjectContainer db = Db4oFactory.OpenFile(_databasePath))

    {

        db.Store(personToSave);

    }

}

Og her har jeg ikke utelatt noe annet en using-deklerasjonene i toppen av fila. Databasen jeg oppretter tar i mot et hvilket som helst C# objekt – det inneholder ingenting spesielt, men basen vet likevel akkurat hva den skal gjøre med den. Enklere kan det rett og slett ikke bli.

Dette er første del av en artikkelserie om objekt-orienterte databaser, basert på mitt NNUG-foredrag om samme tema. Fortsettelsen følger om en dag eller to..

Knagger: , ,

Foredrag på NNUG 25. februar

Sunday, February 22nd, 2009
Ingen kommentarer

Førstkommende onsdag holder jeg foredrag på NNUG i Bergen. Temaet er object-orienterte databaser. Du trenger ikke vite noe som helst om denne teknologien på forhånd; jeg vil dekke det du behøver å vite, og forklare hvorfor det er noe vi skal bry oss om.

Flere og flere utviklere ser verdien av prinsipper som Domain-driven design og Model First, hvor man fokuserer på å utvikle en konseptuell modell først, og fra dette utleder lagringsmodellen. O/R mappere som NHibernate (som ble presentert forrige uke) hjelper oss med dette. Men hvorfor er det alltid gitt at vi skal “skvise” objektene våre ned i en relasjonsdatabase? En objektdatabase er en databasemodell hvor informasjon er representert i form av objekter, ikke som relasjonstabeller. I denne presentasjonen vil Torbjørn fortelle om denne teknologien, hvilke styrker den har, og demonstrere praktisk bruk i .NET.

På samme møtet vil Mark Nijhof lære oss om SOLID prinsippene i objectorientert design – en forelesning jeg gleder meg veldig til. Hvis du er i Bergen til uken og ikke har gjort det enda, så er det på tide at du melder deg på. Det er som vanlig gratis.., inkludert pizza.

Jeg kommer også til å publisere en artikkelserie her på bloggen om objektdatabaser, så om du ikke har anledning til å stille på onsdag så kan du likevel få med deg det meste her på bloggen.

PS: Det var et podcast som gjorde meg interessert i objektdatabaser. Vil du også bli inspirert kan du lytte til Alt.NET podcast #14.

Fem vekttall NHibernate

Sunday, January 11th, 2009
Ingen kommentarer

nhibernate.jpgEn av de tingene jeg prioriterte høyt på min .net ninja backlog var å lære meg NHibernate. Det er mange måter å lære seg nye ting på, men her er min plan. Jeg går frem på det jeg kaller universitetsmåten, som består av en god del leksjoner, en del lesestoff, og noen praktiske oppgaver. Alt i alt forsøker jeg å sette sammen det som en gang var et typisk kurs på 5 vekttall.

Jeg har funnet en meget bra video-serie som heter Summer of NHibernate, hvor Steve forteller og viser deg alt du trenger å vite for å komme igang. Hver sesjon er på rundt en og en halv time, så her er det mye stoff. Jeg innbiller meg at dette er en bra læreform. Det vil kanskje kreve mye tid, men jeg blir på denne måten ikke fristet til å skumme over ting jeg oppfatter som enkle eller uviktige, og får dermed en veldig god basisforståelse.

Video-leksjoner:

  • Session 01: Setup and Basic Usage Pattern
  • Session 02: Exploring Query Methods and Syntaxes
  • Session 02a: Exploring Query Methods and Syntaxes (con’t)
  • Session 03: Exploring INSERT, UPDATE, and DELETE Semantics
  • Session 04: Exploring Transactions and Concurrency
  • Session 05: Modeling Foreign-Key Relationships in NHibernate
  • Session 06: Advanced Querying of Child Collections
  • Session 07: Exploring m:n Relationships, Views, and Components
  • Session 08: Effective Techniques for Database-Driven Modeling
  • Session 09: Effective Model-Driven Schemas
  • Session 10: Stored Procedures, Interceptors and NHibernate Query Analyzer –oh my!
  • Session 11: Techniques for Modeling Inheritance in the Database
  • Session 12: Detached Objects, Detached Criteria, and Working Without a Session
  • Session 13: Managing Session Lifecycle in a Stateless Web Application
  • Session 14: Migrating to NHibernate 2.0 and Further Exploration

I tillegg har vi én gjesteforelesning:

Lesestoff for selvstudie:
Jeg har samlet sammen endel linker til artikler jeg kunne tenke meg å lese etterhvert som jeg kommer inn i NHibernate. Spesielt er det et par områder som Summer of NHibernate ikke dekker, nemlig Fluent NHibernate og Linq to NHibernate, så dette må jeg lese selv.

Her er artiklene – i tilfeldig rekkefølge. Gjennom å lese disse vil jeg sikkert også finne andre artikler av interesse.

Praktiske oppgaver:

Jeg har flere prosjekter på gang hvor jeg har tenkt å benytte NHibernate, bl.a. Contiki Center og Vil Du Bli En .NET Ninja-spillet. Det er også snakk om å bytte ut data access laget til The Forecast Exchange med NHibernate – jeg vet ikke hvor mye jeg kommer til å bidra der, men jeg kan jo hjelpe til litt om det trengs.

Referansemateriale og community:

Til sist er det alltid greit å ha tilgang til documentasjon samt et levende community med entusiaster når man skal lære seg noe nytt. Her er noen sentrale linker.

Så dette er altså min studieplan relatert til NHibernate. Jeg er allerede godt igang med videoene, og satser på å være gjennom dem om en tre ukers tid. I februar bør jeg for alvor sette igang med prosjektene mine.

Store filer i databasen

Thursday, January 8th, 2009
3 kommentarer

For tiden er jeg opptatt med å løse noen problemer vi har i produktet vårt relatert til dokumenthåndtering. Vi lagrer dokumentene som blobber i databasen, og de siste dagene har jeg kommet over flere eksempler på hvor lett det er å gjøre ting feil i slike senarier.

WTF 1:

For å håndtere store filer er vi nødt til å splitte dem opp – vi kan ikke behandle de komplette filene i minne. Før vi splitter opp ønsker vi å finne størrelsen på filen. Og hva gjør vi da? Jo, vi laster hele filen i minne og sjekker lengden!

Det verste er at filstørrelsen allerede finnes lagret i et eget felt i basen, men av en eller annen grunn stoler vi ikke helt på denne, og velger å gjøre det på den kostbare måten som får serveren til å knele for store filer.

WTF 2:

Et annet, morsomt eksempel vi kom over i går var koden for å slettemarkere en fil. Alt som skal gjøres er å flippe en bit fra true til false (eller var det muligens motsatt?). Men for å gjøre det laster vi først hele raden fra databasen, som desverre også inkluderer fil-blobben. Så hvis noen for eksempel vil slettemarkere en fil på 100MB, så leser vi først 100MB fra databasen før vi endrer vår bit fra 1 til 0 og oppdaterer.

Nå må ingen føle seg støtt av disse historiene. Alle kan gjøre slike ting fra tid til annen – de fleste, om ikke alle, gjør slike ting fra tid til annen. Men i et stort prosjekt i stadig utvikling er det viktig å sette av tid til å fange opp og jobbe med problemer som disse – spesielt når det dreier seg om produktets absolutte kjernefunksjonalitet.

Jeg garanterer en stor forbedring i neste patch!

Første erfaring med Dynamic Data

Wednesday, November 19th, 2008
1 kommentar

I Contiki bruker vi en velprøv metode tuftet på velkjent teknologi for å holde rede på våre kunder og deres installasjoner av vårt produkt – nemlig en flatfil i Excel.

Nå har endelig noen blitt så trøtte av denne løsningen at man har bestem at noe må gjøres. Jon Arild kom da i dag med den lure ideen at vi kunne bruke Dynamic Data (tidligere omtalt her) til å smelle opp en rask webløsning som publisere rdataene og gir editeringsmuligheter til dem som trenger dem. Så her er hva vi gjorde, og hvor lang tid det tok:

  1. Analyserte Excel-filen, og identifiserte hvordan den burde brytes opp i databasetabeller. 15 minutter.
  2. Forbedringer av Excel-filen for å gjøre det enklere å generere en database fra den. Omtrent 60 minutter.
  3. Importerte Excel-filen til en Access database. Et tungvindt grensesnitt og merkelig oppførsel gjorde at dette tok omtrent 45 minutter.
  4. Exporterte Access-basen til SQL server. 30 sekunder.
  5. Fikset opp i rare avgjørelser utført av eksporten. 2 minutter.
  6. Opprettet en ASP.NET DybamicData Web Site. Nesten 10 sekunder.
  7. Opprettet en LINQ to SQL modell basert på basen. 12 sekunder.
  8. Konfigurasjon av DynamicData-løsningen. Omtrent ett minutt. (Måtte lete litt nemlig. Trodde den ene linjen som skulle endres befant seg i web.config, men den var i stedet i global.asax.)
  9. Konfigurere siten til å bruke Forms based authentication. La til bruker, roller og tilgangsrettigheter. 2 minutter.
  10. Opprettet en spliter ny påloggings-side. “Add new item” + drag’n'drop av login-kontroll tok kanskje 15 sekunder.

Vi hadde egentlig en fungerende løsning etter punkt 8, men vi ønsket også en uathentiseringsløsning, så da måtte vi jobbe litt til. Men det som tok tid var altså å massere dataene våre for å få en fornuftig base. Selve løsningen, med fullstendig CRUD GUI for hele basen, tok under fire minutter å sette opp.

Siste kommentarer

Torbjørn
PS: Takk til Børge Hansen, som delte SCARF-modellen med meg!...
Børge Hansen
Denne likte jeg veldig godt. Du skriver godt og har gode betraktninger  Keep it up – flere trenger å tørre å lære mer om ledelse – du l...
Tormod
Er egentlig ikke overrasket. F# sin fortè er programmererens produktivitet/kvalitet og anledning til parallell kjøring. Men kjøremotoren har ...
Stian
Ville også prøvd med et større problem (x100 eller x1000 f.eks). Når man snakker så små brøkdeler av et sekund som her så kan tiden for en ell...
Torbjørn
Har ikke sjekket - tar en titt i morgen hvis tid :)...
Einar W. Høst
Mhp tco: hva sier ILSpy?...
Torbjørn
Har ikke sett noe på PSeq før, men kjenner til den typen funksjoner fra blant annet Clojure. Og problemet med slike funksjoner i sammenhenger som de...
Håvard
Veldig bra sammenligning! Har du sett på ytelsen av PSeq.* fra powerpakken? Tipper den vil gi performancehit på små mengder, men kan kanskje resul...
Torbjørn
Jeg kom på en demonstrasjon-variant til jeg burde inkludere, nemlig bruk av list comprehension (en type computation expression (også kalt monads)). ...
Einar W. Høst
Interessant, det blir en trade-off mellom eleganse og fart på en måte. Den funksjonelle løsningen med vanlig filter er ren og pen, mens den imperat...
Creative Commons-lisens
Innholdet på denne bloggen er tilgjengelig under Creative Commons Navngivelse-Ikkekommersiell-DelPåSammeVilkår 3.0 Norge lisens.

Programmeringsbloggen
Kjempekjekt.com

© 2006-2013 Torbjørn Marø

Jeg har vært en profesjonell programmerer siden 1999, og dette er min blogg. Målet med bloggen er å stimulere meg selv og alle andre til kontinuerlig eksperimentering og læring.

Jeg forsøker å være allsidig, og programmerer blant annet i C#, Ruby, Erlang og Clojure.

Jeg praktiserer TDD og andre smidige utviklingspraksiser. Jeg er opptatt av kvalitet og ren kode.

Dette og ganske mye mer kan du lese om på denne bloggen!