SQL Server på svenska


När vill vi använda en float? - 2020-01-20

Nu när vi har tittat på float i ett antal inlägg för att kolla på dess problem så kan man få uppfattningen att float alltid är sämre än decimal. Och så är det ju självklart inte. Det finns 3 huvudsakliga fall när man gärna vill använda en float. Det är vid väldigt små tal, det är vid väldigt stora tal och det är när man gärna vill ha en onoggrannhet. Låt oss först titta på väldigt stora tal, på bilden under.

Här ser vi tydligt att detta stora tal går bra att spara i en float och i en decimal. Om vi i följande 2 bilder testar att multiplicera med 10 så ska vi se att decimal inte klarar av så stora tal längre, men det gör float.

Slutsatsen är mycket enkel, ibland har man så stora tal att man behöver använda en float. Exakt samma sak gäller för mycket små tal, men jag kommer inte visa det för det känns lite för uppenbart. (Testa gärna själv om du känner dig osäker.) Det betydligt mer intressanta fallet ska vi titta på i nästa avsnitt, när onoggrannhet är något vi önskar oss.

När är float exakt och oexakt? - 2020-01-15

Orsaken till att float inte kan spara talet 0.1 exakt är ganska enkelt, float sparar decimaltal i bråk som 1/2^n. Alltså 1/2, 1/4, 1/8, 1/16 osv. Och utifrån detta går det inte att spara talet 0.1 exakt, men talet 0.5 går bra eftersom det är 1/2. Låt oss titta på ett tal som går bra att spara.

Som ni tydligt ser så blir detta tal exakt, och orsaken är att 0.15625 också är 1/8+1/32. Alltså går det att spara tal som är en kombination av ett antal 1/2^n exakt. Alla andra tal kommer vara ungefärliga, exempelvis det nedan.

Här kan man tydligt se att 0.15624 inte går att spara exakt i en float. Det är det viktiga i detta inlägg, alla tal som går att skriva som en kombination utav flera 1/2^n är exakta, alla andra kommer vara en avrundning.

Jag skulle säga att orsaken till detta är ganska matematisk, och det beror på att float sparar sina tal i basen 2 istället för basen 10 som vi normalt gör. Och alla olika baser har egentligen samma problem, fast för olika tal. I basen 10 går det bra att spara talet 1/10 men inte 1/3. I basen 2 går det bra att spara 1/16 men inte 1/10. (Vill du djupdyka i detta måste du läsa på en del om matematik, och denna blogg kommer lämna just den matematiska delen nu och fortsätta titta på databaser och SQL Server.)

Float kan inte spara 0.1 exakt - 2020-01-13

Orsaken till problemet i förra inlägget, att en summa av många 0.1 aldrig blir 8.0, är att det finns inget exakt tal 0.1 för float. (I hela detta inlägg så gäller samma sak för real.) Utan talet 0.1 är hela tiden en avrundning och när man adderar många avrundningar på varandra så kan det ibland bli fel.

Tittar vi på en decimal så kan vi se att talet 0.1 går att ha exakt, enligt bilden nedan. Om man måste ha exakta tal så går det inte att använda float.

Om vi istället tittar på en float så kan vi tydligt se att den inte är exakt 0.1 när vi jämför den med en decimal, enligt bilden nedan. Och det är denna noggrannheten som orsaker problemet.

När man tittar på detta så blir det ganska uppenbart att det kan bli ett problem med float om man behöver exakt noggrannhet. Vilket float aldrig kan garantera. Det är dock viktigt att komma ihåg att avrundningsfelet ligger bortom den 15 siffran och därigenom uppfylls kravet på att ha 15 siffrors precision som jag nämnde i början av serien om float. Enda orsaken till att det blir ett problem i detta exempel är att vi använder 0.1 i en while-loop vilket tillåter osäkerheten att växa. (I nästa inlägg fortsätter vi titta på detta för att förstå varför det blir såhär.)

Problem med float! - 2020-01-10

Det finns en rad problem och fallgropar med float och real. Och dessa kan enkelt sammanfattas som problem med precisionen. Låt oss ta en titt på ett exempel för att förstå vilken typ av problem som kan uppstå.

Om vi tittar på bilden här under så kan vi tydligt se att en float som har värdet 8 inte riktigt har värdet 8, eftersom då borde while-loopen ha stannat vid 8.

När vi tittar på denna bilden så ser det lite konstigt ut, variabeln har ju värdet 8 så den borde ju ha stannat där. Men om vi minskar precisionen på variabeln så kommer vi tydligare se vad det är som händer.

Här ser vi tydligt att det som händer är att 8.0 inte riktigt finns, utan 7.999 och 8.099 finns. Och eftersom jämförelsen i while-loopen är exakt så kommer den aldrig att bryta. Och orsaken till varför talet 8.0 inte finns, trots att rent matematiskt så borde det finnas beror på hur en float fungerar. Och det känns som vi behöver ett helt inlägg för att djupdyka i detta, så det kommer. Men läxan från dagens inlägg är att float är oprecisa tal, och ska aldrig användas om man behöver ha exakta tal. (Du får samma beteende för real som för float(24).)

Float eller real? - 2020-01-08

När man använder sig av float och real är det viktigt att komma ihåg deras precision. Nämligen att real enbart kan hålla 7 siffrors noggrannhet medan float kan hålla 15 siffror. Det är faktiskt den största anledningen till varför jag ofta behöver använda float istället för real. (Den andra anledningen skulle ju vara för att spara betydligt större tal, men det är sällan man behöver större tal än vad real erbjuder.)

Om vi testar att stoppa in ett tal med 8 siffror i både float och real, kan vi enkelt se att real måste avrunda.

Som vi ser fungerar allt som vi hade förväntat oss. (Hade vi flyttat decimaltecknet åt något håll hade vi fått samma beteende, prova själv om du vill testa.) En sak som går att göra med float men inte med real är att bestämma storleken. Om vi anger en float(24) kommer vi i praktiken att få en real. Som du kan se här under.

Du kan med andra ord välja att enbart använda dig av float och aldrig real. Vilket man gör spelar ingen roll, och det finns olika åsikter om det. Det viktigaste är att vara konsekvent i hela databasen, så använd inte float(24) ibland och real ibland.

Hur ser lönen ut för en SQL Server expert? - 2020-01-07

Nu är löneundersökningen gjort, som jag för mindre än 1 månad uppmanade er att delta i, och resultatet finns att tillgå på länken här under. Gå in och titta själva för att se all matnyttig info som finns där.

https://www.brentozar.com/archive/2020/01/the-2020-data-professional-salary-survey-results-are-in/

Det finns några slutsatser man kan dra från denna studie. (OBS! det är inte supermånga från Sverige som deltog, så man kan inte anta allt för mycket från den.) Det första är att folk rent ut sagt är dåliga på att ange siffror rätt (troligen). Det är 1 person i Sverige som anger att hen tjänar 6280 i månaden, och 1 person som tjänar 426000 i månaden. Jag misstänker att dessa är fel så jag har tagit bort dem från min analys.

När jag tittar på siffrorna så ser jag att medianlönen för er SQL Server experter är ungefär 50 tusen i månaden. Vilket jag skulle säga är en bra lön, jämfört med många andra yrken. Jag kan också se att 3 personer tjänar mellan 30 och 40 tusen, och dessa personer har jobbat minst antal år med SQL Server. Jag ser att flest personer ligger mellan 40 och 50 tusen, nämligen 10 stycken. Sen ligger 5 personer mellan 50 och 60 tusen, och 6 personer mellan 60 och 70 tusen. Och slutligen har vi 3 personer som ligger mellan 70 och 80 tusen.

Där har vi det, en sammanställning över vad en SQL Server expert borde tjäna i Sverige idag. Jag hoppas alla er som ligger i den lägre delen av kurvan tar med sig detta till årets lönesamtal. Ingen av oss vill ju bidra till lönedumpning ;-)

Float och real - 2020-01-03

Det finns 2 kolumntyper i SQL Server som tillåter att man sparar icke exakta tal. Det är float och real, där float är den större av de två.

Real tar upp 4 bitgrupper (bytes) och kan spara upp till 7 siffrors precision. En real kan spara tal från -3.40E+38 till -1.18E-38 samt 0 samt 1.18E-38 till 3.40E38. Detta betyder att real kan spara både mycket stora och mycket små tal, både på den negativa och positiva sidan.

Float tar upp 8 bitgrupper och kan spara tal med upp till 15 siffrors precision. Det är möjligt att spara tal från -1.79E+308 till -2.23E-308 samt 0 samt 2.23E-308 till 1.79E+308. Så med andra ord ungefär som real men med betydligt högre upplösning och betydligt större tal.

Hur stora tal man kan spara är inget som jag lägger på minnet, men däremot är det viktigt att förstå hur dessa kolumntyper fungerar och när man ska använda dem. Och det kommer jag gå igenom under en rad olika inlägg framöver. På bilden nedan så kan ni se hur man använder dem.

2 månader! - 2020-01-02

Nu har ännu en månad med bloggen gått, och jag tackar alla er som har följt den. Det är ju trots allt för er jag skriver den. Under den senaste månaden har det blivit 7 matnyttiga inlägg, vilket är lite färre än de 10 jag hade hoppats på. Orsaken är väldigt enkel, julen åt upp min tid mer än jag hade tänkt mig, vilket nu när jag säger det känns ganska uppenbart.

Ni som har följt mig under hela månaden har märkt att det har tillkommit en rad nya funktioner på sidan, bland annat att man enkelt kan kopiera koden. Jag förväntar mig att sidan kommer fortsätta att uppdateras under den kommande månaden. Parallellt med att jag hoppas kunna skriva 10 nya inlägg under månaden.

Om ni har något som ni önskar att jag tar upp lite mer i detalj är det bara att skicka ett mejl till mig, på info@erikdahlen.se. Det kan även vara önskemål eller förslag om förändringar på själva sidan. Nu när bloggen är under uppbyggnad så har man större möjlighet att påverka ;-)

