Evolutionary Database Design Dutch

Evolutionair Database Design

Door Martin Fowler en Pramod Sadalage

Vertaald naar het Nederlands door Bart van Kuik

In de laatste jaren hebben wij een aantal technieken ontwikkeld die het mogelijk maken om het database ontwerp evolutionair mee te ontwikkelen, tegelijk met de ontwikkeling van de applicatie. Dit is een belangrijke mogelijkheid voor agile methoden. De technieken leunen op de toepassing van continue integratie en geautomatiseerde refactoring naar database development, gecombineerd met een nauwe samenwerking tussen DBA's en applicatie-ontwikkelaars. De technieken werken in zowel pre-productie als reeds uitgerolde systemen.

In de laatste paar jaar hebben we de opkomst gezien van een nieuwe slag van software methodieken, de agile methodieken. Deze stellen nieuwe en belangrijke eisen aan het design van een database. Een van de meest belangrijke van deze eisen is die van het evolutionaire ontwerp. Bij een agile project neem je aan dat de requirements van het systeem niet van tevoren kunnen worden vastgelegd. Als gevolg daarvan wordt een gedetailleerde ontwerpfase aan het begin van het project onpraktisch. Het ontwerp van het systeem moet zich ontwikkelen tegelijk met de iteraties van de software. Agile methoden, met name extreme programming (XP), hebben een aantal technieken die dit evolutionaire ontwerpen mogelijk maken.

Veel mensen vroegen zich af of evolutionair ontwerp kon worden toegepast op een systeem met een groot database component. Er waren vele mensen die ons zelfs vertelden dat het onmogelijk was -- een verontrustende gedachten toen ThoughtWorks begon aan een groot database-georiënteerd project waarbij gebruik werd gemaakt van vele agile en XP technieken.

Dit artikel beschrijft de technieken die het ons toestonden om dit onmogelijke te doen. Wij claimen niet dat we het database evolutie probleem volledig hebben opgelost, maar we denken dat we een set van technieken hebben gedemonstreerd die vele mensen bruikbaar zullen vinden.

Omgaan met verandering

Een van de belangrijkste eigenschappen van agile menthodieken is de houding ten opzichte van verandering. De meeste gedachten over het ontwikkelen van software gaan over het vroeg begrijpen van de requirements, deze ondertekenen, de requirements gebruiken voor een ontwerp, ook deze weer ondertekenen en vervolgens beginnen met de ontwikkeling. Dit is een plan-gedreven cyclus, waaraan vaak wordt gerefereerd (en meestal met dédain) als de waterfall benadering.

Zulke benaderingen trachten veranderingen te minimaliseren door uitgebreid en van tevoren werk te verrichten. Zodra dit werk is voltooid, kunnen veranderingen grote problemen veroorzaken. Ten gevolge hiervan zullen deze benaderingen op problemen stuiten wanneer de requirements veranderen, en omgaan met bijzonder veranderlijke requirements is dus een groot probleem bij zulke methodieken.

Agile processen benaderen dit anders. Zij proberen om verandering te verwelkomen en staan het toe dat zelfs laat in het ontwikkelproces veranderingen kunnen plaatsvinden. Veranderingen worden gecontroleerd, maar de houding van het proces is om verandering zoveel mogelijk toe te staan. Dit is gedeeltelijk om te beantwoorden aan de inherente instabiliteit van requirements in vele projecten, en gedeeltelijk ook om beter dynamische bedrijfsomgevingen te ondersteunen door deze te helpen veranderen met de druk van de markt.

Om dit te laten werken, is een andere houding nodig ten opzichte van ontwerpen. In plaats van te denken aan het ontwerp als een fase, die grotendeels af is wanneer constructie begint, moet naar het ontwerp gekeken worden als een doorgaand proces dat wordt afgewisseld met constructie, testen en zelfs opleveren. Dit is het contrast tussen gepland en evolutionair ontwerp. Eén van de belangrijkste bijdragen van agile methoden is dat zij technieken meebrachten die evolutionair ontwerp toestonden op een gecontroleerde manier. Dus in plaats van de gebruikelijke chaos die vaak gebeurd wanneer het ontwerp niet van tevoren is vastgelegd, kunnen deze methoden technieken aanreiken om evolutionair ontwerp te beheersen en bruikbaar te maken.

