KAPITOLA 6 Databáze Když běží nějaká linuxová aplikace, všechna data, která jsou použita v této aplikaci, se nacházejí v systémové paměti. Jakmile běh aplikace skončí, data z paměti budou ztracena. Když aplikaci spustíte příště, libovolná data z předcházející relace již nebudou dostupná. Většina aplikací pracujících s daty ovšem vyžaduje, aby data byla dostupná v různých relacích. Možnost ukládat data je tudíž zásadním požadavkem pro každou aplikaci, která pracuje s historickými daty, což mohou být například záznamy o zaměstnancích, evidence majetku, vedení účetnictví atd. Tato kapitola popisuje dvě metody, které implementují ukládání dat v linuxových aplikacích. Nejprve vám předvedeme metodu, která využívá zabudovaný databázový engine. Zabudování databázového enginu do aplikace vám poskytne jednoduchou funkcionalitu pro uložení dat bez toho, abyste museli řešit režii a správu samostatného databázového serveru. Následně vám předvedeme metodu, která využívá plnohodnotný databázový server s otevřeným zdrojovým kódem. Když je použit databázový server, zákazníci mohou k vašim datům přistupovat z kteréhokoliv místa v místní síti (nebo také prostřednictvím sítě internet!).
Trvalé uložení dat Klíčem k trvalému ukládání dat je schopnost rychle získávat uložená data. Moderní databáze využívají pro rychlý přístup k uloženým datům poměrně velké množství různých technik a metod, přičemž existuje spousta názorů na to, jak má vypadat ideální návrh, konfigurace a řízení databáze. Linux naštěstí nabízí produkty, které pokrývají široké spektrum řešení. Ukládání dat bývá v linuxových aplikacích obvykle implementováno jedním ze tří následujících způsobů:
Prostřednictvím čtení a zápisu do standardních souborů.
Prostřednictvím zabudovaného databázového enginu.
Prostřednictvím externího databázového serveru.
Každá z metod má svá pro i proti, která je nutné při tvorbě aplikace ukládající data brát v úvahu.
188
Kapitola 6 – Databáze
Použití standardního souboru Nejzákladnější formou používanou pro ukládání dat je uložení dat do nějakého standardního souboru na vašem pevném disku. V Linuxu je možné zapsat data do nějakého souboru na disku a následně k těmto datům přistupovat. Systém Linux může kontrolovat přístup uživatelů k těmto souborům, což znamená, že můžete zajistit, aby k uloženým datům nemohli neoprávněně přistupovat cizí uživatelé nebo aplikace. Ve většině linuxových aplikací probíhá práce se soubory v několika krocích. Tyto kroky názorně ukazuje obrázek 6.1.
Obrázek 6.1. Většina programovacích jazyků v Linuxu poskytuje funkce, které jsou nezbytné pro otevření souborů, zápis dat, čtení dat a uzavření souborů. Velkou nevýhodou použití standardních souborů pro ukládání dat je výkon. Ačkoliv vytvoření souborů a následný zápis dat je velmi jednoduchý úkol, vyhledávání dat uložených v souboru už tak jednoduché není. Vyhledání konkrétního záznamu v souboru, který například obsahuje tisíce různých záznamů, obvykle znamená, že pro jeho získání musíte přečíst všechny záznamy, jež jsou v daném souboru k dispozici. A to může být hodně pomalá činnost. Pro ukládání dat je tak mnohem vhodnější použít databázi.
Použití databáze Současná databázová teorie nabízí mnoho metod vedoucích ke zvýšení výkonu vyhledávání dat v databázi. Místo ukládání datových záznamů do souboru v pořadí, v jakém byly přidány, databázový systém umožňuje uspořádat záznamy podle hodnot, které jsou nazývány jako klíče, přičemž pro tyto klíče může vytvořit samostatné soubory, jež obsahují ukazatele na příslušné záznamy. Tímto vám chceme sdělit, že uspořádání dat podle nějakého jedinečného klíče slouží k tomu, aby databáze mohla opravdu rychle získat požadované informace. Rychlost této metody pro přístup k datům se vůbec nedá srovnat s rychlostí metody, ve které je nezbytné prohledat všechny záznamy.
Linux PROFESIONÁLNĚ – programování aplikací
189
Samozřejmě se pak nabízí otázka, jak takový databázový systém vůbec naprogramovat. Vytvoření řádné logiky pro implementaci databáze vyžaduje velké množství kódu, přičemž existují dva přístupy, jak implementovat databázovou logiku pro vaši aplikaci. První přístup spočívá v tom, že do vaší aplikace se zahrnou jednoduché databázové funkce, jejichž funkcionalita je zajišťována prostřednictvím jednoduchých knihoven. Toto ukazuje obrázek 6.2.
Obrázek 6.2. Knihovna databázového enginu poskytuje funkce pro vytváření databázových souborů, pro vkládání, změny a odstraňování záznamů a v neposlední řadě i funkce používané pro dotazy na obsah databáze. Protože tyto databázové funkce jsou implementovány do kódu samotné aplikace, nepotřebujete nějaký externí databázový server, který by bylo nutné spravovat. Řečeno jinými slovy – všechny databázové funkce tvoří nedílnou součást aplikace. To znamená, že aplikace jako taková si sama spravuje příslušné datové soubory (včetně přístupu k nim). Nedostatky zabudovaného databázového enginu se projeví ve víceuživatelském prostředí. Když používáte pouze jedinou aplikaci, nevznikají žádné problémy s přístupem k databázovému souboru a s jeho případnou aktualizací. Pokud se ale více uživatelů začne současně snažit o přístup k souboru databáze (a o uložení svých změn), může snadno dojít k porušení integrity dat. V takovém případě je potřeba, aby přístup k databázovým datům řídil jeden jediný subjekt, který bude rovněž rozhodovat o tom, kdy budou aktualizovaná data k dispozici pro ostatní uživatele. A toto je okamžik, kdy přichází na scénu databázový server, který má na starosti kompletní správu dat v databázi. Aplikace, které chtějí přistupovat k datům v databázi, tak musí činit prostřednictvím tohoto databázového serveru. Databázový server může nejenom určovat, k jakým datům mohou mít jednotliví uživatelé přístup, ale také to, jak budou data od jednotlivých uživatelů uložena do databáze. Typické prostředí s databázovým serverem je ukázáno na obrázku 6.3.
190
Kapitola 6 – Databáze
Obrázek 6.3. Aby mohly aplikace komunikovat s databázovým serverem, opět musejí používat nějakou knihovnu funkcí. Taková knihovna poskytuje funkce, které například zajišťují připojení k serveru, vkládání, změnu a odstraňování dat v databázi či vykonávání dotazů pro databázi. Aby s databázovými servery mohla pracovat velká skupina různých klientů, bylo pro zjednodušení celého procesu vymyšleno několik standardů. Sem například patří standard SQL (Standard Query Language, doslova standardní dotazovací jazyk), který je používán jako standardní protokol pro zasílání příkazů databázovému serveru a pro získávání výsledků. Následující části této kapitoly představují dva oblíbené databázové servery pro Linux. Berkeley DB je ukázkou databázového enginu zabudovaného do aplikace, zatímco PostgreSQL demonstruje možnosti centrálního databázového serveru.
Balíček Berkeley DB Open source balíček Berkeley DB patří mezi nejvíce oblíbený a nejvíce používaný databázový engine, který vám nabízí velké množství pokročilých databázových funkcí prostřednictvím snadno použitelné knihovny, kterou můžete připojit k vašim aplikacím napsaným v jazyce C nebo C++. Životní dráha Berkeley DB je docela pestrá. Jak již napovídá samotný název balíčku, jeho vývoj odstartoval na kalifornské univerzitě v Berkeley jako jednoduchý databázový projekt, který byl určen pro operační systém BSD verze 4.4. Po nějaké době se ovšem stal natolik oblíbeným, že společnost Netscape Corporation v roce 1996 požádala jeho autory o uvolnění Berkeley DB k obecnému použití. Díky tomu byla založena společnost Sleepycat Software Incorporated, která měla pokračovat v dalším vývoji Berkeley DB – ovšem již nezávisle na unixové distribuci BSD. Společnost Sleepycat
Linux PROFESIONÁLNĚ – programování aplikací
191
Software následně tento produkt vydala nejenom pod komerční licencí (pro podporu komerčních instalací), ale také ve formě otevřeného kódu (tzv. licence Sleepycat). Před nějakou dobou byla společnost SleepyCat Software (a tudíž i produkt Berkeley DB) odkoupena společností Oracle. Přestože je Oracle jedním z předních komerčních dodavatelů databázových systémů, produkt Berkeley DB je stále k dispozici ve formě otevřeného kódu. Následující části této kapitoly popisují, jak se dá balíček Berkeley DB stáhnout, zkompilovat, nainstalovat a používat ve vašich linuxových aplikacích.
Stažení a instalace Protože Berkeley DB patří mezi oblíbené balíčky, je součástí mnoha linuxových distribucí (a v některých je dokonce k dispozici i ve standardních instalacích). Pokud Berkeley DB není nainstalován ve vašem systému, můžete jej nainstalovat dodatečně v podobě balíčku předkompilovaného pro vaši konkrétní distribuci, nebo si z webu Oracle stáhnout nejnovější verzi zdrojových souborů, které si sami zkompilujete a následně nainstalujete. Když se rozhodnete použít předkompilovaný balíček, postupujte podle obvyklého postupu pro instalaci softwaru ve vaší distribuci. Nezapomeňte nainstalovat jak samotné soubory knihoven, tak i soubory pro vývoj. Obvykle jsou rozděleny do dvou balíčků, které je potřeba nainstalovat samostatně. Nejnovější verze Berkeley DB je k dispozici na webu Oracle. V současné době ji můžete najít na adrese www.oracle.com/technology/products/berkeley-db/index.html. V pravém horním rohu stránky klikněte na červené tlačítko Download. V době psaní této knihy byla nejnovější verze označena 4.5.20 (v době překladu této knihy je aktuální verze 4.6.21, poznámka redaktora). Berkeley DB je pochopitelně k dispozici v několika různých konfiguracích a formátech balíčků. Pro instalaci balíčku v Linuxu si stáhněte balíček s příponou .tar.gz (je jedno, zdali se šifrováním AES nebo bez něj). Stažený soubor si ve vašem linuxovém systému uložte do pracovního adresáře. Protože je balíček distribuován ve formě zdrojového kódu, musíte jej prvně rozbalit a následně zkompilovat. Pro rozbalení zdrojového balíčku použijte následující příkaz: $ tar -zxvf db-4.5.20.tar.gz
Tento příkaz vytvoří ve vašem pracovním adresáři nový podadresář db-4.5.20 a rozbalí do něj všechny soubory se zdrojovým kódem. Balíček Berkeley DB se kompiluje poněkud odlišným způsobem, než jak je tomu v případě jiných balíčků, které jsou k dispozici ve formě otevřeného kódu. Jako první krok musíte přejít do příslušného podadresáře build_xxx, který se nachází v hlavním adresáři. V případě linuxových systémů se jedná o adresář build_unix. Z tohoto místa pak spusťte konfigurační program, který se nachází v adresáři dist. Kód pro vykonání těchto činností vypadá takto: [db-4.5.20]$ cd build_unix
192
Kapitola 6 – Databáze
[build_unix]$ ../dist/configure
Konfigurační utilita ověří vlastnosti systému a následně vytvoří soubory, které jsou potřebné pro zkompilování aplikace. Jakmile je tato činnost ukončena, v adresáři build_unix spusťte příkaz make: [build_unix]$ make
Po skončení kompilace nainstalujte do vašeho systému knihovnu a soubory pro vývoj prostřednictvím příkazu make s parametrem install: [build_unix]$ make install
Nezapomeňte, že tento krok byste měli provést jako uživatel root. Jakmile máte knihovnu a soubory pro vývoj úspěšně nainstalovány, můžete se pustit do programování.
Kompilace programů Knihovna Berkeley DB a soubory pro vývoj se standardně nainstalují do čtyř podadresářů, které jsou umístěny v adresáři /usr/local/BerkeleyDB.4.5. Jedná se o tyto čtyři podadresáře:
Bin. Obsahuje utility pro zkoumání a opravování databázových souborů Berkeley DB.
Docs. Obsahuje HTML dokumentaci pro API C a další utility.
Include. Obsahuje hlavičkové soubory C a C++ pro komplikaci aplikací využívajících knihovnu Berkeley DB.
Lib. Obsahuje soubory sdílených knihoven pro kompilaci a běh aplikací využívajících knihovnu Berkeley DB.
Abyste mohli spouštět aplikace, které využívají knihovnu Berkeley DB, musíte do seznamu knihoven dostupných v systému přidat adresář lib. Seznam adresářů, které Linux prochází při hledání souborů knihoven, máte k dispozici v souboru /etc/ld.so.conf. Jako uživatel root přidejte do tohoto seznamu nový adresář /usr/local/BerkeleyDB.4.5/lib (a pochopitelně neodstraňujte žádnou položku z tohoto seznamu). Jakmile máte obsah souboru /etc/ld.so.conf aktualizovaný, spusťte utilitu ldconfig (opět jako uživatel root), aby se změna projevila v systému. Nyní je váš systém připraven na běh aplikací využívajících knihovnu Berkeley DB. Když budete kompilovat nějakou takovou aplikaci, musíte kompilátoru sdělit, kde jsou k dispozici hlavičkové soubory a soubory knihovny. U linkeru musíte dále specifikovat knihovnu db. Zde je ukázka kompilace aplikace, která využívá knihovnu Berkeley DB: $ cc -I/usr/local/BerkeleyDB.4.5/include -o test test.c -L/usr/local/BerkeleyDB.4.5 -ldb
Parametrem -I specifikujete umístění hlavičkových souborů, potřebných ke kompilaci. Parametrem -L pak umístění souborů knihoven, které jsou nutné pro zkompilování spustitelné aplikace.
Linux PROFESIONÁLNĚ – programování aplikací
193
Základní práce s daty Když nyní máte knihovny Berkeley DB nahrány a nakonfigurovány ve vašem systému, můžete je začít používat ve vašich vlastních aplikacích. Následující část popisuje kroky, které jsou nezbytné k tomu, abyste mohli začít využívat Berkeley DB pro databázovou podporu ve vašich aplikacích.
Otevření a zavření databáze Než můžete přistoupit k databázovému souboru Berkeley DB, musíte jej prvně otevřít. Jakmile s ním přestanete pracovat, musíte jej zavřít, jinak riskujete poškození dat. Pro přístup k databázovému souboru se používá ovladač DB. Ten získáte prostřednictvím funkce db_create(): int db_create(DB **dbp, DB_ENV *env, u_int32_t flags)
Parametr dbp specifikuje ovladač DB, který bude použit pro přístup k souboru. Parametr env specifikuje prostředí, pod kterým bude databázový soubor otevřen. Pokud je tento parametr roven NULL, databáze je považována za samostatnou, takže veškerá provedená nastavení se budou týkat pouze tohoto souboru. Alternativně můžete specifikovat hodnotu DB_ENV pro seskupení této databáze společně s jinými databázemi do nějakého prostředí. Všechna nastavení, která budou provedena pro dané prostředí (např. zamykání souborů), se pak projeví ve všech databázích, jež do něj patří. Parametr flags by měl být nastaven na 0 pro databáze, které běží v linuxovém prostředí. Když funkce db_create() uspěje, vrátí hodnotu 0. Když dojde k chybě, vrácená hodnota je nenulová. Jakmile máte vytvořen ovladač DB, prostřednictvím funkce open() otevřete nový nebo nějaký stávající soubor databáze: int DB->open(DB *db, DB_TXN *txnid, const char *file, const char *database, DBTYPE type, u_int32_t flags, int mode)
Funkce open() používá ovladač db, který byl vytvořen funkcí db_create(). Parametr txnid specifikuje otevřený objekt transakce, pokud příkaz je součástí transakce. Parametr file specifikuje název souboru, který je používán pro databázi; parametr database pak specifikuje název databáze, jež je uložena v tomto souboru. Berkeley DB umožňuje, aby v jednom fyzickém souboru mohlo být uloženo více databází. Pokud nějaký databázový soubor obsahuje větší množství databází, musíte každou z nich otevírat samostatným voláním open(). Pokud vytváříte novou databázi, musíte v parametru type uvést typ databáze. V době psaní této knihy byly podporovány následující čtyři typy:
DB_BTREE. Databáze má strukturu uspořádaného stromu. To znamená, že data jsou uspořá-
dána podle hodnot klíče.
DB_HASH. Rozšířená lineární hashovací tabulka (extented linear hash table) – data jsou uspořádána podle hashované hodnoty klíče.
DB_QUEUE. Fronta záznamů s pevnou délkou. Jako klíč slouží pořadové číslo záznamu.
194
Kapitola 6 – Databáze DB_RECNO. Fronta záznamů s pevnou nebo proměnlivou délkou. Jako klíč slouží pořadové
číslo záznamu. Typy DB_BTREE a DB_HASH poskytují rychlý přístup k datům, neboť data jsou uspořádána již během svého vkládání do databázového souboru. To samozřejmě znamená, že vkládání nových záznamů probíhá o něco pomaleji, protože data musejí být v databázovém souboru umístěna na konkrétní místo. Různými experimenty bylo zjištěno, že v případě velmi velkých databází poskytuje metoda DB_HASH o něco lepší výkon než metoda DB_BTREE. Typy DB_QUEUE a DB_RECNO se často používají pro data, která jsou uspořádána podle pořadového čísla záznamu. A právě toto pořadové číslo je použito jako klíč, což znamená, že záznamy je možné získávat pouze pomocí těchto čísel. To se vám může zdát jako omezení, ovšem pouze do té doby, než zjistíte, že vkládání a získávání záznamů v těchto typech databází probíhá extrémně rychle. Pokud tedy potřebujete rychle ukládat a získávat data z databáze, tyto typy budou pro vás ideální. Když otevíráte nějakou existující databázi, pro parametr type můžete použít hodnotu DB_UNKNOWN. V takovém případě se Berkeley DB automaticky pokusí určit typ databáze. Pokud se určení typu databáze nepovede, funkce open() skončí neúspěchem. Parametr flags určuje, jakým způsobem může být soubor databáze otevřen. Hodnoty, které je možné použít, názorně shrnuje následující tabulka. Hodnoty pro flags
Popis
DB_AUTO_COMMIT
Použije transakci pro otevření souboru s databází. Když volání uspěje, operaci bude možné obnovit (recoverable). Když volání neuspěje, soubor s databází nebude vytvořen.
DB_CREATE
Vytvoří databázi (pokud neexistuje).
DB_DIRTY_READ
Operace čtení v databázi může vyžadovat vrácení změněných, ale zatím neuložených dat.
DB_EXCL
Vrátí chybu, pokud soubor databáze již existuje.
DB_NOMMAP
Soubor databáze nebude mapován do paměti.
DB_RDONLY
Databáze bude otevřena v režimu pouze pro čtení.
DB_THREAD
Vrácený ovladač databáze bude možné použít ve více vláknech.
DB_TRUNCATE
Vyprázdní libovolnou databázi, která existuje v databázovém souboru.
Hodnoty uvedené v této tabulce je možné kombinovat prostřednictvím symbolu | (logický operátor OR). To znamená, že můžete například použít hodnoty DB_CREATE | DB_EXCL pro vytvoření nové databáze a vrácení chyby v případě, kdy soubor databáze již bude existovat. Parametr mode specifikuje unixová přístupová práva k souboru. Když zadáte nulovou hodnotu, vlastník souboru i skupina budou mít právo pro čtení a zápis, zatímco zbytek světa k danému souboru mít přístup nebude. A zde je příklad, který ukazuje vytvoření ovladače databáze a otevření nové databáze:
Linux PROFESIONÁLNĚ – programování aplikací
195
DB *dbp; int ret; ret = db_create(&dbp, NULL, 0); if (ret != 0) { perror("create"); return 1; } ret = dbp->open(dbp, NULL, "test.db", NULL, DB_BTREE, DB_CREATE, 0); if (ret != 0) { perror("open"); return 1; }
Pomocí tohoto krátkého kódu zavoláme funkci db_create(), která vytvoří ovladač databáze dbp. Prostřednictvím něj pak vytvoříme nový databázový soubor test.db se strukturou uspořádaného stromu (DB_BTREE, viz dříve uvedený seznam typů databáze) a s výchozími přístupovými právy.
Vkládání nových dat Když teď máte otevřen nový databázový soubor, je ten správný čas do něj vložit nějaká data. K tomu slouží funkce put(). Její syntaxe je následující: int DB->put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags)
Parametry db a txnid mají stejný význam jako u funkce open(). Specifikují ovladač databáze a transakci, která má být použita pro funkci. Parametry key a data pak určují dvojici klíč-hodnota, která bude uložena do databáze. Struktura DBT je použita pro každý definovaný prvek data a size. To znamená, že prvek key.data obsahuje hodnotu pro klíč záznamu, zatímco prvek data.data obsahuje datovou hodnotu záznamu. Parametr flags určuje, jakým způsobem budou nová data vložena do souboru databáze. U databází DB_QUEUE a DB_RECNO můžete použít hodnotu DB_APPEND, která vloží data na konec souboru. U databází DB_BTREE a DB_HASH můžete použít hodnotu DB_NOUPDATA, která zajistí, že záznam bude do databáze přidán pouze tehdy, když databáze nebudou obsahovat stejnou kombinaci klíče a hodnoty. Hodnota DB_NOOVERWRITE pak zabraňuje, aby nová data přepsala stávající klíč. Kombinace klíče a hodnoty může být občas matoucí. Spousta lidí se totiž domnívá, že jsou díky tomu omezeni na jednu datovou hodnotu na záznam. Ale tato datová hodnota může být libovolného typu (včetně struktury). To znamená, že si můžete vytvořit vlastní strukturu s mnoha prvky dat (v závislosti na požadavcích vaší aplikace). Každá instance struktury C pak bude v souboru databáze uložena jako jediná datová hodnota.
196
Kapitola 6 – Databáze
Tuto situaci demonstruje program newemployee.c, který je uveden v následujícím výpisu: /* * Professional Linux Programming - Adding new employee record. */ #include <stdio.h> #include
#define DATABASE "employees.db" int main() { DBT key, data; DB *dbp; int ret; struct data_struct { int empid; char lastname[50]; char firstname[50]; float salary; } emp; ret = db_create(&dbp, NULL, 0); if (ret != 0) { perror("create"); return 1; } ret = dbp->open(dbp, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0); if (ret != 0) { perror("open: "); return 1; } while(1) { printf("Enter Employee ID: "); scanf("%d", &emp.empid); if (emp.empid == 0) break; printf("Enter Last name: "); scanf("%s", &emp.lastname); printf("Enter First name: "); scanf("%s", &emp.firstname); printf("Enter Salary: "); scanf("%f", &emp.salary);
Linux PROFESIONÁLNĚ – programování aplikací
197
memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.data = &(emp.empid); key.size = sizeof(emp.empid); data.data = &emp; data.size = sizeof(emp); ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE); if (ret != 0) { printf("Employee ID exists\n"); } } dbp->close(dbp, 0); return 0; }
Program newemployee.c vytvoří ovladač databáze a otevře soubor employees.db jako jedinou samostatnou databázi. Přípona .db sice není povinná, nicméně v případě databázových souborů Berkeley DB se používá docela často. Následně je cyklus while() použit pro získání informací o novém zaměstnanci od uživatele. Pro prvek dat (data element) je v databázi použita strukturu emp. Ta obsahuje celočíselné ID zaměstnance, řetězce lastname a firstname a hodnotu platu. Jakmile jsou od uživatele získány tyto hodnoty, jsou ihned umístěny do struktury emp. Před použitím objektů DBT key a data je vždy dobré vynulovat prostřednictvím funkce memset oblast paměti, která je pro ně vyhrazena. Tím zabráníte tomu, aby se do prvků dat zatoulaly nějaké nechtěné bity. Následně je hodnota klíče nastavena na ID zaměstnance a hodnota dat na celou strukturu emp. Jakmile je vše na svém místě, je zavolána funkce put() s parametrem DB_NOOVERWRITE, aby pokus o přidání zaměstnance, jehož ID v databázi již existuje, vyhodil chybu. Pokud chcete aktualizovat záznamy existujících zaměstnanců, stačí tento parametr odebrat. Cyklus while() skončí tehdy, jakmile uživatel zadá nulové ID zaměstnance. Následně bude soubor databáze zavoláním funkce close() korektně uzavřen. Při kompilaci této aplikace nezapomeňte použít správné hlavičkové soubory a knihovny. Poté aplikaci spusťte. Pokud je všechno v pořádku, měli byste být schopni přidávat do databáze nové záznamy o zaměstnancích. Když ukončíte běh programu, měli byste v adresáři vidět soubor databáze pojmenovaný jako employees.db.
Získávání dat Když do souboru databáze ukládáte nějaká data, je velmi pravděpodobné, že je budete chtít taky někdy později získat zpět. K tomu slouží funkce get(): int DB->get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags)