facebook LinkedIN LinkedIN - follow
Tematické sekce
 
Branžové sekce
Přihlášení SystemNEWSPřehledy
 
Tematické seriály

Jak uřídit IT projekt a nezbláznit se

Užitečné tipy a nástroje pro řešení problémů řízení inovací a vývoje produktů...

články >>

 

Industry 4.0

Průmysl 4.0

Jaký vliv bude mít čtvrtá průmyslová revoluce na výrobu a výrobní firmy?

články >>

 
Nové!

RPA - automatizace procesů

Softwaroví roboti automatizují obchodní procesy.

články >>

 
Nové!

IoT – internet věcí

Internet věcí a jeho uplatnění napříč obory.

články >>

 
Nové!

VR – virtuální realita

Praktické využití virtuální reality ve službách i podnikových aplikacích.

články >>

 
Nové!

Bankovní identita (BankID)

K službám eGovernmentu přímo z internetového bankovnictví.

články >>

 

Příručka úspěšného IT manažera

Dnes je řada IT manažerů opomíjena. Úspěšní bývají brouci Pytlíci a Ferdové...

články >>

 
 
Partneři webu
Big Data a Business Intelligence , AI a Business Intelligence

Refactoring databáze nemusí být noční můrou

Michal Petřík


Refactoring databáze nemusí být noční můrouNástroje pro automatizaci procesu tvorby software udělaly za poslední dekádu neuvěřitelný skok kupředu. Bavíme se o Continuous integration, delivery, deployment, ideálně o DevOps. Oblast vývoje Java, .Net, Javascript a dalších aplikačních platforem nabízí nepřeberné množství nástrojů, které nám ulehčí život a většina zdravě uvažujících IT oddělení je již implementovala nebo o tom velmi vážně uvažuje.


I přesto, že jsou podobné nástroje dostupné i v oblasti relačních databází, nejsou zdaleka tak rozšířené. Aktualizace datového modelu relační databáze v rámci migrace nové verze software je na mnoha místech stále velkou výzvou, přenos změn mezi prostředími je pak kolikrát velmi živou noční můrou (inkonzistence modelu, dat, uložených procedur, atd.). Situaci jednoznačně nahrává častá absence plnohodnotného prostředí, kdy dochází k ad-hoc zásahům do sdílené databáze ze strany více týmů. V takové situaci je samozřejmě nejrychlejší pomocí zavedení alespoň základního procesu, například ve formě centrální správy datového modelu. Veškeré požadavky jsou pak řešeny centrální autoritou, která je odpovědná jak za zanesení požadovaných změn, tak i jejich distribuci do cílové databáze (spíše databází, ale o tom později). Samozřejmě lze namítat, že tento přístup není dostatečně rychlý – agilní. Nicméně pokud se nemá stát z vývoje chaos, je alespoň elementární proces při sdílení prostředků nezbytný. Mimo zavedení základních pravidel vývoje také pomůže, pokud je model centrálně spravován v dostatečně vyspělém modelovacím nástroji – jednoznačně lépe lze identifikovat dopady změn před jejich vlastním provedením a významně se snižuje riziko chyby v DDL/SQL skriptech, jelikož je generuje použitý nástroj.

V rozporu s logikou použití existujících nástrojů a standardizovaných procesů jde fakt, že tyto nejsou v oblasti databází ani zdaleka rozšířeny tak, jak by měly být. To platí jak u nových projektů, tak i běžících – zde je však míra absence jakékoliv podpory procesu ještě vyšší. Důvodů je určitě více, ale mezi ty hlavní patří dle zkušenosti primárně:

  • Představa, že daný nástroj nelze v prostředí implementovat.
  • Předpoklady vysokých nákladů na implementaci nástroje.
  • Obava z nároků na další provoz nástroje.

Jak lze tušit, jsou zmíněné důvody spíše alibi pro obhajobu „proč dané nejde“, než hledání možností, jak současný stav zlepšit. Pojďme se tedy podívat na to, jaké možnosti v oblasti databází opravdu máme, a že se nejedná o cokoliv revolučního, spíše evolučního.

Proč dané téma řešit

Nelze rozporovat, že práce nad databází přináší mnohdy obtížnější problémy, než se kterými se setkáme u aplikací nasazovaných do webových/aplikačních serverů. Ne vždy lze postavit plnohodnotné vývojové prostředí, což je způsobeno například velikostí produkčních dat, jejich citlivostí, licencemi pořizovaného SW, HW, atd. V tomto ohledu však téměř všechny produkty databázových serverů nabízejí tzv. „express“, či „developer“ edice, se kterými lze pro základní potřebu určitě pracovat (virtualizace a nástroje typu Docker navíc výstavbu vývojových prostředí značně urychlují a zjednodušují). Dostupnost dat pro vývoj je bezesporu problém, avšak v mnoha případech je potřebné udržovat hlavně datový model a obslužné programové vybavení (uložené procedury, triggery, …) společně s minimálním setem dat, na kterých lze řešení testovat. Samozřejmě pokud bychom se bavili o datové analytice, je takový přístup naprosto nedostačující, nicméně diskuze tohoto tématu není předmětem textu.