Om man tvingar decimal att avrunda. - 2019-12-19

Vi har tidigare undersökt varför decimal kan ha högre noggrannhet än money, trots att de har lika många decimaler. Och svaret var att decimal håller koll på extra decimaler i bakgrunden. Men låt oss då testa vad som händer om vi tvingar decimal att enbart ha 4 decimaler hela tiden.

En viktig sak att förstå här är att en dator alltid måste göra en avrundning mellan varje steg i en komplicerad uträkning. Varje gång en uträkning sker som har många/oändligt många decimaler måste en dator slänga några vid varje steg i en uträkning. Och vi ska nu titta på hur det blir för decimal när vi tvingar den att avrunda till 4 decimaler i varje steg.

Som vi tydligt ser så får inte en decimal högre noggrannhet än en money när vi tvingar den att också avrunda till 4 decimaler i alla leden. Så nu anser jag att vi har tydligt demonstrerat vad det är som händer, om du fortfarande känner dig osäker så ladda ner koden och testa dig fram eller läs igenom dokumentationen för SQL Server.

En annan observation vi gör här är att decimal nu har valt att avrunda talet enligt vanliga matteregler och inte kört en floor och bara slängt den femte siffran. Frågan den nyfikne då ställer sig är vad som händer om vi istället gör detta för money.

Nu ser vi att money beter sig på samma sätt som tidigare, nämligen att money kör på floor hela tiden. Personligen skulle jag säga att det är en styrka, till skillnad från decimal som ibland kör med floor (titta i ett tidigare inlägg) och ibland med vanlig avrundning. Jag skulle säga att rent generellt så har money betet sig väldigt konsekvent under alla inlägg i denna jämförelsen medan decimal har bytt skepnad. Det viktiga att ta med hem från dessa inlägg är att det finns en rad fallgropar kring olika tal. (Normalt måste man undersöka systemets/projektets krav vid varje ny databas man ska bygga. Och tur är väl det, hade det varit enkelt att köra med en "one size fits all" hade en dator kunnat göra detta och vi varit arbetslösa.)

Jag kommer nu avsluta jämförelsen mellan just decimal och money, det är dags att gå vidare med bloggserien. Nästa gång kommer vi titta vidare på olika kolumnval för tabeller.

Varför kan decimal ha högre noggrannhet i uträkningar? - 2019-12-16

Hur kommer det sig att decimal kan ha högre noggrannhet än money? Jo, egentligen är det ganska enkelt, det finns extra data i bakgrunden. Låt oss titta igenom ett exempel för att förstå vad detta betyder.

Om vi tittar på bilden under, så ser vi att det finns en begränsning i hur många decimaler som denna decimal kan hålla.

Som vi tydligt kan se så klarar inte denna typen av decimal att hålla samtliga decimaler, eftersom de 6 sista siffrorna alla är 0. Tittar vi istället på bilden här under så ser vi att det ändras.

Precis som tidigare så ser vi att med en decimal med mindre storlek så kan vi ha högre noggrannhet i detta exemplet. Frågan man kan ställa sig är varför. Och svaret är att en decimal med mindre storlek kan ha mer extra data i bakgrunden. Låt oss titta på nästa bild för att se ett exempel på detta.

Som vi tydligt kan se här så finns det mer än 4 decimaler i svaret, så fort vi inte längre tvingar SQL Server att max visa 4 decimaler som vi gjort tidigare. Det är alltså så att i bakgrunden har det funnits fler decimaler än vad vi har angivit i våra decimal. Och orsaken till att vi inte har fått samma resultat för money, är att SQL Server inte kan tilldela dem fler extra decimaler i bakgrunden.

Vi har i detta inlägg sett att SQL Server ibland kan tilldela tal extra decimaler i bakgrunden när den genomför komplicerade uträkningar. För att öka noggrannheten på svaret. Dock måste vi veta om när det sker och inte. Det är tyvärr så att man i varje enskilt fall måste undersöka vad som krävs för just detta fallet, och vilken datatyp samt noggrannhet som behövs. Det finns ingen "one size fits all". I nästa inlägg så ska vi fortsätta att undersöka detta för att på riktigt förstå vad som händer.

Fallgropar finns både för money och decimal - 2019-12-13

Nu när resan fortsätter ner i djupet, om skillnaden mellan decimal och money, låt oss först titta på var vi stod. I denna första bild här under så ser vi att med en decimal får vi högre noggrannhet för färre bitgrupper (bytes).

Om allt var enkelt borde det vara avgjort nu, decimal är bättre på alla vis än money. Men tyvärr så är det inte riktig så enkelt. Låt oss ändra lite i storleken på decimal och se vad som händer.

Från denna bilden så kan vi dra 2 stycken lärdomar. Först och främst att storleken för en decimal spelar roll, och ökar vi storleken här så minskar vi helt plötsligt upplösningar på svaret. (Orsaken till detta ska vi titta lite på i nästa inlägg.) Och för det andra så ser vi även decimal avrundar på samma sätt som money, nämligen att de gör en floor. Vilket betyder att man inte avrundar utan man slänger alla överblivna siffror. Det är standard inom så gott som alla programmeringssystem. (Vi får prata om avrundning i SQL Server i framtiden.)

