Gå til innholdet

Plasser data der de hører hjemme

Finnes også på 28 språk

English · Español · 日本語 · Português (Brasil) · Français · Deutsch · Italiano · 한국어 · 简体中文 · Português (Portugal) · 繁體中文 · Bahasa Indonesia · Türkçe · Polski · Tiếng Việt · ไทย · Nederlands · العربية · עברית · Українська · हिन्दी · Русский · Svenska · Dansk · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

Two identical drawers on a workbench, seen from above: one jammed with everything mixed together, one divided so each kind of thing has its own compartment.
Bildet er laget med KI

Modul 4 av 6 i kapitlet Modeller data for mening, kapittel 2 i kurset Data Architect. Hver modul står på egne ben. Forrige: Bygg den logiske modellen · Neste: Design til tredje normalform, og trekk deg så litt tilbake

Spørsmålet denne modulen besvarer: Hvordan hjelper normalisering meg med å finne ut hvor data egentlig hører hjemme?

Vi har en logisk modell: entiteter, relasjoner, attributter og nøkler. Nå vil jeg stille et av de viktigste spørsmålene i datamodellering: hører disse dataene egentlig hjemme her?

Det høres enkelt ut. Det er det ikke. Jeg har sett mange systemer der hvert eneste felt ga mening da noen opprettet det. Problemet var ikke at feltene var latterlige; det var at faktaene var lagret på feil sted. En levering inneholder informasjon som egentlig beskriver et distribusjonssenter. Den samme adressen står på hundrevis av poster. Ett felt inneholder tre verdier skilt med komma. En endring i ett forretningsfaktum betyr at 10 000 poster må oppdateres. Det er problemet normalisering hjelper oss å løse, og før vi drukner i databaseterminologi, her er hele ideen: plasser et faktum der det hører hjemme. Alt annet i denne modulen hjelper oss å gjøre det mer systematisk.

Normalisering er å organisere data slik at hvert faktum lagres én gang, på stedet det hører hjemme. Når én tabell gjør for mange jobber, deler vi den opp i tabeller som hver beskriver én ting, og kobler dem sammen med nøkler.

Hvorfor bry seg? Fordi et faktum som er lagret én gang, er et faktum vi endrer én gang. Normalisering hindrer redundans, det samme faktumet kopiert over mange poster, og med den inkonsistensene som sniker seg inn når én kopi blir oppdatert og de andre ikke. Det er derfor den passer for transaksjonssystemer som Salesforce, der poster opprettes og oppdateres hele dagen.

Vi normaliserer i trinn som kalles normalformer, og hver av dem stiller ett enkelt spørsmål:

  • Første normalform (1NF): én verdi per felt, og noe som identifiserer hver rad entydig.
  • Andre normalform (2NF): hvert faktum beskriver hele det som identifiserer raden, ikke bare en del av det.
  • Tredje normalform (3NF): hvert faktum beskriver denne tingen, ikke noe annet den henger sammen med.

Det finnes flere former enn den tredje. Jeg sier et ord om dem senere, og om hvorfor vi vanligvis stopper ved den tredje. Først skal vi se de tre trinnene skje.

Når jeg underviser dette live, starter jeg ikke med leveringer. Jeg starter med hunder. Alle forstår hunder, så ingen blir distrahert av virksomheten, og vi kan se dataene prøve å finne hjemmet sitt. Så tar vi de samme grepene med oss til Steve Trucking.

Start: det rå regnearket. Jeg legger opp et par hunder på skjermen, og så legger rommet til sine. I løpet av noen minutter har vi én stor liste: hunden, året den ble født, hvem som eier den, hvor eieren bor, rasen, hvem som avlet den, og triksene den kan.

HundFødtEierPostnr.ByRaseOppdretterTriks
Bella2017Marcus80202DenverLabradorMaple RidgeSitt, Bli, Gi labb
Milo2019Marcus80202DenverPuddelGolden MeadowSitt, Rull rundt
Max2022Ana64105Kansas CityBlandingSitt, Død hund
Luna2020Kenji98101SeattleHuskyCascadeSitt, Bli, Snurr rundt
Rocky2024Priya30301AtlantaBeagleMaple RidgeSitt
Coco2014Ana64105Kansas CityChihuahuaLittle PawsGi labb, Snurr rundt