Hlubší analýzou problémů spojených s vývojem nad databází dospějeme k závěru, že se situace vlastně zas až tak neliší od vývoje jiných aplikací, u kterých je v době implementace nutné řešit například integrace na nedostupná rozhraní, simulaci vysoké zátěže pro ověření fail-over mechanismů, atd. Závěrem tedy je, že je nezbytné si vždy „nějak“ poradit a v 80 % případů dostatečné řešení existuje, přičemž 20 % případů lze řešit zvýšeným úsilím. Pojďme si nyní projít typický scénář zanesení změny do aplikační databáze, například v podobě aditivní změny atributu v entitě. Vývojář vytvoří DDL/SQL skript s požadovanou změnou, otestuje kód na lokálním prostředí a následně skript zpropaguje do verzovacího systému. V tomto bodě často vyvstávají nepříjemné otázky typu:

  • Kdo zajistí nasazení změn na další prostředí?
  • Jak se změna zpropaguje k ostatním vývojářům (myšleno přímo do jejich databáze, jelikož stažení skriptu změn ještě nutně nemusí znamenat jeho aplikaci)?
  • Jak bude zajištěno předání změn zákazníkovi?
  • Nebyla již změna na prostředí nasazena?

Tato situace je velmi častá a typicky se řeší poctivou administrativou, která eviduje veškeré změny ve všech prostředích. Celé řešení stojí na precizním respektování procesu, naneštěstí padá s prvním ad-hoc hotfixem, který musí jít nutně do produkce, a proces v důsledku poruší (ruku na srdce, touto situací jsme si prošli všichni).

Dostupné nástroje