På nästa bild så ser vi att storleken på decimal ökar om vi skulle öka upp antalet nollor, vilket inte händer för money. Helt plötsligt så skulle man spara en del plats på att använda sig av en money istället.

Som ni ser så spelar det stor roll om man använder sig utav money eller deciamal. En viktig observation här är att money beter sig konstant lika dant oavsett vad som händer men det gör inte decimal. Och det ska vi prata lite mer om i nästa inlägg.

Vad tjänar du? En väldigt viktig fråga! - 2019-12-12

Denna gång kommer något helt annat. Själv följer jag andras bloggar för att hålla koll på vad som händer i fältet. Och här kommer ett inlägg från en blogg jag själv följer. Inlägget går ut på att folk som jobbar med databaser och SQL Server ska gå in och ange vad de jobbar med och vad de tjänar, så vi alla kan bli en aning bättre på veta vad vi borde ligga någon stans. Och eftersom det huvudsakligen spelar för roll vad andra tjänar i Sverige så ber jag er alla gå in och ange vad ni tjänar.

https://www.brentozar.com/archive/2019/12/are-you-underpaid-lets-find-out-the-data-professional-salary-survey-is-open/

Fördelen är enkel, om många berättar vad de tjänar som databasprogrammerare/databasadministratörer/databasexperter osv. så kan vi veta om vi bör kräva högre lön eller inte. Och för er som redan har bra lön är det ju bra om det inte finns andra som dumpar lönen för vårt yrke. Så gå in och uppge vad du tjänar. (Allt sker så klart anonymt.)

Var försiktig när du räknar med money - 2019-12-10

OBS! Exemplet i denna post är hämtad från följande inlägg på stackoverflow. Vill du hellre läsa originalet istället för min version gör gärna det på följande länk här under. För er som vill läsa min svenska version av problemet kan göra det här.

https://stackoverflow.com/questions/582797/should-you-choose-the-money-or-decimalx-y-datatypes-in-sql-server

Det är så att det ibland inte alls är bäst att spara belopp i money. Och det kan det vara när man ska använda beloppen i olika uträkningar i en mer komplicerade query. Här under ser vi ett exempel på exakt samma uträkning som får två olika svar beroende på om man använder money eller decimal.

Som ni ser så tappar money bort decimalerna i uträkningen medan decimal inte gör det. Detta gör att man måste vara på sin vakt när man använder money. Men som ni ser från bilden här under så går det att använda money i detta exemplet så länge man inte använder money i variabeln för divisionen.

I nästa inlägg kommer vi gå lite djupare ner på varför det blir såhär. Men det viktiga att ta med sig hem ifrån detta inlägg är att det gå bra att spara belopp i money om man inte använder det i komplicerade uträkningar. Ska man göra det måste man tänka igenom saken lite noggrannare. (Viktigt att komma ihåg är att decimal också innehåller liknande fallgropar, som jag snart kommer gå igenom.)

Money och smallmoney - 2019-12-05

Då går vi vidare till nästa 2 typer av nummer, även dessa med fix noggrannhet. money och smallmoney. Som det låter så är dessa till för att spara belopp i. Bägge har alltid 4 decimaler, så länge man inte kör med Informatica vilket jag aldrig har sätt någon göra men i så fall använder de enbart 2 decimaler.

Smallmoney är en mindre datatyp som enbart tar upp 4 bitgrupper (bytes). Den tillåter enbart att man sparar nummer från -214,748.3648 till och med 214,748.3647. Orsaken till att dessa sällan används är att 214 tusen är inte så himla mycket, så det är ofta man behöver möjlighet att kunna spara större tal. Kom ihåg att om din databas ska spara andra valutor så kan 214 000 ibland vara ganska små summor. (Exempelvis är den japanska yenen inte värd så mycket.)

Money är nog den vanligaste typen och den tar upp 8 stycken bitgrupper (bytes). Den tillåter att man sparar tal från -922,337,203,685,477.5808 till och med 922,337,203,685,477.5807. Här under kan du se hur man använder dem.

När det kommer till belopp är det ofta att rekommendera att spara dem i money, dels eftersom det är en exakt siffra och dels att användaren av databasen direkt kan se att det är belopp som är sparade i dem. Jag brukar alltid rekommendera att man använder rätt kolumntyp, då blir det enklare när många ska använda datan/databasen. (Kom ihåg att även om du i nuläget tror att du kommer bli den enda som jobbar med den, så ändras sånt ofta med tiden.)

Även parametern är avgörande för decimal - 2019-12-03

Under förra inlägget i serien så såg vi att det spelade roll för en decimal vilken storlek man valde. Och jag visade att två olika tabeller där enbart storleken skiljde sig åt kunde spela stor roll för vilken execution plan som SQL Server väljer. Nu tänkte jag lite fort visa vad det beror på. (Utan att titta ner i de riktigt djupa detaljerna.)