Det fungerer. Alle regneark fungerer den første dagen. Men se hva som allerede er galt. Hvordan finner jeg alle hundene som kan Gi labb? Anas postnummer står på to rader, og det samme gjør Marcus’ postnummer: hva skjer hvis noen oppdaterer den ene og ikke den andre? Maple Ridge står der to ganger, og det samme gjør Kansas City. Og Max kom fra et dyrehjem, så det finnes ingen oppdretter i det hele tatt.

Trinn 1: første normalform. To regler. Hvert felt inneholder én enkelt verdi, så kommalisten med triks må bort. Og hver rad trenger noe som identifiserer den entydig. Ikke hundens navn; det finnes mange hunder som heter Max. En ID: en automatisk generert ID eller en GUID. Triksene flyttes ut i egne rader, én rad for hver hund og hvert triks. Og når et triks har sin egen rad, er det plass til det vi aldri kunne si i en kommaliste: hvor vanskelig trikset er, hvor godt denne hunden gjør det, og når den lærte det.

Hund (identifisert av Hund-ID)

Hund-IDNavnFødtEierPostnr.ByRaseOppdretter
D-001Bella2017Marcus80202DenverLabradorMaple Ridge
D-002Milo2019Marcus80202DenverPuddelGolden Meadow
D-003Max2022Ana64105Kansas CityBlanding
D-004Luna2020Kenji98101SeattleHuskyCascade
D-005Rocky2024Priya30301AtlantaBeagleMaple Ridge
D-006Coco2014Ana64105Kansas CityChihuahuaLittle Paws

Hundetriks (identifisert av Hund-ID + Triks)

Hund-IDTriksVanskelighetsgradFerdighetsnivåLært
D-001SittLettEkspert2017-11
D-001BliLettEkspert2018-01
D-001Gi labbMiddelsGod2018-06
D-002SittLettEkspert2020-02
D-002Rull rundtVanskeligLærer2023-05
D-003SittLettGod2022-06
D-003Død hundVanskeligLærer2024-03
D-004SittLettEkspert2020-11
D-004BliLettGod2021-01
D-004Snurr rundtMiddelsEkspert2021-06
D-005SittLettLærer2025-02
D-006Gi labbMiddelsEkspert2015-06
D-006Snurr rundtMiddelsLærer2025-04

Nå er «alle hundene som kan Gi labb» et enkelt spørsmål. Men legg merke til hva Hundetriks identifiseres av: ikke én ting, men to ting sammen, hunden og trikset. Hold fast på det.

Trinn 2: andre normalform. Andre normalform betyr bare noe når en rad identifiseres av en kombinasjon, og det gjør Hundetriks. Så jeg spør om hver kolonne: beskriver den hele kombinasjonen, eller bare en del av den? Ferdighetsnivå beskriver denne hunden som gjør dette trikset: Bella er ekspert på Sitt, Rocky lærer det fortsatt. Lært, det samme. Men Vanskelighetsgrad? Sitt er lett uansett hvilken hund som gjør det. Det beskriver trikset, bare en del av nøkkelen, og det er derfor «Lett» gjentas på hver Sitt-rad. Så trikset får sin egen tabell, og det som er igjen, er paret.

Triks

Triks-IDTriksVanskelighetsgrad
T-01SittLett
T-02BliLett
T-03Gi labbMiddels
T-04Rull rundtVanskelig
T-05Død hundVanskelig
T-06Snurr rundtMiddels

Hundetriks (Hund-ID + Triks-ID)

Hund-IDTriks-IDFerdighetsnivåLært
D-001T-01Ekspert2017-11
D-001T-02Ekspert2018-01
D-001T-03God2018-06
D-002T-01Ekspert2020-02
D-002T-04Lærer2023-05
D-003T-01God2022-06
D-003T-05Lærer2024-03
D-004T-01Ekspert2020-11
D-004T-02God2021-01
D-004T-06Ekspert2021-06
D-005T-01Lærer2025-02
D-006T-03Ekspert2015-06
D-006T-06Lærer2025-04

