# Databas

## Vad det är

En databas är en mängd data som hålls i en fast struktur, med regler för vad som får komma in, så
att program kan hitta, ändra och kontrollera innehållet. Samma ord, ofta förkortat DB, används
också löst om programmet som sköter förvaringen. Det exakta namnet på det programmet är
databashanterare, på engelska database management system eller DBMS. Ordlistan från NIST återger
två definitioner, och den bredare beskriver ett förråd av information eller data som kan vara,
men inte behöver vara, ett traditionellt relationsdatabassystem.

Ordet gör tre jobb, och ett samtal går i cirklar när två personer menar olika saker. Det står för
innehållet: kunderna, beställningarna och sensoravläsningarna som en organisation sparar. Det står
för motorn som håller dem: PostgreSQL, SQL Server, SQLite. Och inuti en server står det för en
behållare bland flera. Handledningen till PostgreSQL ställer upp nivåerna: rader med namngivna,
typade kolumner bildar tabeller, tabeller grupperas i databaser, och de databaser som en
serverinstans hanterar tillsammans bildar ett databaskluster. SQL Server drar samma gräns mellan
en instans och de databaser den rymmer. ”Databasen är långsam” kan alltså betyda en tabell, en
behållare eller en hel maskin.

De flesta motorer i dagligt bruk är relationella: de lagrar data som relationer, den matematiska
termen för tabeller, och tar emot SQL-frågor. Handledningen till PostgreSQL nämner andra upplägg.
Filerna och katalogerna i ett Unix-liknande system bildar en hierarkisk databas, och
objektorienterade databaser kom senare. Redis beskriver sig som en datastrukturserver: i stället
för tabeller erbjuder den strängar, hashar, listor, mängder och andra inbyggda typer, som används
för cachning, köer och händelsehantering.

Motorer skiljer sig också i var de körs. En klient/server-motor är en långlivad process som många
program når över ett nätverk. En inbäddad motor är ett bibliotek inuti ett enda program, och
SQLite håller en hel databas, med tabeller, index, triggers och vyer, i en enda vanlig fil.
Projektet säger själv att det konkurrerar med `fopen()` snarare än med serverdatabaser. Skillnaden
syns i hur ett program ansluter:

```sh
# client/server: connect to a service that is already running
psql "host=db.internal dbname=shop user=app"

# embedded: the program opens a file and the engine runs inside it
sqlite3 shop.db
```

En tredje familj är byggd för analys. BigQuery lagrar varje kolumn för sig, medan många
traditionella system håller en rads fält samlade på disk. Radlagring passar när du slår upp en
enskild post; kolumnlagring passar när du summerar ett fält över miljontals rader, eftersom
databasfrågan då läser just den kolumnen och lämnar resten i fred.

## Varför det spelar roll

Filer rymmer också data. En databas lägger till löften om innehållet, för det läge då många
program använder det på samma gång.

Det första löftet är en konsekvent bild vid samtidig användning. PostgreSQL ger varje sats en
ögonblicksbild av datan som den såg ut vid en viss tidpunkt, en design som kallas multiversion
concurrency control, MVCC, så att läsning aldrig blockerar skrivning och skrivning aldrig blockerar
läsning. SQLite tillåter hur många läsare som helst samtidigt och en skrivare åt gången, medan
övriga skrivare väntar på sin tur. De två passar olika antal skrivare, och det antalet gör en stor
del av valet.

Det andra löftet är att datan behåller sin form. Ett databasschema anger vilka kolumner en tabell
har och vilken typ var och en håller; nycklar och villkor anger vilka rader som får finnas. När
databasen själv upprätthåller reglerna följer varje program som skriver till den dem. När reglerna
bara finns i applikationskoden lämnar det första program som hoppar över dem rader efter sig, och
varje senare databasfråga måste sedan försvara sig mot dem.

Det tredje är ett gemensamt språk, med dialekter. SQL är standarden ISO/IEC 9075, senast
reviderad som SQL:2023, men bilagan om standardefterlevnad i dokumentationen för PostgreSQL
noterar att inget nuvarande system gör anspråk på full överensstämmelse med standardens Core. Ett
schema och dess databasfrågor hör till sin motor, och att flytta dem till en annan är ett eget
projekt med egen testning.

Dokumentationen för SQLite gör valet av motor till en kort checklista. Data som ligger på andra
sidan ett nätverk från koden som skickar SQL, många processer som skriver i samma ögonblick eller
innehåll på väg mot terabyteklassen pekar var och en mot klient/server; annars är SQLite det
enklare svaret. Rapportering i stor skala lägger till en fråga till: om tunga läsningar hör hemma
på en separat analyskopia, fylld via ETL, så att en lång rapport aldrig konkurrerar med de
databasfrågor som kunderna väntar på.

## Så ser det ut i praktiken

Databaserna här sträcker sig från över 100 i en och samma roll till en enda SQLite-fil.

