Ganzenmigraties voor soepele databaseveranderingen

Hallo, maat!

Vandaag gaan we het hebben over wat database-migraties zijn en waarom ze zo belangrijk zijn. In de wereld van vandaag is het geen verrassing dat eventuele veranderingen aan een database zorgvuldig moeten worden uitgevoerd en volgens een specifiek proces. Idealiter zouden deze stappen geïntegreerd moeten zijn in onze CI/CD-pijplijn zodat alles automatisch verloopt.

Dit is onze agenda:

  1. Wat is het probleem?
  2. Hoe lossen we het op?
  3. Een eenvoudig voorbeeld
  4. Een complexer voorbeeld
  5. Aanbevelingen
  6. Resultaten
  7. Conclusie

Wat is het Probleem?

Als jouw team nog nooit te maken heeft gehad met database-migraties en je niet helemaal zeker weet waarom ze nodig zijn, laten we dat dan uitzoeken. Als je de basis al kent, kun je gerust verdergaan.

Belangrijkste Uitdaging

Wanneer we “geplande” en “soepele” veranderingen aan de database aanbrengen, moeten we de beschikbaarheid van de service behouden en voldoen aan SLA-vereisten (zodat gebruikers geen downtime of vertraging ondervinden). Stel je voor dat je het type van een kolom in een tabel met 5 miljoen gebruikers wilt wijzigen. Als je dit “frontaal” aanpakt (bijvoorbeeld gewoon ALTER TABLE uitvoert zonder voorbereiding), kan de tabel voor een aanzienlijke tijd worden vergrendeld – en je gebruikers zouden zonder service achterblijven.

Om dergelijke hoofdpijn te voorkomen, volg twee regels:

  1. Voer migraties uit op een manier die de tabel niet vergrendelt (of minimaliseert de vergrendeling ten minste).
  2. Als je een kolomtype moet wijzigen, is het vaak gemakkelijker om eerst een nieuwe kolom met het juiste type te maken en daarna de oude te verwijderen.

Een ander probleem: versiebeheer en terugdraaien

Soms moet je een migratie terugdraaien.

Dit handmatig doen — de productie-database in gaan en met gegevens rommelen — is niet alleen riskant, maar ook waarschijnlijk onmogelijk als je geen directe toegang hebt. Dan komen speciale migratietools goed van pas. Ze stellen je in staat om wijzigingen op een nette manier toe te passen en indien nodig terug te draaien.

Hoe lossen we het op? Gebruik de juiste tools

Elke taal en ecosysteem heeft zijn eigen migratietools:

  • Voor Java zijn Liquibase of Flyway gebruikelijk.
  • Voor Go is een populaire keuze goose (deze zullen we hier bekijken).
  • Enzovoort.

Goose: wat het is en waarom het nuttig is

Goose is een lichte Go-hulpprogramma dat je helpt om migraties automatisch te beheren. Het biedt:

  • Eenvoud. Minimale afhankelijkheden en een transparante bestandsstructuur voor migraties.
  • Veelzijdigheid. Ondersteunt verschillende DB-drivers (PostgreSQL, MySQL, SQLite, enz.).
  • Flexibiliteit. Schrijf migraties in SQL of Go-code.

Het installeren van Goose

Shell

 

Hoe Het Werkt: Migratiestructuur

Standaard zoekt Goose naar migratiebestanden in db/migraties. Elke migratie volgt dit formaat:

Shell

 

  • NNN is het migratienummer (bijv. 001, 002, enz.).
  • Daarna kun je een beschrijvende naam hebben, bijvoorbeeld init_schema.
  • De extensie kan .sql of .go zijn.

Voorbeeld van een SQL-migratie

Bestand: 001_init_schema.sql:

SQL

 

Ons Eerste Voorbeeld

Een Kolomtype Wijzigen (String → Int)

Stel dat we een tabel gebruikers hebben met een kolom leeftijd van het type VARCHAR(255). Nu willen we dit wijzigen naar INTEGER. Dit is hoe de migratie eruit zou kunnen zien (bestand 005_change_column_type.sql):

SQL

 