Den Hundetriks-tabellen er den vi fant i modul 2, og den har et navn i datamodellering: en kobling (junction), eller som jeg kaller det, et logisk koblingsobjekt. En hund kan mange triks; et triks kan mange hunder. Koblingsobjektet står mellom dem, og det er ikke tomt rørleggerarbeid: det inneholder faktaene som hører til selve relasjonen, ferdighetsnivået og datoen. Vi møter det igjen i modul 6, og i kapittel 3 ser vi at Salesforce bruker «junction object» i en snevrere betydning: et koblingsobjekt i Salesforce (Salesforce Junction Object) er et egendefinert objekt med to master-detail-relasjoner (kapittel 3, modul 7).

Trinn 3: tredje normalform. Nå tilbake til Hund-tabellen. Alt i den identifiseres av Hund-ID, så andre normalform har ingenting å si. Tredje normalform stiller et annet spørsmål: beskriver dette faktumet hunden, eller noe annet hunden henger sammen med? Rasen er en egen ting: en labrador er en labrador uansett hvilken hund det er, og fakta om den, som størrelsen, hører til rasen, ikke til Bella. Postnummeret og byen beskriver eieren, ikke hunden: det er der Ana bor, uansett hvilken av hundene hennes vi ser på. Opplysningene om oppdretteren beskriver oppdretteren. Hver av dem er et faktum om et annet faktum, så hver flytter til sin egen tabell, og hunden peker på den med en fremmednøkkel:

  • Hund: Hund-ID, Navn, Født, Eier-ID, Rase-ID, Oppdretter-ID
  • Eier: Eier-ID, Navn, Postnr., By
  • Rase: Rase-ID, Rase, Størrelse
  • Oppdretter: Oppdretter-ID, Navn, By
  • Triks og Hundetriks, fra trinn 2

Ana er lagret én gang nå, og begge hundene hennes peker på henne. Maple Ridge er lagret én gang, og Rase-tabellen gir oss et hjem for fakta om hver rase, som størrelsen, som regnearket ikke hadde noe sted å legge. En fremmednøkkel kan være tom: Max har ingen Oppdretter-ID, og det er et ærlig svar, ikke et hull. Så kaster jeg et lurespørsmål ut i rommet: når eieren fikk hunden, hvor skal den datoen stå? På hunden. En hund har én eier om gangen i denne modellen, så den datoen beskriver hundens relasjon til eieren sin.

Du kunne gått ett steg lenger og skilt byen fra postnummeret; lærebøkene gjør det. I praksis holdes en adresse samlet, og Kansas City ligger uansett i to delstater, en fin påminnelse om at den virkelige verden ikke leser lærebøkene våre.

Det er progresjonen: et regneark, så tre spørsmål, og hvert faktum havner på ett sted. Ta et skritt tilbake og se på hva vi bygde. Én rotete liste ble seks tabeller, som hver beskriver én ting, koblet sammen med nøkler:

Hundemodellen etter tredje normalform Seks bokser koblet med linjer. En eier eier én eller mange hunder. En hund har én eier, er én rase og ble avlet av null eller én oppdretter (en oppdretter avler én eller mange hunder). Mellom Hund og Triks sitter Hundetriks: en hund kan null eller mange hundetriks, et triks kan av null eller mange hundetriks, og hvert hundetriks hører til nøyaktig én hund og ett triks. eier avler er en kan kan av Eier Oppdretter Hund Rase Hundetriks Triks nøyaktig én null eller én én eller mange null eller mange © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Ingen trengte et eneste Salesforce-ord for å henge med på det. Det er bare hundene, menneskene rundt dem, og det de kan.

Hundene gjør grepene lette å se. En ekte virksomhet gjør at de betyr noe, fordi de samme feilene koster ekte penger i stor skala. Så la oss ta de samme tre spørsmålene med til Steve Trucking. Tenk deg at selskapet holder styr på leveringene sine slik:

LeveringDetaljhandelspartnerDistribusjonssenterDC-byTeamLastebil
1001KeystoneKeystone Phoenix DCPhoenixTeam 12117
1002KeystoneKeystone Phoenix DCPhoenixTeam 8122
1003KeystoneKeystone Phoenix DCPhoenixTeam 12117