Een belangrijk deel van deze benadering is iteratief ontwikkelen, waarbij de volledige software life-cycle vele keren wordt gedraaid binnen de tijdsduur van het project. Agile processen draaien de complete life-cycle af in elke iteratie, waarbij deze wordt afgesloten met werkende, getestte en geïntegreerde code voor een kleine subset van de requirements van het uiteindelijke product. Deze iteraties zijn kort, meestal hebben ze een looptijd van een week tot een paar maanden, met een voorkeur voor kortere iteraties.

Hoewel deze technieken zijn gegroeid qua gebruik en interesse, blijft één van de grote vragen hoe evolutionair ontwerp werkt voor databases. De meeste mensen beschouwen database-ontwerp als iets dat absoluut van tevoren gepland moet worden. Veranderen van het database schema later in de ontwikkeling leidt meestal tot wijdverbreidde fouten in de applicatie-software. Verder zal het veranderen van een schema na de uitrol van de applicatie resulteren in pijnlijke migratie-problemen.

In de loop van de laatste drie jaar zijn wij betrokken geweest in een groot project (genaamd Atlas) dat evolutionair database ontwerp heeft gebruik en het werkend heeft gemaakt. Bij dit project waren minstens 100 mensen betrokken, werkzaam op meerdere kantoren wereldwijd (Amerika, Australië, Indië). Het betreft ongeveer een half miljoen regels code en meer dan 200 tabellen. De database ontwikkelde zich tijdens het anderhalf jaar van de initiële ontwikkeling en blijft zich verder ontwikkelen ook al is het in productie bij meerdere klanten. Tijdens dit project zijn we begonnen met iteraties van een maand, maar na een paar maanden veranderden we dit naar tweewekelijkse iteraties die beter werkten. De technieken die we beschrijven hier zijn diegene die we (of preciezer gezegd Pramod) hebben gebruikt om dit werkend te krijgen.

Sinds dit project ging draaien, hebben we deze technieken in meer van onze projecten gebruikt en hierdoor hebben we ervaring opgedaan in meerdere opdrachten. We hebben ook inspiratie, ideeën en ervaring opgedaan in andere agile projecten.

Beperkingen

Voordat we in de techniek duiken is het belangrijk om te herhalen dat we niet alle problemen van evolutionair database design hebben opgelost. In het bijzonder:

We beschouwen deze problemen niet als inherent onoplosbaar, tenslotte wilden veel mensen niet geloven dat we deze konden oplossen. Maar tot we dat wèl doen, zullen we ook niet claimen dat we ze hebben opgelost.

De technieken

Onze benadering van evolutionair database design rust op een handvol belangrijke technieken.

DBA's werken nauw samen met ontwikkelaars

Eén van de stellingen van agile methoden is dat mensen met verschillende skills en achtergronden zeer nauw samen dienen te werken. Zij kunnen niet alleen via formele meetings en documenten communiceren. In plaats daarvan moeten ze continue met elkaar praten en werken. Iedereen wordt hierdoor beïnvloed: analisten, PM's, materie-deskundigen, ontwikkelaars... en DBA's.

Elke taak waaraan een ontwikkelaar werkt, kan potentieel de hulp van een DBA nodig hebben. Zowel de ontwikkelaars als de DBA moeten bekijken of een ontwikkel-taak belangrijke veranderingen kan maken in het database schema. Zoja, dan dient de ontwikkelaar de DBA te raadplegen om te beslissen hoe de verandering moet worden gemaakt. De ontwikkelaar weet welke nieuwe functionaliteit nodig is en de DBA heeft het globale overzicht van de data in de applicatie.