I den stora änden ligger en roll som databasingenjör på ett snabbväxande techföretag, där uppdraget
var att
[skapa, förvalta och optimera över 100 databaser i PostgreSQL, Microsoft SQL Server och Google BigQuery](/sv/portfolio/architected-created-and-managed-100-postgresql-ms-sql-12/).
De flesta av dem höll GIS-data och tidsseriedata som sensoravläsningar, loggar och mätvärden i
realtid. Arbetet gav normaliserade och denormaliserade scheman för PostgreSQL och SQL Server, med
spatial indexering (PostGIS på PostgreSQL-sidan) och tidsseriepartitionering, medan BigQuery bar
stora mängder tidsseriedata i tidspartitionerade, klustrade tabeller. Med indexering,
materialiserade vyer och cachning på plats minskade svarstiderna för databasfrågor mot GIS- och
tidsseriedata med 40–60 %, och automatiserad övervakning minskade driftstoppen med 50 %.

I den lilla änden
[rymmer en enda SQLite-fil fakta bakom ett CV, ett referensblad, en portfölj och ett personligt brev](/sv/portfolio/built-a-database-driven-cv-and-portfolio-generator-144/)
på tre språk. Dess tjugotre tabeller fylls av en datapipeline i nitton steg, och ett enda kommando
bygger hela databasen från grunden; varje steg är idempotent, alltså säkert att köra igen. Fyrtioen
Python-moduler, 10 580 rader sammanlagt, renderar sex utdataformat ur den. En profil väljer vilka
resultat som visas och i vilken ordning, så ett dokument riktat till en viss sorts läsare är, med
sidans egna ord, ”en databasfråga snarare än en kopia”. Sidan nämner också priset: systemet är nu
det enda sättet att ta fram ett dokument.

Mellan de storlekarna står frågan som varje hårt belastad databas till slut möter, och
[en anteckning om att optimera innan du shardar](/sv/notes/optimise-before-you-shard/) besvarar
den med en arbetsordning: titta, skärp, flytta läsningarna från primärnoden, partitionera
tabellerna runt den heta punkten och sharda först när en maskin är full av bra arbete. Att titta
betyder att fråga PostgreSQL själv: `pg_stat_statements` för de satser som kostar mest totalt,
sedan `EXPLAIN (ANALYZE, BUFFERS)` för vad den dyraste av dem gör.

## Var det går fel

De flesta problem med en databas börjar i ett beslut som fattades tidigt, när datan var liten och
beslutet såg gratis ut.

**Två kopior av samma uppgift glider isär.** CV-generatorn ovan finns för att fakta som hålls i
fyra dokument rättas fyra gånger, tills två av dem säger emot varandra och ingenting visar vilket
som gäller. Samma sak händer en tabell som exporteras till ett kalkylark och redigeras där, eller
en andra tjänst med en egen kundlista. Ge varje uppgift en enda plats som äger den, och låt varje
annan kopia säga var den kommer ifrån och när den togs. Anteckningens cache följer den regeln
strikt: den får tala om för en köpare att en vara är fullt reserverad, men varje ja kommer
fortfarande från databasen.

**Fler maskiner kommer innan någon har läst frågeplanerna.** Att dela upp data över flera servrar
sprider de långsamma satserna över mer hårdvara utan att göra någon av dem billigare, och det
lägger en bestående kostnad på allt annat. Som anteckningen räknar upp körs varje
databasmigrering, säkerhetskopiering, återställning och rapport en gång per shard, och en join
över flera shards blir applikationskod. Läs `pg_stat_statements` och frågeplanerna först, och
behåll det de visar som utgångsläge.

**En läsning hamnar på en kopia som ligger efter.** En strömmande replik tar läsningar från
primärnoden och ligger hela tiden en liten bit efter den. En användare som just har skrivit något
och sedan läser tillbaka det från repliken kan få se det gamla värdet. Läs en användares egna
nyliga skrivningar från primärnoden.

**Rapporter och kunder delar en motor.** En rapport som skannar två års historik håller minne och
disk som butikens egna databasfrågor behöver, och de som handlar märker det. Flytta tung analys
till en kopia i ett analysdatalager, och låt den arbetande databasen sköta de många små läsningar
och skrivningar som den finns till för.

## Läs mer

- [NIST glossary: database](https://csrc.nist.gov/glossary/term/database) — två korta
  definitioner ur publikationer från NIST, varav den ena ger plats för databaser som inte är
  relationella.
- [PostgreSQL tutorial: Concepts](https://www.postgresql.org/docs/current/tutorial-concepts.html)
  — tabeller, rader, kolumner, databaser och databasklustret, på en enda sida.
- [PostgreSQL: Introduction to MVCC](https://www.postgresql.org/docs/current/mvcc-intro.html) —
  hur ögonblicksbilder låter läsare och skrivare arbeta utan att blockera varandra.
- [PostgreSQL: SQL Conformance](https://www.postgresql.org/docs/current/features.html) — delarna
  och versionerna av ISO/IEC 9075, och vad överensstämmelse med Core innebär.
- [Appropriate Uses For SQLite](https://www.sqlite.org/whentouse.html) — var en inbäddad motor
  passar, var en klient/server-motor passar bättre, och en checklista för valet.
- [Overview of BigQuery storage](https://cloud.google.com/bigquery/docs/storage_overview) — rad-
  och kolumnorienterad lagring, och varför analys gynnar den senare.

<https://engineer.company/sv/glossary/database/>