Ved første øyekast er ingenting her komplisert. Men se på distribusjonssenteret. Vi gjentar «Keystone Phoenix DC, Phoenix» på hver levering som drar derfra: Steve Trucking gjør rundt 3 300 leveringer om dagen fordelt på ni DC-er, så noen hundre om dagen fra hvert. Hva skjer hvis det DC-et flytter? Hvor mange poster endrer vi, og hva skjer hvis én blir glemt? Nå sier dataene at DC-et ligger i to byer samtidig. Det er en oppdateringsanomali. Hva om vi vil sette opp et nytt DC før den første leveringen? Hva om vi sletter den siste leveringen fra et DC: slettet vi nettopp det eneste stedet vi lagret noe om det?

Dette er forskjellige symptomer på det samme problemet: vi blandet sammen fakta om forskjellige ting. Fakta om distribusjonssenteret hører hjemme hos distribusjonssenteret. Fakta om leveringen hører hjemme hos leveringen. Fakta om teamet hører hjemme hos teamet. Det er normalisering i praksis.

Første normalform: ikke skjul gjentatt struktur

Section titled “Første normalform: ikke skjul gjentatt struktur ”

La oss starte med første normalform, eller 1NF, der folk noen ganger gjør normalisering vanskeligere enn den trenger å være.

Tenk deg at en levering har et felt som heter Varer: «Kjøleskap, ismaskinsett, bortkjøring». Vi har lagt tre biter informasjon i ett felt. Det virker praktisk, helt til noen spør: «Hvor mange bortkjøringer gjorde vi forrige måned?» Eller tenk deg felt som heter Vare 1, Vare 2 og Vare 3. Det fungerer, helt til leveringen med fire varer. Problemet er ikke at vi valgte feil antall vare-felt. Problemet er at vi ikke kjente igjen den gjentatte strukturen. En levering kan ha flere varer. Det er data vi bør modellere: leveringslinjen vi fant i modul 2.

En leverings varer, på tre måter Tre kort viser den samme leveringens varer lagret på tre måter. Ett felt: levering 1001 har et felt Varer med teksten «Kjøleskap, ismaskinsett, bortkjøring», som ikke kan svare på hvor mange bortkjøringer det var forrige måned. Gjentatte felter: Vare 1 kjøleskap, Vare 2 ismaskinsett, Vare 3 bortkjøring, som ikke kan romme en levering med fire varer. En underordnet post, uthevet: levering 1001 har tre leveringslinjer, kjøleskap, ismaskinsett og bortkjøring, og den neste varen er en ny post, ikke et nytt felt. En merknad under: hvis noe kan skje mange ganger, kan det være en annen entitet som prøver å komme ut. Ett felt tre fakta gjemt i én verdi LEVERING 1001 Varer: Kjøleskap, ismaskinsett, bortkjøring SPØRSMÅLET DET IKKE KAN SVARE PÅ Hvor mange bortkjøringer forrige måned? Gjentatte felter Vare 1, Vare 2, Vare 3 LEVERING 1001 Vare 1: Kjøleskap Vare 2: Ismaskinsett Vare 3: Bortkjøring LEVERINGEN DET IKKE KAN ROMME Den med fire varer En underordnet post en leveringslinje for hver LEVERING 1001 Leveringslinje: Kjøleskap Leveringslinje: Ismaskinsett Leveringslinje: Bortkjøring DEN NESTE VAREN En ny post, ikke et nytt felt Hvis noe kan skje mange ganger, kan det være en annen entitet som prøver å komme ut. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Den praktiske lærdommen fra 1NF: ikke skjul gjentatt struktur inni felt. Hvis virksomheten forteller deg at noe kan skje mange ganger, lytt. Det kan være en annen entitet som prøver å komme seg ut.

Du ser dette i ekte orger hele tiden. Noen trenger en beskrivelse på flere språk, så de oppretter et felt som heter Description_English, så Description_French, så Description_German. Eller en godkjenning trenger noen få personer, så vi får Godkjenner 1, Godkjenner 2, Godkjenner 3. Når jeg finner det i en gjennomgang, blir det et klaps på fingrene: rett opp datamodellen. Ett eller to, kanskje, hvis virksomheten virkelig bare har ett eller to. Alt utover det bør være et underordnet objekt: en Oversettelse med et språk, et Godkjenningstrinn med en godkjenner. Neste språk, eller den fjerde godkjenneren, blir en ny post, ikke et nytt felt og en utrulling.

