Hoppa till innehåll

Designa till tredje normalformen, backa sedan

Finns även 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 · العربية · עברית · Українська · हिन्दी · Русский · Dansk · Norsk bokmål · Suomi · Español (México) · Français (Canada) · Deutsch (Schweiz)

A park seen from above: paths at right angles, and one diagonal shortcut that people kept walking, now deliberately paved, with the old worn track still faint beside it.
Bilden är skapad med AI

Modul 5 av 6 i kapitlet Modellera data för mening, kapitel 2 i kursen Data Architect. Varje modul står på egna ben. Föregående: Lägg data där de hör hemma · Nästa: Gör modellen till Salesforce

Frågan den här modulen besvarar: När ska jag medvetet gå bort från en ren, normaliserad modell?

I förra modulen sa jag åt dig att designa för tredje normalformen.

Nu ska jag säga åt dig att bryta mot den.

Ibland.

Det är en viktig skillnad. Det är stor skillnad på att av misstag bygga en rörig datamodell och att medvetet denormalisera en ren. Om du inte förstår var data hör hemma från början är det ingen arkitektur att kopiera dem någon annanstans. Det är bara duplicering.

Men när jag väl förstår den rena logiska modellen kan jag fatta ett medvetet beslut om att forma data annorlunda för de människor och system som använder dem.

Designa till tredje normalformen där det är möjligt. Backa sedan när det behövs.

Lägg märke till vad den meningen inte säger. Den säger inte att tredje normalformen är lättare att förstå. Ibland är den svårare: en helt normaliserad modell kan sprida ut en affärsidé över fem objekt, och de som använder den måste sätta ihop den igen i huvudet. Normalisering säger mig var varje faktum hör hemma. Den lovar inte att det är den form som är lättast att läsa, använda eller rapportera på. Det är precis därför det är en designfärdighet att backa, och inget misslyckande.

Börja med att modellera sanningen. Bestäm sedan hur den sanningen behöver levereras.

Tillbaka till hundarna, och den här gången gör vi några medvetna val.

Ras: en plocklista eller en egen tabell? Kör den genom frågorna jag ger dig längre fram i den här modulen. Finns det mer än en kolumn med information? Ja: storleken, åtminstone. Hur många värden? Kennelklubbar erkänner några hundra raser (bara American Kennel Club listar 205), långt över min tumregel på ungefär 20. Så Ras förtjänar en egen tabell, och varje hund pekar på sin ras. Det avgör frågan vi har burit med oss sedan modul 1: Ras är en egen ruta.

Färdighetsnivå: en plocklista. Lär sig, Bra, Expert. Tre etiketter, inget mer att säga om dem, och de kommer inte att ändras. Det är precis vad en plocklista är till för.

Hur många trick kan varje hund? Svaret finns redan i modellen: räkna hundens Hundtrick-poster. Men tränaren vill ha det numret i varje rapport, för att sortera och filtrera på det, utan att bygga en rapport över två tabeller. Så jag backar, och håller en räknare Kända trick direkt på hunden. Det är en kopia. Sanningen bor fortfarande i Hundtrick; räknaren är en representation av den, och den måste hålla jämna steg. Salesforce ger oss ett rent sätt att göra precis det, och vi ser det i modul 6.

Nu kommer vändningen: hundskolan börjar ta emot katter. Vad gör vi? Ett alternativ: lägg till en Katt-tabell bredvid Hund-tabellen, och ett Kattrick bredvid Hundtrick. Allt fördubblas: två av varje skärmbild, två av varje rapport, och den dag de tar emot kaniner, tre. Det andra alternativet: ta ett steg tillbaka och lägg märke till att en katt har en ägare, kanske en uppfödare, en ras, ett födelsedatum och, med tålamod, ett trick eller två. Samma fakta och samma relationer som en hund. Så vi generaliserar: ett Husdjur, med en Art, hund eller katt. Varje ras hör också till en art, och det är där arten egentligen bor: en labrador är en hund. Husdjuret bär en kopia, med avsikt, så att varje skärmbild och rapport kan börja med ”hund eller katt?” utan att slå upp rasen. Ännu en medveten kopia, och i modul 6 får den ett eget jobb.

Det är att designa för förändring, och det är en avvägning. Generalisera för tidigt, så blir allt en vag ”Sak” med ett typfält som ingen förstår. Jag generaliserar när verksamheten faktiskt kommer med den andra sorten, och de två delar nästan allt, som hundar och katter gör här. Om katter behövde helt andra fakta skulle jag tänka efter en gång till.

