pátek 30. prosince 2016

NoSQL - Život nepodléhá třetí normální formě

BigData, NoSQL...

Asi každý se již setkal s těmito názvy, které jsou často spojovány se jmény jako je Google, Facebook či Amazon.

Co to vlastně znamená?

Díky rozmachu internetu na běžnou část populace, začalo docházet k exponenciálnímu nárůstu dat, které je třeba uchovávat a zároveň v nich "dolovat". Klasické relační databáze, které díky ACID udržují validní stav dat, se staly nevhodnou variantou. Ano, ani MS SQL a ani Oracle není vhodná databáze na Big Data.

Existuje mnoho důvodů, proč relační databáze není ideální variantou pro větší systémy. Zde je pár příkladů:

1. Vertikální škálování - tedy databázový stroj se nedá donekonečna výkonostně nafukovat
2. Pevná struktura - předem definovaná struktura dat, není pro vetší a rychle se měnící systémy, žádoucí
3. Migrace - Pro změnu struktury je často třeba sofistikovaná migrace přes SQL
4. SQL - dotazování pomocí tohoto jazyku je sice jednoduché, ale zároveň dost omezující

 Co tedy znamená NoSQL?

V první řadě by bylo vhodné říct, že označení NoSQL není zrovna vhodný název. Do této rodiny totiž dnes spadá několik typů databází. Pojďme si je v rychlosti projít:

Objektová databáze
První takzvanou NoSQL databází byla objektová. Šlo o to, že v době dominance objektově orientovaných jazyků (ještě stále to platí, nicméne funkcionální přístup ukazuje lepší koncept), se došlo do bodu, kdy mapování tabulek z relační databáze na objekty může být náročné. Vzniklo mnoho ORM knihoven, napříč všemi objektově orientovanými jazyky (C# - Entity Framework, Java - JPA, apod).  Proto vznikl koncept objektové databáze, která se snažila odbourat dané mapování a zvýšit tak výkon. Bohužel nikdy nedošlo k většímu rozmachu těchto databází a dnes se dá v podstatě říci, že se jedná o upadající koncept.

XML databáze
Označení není asi úplně správné, ale koresponduje přesně s tím, co takový typ databáze dělá. Jedná se o to, že data jsou ukládána v podobě XML dokumentů a jejich schématem je v podstatě XSD. Tento typ databází je vhodný zejména v případě složitých struktur jednotlivých dokumentů. Jistě bude stále existovat segment, kde tento druh databází bude využíván.

Key-Value databáze
Toto označení se vztahuje na databáze, které ukladají svá data do jakési hash mapy. Tedy klíč reprezentuje metadata a hodnota je reálná uložená hodnota. Tyto mapy jsou ukládány v blocích, které je unifikováno vlastním klíčem, který je použit pro přístup k daným datům.
První koncept přinesl Google, který dal světu Hadoop. Ten byl poté uvolněn pod Apache a stal se open source projektem. Pro dotazování se využívá přístup Map-Reduce.

Dokumentová databáze
Tento typ databáze vychází z principu key-value, kdy value reprezentuje dokument, což je struktura, nejčastěji reprezentovaná pomocí JSON formátu. Jednotlivé dokumenty mají svůj klíč v rámci celé kolekce a umožňují vazby na další dokumenty. Nejpopulárnější databází tohoto formátu je MongoDB.

Sloupcová databáze
Vychází z principu NoSQL databází s tím, že se nejvíce podobá relačním databázím. Data jsou reprezentována v tabulce se sloupci. Narozdíl od relační databáze je ovšem možné aby jednotlivé řádky obsahovaly jiné sloupce. Tedy nejedná se o pevnou strukturu v rámci celé tabulky.

Grafová databáze
Tento typ databáze je asi nesložitější a zároveň nejnovějším návrhem. Jedná se o to, že jednotlivá data mohou být propojována na další data pomocí vlastních vazeb. V té chvíli vznikají vazby jako: "uživatel vlastní", "role spadá do", apod. Grafová databáze umožňuje navrhnout strukturu tak, aby skutečně kopírovala reálný svět.

Správný výběr
V rámci projektu, na kterém v současné době pracuji, jsem hledal úložiště, které by mi splňovalo několik kritérií:


  1. Úložiště musí mít horizontální škálování. Tedy bude možné přidáváním dalších virtuálních strojů, zvyšovat výkon.
  2. Dostupnost je nejdůležitější vlastnost. Prominu úložišti dočasnou "zastaralost" dat, ale určitě ne výkyv v dostupnosti.
  3. Bude docházet k častým změnám v modelu aplikace. Rád bych tedy úložiště, ve kterém nebudu muset dělat složité migrace.
  4. Rád bych, aby databáze uměla zpracovávat JSON a to přirozenou formou. Nechci nic slyšet o formátech jako XML, apod. Nežijeme v pravěku.
  5. Jelikož server API je GraphQL, tak bych rád databázi, pro kterou bude tento způsob přirozený.
  6. Musí existovat možnost, jak se na databázi napojit přes Node.JS
Po sepsání základních požadavků, jsem se pustil do výběru hledání. Finále je vcelku jasné. MongoDB. I přes některá svá úskalí je to nejlepší varianta, která se dá zvolit. Splňuje základních 6 bodů, které jsem si dal.

Co MongoDB neumí?
Určitě se nedá říct, že tento typ databáze je spásou na vše. Tak například: "Těžko budete zařizovat bulk operace, jako hromadný insert. Dvoufázový commit sice MongoDB má, ale v tomto stavu se rapidně začně snižovat i výkon. Relace mezi daty si musíte hlídat v aplikaci."
Věcí, které při přechodu z klasických SQL databází člověk musí oželet, je více. Buď se s tím smíříte a nebo se vrátíte :)