Andre normalform, eller 2NF, betyr noe når en post identifiseres av en kombinasjon av ting. Ta leveringslinje. Den har sin egen post-ID, men hver enkelt er unik ved levering + produkt. Tenk deg at vi lagrer leveringen, produktet, antallet og produktets beskrivelse.

Antall gir mening her: det beskriver dette produktet på denne leveringen. Men produktbeskrivelsen beskriver ikke kombinasjonen; den beskriver produktet. Legg den på hver leveringslinje, så gjentar vi den hver gang den kjøleskapsmodellen går ut på en ny lastebil. Det er hintet om at faktumet hører hjemme et annet sted.

Så 2NF-spørsmålet er: beskriver dette attributtet hele tingen jeg identifiserer, eller bare en del av den? Hvis det bare beskriver produktet, hører det til produktet. Hvis det beskriver produktets plass på akkurat denne leveringen (antallet, om det skal installeres), hører det hjemme på leveringslinjen. Mange admins kommer aldri bevisst til å si: «Nå bruker jeg andre normalform.» Det er helt greit. Jeg bryr meg mye mer om at du lærer å spørre: hva beskriver dette faktumet egentlig?

Tredje normalform: ikke lagre fakta om andre fakta

Section titled “Tredje normalform: ikke lagre fakta om andre fakta ”

Nå den jeg bryr meg mest om i daglig modellering: tredje normalform, eller 3NF.

Hvert distribusjonssenter har en leder på detaljhandelspartnerens side, en som bruker partnerportalen. Tenk deg at vi legger navnet på DC-lederen direkte på hver levering. Hva skjer når DC-et får en ny leder? Vi oppdaterer hver levering fra det DC-et. Det er den samme lukten igjen: vi gjentar et faktum som hører hjemme et annet sted. Leveringen drar fra et DC; DC-et har en leder. Det er to relasjoner, og navnet på lederen hører hjemme hos DC-et.

Den klassiske lærebokversjonen er adressen: postnummer, by og delstat lagret sammen på hver post, når by og delstat vanligvis følger av postnummeret. Samme form, samme spørsmål.

Et faktum om et annet faktum: DC-lederen To paneler. På hver levering: en leveringspost med post-ID, leveringsdato, distribusjonssenter og DC-ets by og leder, begge merket som gjentatt. Lagret én gang, hos DC-et: leveringen beholder post-ID, leveringsdato og distribusjonssenter-ID og går fra et distribusjonssenter, som har sin egen post-ID, navn, by og leder. En merknad under: en ny DC-leder betyr hundrevis av oppdateringer til venstre og én til høyre. PÅ HVER LEVERING LAGRET ÉN GANG, HOS DC-ET går fra Levering Leverings-ID POST-ID Leveringsdato Distribusjonssenter DC-by GJENTATT DC-leder GJENTATT Levering Leverings-ID POST-ID Leveringsdato Distribusjonssenter-ID Distribusjonssenter Distribusjonssenter-ID POST-ID Navn By Leder En ny DC-leder: hundrevis av oppdateringer til venstre, én til høyre. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Det praktiske 3NF-spørsmålet er: beskriver dette faktumet denne tingen, eller noe annet denne tingen henger sammen med? Jeg vil at du skal stille det hele tiden.

Ta nå et skritt tilbake, på samme måte som vi gjorde med hundene. Leveringstabellen vi startet med, har blitt fem ting, som hver har sine egne fakta: leveringslinjen kom ut ved første normalform, produktet ved andre, og distribusjonssenterets by og leder flyttet til distribusjonssenteret ved tredje.