Om dit mogelijk te maken moet de DBA zich toegankelijk en beschikbaar maken. Maak het gemakkelijk voor een ontwikkelaar om gewoon even langs te komen voor een paar minuten en wat vragen te stellen. Verzeker je ervan dat de DBA op de hoogte is van applicatie-ontwerp sessies zodat ook hij op zijn beurt gemakkelijk even langs kan komen. In vele omgevingen zien we dat mensen barrières opwerpen tussen de functies van DBA en applicatie-ontwikkelaar. Die barrières moeten omver worden gehaald om een evolutionair database design proces mogelijk te maken.

Iedereen krijgt zijn eigen database

Evolutionair design erkent, dat mensen moeten leren door dingen uit te proberen. In termen van programmeren betekent dit, dat ontwikkelaars experimenteren met hoe een bepaalde feature moet worden geïmplementeerd en waar het mogelijk is dat er een paar pogingen worden gedaan voordat wordt gekozen voor tussen een te prefereren alternatief. Database design kan ook zo gebeuren. Hieruit volgt dat het belangrijk is dat elke ontwikkelaar zijn eigen zandbak heeft waar geëxperimenteerd kan worden en waar de veranderingen niet direct het werk van anderen beïnvloeden.

Veel DBA's zien meerdere databases als gruwel, als iets dat te lastig is om mee te werken in de praktijk, maar wij hebben ervaren dat het gemakkelijk is om een stuk of honderd instanties te managen. De essentie is om te beschikken over tools die omgaan met databases zoals je ook zou omgaan met bestanden.

Ontwikkelaars integreren regelmatig in een gedeelde master

Alhoewel ontwikkelaars regelmatig kunnen experimenteren op hun eigen gebied, is het belangrijk om de verschillende benaderingen regelmatig weer bij elkaar terug te brengen. Een applicatie heeft een gedeelde master database nodig waaruit al het werk vloeit. Wanneer een developer aan een taak begint, kopiëren zij de master naar hun eigen werkruimte, gaan aan het werk en integreren hun veranderingen terug in de master. Als een vuistregel zou iedere ontwikkelaar dagelijks moeten integreren.

Laten we een voorbeeld nemen waarbij Mike begint aan een ontwikkel-taak om tien uur 's-ochtends (we nemen even aan dat hij ook inderdaad zo vroeg binnenkomt). Als onderdeel van deze taak moet hij veranderingen maken in het database schema. Als de verandering gemakkelijk is, zoals het toevoegen van een kolom, hoeft hij alleen maar te beslissen hoe hij deze verandering zelf maakt. Mike verzekert zichzelf ervan dat de kolom die hij wil toevoegen niet al bestaat in de database, en dit doet hij door middel van een data dictionary (hierover later meer). Als het gecompliceerder is, dan pakt hij de DBA even beet en bespreekt de mogelijke veranderingen met hem/haar.

Zodra hij klaar is om te beginnen, pakt hij een kopie van de database master en kan hij vrijelijk zowel het database schema als de code wijzigen. Omdat hij in zijn eigen zandbak zit, hebben zijn veranderingen geen impact op anderen. Op een bepaald punt, zeg rond 3 uur 's-middags, heeft hij een aardig idee van wat de veranderingen in de database moeten worden ook al is hij niet helemaal klaar met zijn taak. Op dit punt spreekt hij de DBA even aan en vertelt hem over de verandering. Nu kan de DBA nog bepaalde punten aanhalen waar Mike niet aan had gedacht. Meestal is alles OK en maakt de DBA de verandering (door het toepassen van één of meer database refactorings, waarover later meer). De DBA maakt de veranderingen onmidddelijk (tenzij het destructieve veranderingen zijn -- ook daarover later meer). Mike kan verder gaan met zijn taak en kan de code committen op elk willekeurig moment wanneer de DBA de veranderingen heeft gemaakt in de master.

Wellicht herken je dit principe als die van Continuous Integration, die wordt toegepast op source code management. Inderdaad, dit betreft feitelijk het behandelen van de database als gewoon een stuk source code. De master database wordt onder configuration management gehouden in haast dezelfde manier als de source code. Wanneer we een succesvolle build hebben, wordt de database ingecheckt in het configuration management system samen met de code zodat we een complete en gesynchroniseerde versie historie hebben van beide.