Vilken execution plan som SQL Server väljer beror i detta fallet helt på vilken parameter man använder i sin where clause. Om vi tittar på bilden under så kan vi se att bägge execution plan går att få för tabellen med mindre storlek.

Som ni ser så är det valet av parameter som styr vilken execution plan som SQL Server väljer. Men från bilden under så ser ni att gränsen skiljer sig åt om man väljer den större storleken.

Som ni ser så spelar det roll vilken parameter man väljer. Och att gränsen där det spelar roll skiljer sig beroende på storleken för kolumnen. Med andra ord, alla val ni gör när ni designar en tabell spelar roll för prestandan längre fram. Det är det viktigaste jag vill lära er i detta inlägg, om ni gör dåliga val av tabeller så kan det påverka prestandan. (Detaljer om execution plan kommer i framtida inlägg.)

1 månad! - 2019-12-02

Då är det dags att fira att bloggen är 1 månad gammal! Inget superstort, men det gäller att fira de små framstegen. Under månaden som gått har vi huvudsakligen tittat på kolumner i tabeller. Och det kommer vi fortsätta med, tills vi går vidare med mer avancerade saker kring tabeller.

Jag tänkte passa på att nämna några saker som har hänt denna månaden. Jag har skrivit 12 stycken matnyttiga inlägg, och hoppas att det blir åtminstone 10 stycken nu under december. Och sen kan vi titta på bilden nedan för att se hur många besökare bloggen har haft, och jag hoppas att det ska öka.

Jag kan också berätta att jag planerar att snart uppdatera utseendet på sidan. Då ska ni kunna ladda ner den kod jag använder mig av, för att slippa skriva av den. Och en rad nya saker kommer också bli möjligt, så stanna kvar på denna blogg så kommer ni snart märka förbättringarna.

För decimal spelar storleken roll - 2019-11-29

Låt mig här under visa ett kort exempel på att det spelar roll vad man gör för val med storleken. Om man ökar storleken kommer det att få effekter på prestandan, trots att det sker inom begränsningen så att lika många bitgrupper (bytes) sparas. Här under ser ni en bild som visar att dessa två olika storlekar på decimal tar upp lika mycket plats.

Som ni ser så är dessa två tabeller nästan identiska, med helt identisk data. Och den enda skillnaden mellan de två är storleken på decimal, och i databasen tar dessa två storlekar upp exakt lika mycket plats. Då hade man kunnat tänka sig att det inte spelar någon roll vilket man ska välja, men titta då på nästa bild.

Som ni ser så blir det ganska olika execution plan för dem. Ni kan säkert själva lista ut att det kan spela roll för prestandan vilken SQL Server använder sig av. Så här kan jag ge ett tips, tänk noga igenom alla val som ni gör! (Vi kommer inte i detta inlägg gå igenom hur man tolkar en execution plan och hur man kan använda den för att optimera databasen. Det kommer i framtida serier. Men nu vet ni i alla fall om att tabellval spelar roll för prestandan.)

Decimal och numeric - 2019-11-26

Ofta när man ska spara tal så räcker det inte med heltal utan man behöver kunna spara decimaltal. Och just därför finns flera typer av decimaltal. Vi börjar med att gå igenom de 2 med fix längd (noggrannhet), decimal och numeric.

Dessa två typerna, decimal och numeric, är i bokstavligen samma typ. Så det går i praktiken att använda sig utav vilken man helst vill. Personligen använder jag oftast decimal eftersom jag tycker det låter naturligt att spara decimaltal i en decimal. Det jag kan starkt rekommendera är att använda samma överallt, oavsett vilken man bestämmer sig för.

När man använder en decimal så behöver man ange vilken storlek och var man vill ha decimaltecknet. Det bestäms såhär, decimal(n,m) där n är längden och m är positionen på decimaltecknet. Exempelvis decimal(5,2), som tillåter tal mellan -1000 och 1000 och med två decimalers noggrannhet. (Från och med -999,99 till och med 999,99)

När man ska använda sig utav en decimal är det viktig att först fundera noga på vilken storlek man behöver. Större tal kräver större utrymme och större prestanda. Dock är det inte linjärt utan det finns vissa steg. Decimal med längden 1-9 tar upp 5 bitgrupper (bytes), längden 10-19 tar upp 9, 20-28 tar upp 13 samt 29-38 tar upp 17. Större än 38 går inte att lagra i en decimal. (Ett exempel kan ni se i bilden nedan.)

Trots att det tar upp lika mycket plats i databasen att ha en decimal(5,2) som det tar att ha en decimal(9,4) rekommenderar jag inte att alltid använda den större. Visst är det bra att kunna lagra större tal utan att det krävs extra utrymme, men det alltid mer komplicerat än så. Jag rekommenderar alltid att försöka skapa begränsningar i systemet, som stämmer överens med ens affärslogik.

Tinyint eller char i tabeller? - 2019-11-22