Steve Trucking etter normalisering Fem bokser koblet med linjer. En detaljhandelspartner driver null eller mange distribusjonssentre. En levering går fra nøyaktig ett distribusjonssenter og inneholder én eller mange leveringslinjer. Hver leveringslinje er nøyaktig ett produkt, og et produkt finnes på null eller mange leveringslinjer. driver går fra inneholder finnes på Detaljhandelspartner Levering Leveringslinje Produkt Distribusjonssenter nøyaktig én null eller én én eller mange null eller mange © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Samme tre spørsmål, samme resultat: hvert faktum på ett sted.

En enkel måte å tenke på 1NF, 2NF og 3NF

Section titled “En enkel måte å tenke på 1NF, 2NF og 3NF ”

Du kan bruke et helt databasekurs på normalisering. Det skal ikke vi. I dette kurset vil jeg at du skal ha en arbeidende arkitekts forståelse:

  • 1NF: skjuler jeg flere verdier eller gjentatte strukturer inni et felt eller en post?
  • 2NF: beskriver dette faktumet hele tingen jeg identifiserer?
  • 3NF: beskriver dette faktumet virkelig denne entiteten, eller noe som henger sammen med den?

Det er ikke definisjoner til en lærebok i databaser. Det er spørsmål jeg faktisk kan bruke mens jeg designer.

Ja, normalisering går lenger: Boyce-Codd-normalform (BCNF) strammer inn reglene rundt 3NF for modeller med mer kompliserte nøkler, og det finnes fjerde, femte og til og med sjette normalform. De handler om sjeldnere former for gjentakelse, den typen som kommer fra uvanlige nøkkelstrukturer mer enn fra vanlige forretningsposter. Mye teori, og etter min erfaring ikke verdt hodebryet for den typen systemer vi bygger på Salesforce. I forretningssystemer går presset vanligvis den andre veien: det er mye mer sannsynlig at vi trekker oss tilbake fra tredje normalform, for brukerne, rapporteringen og ytelsen, enn at vi går forbi den. Det er neste modul. Vit at de videre formene finnes, men for det meste av det vi gjør, gir 1NF til 3NF oss tankeverktøyene vi trenger.

Her er mitt standpunkt. Når jeg prøver å forstå en virksomhet og designe den logiske modellen, vil jeg starte rent: fakta om leveringen hos leveringen, fakta om distribusjonssenteret hos DC-et, fakta om lastebilen hos lastebilen, gjentatte begreper modellert som begreper. Jeg vil ikke ha et forretningsfaktum kopiert rundt i hele modellen bare fordi det kanskje gjør en skjerm eller en rapport enklere. Ikke ennå.

Men normalisering er ingen religion. Målet er ikke en mest mulig akademisk ren modell. Jeg har sett arkitekter bli så opptatt av renhet at modellen blir smertefull for alle som må bruke den. Vi prøver ikke å vinne en konkurranse i normalisering; vi bygger et system, og det systemet har brukere, rapporter, integrasjoner, ytelseskrav, skala og, i økende grad, KI (AI) som leser dataene. De kan ønske seg dataene i andre former.

Så utgangspunktet mitt er design til tredje normalform der det er mulig, og trekk deg tilbake når det er nødvendig: forstå først hvor hvert faktum hører hjemme. Hvis vi så skal bryte med det, vil jeg vite hvorfor. Hvis svaret er «fordi jeg ikke visste hvor ellers jeg skulle legge feltet», er det ikke godt nok. Hvis svaret er «vi kopierte denne verdien med vilje fordi det gjør resultatkortet for partnerne enkelt, og vi har en pålitelig måte å holde den synkronisert på», da har vi en arkitektursamtale.

Når jeg normaliserer en logisk modell, ser jeg etter:

  • Gjentatte verdier eller strukturer som bør modelleres separat.
  • Attributter som beskriver en annen entitet enn den de er lagret på.
  • Fakta som er duplisert unødvendig over mange poster, og avhengighetene som gjør dem inkonsistente.
  • Forretningsbegreper som er skjult inni felt.
  • En ren modell som representerer sannheten før noen implementeringskompromisser.

Ikke fordi alle fysiske systemer må forbli perfekt normaliserte. Snarere tvert imot. I neste modul bryter vi med den rene modellen med vilje, for brukerne, rapporteringen, skalaen, analysen og KI, og vi gjør det med full oversikt over hva vi bytter bort.