Bij source code wordt veel van de lasten van integratie afgehandeld door source code control systems. Voor databases dient iets meer moeite te worden gedaan. Een verandering aan de database dient netjes te gebeuren, namelijk als geautomatiseerde database refactorings, waarover later meer. Daarnaast moet de DBA kijken naar elke database-verandering en zich ervan verzekeren dat het past binnen het algemene idee van het database schema. Om dit soepel te laten verlopen, moeten grote veranderingen niet als een verrassing komen als het tijd is om te integreren -- daarom dient de DBA nauw samen te werken met de ontwikkelaars.

We benadrukken dat regelmatig geïntegreerd moet worden, omdat onze ervaring is dat het veel gemakkelijker is om regelmatig kleine integraties te maken dan onregelmatig grote integraties. Het lijkt dat de lasten van het integreren exponentieel toenemen met de grootte van de integratie. Zodoende is het maken van vele kleine veranderingen in de praktijk veel gemakkelijker, ook al lijkt dit in eerste instantie niet zo voor velen. Ditzelfde effect wordt ook onderkend door mensen in de Software Configuration Management community voor source code.

Een database die bestaat uit schema en test data

Als we over een database praten hier, bedoelen we niet slechts een schema, maar ook aardig wat data. Deze data bestaat uit min of meer statische data voor de applicatie, zoals de onvermijdelijke lijst van alle staten van Amerika maar ook test data zoals een paar klanten.

Die data is nodig om een aantal redenen. De belangrijkste is om testen mogelijk te maken. Wij geloven rotsvast in het gebruik van een groot aantal geautomatiseerde testen om de ontwikkeling van een applicatie te stabiliseren. Dit is een gebruikelijke benadering in agile methoden. Om deze testen efficiënt te laten werken, is het logisch om te werken op een database die reeds beschikt over wat test data, waarvan alle testen kunnen aannemen dat die er is voordat ze uitgevoerd worden.

Naast het helpen om de code te testen, staat de aanwezigheid van testdata ook toe om onze migraties te testen wanneer we het schema van de database veranderen. Omdat we test data hebben, worden we geforceerd om ons ervan te verzekeren dat schema-veranderingen kunnen omgaan met testdata.

In de meeste projecten die we gezien hebben is deze testdata fictief. Maar in een paar projecten hebben we gezien dat mensen echte data gebruiken voor de testen. In deze gevallen is de data geëxtraheerd van vorige legacy systemen met geautomatiseerde data migratie scripts. Het moge duidelijk zijn dat niet alle data onmiddelijk gemigreerd kan worden, omdat in de eerste cycli van het ontwikkelproces slechts een klein deel van de database is ontwikkeld. Maar het idee is om iteratief de migratiescripts te ontwikkelen, net als de database en de applicatie. Dit helpt niet alleen om migratie-problemen vroeg uit de weg te ruimen, maar het maakt het ook gemakkelijker voor materie-deskundigen om te werken met het groeiende systeem, omdat zij bekend zijn met de data en vaak kunnen helpen met het identificeren van probleemgevallen die problemen kunnen veroorzaken voor het database- en applicatie-ontwerp. Dientengevolge zijn wij van mening dat getracht moet worden om echte data te gebruiken vanaf de eerste iteratie van je project.

Alle veranderingen zijn database refactorings

De techniek van refactoring gaat over het gedisciplineerd toepassen van gecontroleerde technieken om een bestaande code base te veranderen. Op eenzelfde manier hebben wij verschillende database refactorings geïdentificeerd die soortgelijke gedisciplineerde controle geven over veranderingen aan een database.

Eén van de grote verschillen bij database refactorings is dat het drie verschillende veranderingen betreft die gelijktijdig moeten plaatsvinden:

  1. Veranderen van het database schema
  2. Migreren van de data in de database
  3. Veranderen van de API naar de database

Dus wanneer we een database refactoring beschrijven, dienen we alle drie aspecten te beschrijven en ons ervan te verzekeren dat alledrie ook zijn toegepast voordat andere database refactorings worden toegepast.