När man funderar på att använda sig utav en tinyint för att spara grupptillhörighet så är det viktigt att komma ihåg att även char finns. Bägge dessa två tar upp en bitgrupp (byte) och är således lika effektiva. Men det finns en viktig skillnad, tinyint är heltal medan char är bokstäver. Alltså bör du spara grupper som är numrerade i tinyint och grupper som är bokstavsspecifika i char.

Ett tydligt exempel på detta är kön. Det går alldeles utmärkt att spara kön i en tinyint, och exempelvis använda 1 som man, 2 som kvinna, 3 som trans och 4 som okänd. Men jag skulle rekommendera att använda en char istället, och exempelvis använda m som man, k som kvinna, t som trans och o som okänd. Det spelar ingen större roll för prestandan, men det är enklare att läsa och risken är mindre att man blandar ihop vilken som är man, kvinna, trans och okänd.

En viktig rekommendation från ovan exempel, använd helst inte svenska ord inom kodning. Använd helst engelska, exempelvis male, female och unknown. (Det är oftast bäst att hålla hela databasen samt programmen som använder den helt på engelska, för att minimera risken för missförstånd.)

Heltal i tabeller - 2019-11-20

Efter en lång genomgång av texter i tabeller så är det dags för olika typer av heltal. Dessa är betydligt enklare än andra kolumntyper, det finns inte så många olika funderingar. Det enda som avgör om du bör använda dig utav en tinyint, smallint, int eller bigint är hur stora heltal du måste spara. Desto större du väljer, desto mer plats tar de upp.

Tinyint tar upp 1 bitgrupp (byte) och tillåter tal från 0 till och med 255. En vanlig användningen för denna typen av heltal är när man ska spara enum, eller olika grupper.

Smallint tar upp 2 bitgrupper och kan spara tall från -32,768 till och med 32,767. Detta är troligen den ovanligaste heltalstypen, och används sällan i verkliga miljöer.

Int tar upp 4 bitgrupper och kan vara ett heltal från -2,147,483,648 till och med 2,147,483,647. Denna används för de flesta tal när man behöver använda sig utav ett heltal.

Bigint tar upp 8 bitgrupper och kan vara ett tal från -9,223,372,036,854,775,808 till och med 9,223,372,036,854,775,807. Denna heltalstyp behövs när man ska spara stora tal.

Här under kan ni tydligt se att de större heltalstyperna tar större plats för att spara samma siffra. Vilket tydligt visar valet som finns, ge möjlighet för stora tal eller spara utrymme.

Varför inte alltid använda sig av varchar(max)? - 2019-11-18

Efter förra inlägget skulle man definitivt kunna ställa sig frågan varför man inte bara omvandlar alla text och ntext till varchar(max) och nvarchar(max). Och det är en bra fråga, och svaret är lite komplicerat. Om man ska spara väldigt långa texter så kan man absolut behöva använda sig utav (max). Och i så fall gör man det. En varchar(max) fungerar att använda istället för en varchar(n). Där n kan vara ett tal mellan 1 och 8000. Det kan man se på bilden här under.

Som ni ser så fungerar båda lika bra för att spara en text. Så man skulle helt enkelt kunna spara alla texter i varchar(max), och då kan man ställa sig frågan varför SQL Server ens har varchar(n). Och svaret är självklart att det finns fördelar med varchar(n).

Tyvärr kommer jag inte beskriva alla fördelar med varchar(n) istället för varchar(max) just nu. Det är ganska komplicerat och kommer finnas med i framtida inlägg när vi diskuterar optimering och index. Det du bör komma ihåg är att varchar(max) kan komma att kosta prestanda när du bygger komplicerade queries. Exempelvis som du ser i bilden här under så kan man inte använda varchar(max) som primary key. (Fler begränsningar finns.) Så använd varchar(max) enbart där du måste. (Vi kommer även prata om hur man kan gå runt en del av begränsningarna i framtida inlägg.)

Använd aldrig text och ntext - 2019-11-14

När det kommer till att spara text i kolumner så kan man tro att det är lämligt att ibland använda sig utav typerna text och ntext. Men det är helt fel, trots att de fortfarande går att använda. Tittar vi på bilden här under så ser vi att det går helt utmärkt.

Orsaken till att man inte ska använda dem är att SQL Server kommer blocka bort dem. Det innebär inte att du omgående måste bygga om din databas, men det innebär att någon gång i framtiden så kommer du inte längre kunna uppdatera din SQL Server om du använder dem. Det du bör göra är att aldrig använda dem när du skapar nya tabeller och suggestivt ta bort dem varje gång du stöter på dem.

Om du har en databas med någon utav dessa datatyper så är det dags för dig att göra upp en plan för att byta ut dem. Det första du måste tänka på är vilken kolumntyp du ska ha istället. Och det första är enkelt, ntext motsvarar nvarchar och text motsvarar varchar. En lite klurigare sak att fundera kring är att bestämma en längd, eftersom text inte behöver en angiven längd så måste du avgöra vilken längd du vill ha. Ett sätt är att undersöka längden som redan finns i tabellen, ungefär som bilden nedan.

