Přechod z MySQL na CouchDB, část první

Pokud máte databázi postavenou na MySQL, možná jste zvědaví, jestli, a hlavně jak, je možné s vaší databází přejít na CouchDB. Největší překážkou není technická stránka vytvoření CouchDB nebo ukládání informací; nejnáročnější je začít uvažovat o datech jiným způsobem a uvědomit si, jak to změní logiku vaší aplikace.

Seriál: Nerelační databáze (11 dílů)

  1. CouchDB – tak trochu jiná databáze (1. část) 24.8.2009
  2. CouchDB – tak trochu jiná databáze (2. část) 31.8.2009
  3. CouchDB – tak trochu jiná databáze (3. část) 7.9.2009
  4. MySQL v roli neschémové databáze 6.1.2010
  5. Základy Amazon SimpleDB 30.3.2010
  6. Návrh databáze – NoSQL vs SQL 31.3.2010
  7. Amazon SimpleDB prakticky v PHP 15.4.2010
  8. Vyskúšajme si Tokyo Cabinet 4.5.2010
  9. Redis: key-value databáze v paměti i na disku 7.10.2010
  10. Přechod z MySQL na CouchDB, část první 17.2.2011
  11. Přechod z MySQL na CouchDB: Druhý díl 24.2.2011

Disclaimer: Článek je překladem článku How to move from MySQL to CouchDB z blogu CouchOne. Překlad i s originálními ilustracemi vychází s laskavým svolením společnosti CouchOne. Autor článku pracuje v CouchOne jako člen výboru a viceprezident pro dokumentaci, v minulosti psal dokumentaci k MySQL.

qrcode

K článku není ukázka

K článku není k dispozici zdrojový kód

Začneme tím, že se podíváme, jak lze strukturu databáze v MySQL převést na CouchDB, a jak se dotazy na CouchDB liší od způsobu používaného v MySQL.

Úvodní zamyšlení nad strukturou dat

MySQL (a další SQL databáze a jiné databáze založené na tabulkách) vás nutí uvažovat o datech jako o tabulkách. Všechna vaše data tvoří tabulku a při ukládání složitých struktur může být jedna informace rozložena do více tabulek. Pro některé aplikace a datové typy je to naprosto logická a rozumná forma uložení dat a přístupu k nim. Ale někdy tabulková struktura příliš neodpovídá datům, které chcete ukládat.

Ukažme si to na typickém příkladu, databázi receptů. To je něco, co dobře znám, protože server Cheffy.com je postavený na MySQL. Jádro databáze tvoří tabulka nazvaná recepty (Recipe), která obsahuje název receptu, podtitul, popis a počet porcí. Další údaje vztahující se k receptu, jako je seznam přísad (Ingredients), postup práce (Method), metadata a klíčové slova (Keywords), jsou uložené v dalších tabulkách, navázaných k samotnému receptu pomocí unikátního ID receptu. Velmi zjednodušeně je to vidět na následujícím obrázku.

Tato struktura může mít své výhody – určité operace mohou být například velmi jednoduché a přímočaré. Například: chcete najít všechny recepty, mezi jejichž přísady patří „mrkev“? Můžete nad tabulkou přísad vykonat dotaz na „mrkev“, a z něj získat seznam odpovídajících receptů. Za pomoci spojování tabulek můžete získat seznam receptů, jejich názvů a dalších informací z tabulky recepty tak, že budete hledat v tabulce přísady a přes ID receptu spojíte tuto tabulku s tabulkou recepty.

Zatímco tento způsob vyhledávání je jednoduchý, získání všech údajů o receptu, například pro jeho zobrazení uživateli, může být skutečně složité. Šlo by to jedním dotazem, ale někdy to bývá snazší pomocí více dotazů: jedním k němu získat údaje z tabulky recepty, druhým jeho přísady, dalším metadata atd. To vše je automaticky vykonáno v rámci aplikační vrstvy a výsledkem je objekt, který se pak použije jako základ pro formátované zobrazení receptu uživateli.

Ve většině aplikací je buď pro tento účel vytvořena speciální vrstva, a nebo se použije jeden z mnoha objektově-relačních mapovacích systémů, které mapují data ze struktury tabulek na vrcholový objekt, se kterým pak pracuje aplikace (a uživatel). Recepty jsou jen jedním z příkladů, obdobně je na tom i mnoho jiných různých aplikací, včetně fakturace (faktura, dodavatel, místo určení, položky faktury) a příspěvků na blogu (obsah příspěvku, klíčové slova, autor, komentáře).