Wat er hier gebeurt:

  1. Up migratie

    • We wijzigen de kolom leeftijd naar INTEGER. De clausule USING (leeftijd::INTEGER) vertelt PostgreSQL hoe bestaande gegevens naar het nieuwe type moeten worden geconverteerd.
    • Merk op dat deze migratie zal mislukken als er gegevens in leeftijd staan die niet numeriek zijn. In dat geval heb je een complexere strategie nodig (zie hieronder).
  2. Teruggaande migratie

    • Als we terugdraaien, stellen we age weer in op VARCHAR(255).
    • We gebruiken opnieuw USING (age::TEXT) om van INTEGER terug naar tekst te converteren.

De Tweede en Complexe Gevallen: Multi-Stap Migraties

Als de kolom age rommelige gegevens kan bevatten (niet alleen nummers), is het veiliger om dit in verschillende stappen te doen:

  1. Voeg een nieuwe kolom toe (age_int) van het type INTEGER.
  2. Kopieer geldige gegevens naar de nieuwe kolom, en behandel of verwijder ongeldige invoer.
  3. Verwijder de oude kolom.
SQL

 

Om een juiste terugrol mogelijk te maken, spiegelt de Terug sectie gewoon de acties in omgekeerde volgorde.

Automatisering is de Sleutel

Om tijd te besparen, is het echt handig om migratiecommando’s toe te voegen aan een Makefile (of een ander build-systeem). Hieronder staat een voorbeeld Makefile met de belangrijkste Goose-commando’s voor PostgreSQL.

Laten we aannemen:

  • De DSN voor de database is postgres://user:password@localhost:5432/dbname?sslmode=disable.
  • Migratiebestanden bevinden zich in db/migrations.
Shell

 

Hoe te gebruiken?

1. Maak een nieuwe migratie (SQL-bestand). Dit genereert een bestand db/migrations/002_add_orders_table.sql.

Shell

 

2. Pas alle migraties toe. Goose zal een schema_migrations tabel in je database aanmaken (als deze nog niet bestaat) en nieuwe migraties in oplopende volgorde toepassen.

Shell

 

3. Rol de laatste migratie terug. Rol gewoon de laatste terug.

Shell

 

4. Rol alle migraties terug (wees voorzichtig in productie). Volledige reset.

Shell

 

5. Controleer de migratiestatus.

Shell

 

Voorbeeld van uitvoer:

Shell

 

Samenvatting

Door gebruik te maken van migratietools en een Makefile, kunnen we:

  1. Directe toegang tot de productie-database beperken, waardoor wijzigingen alleen via migraties worden aangebracht.
  2. Eenvoudig databaseversies bijhouden en ze terugdraaien als er iets misgaat.
  3. Een enkele, consistente geschiedenis van databasewijzigingen behouden.
  4. “Vlotte” migraties uitvoeren die een draaiende productieomgeving in een microserviceswereld niet zullen verstoren.
  5. Extra validatie verkrijgen — elke wijziging zal door een PR- en codebeoordelingsproces gaan (ervan uitgaande dat je die instellingen hebt ingevoerd).

Een ander voordeel is dat het gemakkelijk is om al deze commando’s in je CI/CD-pijplijn te integreren. En onthoud — veiligheid boven alles.

Bijvoorbeeld:

YAML

 

Conclusie en tips

De belangrijkste ideeën zijn zo simpel:

  • Houd je migraties klein en frequent. Ze zijn gemakkelijker te beoordelen, te testen en indien nodig terug te draaien.
  • Gebruik dezelfde tool in alle omgevingen zodat dev, stage en prod gesynchroniseerd zijn.
  • Integreer migraties in CI/CD zodat je niet afhankelijk bent van één persoon die ze handmatig uitvoert.

Op deze manier heb je een betrouwbaar en gecontroleerd proces voor het wijzigen van je databasestructuur – een dat de productie niet verstoort en je in staat stelt snel te reageren als er iets misgaat.

Veel succes met je migraties!

Bedankt voor het lezen!

Source:
https://dzone.com/articles/goose-as-crucial-tool-for-your-service