Závěr
Většině databázistům jistě budou vadit dané nevýhody, které sebou tento princip přináší. Nicméně, kdo kdy navrhnul strukturu v relační databázi tak, aby mohl říci: "Jsem schopen obhospodařit jakýkoli požadavek na má data."? Odpověď je nikdo. A důvodem budiž třeba to, že život nepodléhá třetí normální formě.

Uvedu příklad, který jsem si vypůjčil z knihy "Big Data a NoSQL databáze":
Představte si situaci, že vlastníte stackoverflow.com, kde uživatelé pokládají otázky. V klasické relační databázi byste nejspíše měli tabulky jako otázka, uživatel. Uživatel by například obsahoval sloupec město, což by byla jeho aktuální adresa, kde bydlí. Samozřejmě by se uživatel mohl přestěhovat a tím by se změnilo i jeho bydliště. Vazba mezi uživatelem a otázkou by byla 1:N. Tady je zatím vše v pořádku, do doby, než dojde k požadavku, abyste zjistili, ze kterého města bylo pokládáno nejvíce otázek. V té chvíli by samotný návrh nebyl schopen obhospodařit tento požadavek. Sice jsme strukturu navrhli správně, nicménéně jsme si neuvědomili, že svět se nechová podle normálních forem. Asi by nám nezbylo nic jiného, než u změny bydliště si v čase uchovávat i změnu. Pak by nejspíše existovala tabulka bydliště, která by v podstatě musela udžovat změnu v čase.

Líbí se mi tento příklad. Ukazuje přesně to, že dopředu nikdy nemůžeme vědět, jaký bude požadavek na naše data. V dokumentové databázi se často data ukládají tak, že vazby jsou sice možné, ale nejsou hlavním stavebním kamenem. Jinak řečeno, v kolekci otázka by se uložila sice reference na uživatele, ale současně s tím i aktuální stav uživatele, tedy jeho jméno, adresa, apod. Ano porušili jsme sice normální formu, ale zároveň jsme umožnili vetší flexibilitu ohledně dolování dat. Navíc jsme se víc přiblížili realitě, tedy tomu, že v daném čase se uživatelka ještě nevdala a nezměnila příjmení a Franta ještě nebydlel v Praze, ale v Brně :)