Tento přístup založený na tabulkách není z principu špatný, ale v této situaci je zásadní informace rozložena do více tabulek, a to vede k nutnosti synchronizovat spolu tyto tabulky. Například, co se má stát, pokud se smaže záznam? Musíte smazat všechny další záznamy, které se na něj mohly odkazovat (buď ručně, nebo pomocí klauzule ON DELETE CASCADE). Obdobně také při načítání údajů jednoho receptu budete muset nakonec provést 5-10 dotazů na data.

CouchDB volí jiný přístup. Namísto více tabulek, do kterých se ukládají různé typy informací, do CouchDB ukládáte jeden typ struktury dat ve formátu JavaScript Object Notation (JSON). Formát JSON umožňuje sloučit jakkoliv složitou strukturu atributů, polí, objektů a skalárních typů do jednoho záznamu. To znamená, že nyní můžete vaši starou entitu, rozprostírající se skrz několik tabulek, vyjádřit jako jeden „dokument“.

{
   "title" : "Carrot and Coriander Soup"
   "servings" : 4,
   "subtitle" : "Delicious with wholemeal bread",
   "ingredients" : [
      {
         "amount" : 250,
         "ingredient" : "Carrots",
         "measure" : "g"
      },
      {
         "amount" : 75,
         "ingredient" : "Coriander",
         "measure" : "g"
      },
      {
         "amount" : 250,
         "ingredient" : "Vegetable Stock",
         "measure" : "ml"
      }
   ],
   "method" : [
      {
         "step" : 1,
         "instruction" : "Chop carrots"
      },
      {
         "step" : 2,
         "instruction" : "Cook all ingredients in pan"
      },
      {
         "step" : 3,
         "instruction" : "Liquidize"
      }
   ],
}

Teď je vše, co můžete chtít dělat s vaším receptem, na jednom místě, a můžeme ho načíst z databáze CouchDB v rámci jedné operace.

Databáze nemá žádnou definici dat či obsahu – každý dokument v databázi CouchDB může obsahovat cokoliv v jakékoliv struktuře. Můžete ale při ukládání dokumentu do databáze ověřit jeho strukturu provedením validační procedury. Validace se může týkat jak položek, tak jejich obsahu.

Také si uvědomte, že tato neexistence pevné struktury dat přináší větší volnost v tom, jaké údaje ukládáte, a jak. Pokud chcete do vašeho dokumentu obsahujícího recept přidat nový oddíl pro uchování dat, kdo recept vložil, stačí jen rozšířit strukturu dokumentu.

Neexistuje také představa více tabulek. Existuje jen databáze, a dokumenty obsažené v této databázi. Pokud chcete podporovat různé typy údajů v jedné databázi, pak můžete přidat další položku do dokumentu. Pro identifikaci receptu byste například mohli použít:

{
   "type" : "recipe",
   "title" : "Carrot and Coriander Soup"
   "servings" : 4,
   "subtitle" : "Delicious with wholemeal bread",
...
}

Tato identifikace typu záznamu může být použita v jiných částech databáze pro rozpoznání (a výběr) dat, které se mají nahrát.

Pokud je všechno dokumentem, jak vybrat seznam záznamů?

V první části jsem ukázal, jak sestavit jednoduchý SQL dotaz, který z MySQL databáze vybere seznam všech receptů, mezi jejichž přísady patří mrkev. V MySQL se to udělá tak, že se vyhledává v tabulce přísad a pomocí získaného ID receptů se tato tabulka spojí s tabulkou recepty, z níž lze vyčíst názvy receptů. Kvůli zlepšení rychlosti provádění dotazu byste obvykle použili index, který ušetří postupné procházení jednoho záznamu za druhým.

CouchDB považuje všechno za dokumenty, a neposkytuje způsob, jak hledat podle určitého sloupce tabulky, protože v ní nejsou žádné sloupce ani tabulky. Když ale její záznamy nemají pevnou strukturu (a databázový engine nedokáže identifikovat datové položky v dokumentu bez pevné formy), jak pak provést operace, které normálně pracují nad seznamem nebo tabulkou? Všechny dotazy, počínaje jednoduchým „Vypiš všechny recepty“ až po „Najdi všechny recepty, do kterých patří mrkev“, totiž spoléhají na to, že někde existuje nějaký seznam.