Odpovědí na výše uvedené otázky a vzniklé problémy je nepřekvapivě automatizace, tedy programově řízená správa verzí změn, které se nad databází aplikují. Pro účely tohoto článku využiji příkladu dvou populárních nástrojů Flyway (https://flywaydb.org/) a Liquibase (http://www.liquibase.org/). Jedná se o open-source nástroje primárně pro Java vývoj, nicméně pro svět .Net existují neméně vhodné alternativy například v podobě Entity frameworku, atd.

V jednoduchosti je krása a jednoduché věci jsou (při vývoji SW obzvlášť) většinou nejvíce efektivní (viz známý KISS princip). Shodné platí i pro uvedené nástroje, které ve zkratce pracují takto:

  • Vývojář spustí dedikovaný nástroj (Flyway / Liquibase), přičemž konfiguračně předá informaci o databázi, do které se mají změny aplikovat a také zdrojových kódech (DDL, procedury, …), které tyto změny definují – typicky reprezentováno konfiguračním skriptem s popisem změn (případ Liquibase), případně jmennou konvencí změnových skriptů (01, 02, 03 … atd., případ Flyway).
  • Nástroj ověří, zda cílová databáze obsahuje informace o verzích – většinou je to realizováno jednoduchým číselníkem s informacemi o nasazených skriptech. Pokud daný číselník neexistuje, nástroj jej vytvoří.
  • Porovnáním informací o posledních zanesených změnách z číselníku v databázi a lokální konfigurace změnových skriptů je jednoznačně určena množina úprav, které se mají aplikovat.
  • Nástroj následně zajistí aplikaci všech změn a aktualizaci verzovacích informací.

Na první pohled se může použití nástroje jevit jako pouze nepatrný posun oproti dodržování předepsaného manuálního procesu. Pojďme si ale připomenout, co nám tento přístup vlastně v základu umožní:

  • Aktualizaci databáze lze hladce zařadit do standardního build procesu celé aplikace. Není tedy nutné cokoliv řešit manuálně (změny se aktualizují z verzovacího systému a nástroj zajistí vše ostatní).
  • Změny lze velmi jednoduše distribuovat a synchronizovat mezi vývojáře i prostředí.
  • Stav databáze je jasně popsán, přičemž nástroje typicky kontrolují i konzistenci změnových skriptů (pomocí hash funkce). Snižuje se tedy riziko, že dojde ke změně zdrojového skriptu po jeho aplikaci v databázi.

Výše uvedené body jsou pouze základními vlastnostmi, které však i tak zásadně pomohou. Na základě volby konkrétního nástroje lze dosáhnout i dalších ulehčení. Nástroj Flyway například spravuje čisté DDL/SQL skripty. Vývojář je tedy plně odpovědný za obsah a nástroj pouze zajistí, že je vše nasazeno ve správném pořadí a aktualizováno. Nástroj Liquibase navíc k podpoře klasických DDL/SQL skriptů dává možnost zápisu v DSL (Domain Specific Language, v případě Liquibase v XML, JSON nebo YAML formátech, případně v nativním SQL), kdy je konkrétní zápis DDL/SQL zobecněn na úrovni nástroje. Není tedy nutné znát přesnou podobu dialektu Oracle, MS SQL, Sybase, atd., ale lez pouze zapsat požadavek na vytvoření tabulky. Nástroj následně provede vygenerování DDL/SQL ve správném dialektu pro daný databázový stroj. V prostředí, kde se pracuje s více typy databází, se tato možnost velmi hodí. Vlastní DSL zápis pak nabízí i další možnosti v podobě logických podmínek, ověřovacích funkcí, apod. Lze tedy docílit stavu, kdy jeden změnový skript obsahuje kompletní požadavek, ale je v něm jednoznačně odlišeno, že například na prostředí A je nasazován jiný set čtecích práv než na prostředí „B“. Nástroj pak na základě JDBC připojení a typu databáze jednoznačně určí, na kterém prostředí se pracuje a aplikuje pouze dedikované změny.

Třešničkou na dortu je bezesporu podpora funkce rollback u všech příkazů (situace, kdy je nutné řešit již existující data, však musí vývojář logicky řešit specifickým skriptem) a také fakt, že XML/JSON/YAML zápis se na rozdíl od DDL/SQL mnohem lépe zpracovává dalšími nástroji. Jak již bylo zmíněno, je Liquibase open-source nástrojem. Případné rozšíření o vlastní příkazy DSL je tedy naprosto standardní možností.

<changeSet
 context="db_intern1, db_intern2, test"
 author="developer#1"
 id="unique-changeset-id">
   <comment>
     Doplnění nových sloupců do entity my_entity_prod
   </comment>
   <addColumn tableName="my_entity_prod">
      <column name="atr1" type="smallint" />
      <column name="atr2" type="int" />
      <column name="atr3" type="varchar(100)" />
   </addColumn>
</changeSet>
Obr. 1: Ukázka zápisu změny.

Vše dosud uvedené neplatí pouze pro změny datového modelu, ale samozřejmě i pro další artefakty, jako například triggery, uložené procedury, atd. V případě uložených procedur se bavíme o detekci změn per procedura, toto lze ale opět zajistit výpočtem hash nad lokálními zdrojovými kódy a realitou uloženou v konkrétní databázi. Takové řešení lze poměrně rychle vytvořit manuálně, případně je dostupné jako placené rozšíření Liquibase.

Možnosti zavedení nástrojů do vašeho procesu

Jedním z hlavních důvodů pro nezavedení nástroje je obava z velkých obtíží při jeho integraci. Pravdou je, že zavedení na novém projektu a například již 10 let běžícím, bude bezesporu odlišné. U projektů v údržbě existují dle všeho dva možné přístupy:

  • velký třesk,
  • jako bychom to používali odjakživa.

V prvním případě je nutné udělat kompletní reverse engineering stávající databáze, získaný výstup je následně zanesen do nástroje. Tento přístup je jednoznačně precizní a dokáže odhalit mnoho „kostlivců ve skříni“ - je ale opravdu náročný. Ne vždy jde vše tak hladce, navíc u opravdu velkých databází může proces trvat opravdu dlouho. Nespornou výhodou je však 100% jistota, že lze databázi postavit takříkajíc od nuly.

Druhý přístup lze jednoduše shrnout jako „a teď“. Aktuální stav databáze se prohlásí za status quo a od toho bodu se používá výhradně nástroj. Z pohledu nezaujatého uživatele lze nabýt dojmu, že se nástroj používal vždy. Tento přístup je osvědčený a ve většině případů řádově jednodušší na realizaci – mimo to se lze minimálně v počátku používání relativně bezpečně rozhodnout k odrolování celé aktivity. Výhoda prvního přístupu s kompletní výstavbou DB od nuly se stírá v případě využití dumpu databáze z okamžiku, kdy jsme verzování aplikovali. Nemáme tedy ověřenu možnost postavení DB tzv. od nuly, ale víme, že lze použít dump a všechny následné změny (a upřímně, je toto opravdu taková nevýhoda, když se dumpy standardně používají při stavbě nových prostředí?). Nástroje pro podporu refactoringu databází rozhodně nejsou žádnou horkou novinkou posledních měsíců a nabízejí dostatečnou vyspělost pro seriózní použití. I přes tento stav však nejsou dostatečně rozšířené a spoustu IT oddělení o nich neví nebo se danou oblast z různých důvodů neodvažuje řešit. Obecně by mělo platit, že zlepšujeme věci tam, kde bude mít i sebemenší úprava největší pozitivní dopady. Domnívám se, že v mnoha případech výše uvedené platí právě v oblasti databázového refactoringu. Právě proto bychom dnes dostupné možnosti a nástroje pro zlepšení kvality celého procesu dodávek neměli ignorovat.

Michal Petřík Michal Petřík
Autor článku působí na pozici Head of Software Development ve společnosti Profinit.
Chcete získat časopis IT Systems s tímto a mnoha dalšími články z oblasti informačních systémů a řízení podnikové informatiky? Objednejte si předplatné nebo konkrétní vydání časopisu IT Systems z našeho archivu.