När man väl har bestämt längden och datatypen kommer den svåra delen. Det gäller att gå igenom så att man ändrar på alla ställen där det behövs, finns det procedurer, vyer eller annat som förväntar sig att kolumnen är en text så måste man modifiera även dem.

Collate på en enskild kolumn - 2019-11-13

Det är inte så att man enbart kan sätta collate för databasen, trots att det är det vanligaste. Man kan faktiskt sätta collate på varje kolumn. Allt för att kunna spara flera olika typer av texter i samma tabell i samma databas. Det fungerar som bilden nedan visar.

Som ni tydligt ser så går det bra att spara olika typer av char i samma tabell. Vi kommer i framtida inlägg prata mer om collate, men det viktiga här är att komma ihåg att man kan vilja/behöva modifiera collate i vissa specialfall.

Dock måste jag erkänna att jag nästan aldrig använder mig utav detta och jag ser sällan någon annan heller göra det. Men det är lika bra att vi går igenom det också, eftersom det finns och ni måste kunna förstå att möjligheten finns samt känna igen det när ni ser det. (Orsaken till att det inte används så mycket är att man helt enkelt kan använda sig av nchar om man vill kunna använda andra tecken.)

Collate påverkar char - 2019-11-11

Jag funderade ett tag efter mitt förra inlägg och insåg att de utav er som inte ännu är experter på SQL Server kanske tycker att det är lite konstigt att svenska tecken som ö finns med men inte från andra språk. Orsaken är att man kan ställa in språket på en databas, och det påverkar vilka tecken som finns med i en char och varchar.

För att bestämma vilket språk en databas ska köra på så måste man ställa in collate. Det gör man enkelt via ett anrop enligt bilden nedan. Kom ihåg att när man gör det såhär så ställer man in det för hela denna databasen.

När man har ändrat collate för sin databas så påverkar den hur char och varchar fungerar i den databasen. Om ni tittar nu så kommer char kunna innehålla en ж medan ett ö omvandlas till ett o. Alltså inte en så bra inställning när man programmerar i Sverige.

Som ni ser så spelar collate stor roll för en databas. I fortsättningen kommer jag att använda mig utav en svensk version så att jag kan ha å, ä och ö i mina char. Det finns fler viktiga saker att tänka på när man väljer collate, men det kommer vara del utav en framtida serie om "viktiga databasinställningar". Jag ville bara förklara att det inte är magi som avgör vilka tecken som man kan använda i en char, utan det är en inställning. Men kom ihåg lärdomen från detta, om du är osäker på vilka tecken du kommer lagra så är alltid nchar och nvarchar att föredra.

Bonusinlägg om char - 2019-11-08

Idag blir det ett bonusinlägg, eftersom jag har stött på ett problem som jag inte kände till tidigare. Och eftersom du läser dessa så kanske du inte heller känner till det.

Jag har tidigare nämnt att char inte kan hantera alla tecken, till skillnad från nchar. Men när vi tittade på något exempel tidigare så visade det sig att när man försöker stoppa in ett okänt tecken så blir det ett frågetecken. Tyvärr blir det inte alltid så. Titta på bilden här under.

Som vi ser så kan SQL Server omvandla tecknen. Som här ovan där ņ omvandlas till n. Med andra ord så kan något som sparas i en char egentligen ha varit något annat. Jag är ingen språkexpert så jag vet inte skillnaden på dessa, men jag vet att skillnaden är stor på ett o och ett ö i svenskan så jag får antar att andra länder kan se stor skillnad på ņ och n. Slutsatsen är alltså, kom ihåg att använda er av nchar och nvarchar när det behövs. (Trots att de kostar dubbelt så många bitar.)

Fler beslut om texter i tabeller - 2019-11-07

Efter förra inlägget i denna serie så kan man bestämma sig om man vill ha nvarchar eller varchar. Men när valet är gjort så måste man bestämma sig om man vill ha nvarchar eller nchar, respektive varchar eller char. Skillnaden mellan dem är att de som har var med i namnet har en variabel längd medan de andra har en fix längd.

Låt oss först gå igenom vad det betyder med variabel längd eller inte. Jo, det menas med hur mycket plats det kommer ta upp i databasen. Det går alltså utmärkt att ha en sträng som är kortare än maxlängden i både varchar och char. Längden man anger efter både en varchar och char är maxlängden och det går inte att ha längre strängar än vad som är angivet. Alltså skillnaden är att i en sträng som sparas i char(10) alltid kommer uppta 10 platser i databasen, oavsett storleken på strängen. Medan i en varchar(10) så kommer platsen i databasen variera beroende på strängens längd. Kolla in bilden här under.

Som ni tydligt kan se så tar char(3) alltid upp 3 platser, medan varchar tar upp olika mycket beroende på hur lång strängen fakstikt är. Från detta kan man dra slutsatsen att varchar är bättre än char. Och för nästan alla texter som ska sparas så stämmer detta mycket väl. Så det korta svaret är, är du osäker använd en typ med var, framförallt med användarinförd data.