CouchDB podporuje databázový konstrukt nazvaný pohled (anglicky view). Pohledy v CouchDB jsou v principu velmi podobné pohledům v MySQL, jen s tím rozdílem, že v CouchDB nejsou pohledy pouze jednou z více možností, ale jsou jedinou cestou, jak získat z databáze seznam dokumentů. Pohled ve skutečnosti určuje tři věci:

  • strukturu dat obsažených v pohledu. Lze na ni pohlížet stejně jako na definici struktury tabulky, tak jak se zadává v MySQL.
  • sloupce a data, v kterých lze vyhledávat. Výstupem pohledu jsou totiž dvě položky: klíč a seznam hodnot. Klíče tedy určují způsob, jak lze v databázi vyhledávat požadovaný obsah.
  • index struktury a klíčů. Tento index se použije pro zrychlení vyhledávání dat v pohledu.

Pohledy jsou definovány v návrhovém dokumentu, pomocí JavaScriptu, prostřednictvím funkce, která bere dokument jako parametr. Při vytváření pohledu je pak této funkci postupně předán každý dokument v databázi, a ta vygeneruje údaje, které budou výstupy pohledu. Z tohoto JavaScriptového kódu není třeba mít obavy, neprovádí se na klientovi, ale na serveru.

Když se na chvíli vrátíme k MySQL, dotaz (bez klauzule WHERE) vybere sloupce, které mají být vráceny, a vytvoří seznam odpovídajících řádků, který je jeho výstupem. Ukažme si to na SQL dotazu:

Když je dotaz prováděn MySQL, tak MySQL server z informací v tabulce (popř. tabulkách) vytvoří seznam záznamů (a jejich sloupců), které mají být vráceny, takto:

V CouchDB pohled vytvoří seznam záznamů z jednotlivých dokumentů. Vedlejším produktem tohoto procesu je index. Výsledkem je tedy seznam všech údajů, které byly pomocí pohledu vygenerovány z existujích dokumentů.

V MySQL se při provádění klauzule WHERE index (snad) použije k tomu, aby byly vybrány požadované záznamy:

V CouchDB je vygenerovaný pohled vlastně tabulkou, a když je nad pohledem prováděn dotaz, CouchDB použije hodnoty klíčů (a související index, byl vygenerován jako vedlejší produkt vytvoření pohledu) pro výběr požadovaných záznamů:

Tento způsob určení tabulek, nad kterými budou prováděny dotazy, umožňuje zjednodušit a zoptimalizovat získávání údajů z databáze. Ale zároveň také znamená, že je potřeba více popřemýšlet nad tím, jaké dotazy budou nad databází prováděny.

Příště nás čeká…

Teď víte, jak MySQL uchovává údaje a jak na ně lze tvořit dotazy, a jak mohou být tyto vědomosti k užitku při přechodu databáze na CouchDB. Příště začneme podle toho, co jsme se dnes dozvěděli, sestavovat dotazy, a podíváme se také na pokročilejší dotazy a na proces změny databáze.

Komentáře: 42

Přehled komentářů

Jan ....
JakubS Re: ....
imploder Re: ....
jos Re: ....
Čelo Re: ....
LuKo Re: ....
imploder Re: ....
lol couch
JakubS Re: couch
Karel Minařík Re: couch
JakubS Re: couch
Karel Minařík Re: couch
František Kučera Re: couch
Pavel Křivánek přednáška
VM _SQL_
Čelo Re: _SQL_
Balvan Re: _SQL_
David Grudl Už by to chtělo pořádný příklad
okbob Re: Už by to chtělo pořádný příklad
Karel Minařík Re: Už by to chtělo pořádný příklad
100% Lenin Re: Už by to chtělo pořádný příklad
okbob Re: Už by to chtělo pořádný příklad
belzebub nosql je zlo
VM Re: nosql je zlo
jkb Re: nosql je zlo
Karel Minařík Re: nosql je zlo
okbob Re: nosql je zlo
jkb Re: nosql je zlo
okbob Re: nosql je zlo
okbob Re: nosql je zlo
urbino Re: nosql je zlo
František Kučera Motivace?
blizzboz Re: Motivace?
v6ak K čemu neschémovost?
Michal Augustýn Re: K čemu neschémovost?
v6ak Re: K čemu neschémovost?
Michal Augustýn Re: K čemu neschémovost?
v6ak Re: K čemu neschémovost?
Michal Augustýn Re: K čemu neschémovost?
v6ak Re: K čemu neschémovost?
urbino Re: Přechod z MySQL na CouchDB, část první
MarekB. Mají své místo
Zdroj: https://www.zdrojak.cz/?p=3435