Husdjursmodellen efter avvägningarna Husdjursmodellen som en detaljerad datamodell. Husdjur sitter där Hund satt: husdjurs-ID, också känt under sitt chipnummer, ID:n för ägare, uppfödare och ras, Art (en plocklista: hund eller katt), namn, födelsedatum och en räknare Kända trick som behålls för rapportering. Ras är nu kopplad (ett husdjur är av en ras) och har sin egen art, namn och storlek. Husdjurstrick, mellan Husdjur och Trick, har färdighetsnivån som plocklista och inlärningsdatumet; Trickbedömning, under det, har datum, färdighetsnivå och vem som bedömde. En ägare äger husdjur och en uppfödare föder upp dem, som förut. äger föder upp är en kan kan av kontrolleras i Ägare Ägar-ID POST-ID Namn Telefon ZIP Stad Uppfödare Uppfödar-ID POST-ID Namn Stad Husdjur Husdjurs-ID POST-ID Chipnummer OCKSÅ KÄND SOM Ägar-ID Uppfödar-ID Ras-ID Art (plocklista) Namn Födelsedatum Kända trick (antal) Ras Ras-ID POST-ID Art (plocklista) Namn Storlek Husdjurstrick Husdjurstrick-ID POST-ID Husdjurs-ID Trick-ID Färdighetsnivå (plocklista) Inlärningsdatum Trick Trick-ID POST-ID Namn Svårighetsgrad Trickbedömning Trickbedömnings-ID POST-ID Husdjurstrick-ID Datum Färdighetsnivå (plocklista) Bedömd av exakt en noll eller en en eller många noll eller många © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Nu samma sorts val hos Steve Trucking, där insatserna är högre.

Den renaste modellen är inte alltid det bästa systemet

Section titled “Den renaste modellen är inte alltid det bästa systemet ”

Föreställ dig ett team vid ett stopp. Leveransen har sina varor. Installationen har en checklista. Varje steg behöver foton. Mottagaren skriver under.

Den normaliserade modellen är vacker: leverans → leveransrad → installationschecklista → foto, var och en där den hör hemma.

Sedan sätter jag mig med de människor som faktiskt använder den. Ett team avslutar ungefär tio stopp om dagen, på garageuppfarter, ofta utan täckning. Om min vackra modell skickar dem genom en labyrint av skärmbilder och relaterade listor för att avsluta ett enda stopp har jag ett arkitekturproblem.

Datamodellen är inte det enda vi designar.

Vi designar ett system.

Det här är ett av skälen till att jag ibland backar från en perfekt normaliserad modell: användarupplevelsen.

Kanske skulle ett begrepp tekniskt kunna vara en egen entitet, men att separera det lägger till komplexitet som ger väldigt lite värde. Kanske är en förälder med flera nivåer av barn akademiskt ren men eländig att mata in och underhålla. Kanske är begreppet litet, stabilt och används mest som ett val i en lista.

Det är här jag slutar fråga bara ”Var hör det här faktumet hemma i teorin?” och börjar fråga ”Hur kommer det här systemet faktiskt att användas?”

Det betyder inte att varje klagomål på ett extra klick plattar till modellen. Det betyder att användbarhet är ett legitimt underlag för arkitekturen.

Rapportering är ett annat vanligt skäl.

Varje detaljhandelspartner vill ha ett scorecard: leveranser i tid per region, per månad. I den rena modellen känner en leverans till sin distributionscentral, och DC:n känner till sin region. Tekniskt kan vi navigera det.

Men kan rapportverktyget det? Kan de som bygger sina egna rapporter det? Kan de besvara frågan utan en rapportarkitektur som är mer komplicerad än själva frågan?

Det är då jag kanske kopierar eller härleder regionen till leveransen, närmare där den används.

Nu har jag infört duplicering. Så jag behöver en fråga till: vem äger sanningen?

Om källvärdet ändras, vad händer då med min kopia? Ska den ändras? Eller ska den behålla det som var sant när leveransen skedde? Det är olika krav.

Denormalisering tar inte bort komplexitet.

Den flyttar den.

Här är ett mindre exempel som Salesforce-admins stöter på hela tiden. Användaren behöver välja från en uppsättning värden. Skapar jag en till entitet och relaterar till den, eller använder jag en plocklista?

Ta en leverans status: schemalagd, lastad, ute för leverans, på väg fram, levererad, installerad, avvikelse, returnerad. En kort, stabil lista med etiketter. En plocklista är precis vad jag vill ha.

Ta nu typen av stopp: bara leverans, leverans med installation, leverans med bortforsling. Den bär egen information: hur lång tid stoppet tar, vilka färdigheter teamet behöver, vilken installationschecklista som gäller. Den ändras oberoende, och verksamheten förvaltar den. Det är en entitet, inte en etikett.