När ska man använda char då? Varför finns denna kolumntyp ens? Jo, för det är inte så enkelt. När man har en kolumntyp som använder sig av var så kommer det krävas 2 extra bitgrupper (bytes) för varje rad för att hålla koll på den faktiska längden. Om man vet att längden alltid kommer vara den samma för denna kolumn så sparar man lite extra plats genom att använda char. Ett typiskt fall att använda sig utav char är när man har en tabell med ordernummer och dessa innehåller både siffror och bokstäver men alltid har samma längd.

När jag själv använder mig av texter i databaser så skulle jag säga att den vanligaste är nvarchar för alla texter som jag inte helt säkert vet vad som kommer finnas i dem och ibland använder jag char för de fall när man vet vad som ska finnas i dem och då är längden ofta den samma. De två texttyperna nchar och varchar använder jag betydligt mer sällan.

Att spara texter i en tabell - 2019-11-05

Serien om tabeller tuffar på. Normalt behövs kolumner innehållande text. Ett vanligt sätt att spara text på är med nvarchar, vilket ger utvecklaren möjlighet att spara det mesta. En viktig sak att tänka på är att inte använda nvarchar när det finns specialanpassade kolumner att spara datan i. Exempelvis bör geografisk data sparas i geography om möjligt. (Mer om olika typer i framtida inlägg.)

Ett vanligt misstag man gör när man skapar nvarchar-kolumner är att man skapar dem för långa. Undvik att skapa dem längre än nödvändigt, eftersom allt för långa kan påverka prestandan. (Mer om prestandaoptimering kommer komma i framtida bloggserier.) Om du känner dig osäker på vilken längd du ska välja så ska du komma ihåg att det är enkelt att utöka längden längre fram om det skulle behövas, se bara på bilden här under.

En viktig fråga är om man bör använda sig utav nvarchar eller varchar. Och mitt korta svar är, är du osäker så kör med nvarchar. En av orsakerna är att nvarchar tillåter fler typer av tecken, något du kan se i bilden här under där varchar tydligt inte tillåter en bokstav i det kyrilliska alfabetet. Så, om du är osäker på vilka tecken som kommer användas eller om du sparar användarinförd data, välj nvarchar.

Vad är då fördelen med att använda sig utav varchar? Jo, den tar enbart upp hälften så mycket plats för samma mängd tecken. Det kan med andra ord förbättra prestandan i specifika fall. Det är dock ett mindre problem idag än tidigare då lagringsutrymme är billigt nu för tiden. De fall där det passar sig väl att använda sig utav varchar är för kolumner som sparar interna texter som man vet inte innehåller ovanliga tecken. Exempelvis om man har en tabell som loggar varje gång någon del av ett system används.

Tabeller är grunden, tider i kolumner - 2019-11-04

Den första bloggpostsserien drar igång med tabeller, vilket är hela grunden i alla SQL Server. Jag har funderat en lång stund och kunde faktiskt inte komma på en vettig databas utan tabeller. Därför börjar vi där. Och när jag har tänkt igenom allt lite mer så kom jag fram till att det faktiskt finns många fler fallgropar än man kan tro. Men innan vi kommer till de lite svårare valen så kommer jag börja med att gå igenom grunden till tabeller, nämligen kolumner.

När man väljer att ha med tider i sin tabell så finns det flera val man måste göra. Det första är att bestämma sig om man behöver både klockslag och datum. Ett vanligt misstag jag ser är att man inte använder sig utav kolumntyperna time och date utan man kör datetime2 för allt. Det är självklart onödigt om man bara använder sig utav datumen eller klockslagen. Så fundera ett extra varv innan du väljer vilken tid du verkligen behöver. Och kom ihåg, behöver du inte sekunder och millisekunder så kan man alltid använda sig utav smalldatetime.

Oftast kommer man fram till att man behöver använda sig utav både datum och klockslag. Och då finns det inte så många val, då är det datetime2 som gäller. Men så enkelt är det inte, eftersom SQL Server tyvärr har en tidstyp till, nämligen datetime. Dock bör man aldrig använda sig utav datetime eftersom den helt enkelt är sämre än datetime2, och datetime finns enbart kvar för backåtkompabilitet. Och jag ska nu demonstrera varför man inte bör använda datetime.

Som du kan se i bilden ovan så har datetime avrundat millisekunderna lite galet. Orsaken till det är att datetime enbart tillåter millisekunder som slutar på 0, 3 och 7. Men datetime2 tillåter att de slutar på valfri siffra, alltså betydligt bättre. Om du nu inte bryr dig om att ha så hög noggrannhet och någon millisekund hit eller dit inte spel någon roll, då kan du med datetime2 välja lägre noggrannhet och därigenom spara 1 bitgrupp (byte).

Första inlägget - 2019-11-02

Detta är mitt första inlägg och jag kommer inte tillhandahålla någon typ av vettig information i detta inlägg. Syftet är mest att se så att allt fungerar. Men om du lyckas hitta hit innan jag har hunnit lägga till något mer så hoppas jag du återvänder inom kort då jag hoppas ha igång bloggen inom en vecka.

Återkommer snart...