Wij zijn nog steeds in de fase van documenteren van de diverse database refactorings, dus we zijn nog niet in staat om hier gedetaileerd op in te gaan. Desalniettemin zijn er een paar dingen op te merken. Net als code refactorings zijn database refactorings zeer klein. Het concept van een aan elkaar geklonken serie van zeer kleine veranderingen is vrijwel hetzelfde voor databases als voor code. Het feit dat elke verandering uit drie delen bestaat, maakt het des te meer van belang om veranderingen klein te houden.

Veel database refactorings, zoals het toevoegen van een kolom, kunnen gedaan worden zonder aanpassingen aan alle code die de database benadert. Als code het nieuwe schema gebruikt zonder ervan op de hoogte te zijn, wordt die kolom gewoon niet gebruikt. Veel veranderingen hebben echter niet dit kenmerk. We noemen ze destructieve veranderingen, een voorbeeld hiervan is een bestaande nullable kolom not null maken.

Destructieve veranderingen vereisen wat meer voorzichtigheid al naar gelang de ingrijpendheid van de verandering. Een voorbeeld van een kleine verandering is het veranderen van een nullable kolom naar not null. In dit geval kun je waarschijnlijk gewoon je gang gaan en de verandering maken. Het refactoren zorgt voor de data in de database die null is. Meestal is de enige developer die om de eigenschap geeft, ook diegene die de verandering aanvroeg en die developer zal de database mapping code bijwerken. Dit zorgt ervoor dat de update geen andere code zal breken en als dit toch gebeurt dan blijkt dit wanneer een build wordt gemaakt en de testen worden uitgevoerd. (Op ons grote project gaven we onszelf wat ruimte door een week te wachten voordat de database verandering door werd gevoerd.)

Het opdelen van een veelgebruikte tabel in tweeën is echter een moeilijker geval. Hierbij is het belangrijk om iedereen te laten weten dat de verandering eraan komt, zodat zij zich kunnen voorbereiden. Daarnaast is het het waard om te wachten op een veilig moment om de verandering te maken. (Dit soort veranderingen stelden wij uit tot de start van een nieuwe iteratie -- wij vonden het prettig om iteraties van twee weken of korter te gebruiken.)

Het belangrijke is hier om een procedure te kiezen die toepasselijk is voor het soort verandering dat je maakt. In geval van twijfel probeer dan de verandering gemakkelijker te maken. Onze ervaring is dat we onze vingers veel minder vaak brandden dan velen zouden denken, en met een sterke configuration control van het gehele systeem is het in het ergste geval niet moeilijk om handelingen terug te draaien.

Automatiseer de refactorings

In de wereld van code zien we tools voor sommige programmeertalen om veel van de geïdentificeerde refactorings te automatiseren. Dit is essentieel voor databases; op zijn minst op de gebieden van schema-aanpassingen en datamigratie.

Als gevolg hiervan is elke database refactoring geautomatiseerd door het schrijven van SQL DDL (voor de schema verandering) en DML (voor de data migratie). Deze stappen worden nooit handmatig doorgevoerd, in plaats daarvan worden zij met een klein SQL script gedraaid op de master om de veranderingen te maken.

Wanneer dit klaar is, bewaren we deze scriptjes om een complete change log te produceren van alle aanpassingen aan de database als gevolg van de database refactorings. We kunnen dan elke database instantie updaten naar de laatste master door de change log van alle veranderingen te draaien sinds de master is gekopieerd om de oudere database instantie te produceren.

Deze mogelijkheid om geautomatiseerde veranderingen op een rij te zetten is een essentieel stuk gereedschap voor zowel het continue integratieproces tijdens ontwikkeling als voor het migreren van de productiedatabase naar een nieuwe release.

Voor productie-databases maken we geen veranderingen tijdens iteraties. Wanneer we een release doen, die kan gebeuren aan het eind van elke iteratie, draaien we het volledige change log van database refactorings sinds de vorige release. Dit is een grote verandering en dit hebben we alleen gedaan door de applicatie in productie offline te zetten. (We hebben wel wat ideeën voor een 24/7 omgeving, maar we hebben dit feitelijk nog niet hoeven doen.) Het is ook verstandig om dit migratie-schema te testen voordat het gedraaid wordt tegen de live database. Tot nu toe hebben wij ervaren dat deze techniek opmerkelijk goed werkt. Door alle database-veranderingen op te breken in een serie van kleine, simpele veranderingen zijn we in staat geweest om vrij grote veranderingen te maken aan productie-data zonder in de problemen te raken.

