SQL-database og sikker udgivelse

Databasemigreringer: ændr appens SQL-skema uden at miste data

Når en app får rigtige brugere, er en ændring fra navn til fuldeNavnikke længere bare kode. Frontend, backend og database kan være på forskellige versioner, mens medarbejdere samtidig gemmer nye data. En sikker skemamigrering gør ændringen sporbar, kompatibel og mulig at stoppe, før en lille rettelse bliver til nedetid eller datatab.

Udgivet 22. september 2026 · Ca. 14 minutters læsetid

Guiden er til relationelle databaser

Her handler migrering om at ændre strukturen i en SQL-database: tabeller, kolonner, datatyper, indeks, constraints og relationer. Det er et andet problem end at importere kundedata fra Excel eller flytte data mellem systemer. Dokumentdatabaser som Firestore har ikke samme faste skema og kræver en anden migrationsstrategi i applikationskoden.

ÆndringTypisk risikoSpørg før produktion
Ny valgfri kolonneOfte lavereKan gammel kode ignorere den, og er standardværdien bevidst?
Omdøbning eller sletningHøjHvilke gamle appversioner, jobs og rapporter bruger stadig feltet?
Ny påkrævet regelHøjOverholder alle eksisterende rækker allerede reglen?
Ændret datatypeHøjKan alle værdier konverteres entydigt uden tab?
Nyt indeksAfhænger af størrelseHvor længe kører opbygningen, og hvilke writes bliver låst?

Få skema og migrationshistorik ind i Git

Den sikre kilde er ikke hukommelsen om klik i et dashboard. Hver ændring skal ligge som en navngivet migrationsfil sammen med koden, så review, testmiljø og produktion bruger den samme rækkefølge. Supabase advarer konkret mod direkte ændringer i den eksterne database, fordi de går uden om migrationshistorikken og kan få senere deployments ud af takt.

  1. 1. Find den faktiske tilstand: Sammenhold repository, migrationshistorik og produktionsskema. Gæt ikke ud fra ORM-modellen alene.
  2. 2. Vælg ét migrationsværktøj: Brug det, der passer til stacken – eksempelvis Supabase CLI, Prisma Migrate, EF Core Migrations eller databaseværktøjets egen mekanisme.
  3. 3. Gem én forståelig ændring: Navngiv formålet, og hold skemaændring og stor dataomskrivning adskilt, når de har forskellig risiko eller køretid.
  4. 4. Gennemgå den genererede SQL: Et værktøj kan tolke en omdøbning som sletning plus oprettelse eller tilføje grants og revokes, som ikke var tilsigtet.
  5. 5. Lad pipeline eller en navngiven ansvarlig udføre den: Undgå to samtidige, manuelle produktionskørsler fra hver sin computer.

Skift i kompatible etaper

En direkte omdøbning kræver, at al kode skifter i samme øjeblik. Det sker sjældent: gamle browsere, baggrundsjob og flere serverinstanser kan leve videre under deployment. Expand-and-contract-mønstret gør i stedet både gammel og ny version gyldig i en afgrænset overgang.

  1. Udvid: Tilføj den nye kolonne eller tabel uden at fjerne den gamle. Den nye struktur skal i starten tåle, at gammel kode ikke udfylder den.
  2. Skriv kompatibelt: Opdatér applikationen til at skrive den nye form og om nødvendigt også den gamle, mens begge versioner er i drift.
  3. Flyt eksisterende data: Backfill i kontrollerede batches, mål fejl og fremdrift, og gør kørslen sikker at genoptage.
  4. Læs den nye form: Skift læsninger, rapporter, jobs og integrationer, og mål om den gamle struktur stadig bruges.
  5. Stram reglen: Gør først feltet påkrævet eller tilføj den endelige constraint, når data og alle skriveveje er verificeret.
  6. Træk sammen: Fjern gammel kode og senere gammel kolonne i en særskilt release, når rollbackvinduet og den aftalte observationsperiode er lukket.
En ORM-migrering er ikke automatisk sikker. Prisma dokumenterer expand-and-contract som en flertrinsproces, og Microsoft anbefaler at genererede EF Core-migreringer inspiceres og testes, før de rammer produktion. Værktøjet kan oprette filen; det kender ikke jeres trafik, datakvalitet eller rollbackbehov.

Mål låse og køretid på realistiske data

En migrering, der tager få millisekunder på 200 testrækker, kan låse eller belaste en produktionstabel med millioner af rækker. PostgreSQLs dokumentation viser eksempelvis, at forskellige ALTER TABLE-handlinger tager forskellige låse. Et almindeligt indeks kan blokere writes under opbygningen, mens CREATE INDEX CONCURRENTLY har andre begrænsninger og fejltilstande. Kopiér derfor ikke et SQL-trick uden at kontrollere den aktuelle databaseversion og leverandørens driftvilkår.

  • Mål tabellens størrelse, forventet vækst, normal og maksimal trafik samt de queries, der rammer tabellen.
  • Kontrollér låsetype, tabelomskrivning, diskbehov, transaktionslog og timeout for hver konkret SQL-operation.
  • Test på et produktionslignende datasæt uden at sprede ukontrollerede kopier af persondata til udviklingsmiljøet.
  • Sæt en fornuftig ventetid på låse, så migreringen fejler kontrolleret frem for at blokere appen ubestemt.
  • Planlæg store backfills som egne jobs med batchstørrelse, checkpoint, pausemulighed og begrænset belastning.

Test mere end den seneste migrationsfil