Om jag skapar ett objekt för varje begrepp som i teorin skulle kunna normaliseras kan jag bygga ett tekniskt vackert system som ingen tycker om att använda. Om jag gör varje begrepp till en plocklista för att det är enkelt kan jag måla in mig i ett hörn väldigt snabbt.

Så jag frågar: har det egen information? Relationer? Ändras det oberoende? Behöver det förvaltas som data? Kan verksamheten till slut behöva mer av det än en etikett?

Här är frågorna jag faktiskt ställer i ett designmöte.

Finns det mer än en kolumn med information? Om värdet behöver en beskrivning, en varaktighet, en lista med färdigheter, en ägare, så är det inte en etikett längre.

Hur många värden? Min tumregel är ungefär 20. Över 20 värden börjar en plocklista fungera dåligt, och det är dags att tänka på ett objekt. Delstater, femtio stycken, är undantaget vi lever med, och länder är värre; ärligt talat, är det någon som älskar plocklistor med länder? Jag tycker att de är irriterande.

Skapas värdena över tid, och av vem? Att lägga till ett plocklistvärde är en konfigurationsändring, vilket betyder en admin. Om verksamheten lägger till värden varje vecka, och de som lägger till dem inte är admins, ställer en plocklista ett ärende framför varje nytt värde.

Behöver folk filtrera och rapportera på det? Plocklistor är utmärkta för det. Lookup-relationer är inte lika rena. Varje lookup lägger till ett hopp: en rapporttyp följer bara en kort kedja av relaterade objekt (en anpassad rapporttyp tillåter högst fyra objektrelationer), skärmen blir relaterade listor i relaterade listor, och koden blir mer komplicerad.

En värdelista börjar ofta sitt liv som en plocklista och förtjänar med tiden ett eget objekt. Låt den förtjäna det.

En etikett eller en entitet? Status och typen av stopp Två kort. Leveransstatus, en plocklista: åtta stabila värden, vart och ett ett enda ord eller ett ord med bindestreck (Schemalagd, Lastad, Ute-för-leverans, Anländer, Levererad, Installerad, Avvikelse, Returnerad), och vart och ett är bara en etikett. Typ av stopp, en entitet: tjugofyra värden och fler kommer, till exempel bara leverans, leverans plus installation av en tvättmaskin eller en gasspis, leverans plus bortforsling, bara bortforsling, returupphämtning och arton till; vart och ett har sin egen stopptid, teamfärdigheter som behövs och checklista för installation. En anteckning under: över ungefär 20 värden, eller med egna attribut, är det en entitet, inte en etikett. Leveransstatus en plocklista VÄRDENA: 8, OCH STABILA Schemalagd Lastad Ute-för-leverans Anländer Levererad Installerad Avvikelse Returnerad VARJE VÄRDE ÄR Bara en etikett Typ av stopp en entitet VÄRDENA: 24, OCH FLER KOMMER Bara leverans Leverans + installation: tvättmaskin Leverans + installation: gasspis Leverans + bortforsling Bara bortforsling Returupphämtning …och 18 till VARJE VÄRDE HAR SIN EGEN Stopptid Teamfärdigheter som behövs Checklista för installation Över ungefär 20 värden, eller egna attribut: då är det en entitet, inte en etikett. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

En design som fungerar utmärkt med några tusen poster kan bete sig helt annorlunda med miljoner.

Så titta inte bara på diagrammet. Känn till siffrorna.

Steve Trucking gör ungefär en miljon leveranser om året, och växer med 30 % om året. Varje leverans samlar på sig ungefär åtta statusuppdateringar. Det blir åtta miljoner statusposter i år, och ungefär 13,5 miljoner om året till år tre. Lägg till fyra eller fem miljoner foton om året.

Samma modell. Helt annan arkitektur.

Vi går mycket djupare i Arkitektur i stor skala. Kom ihåg tills vidare: volym kan ändra ett beslut i datamodellen. En relation som är logiskt korrekt är inte automatiskt den bästa fysiska designen i varje skala.

Hittills har vi tänkt på det operativa systemet. Koordinatorer planerar rutter för leveranser. Team avslutar stopp. Systemet ändras medan verksamheten är igång.

Men verksamheten vill också analysera flera års historik. Vilka partner och regioner ligger efter? Hur har leveranstiden ändrats? Hur ofta behöver installationer ett andra besök?

Ett analytiskt system kan vilja ha samma information organiserad på ett annat sätt. Du kommer att höra termer som datalager (data warehouse), fakta (fact), dimension och stjärnschema (star schema). Vi packar inte upp dem här; hos Steve Trucking är det Snowflake-lagret, och vi återkommer till det senare i kursen.