Net als het automatiseren van de voorwaardse veranderingen, is het te overwegen om het terugdraaien van elke refactoring te automatiseren. Als je dit doet, ben je in staat om veranderingen aan de database terug te draaien op dezelfde geautomatiseerde manier. We hebben dit nog niet gedaan omdat we er nog niet echt behoefte aan hebben gehad, maar het is hetzelfde principe.

(Een soortgelijk iets wat we hebben gedaan is het ondersteunen van een oude versie van een applicatie met een geupdate versie van de database. Dit hield in dat een compatibility layer geschreven moest worden die het de applicatie toestond om te denken dat hij praatte met de oudere versie van de database, ook al praatte hij in werkelijkheid met de nieuwere.)

Automatisch bijwerken van alle database ontwikkelaars

Het is natuurlijk prima dat mensen veranderingen maken en de master bijwerken, maar hoe weten ze nu dat de master is veranderd? In een traditionele continue-integratie omgeving met source code doen ontwikkelaars hun lokale kopie updaten aan de hand van de master voordat zij committen. Op die manier kunnen ze build-problemen oplossen voordat ze hun veranderingen committen. Er is geen reden dat dit niet gedaan kan worden met de database, maar wij hebben een betere manier gevonden.

Wij werken automatisch iedereen bij op het project wanneer een verandering is gemaakt aan de database master. Hetzelfde refactoring script dat de master bijwerkt, werkt ieders database bij. Als we dit beschrijven, zijn mensen meestal bezorgd dat het automatisch updaten onder de handen van de developers problemen geeft, maar wij hebben ervaren dat dit prima werkt.

Dit werkte alleen manneer mensen verbonden waren met het netwerk. Wanneer ze offline werkten, zoals in het vliegtuig, moesten ze handmatig resyncen wanneer ze weer op kantoor kwamen.

Duidelijk scheiden van alle code die de database benadert

Om de consequenties van database refactorings te begrijpen, is het belangrijk om te zien hoe de database wordt gebruikt door de applicatie. Als SQL her-en-der verspreid is door de code base, is dit bijzonder moeilijk om te doen. Daarom is het belangrijk om een duidelijke database access laag te hebben om te tonen waar de database wordt gebruikt en hoe. Om dit te doen, suggereren we het volgen van één van de patterns van P van EAA.

Een duidelijke database laag heeft een aantal waardevolle bijkomende voordelen. Het minimaliseert de gebieden in het systeem waar developers SQL kennis nodig hebben om de database te manipuleren, wat het leven van die developers gemakkelijker maakt, die niet speciaal vaardig zijn met SQL. Voor de DBA levert dit een duidelijk stuk van de code dat hij kan bekijken hoe de database wordt gebruikt. Dit helpt bij het bereiden van indexen, database optimalisatie en ook het kijken naar de SQL om te zien hoe het opnieuw kan worden geformuleerd om beter te performen. Dit staat de DBA toe om een beter begrip te krijgen van hoe de database wordt gebruikt.

Variaties

Zoals elke set technieken, moeten deze aangepast worden op jouw specifieke omstandigheden. Deze technieken zijn nog steeds redelijk nieuw, dus we zijn niet gestuit op veel variaties, maar hier zijn er een paar die we hebben.
Meerdere database lineages bijhouden

Een simpel project kan het doen met één database master in de repository. Met meer complexe projecten is het nodig om meerdere soorten van de project database te bewaren, waaraan wij hier refereren als database linages. We kunnen een nieuwe lineage maken wanneer we de applicatie branchen die al in productie is gebracht. In essentie is het maken van een nieuwe database lineage hetzelfde als het branchen van de source code van de applicatie, met het verschil dat je ook een lineage maakt als een verschillende set van sample data nodig is, bijvoorbeeld als je veel data nodig hebt om de performance te testen.