En frisk tom database og en gammel database afslører forskellige fejl. Den tomme database viser, om hele historikken kan bygge skemaet fra bunden. En kopi af den aktuelle struktur med realistiske datamønstre viser, om selve opgraderingen kan gennemføres uden tabte værdier, for lange låse eller brudte brugerrejser.

  • Byg en ny database fra alle migrationsfiler, og sammenlign slutskemaet med den forventede model.
  • Opgradér fra den version, produktionen faktisk har – ikke kun fra udviklerens seneste lokale database.
  • Test gammel app mod udvidet skema og ny app mod udvidet skema under overgangsperioden.
  • Kontrollér antal rækker, NULL-værdier, relationer, unikke regler, summer og kendte vanskelige poster efter backfill.
  • Kør de kritiske brugerrejser: opret, redigér, søg, eksportér, rapportér og de relevante baggrundsjob.
  • Gem målt køretid og maksimal låseventetid som grundlag for produktionsvinduet og stopkriterierne.

Adskil migrationsadgang fra appens daglige adgang

Skemaændringer kræver stærkere databaseadgang end almindelig læsning og skrivning. Microsoft anbefaler en særskilt deployment-identitet med skemarettigheder, mens appens runtime-identitet normalt kun bør have de rettigheder, driften kræver. Det begrænser skaden, hvis appens normale credentials lækker.

  • Opbevar produktionsforbindelsen i deploymentplatformens secret store – aldrig i migrationsfilen eller repository.
  • Bind produktionskørslen til godkendt branch, miljø og review, og log hvem eller hvilken pipeline der startede den.
  • Lad præcis én kontrolleret jobinstans anvende migrationshistorikken; start ikke samme ændring fra alle appreplikaer.
  • Fjern eller deaktiver den stærke adgang efter kørslen, hvis platformens model understøtter tidsbegrænset elevation.

Planlæg fremadrettet rettelse – ikke kun “down”

Koderollback og databaserollback er ikke det samme. Når den nye version har gemt data i en ny form, kan en automatisk down migration slette kolonnen og dermed de nye værdier. EF Core-dokumentationen advarer også om, at nedrulning kan medføre datatab. Ofte er den sikreste nødplan at stoppe frigivelsen, lade den kompatible struktur stå og rette fremad med en ny migration.

Før ændringen
Tag og verificér den platformskorrekte backup, men dokumentér også gendannelsestid og hvilke nye writes en fuld restore ville miste.
Under ændringen
Stop ved låseventetid, fejlrate, replikationsforsinkelse eller belastning over de aftalte grænser. Start ikke blindt samme script igen.
Efter ændringen
Bevar den gamle kolonne eller læsevej i observationsperioden, hvis det er en del af expand-and-contract-planen.
Ved fejl
Vælg mellem pause, kode-rollback, korrigerende migration eller restore ud fra de data, der er skrevet siden start – ikke ud fra ønsket om den hurtigste knap.

Typiske fejl

  • Produktionen redigeres i dashboardet: Den synlige rettelse virker nu, men repository og senere miljøer kender den ikke.
  • En kolonne omdøbes direkte: En gammel serverinstans, rapport eller baggrundsopgave spørger stadig efter det tidligere navn.
  • Genereret SQL godkendes uden review: Værktøjet sletter og genskaber et felt, ændrer rettigheder eller vælger en dyr operation.
  • Backfill ligger i samme lange transaktion: Deployment holder låse, fylder loggen eller fejler sent uden tydelig fremdrift.
  • En constraint slås til før oprydning: Eksisterende data bryder reglen, og hele releasekæden stopper.
  • Alle appinstanser migrerer ved opstart: Flere processer konkurrerer om samme skemaændring og kræver samtidig forhøjede rettigheder.
  • Rollback betyder “gendan backup”: Nye ordrer, bookinger eller rettelser siden backuppen forsvinder.

Tjekliste før skemaet ændres i produktion

  • ☐ Produktionsskema og migrationshistorik er sammenholdt med repository.
  • ☐ Ændringen ligger i en navngivet, versionsstyret migrationsfil.
  • ☐ Genereret SQL, rettigheder, datatab, låse og forventet køretid er gennemgået.
  • ☐ Gamle og nye appversioner kan fungere under hele deploymentovergangen.
  • ☐ Omdøbning, datatypeændring eller sletning er delt i expand, backfill og contract, når risikoen kræver det.
  • ☐ Backfill kan pauses, genoptages og afstemmes uden dubletter eller overskrivning.
  • ☐ Hele migrationskæden virker på en frisk database.
  • ☐ Opgradering fra den faktiske produktionsversion er testet med realistiske datamønstre.
  • ☐ Kritiske brugerrejser og datakontroller er afprøvet efter migreringen.
  • ☐ En navngiven ansvarlig eller én pipeline udfører ændringen med særskilt migrationsadgang.
  • ☐ Backupens gendannelse er kendt, og tab af writes ved restore er vurderet.
  • ☐ Stopkriterier, observationer, kode-rollback og fremadrettet rettelse er dokumenteret.
  • ☐ Den gamle struktur fjernes først efter målt nulbrug og en aftalt observationsperiode.

Relaterede guides

Officielle kilder

Principper og eksempler er kontrolleret mod aktuelle primærkilder. SQL-dialekt, låse, transaktioner og migrationsværktøjer varierer, så kontrollér altid den konkrete database, version og hostingplatform, som appen bruger.

Virker appen, men føles hver databaseændring risikabel?

Startklar kan hjælpe med at kortlægge det eksisterende skema, samle manuelle ændringer i en versionsstyret migrationsvej og afprøve deployment, backfill og nødplan på den stack, appen allerede bruger.

Se Startklar-forløbet