Tills vidare: olika konsumenter kan behöva olika former av samma sanning.

Och nu finns det en konsument till: AI.

En mottagare sms:ar: ”Var är min leverans?” En AI-assistent skulle kunna slå upp det här:

Leverans 10427, rutt 3312, stopp 7, lastbil 117, tidsfönster 13.00–15.00.

En traditionell applikation följer gärna de relationerna. Men för att svara mottagaren behöver assistenten kontext som sätts ihop från flera ställen:

Din diskmaskin från Redrock är sjunde stoppet på dagens rutt från distributionscentralen i Phoenix. Lastbilen är tre stopp bort, och du är fortfarande inom ditt tidsfönster 13–15.

Vi har tagit information från flera relaterade entiteter och satt ihop en plattare, kontextrik representation för en viss konsument.

Det betyder inte att jag förstör min normaliserade modell. Och det betyder definitivt inte ”AI gillar platta data, så lägg allt i ett enda jätteobjekt”. Gör inte det.

Sanningskällan förblir ren. AI får en representation som är byggd för det jobb den gör. Det är samma idé som vi just såg med analys:

En sanningskälla kan stödja flera former för konsumtion.

Vi går mycket djupare in på grounding och hämtning senare i kursen.

Det finns en fara här.

Om jag kopierar regionen till leveransen för rapporteringens skull, skickar en plattad version till Snowflake och bygger en kontextrik version för AI-assistenten, vilken är då korrekt?

Den frågan behöver ett svar. Jag vill veta var det auktoritativa värdet bor. Allt annat är en representation av den sanningen för ett syfte.

Det stället är system of record (källsystemet). Denormaliserade kopior kan vara bra: stoppskärmen, scorecardet, Snowflake och AI-kontexten gör var och en sitt jobb bättre med en form som är byggd för dem, och det är helt okej att hänvisa till dem. Men när något ändras börjar ändringen i källsystemet, oftast relationsmodellen, och flödar utåt till varje kopia. Ingen rättar regionen i Snowflake, eller redigerar AI:ns kontext för hand. Rätta det vid källan, och låt ändringen flöda.

Källsystemet: ändringar flödar utåt En ruta överst, källsystemet (system of record), relationellt, där ändringar börjar, med pilar som flödar ned till fyra kopior byggda från det: teamets stoppskärm, med ett stopp allt på en sida; partnerns resultatkort, sena leveranser per region; Snowflake-lagret, många års historik; och AI-kontexten för leveranser, för ”Var är min leverans?”. En anteckning under: ändringar börjar i källsystemet och flödar ut till varje kopia; rätta aldrig en kopia. System of record relationell: ändringar börjar här Teamets stoppskärm ett stopp, allt på en sida Partnerns resultatkort sena leveranser per region Snowflake-lager många års historik AI-kontext för leveranser ”Var är min leverans?” Ändringar börjar i källsystemet och flödar ut till varje kopia. Rätta aldrig en kopia. © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Och det spelar störst roll när data ändras. Om en distributionscentral flyttar till en annan region i dag, ska förra månadens leveranser visa den nya regionen? Kanske. Kanske inte. För historiken kan jag behöva den region som var sann när leveransen skedde. Det är inte längre ett synkroniseringsproblem. Det är ett affärsbeslut.

Det är därför denormalisering aldrig ska ske av misstag. Varje duplicerat faktum väcker frågor om ägarskap, synkronisering, historik och förtroende. Det är avvägningstänkandet från kapitel 1: vet vad du köper (en enklare skärmbild, en enklare rapport, bättre kontext för AI) och vad du betalar (duplicerade data, synkronisering, ett mer komplicerat ägarskap av sanningen). Och eftersom vi började från en ren logisk modell kan vi peka på varje kopia och säga: ”Jag vet att det här hör hemma där borta. Jag lägger en representation av det här på grund av det här kravet.” Det är ett beslut vi kan granska, ifrågasätta och skriva ner, så att nästa arkitekt vet varför.

När jag överväger denormalisering bestämmer jag:

  • Var den auktoritativa källan för varje affärsfaktum bor.
  • Om den rena modellen skapar verkliga problem för användare, rapportering, skala eller prestanda.
  • Om en enklare representation är värd dupliceringen, och hur kopian förblir pålitlig.
  • Om historiska värden ska ändras när den aktuella källan ändras.
  • Om analys eller AI behöver data i en annan form än det operativa systemet.

Utgångspunkten ändras aldrig: vet var sanningen hör hemma. Sedan, när kraven motiverar det, forma den för leverans.

Härnäst kommer Salesforce tillbaka in i bilden. Vi ska göra det vi har designat till en fysisk datamodell.