Als een ontwikkelaar een kopie maakt van de master, dienen ze te registreren welke lineage ze aanpassen. Wanneer de DBA updates draait tegen de master voor een bepaalde lineage, worden de updates gepropageerd naar al de ontwikkelaars die zijn geregistreerd voor die lineage.

Je hebt geen DBA nodig

Dit klinkt allemaal als een hoop werk, maar in feite vereist dit geen groot deel mankracht. Op het Atlas project werkten meer dan dertig ontwikkelaars en een teamgrootte (inclusief QA, analisten en management) van bijna honderd. Op elke gegeven dag hadden we rond de honderd kopieën van verschillende lineages op mensen hun werkstation. Maar met al deze activiteit was slechts één full-time DBA (Pramod) nodig met een paar developers met interesse in DB issues die de DBA taken parttime afhandelden.

De reden hiervoor is automatisering. Als je vastbesloten bent om elke taak te automatiseren, kun je een hoop werk afhandelen met veel minder mensen.
Gereedschappen om te helpen

Dit soort dingen vereist een hoop steeds herhalende taken. Het goede nieuws is dat wanneer je tegen steeds herhalend werk aanloopt in software-ontwikkeling, je in de ideale positie bent om deze te automatiseren. Het resultaat hiervan is dat we aardig wat, vaak eenvoudige, tooltjes hebben ontwikkeld om ons te helpen.

Een van de meest waardevolle automatiseringen zijn een aantal scripts voor algemene database taken.

  1. Een user up-to-date brengen met de huidige master.
  2. Een nieuwe user aanmaken.
  3. Een database schema kopiëren: bijvoorbeeld Sue vindt een bug in haar database en nu kan Mike de database van Sue kopiëren en proberen om de applicatie op zijn eigen workstation te debuggen.
  4. Een user droppen.
  5. Een user exporteren zodat teamleden offline backups kunnen maken van de database waarmee ze werken.
  6. Een user importeren zodat wanneer de teamleden een backup kopie van een database hebben, zij deze backup kunnen importeren en een nieuw schema kunen aanmaken.
  7. Een baseline exporteren -- maak een backup van de master database. Dit is een speciale versie van een user exporteren.
  8. Een difference report maken van een willekeurig aantal schema's, zodat Mike kan uitzoeken welke verschillen er zijn qua structuur tussen die van hem en die van Sue.
  9. Een schema diff'en tegen de master, zodat ontwikkelaars hun lokale kopie kunnen vergelijken met de master.
  10. List alle users.

Analisten en QA mensen moeten vaak een blik kunnen werpen op de test data in de database en moeten gemakkelijk die data kunnen veranderen. Voor dit doel hebben we een Excel applicatie met VBA-scripts gemaakt om de data uit de database te trekken in een Excel bestand, en vice versa om de data weer te backuppen in de database. Alhoewel andere tools bestaan om de inhoud van een database te bekijken en te bewerken, werkt Excel goed omdat zoveel mensen bekend ermee zijn.

Iedereen op het project moet in staat zijn om het database ontwerp gemakkelijk te kunnen verkennen, op deze manier kan iedereen uitzoeken welke tabellen beschikbaar zijn en hoe ze worden gebruikt. We bouwden een HTML-gebaseerde tool om dit te doen die servlets gebruikte om database metadata op te vragen. We deden het modelleren van de data met ERwin en trokken data uit ERwin in onze eigen metadata tabellen.

Verdere stappen en verdere informatie

Dit is in geen geval het laatste wat is gezegd over het onderwerp van evolutionair database design. We willen zeker nog uitvinden of en hoe we deze technieken kunnen uitbreiden om databases te integreren, 24/7 operation en andere probleemgebieden die we nog niet tegengekomen zijn.

Als je meer wilt uitvinden over dit, of je eigen ervaringen wilt uitwisselen; Pramod is een Yahoo egroup voor agile databases gestart. Pramod is ook begonnen met praten over deze technieken op diverse conferenties, dus wellicht krijg je een kans om direct met hem te praten. Uiteraard doen we ook consulting met betrekking tot deze materie.