Tato stránka byla strojově přeložena. Přečtěte si anglický originál. English

Knihovna IBSurgeon

Databázová fyzická struktura (InterBase a Firebird)

Alexey Kovyazin, Sergey Vostrikov, poslední aktualizace 05-června-2004

Fyzická struktura databáze

Proč musíme studovat fyzickou strukturu databáze InterBase?

Obvykle, když mluvíme o fyzické struktuře databáze InterBase, máme na mysli, že představuje data z pohledu nízkoúrovňové organizace dat - až na úroveň bajtů. Mnoho programátorů vyvíjejících aplikace pomocí vysokoúrovňových jazyků zanedbává studium nízkoúrovňových detailů. Nicméně znalost hlavních principů organizace dat uvnitř databáze je klíčem k efektivnímu návrhu databázových aplikací. Proto se podíváme do nitra organizace databáze InterBase a zjistíme, jak je uspořádána.

K čemu tedy slouží systém řízení báze dat (SŘBD)? Samozřejmě k ukládání a správě dat. Zní to banálně, ale stojí za zamyšlení. Uživatel vloží data do SŘBD, který je nějakým způsobem převede do pro něj srozumitelných interních formátů. Můžete si představit „0 a 1“, pokud vám slova „interní datový formát“ způsobují potíže s asociacemi. SŘBD tato data ukládá a při první žádosti je musí extrahovat ze svého formátu, převést do vhodné podoby a předat uživateli.

Předmětem této kapitoly je, jak SŘBD ukládá svá data, v jaké podobě a jak jsou organizována na nejnižší úrovni. Pokusíme se vám vysvětlit, jak z bitů a bajtů ležících na pevném disku získáme cenná data.

Soubory databáze InterBase

Obvykle, když mluvíme o databázi, máme na mysli samotný SŘBD a uživatelské informace, a dokonce i programy klientů, které s daty pracují. V této kapitole budeme databázi považovat za databázové soubory.

Databáze InterBase představuje jeden nebo několik souborů obsahujících informace o všem, co s touto databází souvisí. Výjimkou jsou informace o uživatelích, protože uživatelé jsou definováni na úrovni celého serveru a jsou uloženi zvlášť, v bezpečnostní databázi admin.ib (dříve to bylo ISC4.GDB v verzích před 7).

Rada: Podívejte se na kapitolu „Server a zabezpečení databáze“, abyste se dozvěděli více o principech zabezpečení InterBase.

Takže všechny informace o databázi jsou uloženy v těchto souborech: samotná data, indexy, triggery, uložené procedury atd.

Databáze InterBase pro průměrný projekt představuje jeden soubor, protože moderní verze InterBase mohou používat 64bitové I/O pro práci s datovým souborem, což vám dává možnost mít datový soubor až do velikosti 64 GB. Starší verze InterBase měly omezení 4 gigabajty na každý databázový soubor (až 64 TB pro celou databázi). Jak můžeme předpokládat, 64 gigabajtů je docela dost pro uložení informací téměř jakékoli databázové aplikace. Ale pokud je to nutné, můžeme databázi rozdělit do několika souborů. Mimochodem, existují databáze InterBase o velikosti stovek gigabajtů.

IBSurgeon - průvodce databází InterBase

Musíme podrobně znát strukturu souborů databáze InterBase. A proto je žádoucí mít nějaký vhodný nástroj, který umožňuje pracovat přímo se soubory databáze, ne prostřednictvím jádra serveru InterBase. Nejjednodušší způsob je použít obyčejný hexadecimální prohlížeč a pokusit se pochopit strukturu databázových souborů s ohledem na jejich HEX reprezentaci. Byla by to docela únavná práce.

Ale naštěstí existuje nástroj pro přímou práci s databázemi InterBase. Je to IBSurgeon Editor - nástroj pro přímou nízkoúrovňovou práci s databázemi InterBase, který lze použít pro studium vnitřní struktury databází InterBase a diagnostiku poškozených databází za účelem jejich obnovy. Více podrobností najdete v příloze „Nástroje pro administrátory a vývojáře InterBase“.

IBSurgeon používá vlastní alternativní mechanismus přístupu k databázi, který umožňuje otevřít a prohlížet databáze v jakémkoli stavu, včetně silně poškozených, které nelze otevřít jádrem serveru InterBase/FireBird/Yaffil.

K ilustraci vnitřní struktury databáze použijeme IBSurgeon.

Soubory *.IB/*.FDB zevnitř

IB je přípona doporučená pro soubory databáze InterBase a FDB pro Firebird (dříve to bylo GDB). První věc, kterou musíme říci o struktuře souboru IB, je, že představuje sadu stránek přesně definované velikosti. Velikost databázového souboru je dělitelná velikostí stránky, která je neměnná pro všechny soubory této databáze. Různé verze InterBase podporují různé velikosti stránek, jak je ukázáno v tabulce 1. Velikost stránky se nastavuje při vytváření databáze a nelze ji změnit během jejího životního cyklu. Jinými slovy, velikost stránky můžeme změnit pouze při obnově databáze ze zálohy.

Tabulka 1. Velikosti stránek podporované různými verzemi InterBase

Verze InterBase Velikost stránky, bajty
1024 2048 4096 8192 16384
InterBase 4.0 * * * *
InterBase 5.x * * * *
InterBase 6.x-7.x * * * *

Čtení a zápis dat v databázi se provádí po stránkách; mnoho důležitých charakteristik serveru a databáze, jako je velikost databázové mezipaměti, závisí na velikosti stránky a počítá se ve „stránkách“.

Otevřeme jakoukoli databázi InterBase pomocí IBSurgeon. Stačí dvakrát kliknout na soubor databáze. Obrázek 1 zobrazuje seznam stránek, který se objeví poté, co IBSurgeon otevře databázi:

![](/images/IB DB structure/InterBase database structure_html_m4f802417.png)

Obrázek 1. Seznam stránek databáze

Stránky mohou být různých typů, z nichž každý slouží určitému účelu. Vzájemné závislosti různých typů jsou podmíněně znázorněny na obrázku 2. Obrázek 2 schematicky zobrazuje rozmístění stránek v databázovém souboru - zleva doprava, shora dolů, počítáno od začátku souboru. Stránky stejného typu nejdou přísně jedna za druhou - mohou být snadno smíchány, rozmístěny v souboru v pořadí, v jakém je server vytvořil při rozšiřování nebo vytváření databází.

![](/images/IB DB structure/InterBase database structure_html_4005a6b0.png)

Obrázek 2. Vzájemné závislosti mezi různými typy stránek v databázi InterBase

Musíte si všimnout, že některé typy stránek nemají odkazy na jiné typy stránek. Není zde však žádný rozpor; jde o to, že tyto typy stránek jsou propojeny a používány na jiné strukturální úrovni. Mohou být propojeny s tabulkou RDB$PAGES a dalšími systémovými tabulkami (tuto tabulku a další systémové objekty zvážíme níže - v kapitole „Logická struktura databáze“). Na obrázku 2 vidíme pouze explicitní odkazy mezi stránkami na fyzické úrovni.

Podívejme se podrobně na to, jaké typy stránek existují v databázi InterBase. V souboru ods.h ze sady primárních kódů InterBase jsou informace o všech možných typech stránek. Na tento soubor se budeme často odkazovat, abychom získali data nejen o ODS, ale také o mnoha dalších základních věcech jádra InterBase v původním zdroji. Celkem je deklarováno 11 typů stránek, ale pouze 9 z nich stojí za vysvětlení (jasně to vidíme z tabulky 2). Typy stránek s identifikátory 0 a 1 jsou nedefinované nebo nepoužívané.

Tabulka 3. Typy stránek ve FB

Definice v ods.h Identifikátor typu stránky Popis stránky
pag_undefined 0 Nedefinovaná - pokud má stránka tento typ, je pravděpodobně volná
pag_header 1 Hlavičková stránka databáze
pag_pages 2 Stránka inventáře stránek (nebo stránka inventáře prostoru - SIP)
pag_transactions 3 Stránka inventáře transakcí (TIP)
pag_pointer 4 Ukazatelová stránka
pag_data 5 Datová stránka
pag_root 6 Kořenová stránka indexu
pag_index 7 Stránka indexu (B-strom)
pag_blob 8 Datová stránka BLOB
pag_ids 9 Gen-ids
pag_log 10 Informace o protokolu zápisu s předstihem

Každá stránka má svou hlavičku obsahující informace o typu stránky a čísle další stránky stejného typu. Kompletní seznam parametrů, které každá hlavička stránky obsahuje, získáme, pokud zvážíme strukturu pag v souboru definic ods.h.

/\* Základní hlavička stránky */

typedef struct pag {

SCHAR pag_type; /*identifikátor typu stránky*/

SCHAR pag_flags; /*příznaky stránky*/

USHORT pag_checksum; /*kontrolní součet stránky: po verzi 5.0 se rovná 12345 */

ULONG pag_generation; /*generace stránky */

ULONG pag_seqno; /* WAL sekvenční číslo poslední aktualizace - zastaralé*/

ULONG pag_offset; /* WAL offset poslední aktualizace - zastaralé*/

} *PAG;

Typy stránek a jejich použití

Podívejme se na každý typ stránky podrobně a seznamme se s jejich funkcí a informacemi, které obsahují. Půjdeme krok za krokem - od první stránky.

Jakákoli operace s databází začíná čtením hlavičkové stránky databáze (nebo hlavičkové stránky). Hlavičková stránka databáze je první ve všech souborech databáze. Proto je také první na obrázku 2 (pokud si představíme, že obrázek představuje rozšíření databázového souboru zleva doprava, shora dolů).

Hlavičková stránka obsahuje informace o databázi jako celku. Na obrázku 3 je datová stránka zobrazena tak, jak nám ji ukazuje IBSurgeon:

![](/images/IB DB structure/InterBase database structure_html_m3c792928.png)

Obrázek 3. Hlavičková stránka databáze.

Představu o obsahu hlavičkové stránky získáte, když obdržíte statistiky databáze. K tomu můžete použít nástroj příkazového řádku gstat nebo jiný pohodlnější nástroj pro správu InterBase ze seznamu v příloze „Nástroje pro administrátory a vývojáře InterBase“. Více podrobností o procesu získávání statistik a popisu dat hlavičkové stránky najdete v kapitole „Statistiky“.

Je třeba poznamenat, že hlavičková stránka obsahuje důležité informace, jako je velikost stránky, číslo verze ODS (informace o ní najdete níže), datum vytvoření databáze, informace o transakcích a sadu různých dalších informací. Například ID implementace ukládá informace o tom, pod jakým operačním systémem byla tato databáze vytvořena.

Při připojování k databázi server InterBase přečte prvních 1024 bajtů informací ze začátku souboru a podle přečtených hodnot určí, zda soubor uvedený v připojovacím řádku je databází InterBase nebo ne. Poté server přečte číslo verze ODS z hlavičkové stránky a velikost stránky v této databázi, a pokud je verze ODS kompatibilní s implementací serveru, znovu přečte celou hlavičkovou stránku s použitím správné velikosti stránky získané z prvních 1024 bajtů. Poté se z hlavičkové stránky přečtou další důležité parametry databáze, jako je režim čtení a zápisu, databázový dialekt atd.

Na hlavičkové stránce je odkaz na první z ukazatelových stránek, které ukládají odkazy na datové stránky obsahující metadata: tabulku RDB$Pages (viz níže v kapitole „Logická struktura databáze InterBase“). Na obrázku 2 je tento odkaz znázorněn šipkou s nápisem „Číslo 1. ukazatelové stránky v databázi“. Server přečte číslo 1. ukazatelové stránky z hlavičkové stránky a pokračuje na ni. Ukazatelová stránka se skládá z uspořádaného pole čísel datových stránek, které tvoří určitou tabulku (tabulka je považována za SQL objekt, popsaný logickou strukturou databáze). Nyní můžete vidět, jak IBSurgeon interpretuje ukazatelovou stránku (podívejte se na obrázek 4):

![](/images/IB DB structure/InterBase database structure_html_3bb85660.png)

Obrázek 4. Ukazatelová stránka databáze InterBase

Stránka obsahuje vektor datových stránek; tato data tvoří určitou tabulku v databázi. Tento vektor představuje pole ukazatelů odpovídajících číslům datových stránek v souboru. Server přečte 4bajtové číslo datové stránky a pokračuje na potřebnou datovou stránku. Když přejde na 1. datovou stránku RDB$Pages, server začne vytvářet interní reprezentaci databáze, která je později používána serverem pro všechny operace s databází. RDB$Pages ukládají odkazy nejen na datové stránky obsahující informace o databázi, ale také na ostatní stránky, které hrají roli při zajišťování práce databáze.

Často zmiňujeme tuto tabulku, která přísně vzato patří k logické struktuře databáze. Nicméně vše je propojeno, proto nemůžeme popsat něco, aniž bychom se neodkazovali na něco jiného.

Jedním z důležitých typů stránek je stránka transakčního inventáře (TIP). Tyto stránky, stejně jako všechny stránky, se skládají z hlavičky a hlavní části představující pole 2-bajtových sekvencí. Sekvence popisují stav transakcí v databázi (podrobněji o transakcích viz kapitola „Transakce“).

Tabulka 4. Možné stavy transakcí v TIP

Hodnota sekvence na PIP Význam
0 Transakce nezačala, je aktivní nebo ztracená bez commitu nebo rollbacku
1 Transakce provedla Commit
2 Transakce provedla Rollback
3 Limbo-transakce (pro 2PC)

Každá verze záznamu má svůj identifikátor transakce, což umožňuje současně prováděným transakcím „dozvědět se“ o stavu ostatních a řešit konflikty při víceuživatelské práci (více o verzích záznamů a dalších záležitostech viz kapitola „Multi-generační architektura InterBase“).

Hlavičková stránka databáze, ukazatelové stránky a TIP patří mezi typy stránek „údržby“ (housekeeping), které používá pouze server. Uživatelé InterBase nikdy explicitně nezískávají informace, které obsahují. Stránky, které ukládají informace o alokaci stránek (obvykle označované jako Page Inventory Pages (PIP) nebo Space Inventory Pages (SIP)), také patří mezi typy stránek údržby. Tyto stránky se nacházejí od druhé pozice, tj. první PIP jde hned po hlavičkové stránce, a v databázi se objevují v pevných intervalech stránek jiných typů. Velikost těchto intervalů udává, po kolika stránkách jiných typů se PIP objeví, a závisí na velikosti stránky nastavené pro tuto databázi. Stránky Page Inventory nejsou zohledněny na ukazatelových stránkách a nejsou uvedeny v RDB$Pages. Integrita těchto stránek je zásadní pro úspěšnou práci celé databáze, protože obsah PIP popisuje stav všech ostatních stránek v databázi. Každá databázová stránka může mít 3 stavy: nealokovaná, alokovaná s volným místem, alokovaná a plná. Když je potřeba další místo pro nová data, server zkontroluje PIP, aby zjistil, zda existují nealokované stránky. Pokud taková stránka existuje, server změní její stav na alokovanou s volným místem. Pokud nealokované stránky neexistují, databáze se rozšíří - přidá se nová datová stránka.

Příklad datové stránky v IBSurgeon a dat, která obsahuje, je uveden na obrázku 5.

![](/images/IB DB structure/InterBase database structure_html_1cb26c4f.png)

Obrázek 5. Page Inventory Page

Jakmile je stránka alokována, InterBase zapíše její stav na SIP a poté zapíše samotnou stránku. Poté musíme tuto nově vytvořenou stránku přidat k nějakému velkému počtu stránek, například k datovým stránkám tabulky. K tomu bychom měli zapsat odkaz na tuto novou stránku na poslední stránku tohoto velkého počtu stránek - například na poslední datovou stránku tabulky. Pokud server přeruší svou práci hned po zápisu na SIP, ale nezapíše odkaz na stránky, které odkazují na právě alokovanou stránku, stane se tato stránka osiřelou. Osiřelá stránka je fyzicky vytvořena, rezervována na SIP, ale neexistují na ni žádné odkazy z jiných stránek, což znamená, že ji server nenajde a nezapíše na ni data. Osiřelá stránka je označena červeným čtvercem na obrázku 2. Osiřelé stránky většinou vznikají v důsledku neočekávaného výpadku napájení serveru a jsou „vyléčeny“ speciálním nástrojem pro opravu databází gfix (nebo FirstAID) (nebo IBSurFirstAID).

Před zvážením datových stránek bychom měli zmínit důležité typy stránek: generátorové a indexové stránky. Generátorové stránky představují pole 4-bajtových čísel ukazujících stavy generátorů. Generátor je vlastně obyčejný čítač.

Na obrázku 6 můžete vidět generátorovou stránku. Všimněte si, že ačkoli IBSurgeon zobrazuje názvy generátorů, neznamená to, že tyto názvy jsou uloženy na generátorových stránkách. Je to provedeno pro pohodlí uživatele studujícího databázi. Ve skutečnosti jsou názvy generátorů uloženy v systémové tabulce RDB$Generators.

![](/images/IB DB structure/InterBase database structure_html_7728f31.png)

Obrázek 6. Generátorová stránka (gen-ids)

Jak vidíte v tomto příkladu, databáze obsahuje systémové generátory začínající předponou RDB$ a uživatelsky definované generátory. Pokud chcete vědět o funkci a použití generátorů při vývoji aplikací pro databáze InterBase, viz kapitola „Tabulky. Primární klíče a generátory“. Generátorové stránky jsou zohledněny spolu s dalšími stránkami v tabulce RDB$Pages.

Každá tabulka má alespoň jednu kořenovou stránku indexu, bez ohledu na to, zda má indexy či nikoli. Tato stránka obsahuje ukazatele na indexové stránky pro příslušnou tabulku. Můžeme říci, že kořenová stránka indexu má pro indexové stránky stejný význam jako ukazatelová stránka pro datové stránky. Proto ji IBSurgeon zobrazuje podobným způsobem. Příklad kořenové stránky indexu je uveden na obrázku 7.

![](/images/IB DB structure/InterBase database structure_html_1c46b1cd.png)

Obrázek 7. Kořenová stránka indexu

Kořenová stránka indexu obsahuje seznam stránek, kde jsou uloženy hodnoty indexu, a také informace o indexu - selektivitu indexu a různé příznaky. Podrobněji o indexech, jejich roli a použití v databázích InterBase viz kapitola „Indexy“.

Indexové stránky obsahují přímo hodnoty indexů, nebo pokud je úroveň indexu > 0, odkazy na podřízené indexové stránky. Zde je příklad indexové stránky (obrázek 8).

![](/images/IB DB structure/InterBase database structure_html_m35b3f5ff.png)

Obrázek 8. Indexová (B-strom) stránka

Indexová stránka ukládá komprimované hodnoty indexovaných dat. Používá se poměrně složitý mechanismus indexace, zejména při vytváření složených indexů (zahrnujících několik polí).

Obecně platí, že datové stránky a stránky obsahující hodnoty BLOB ukládají uživatelské informace. Datové stránky obsahují záznamy v uživatelských tabulkách databáze, fragmenty záznamů, staré verze, rozdíly mezi verzemi, pole BLOB a tak dále. Pokud jde o pole BLOB, jsou spojena se záznamy na datových stránkách a obsahují data velké velikosti, která se nemohou nacházet na datové stránce. Referenční způsob ukládání hodnot BLOB umožňuje ukládání velkých dat.

Příklad prezentace datové stránky v IBSurgeon je uveden na obrázku 9:

![](/images/IB DB structure/InterBase database structure_html_235e0c51.png)

Obrázek 9. Datová stránka

Hlavička datové stránky obsahuje typ stránky, identifikátor vlastnické tabulky (relationID). Záznamy jsou na datových stránkách ukládány od konce stránky a jak se plní, jsou alokovány blíže k začátku stránky.

Můžeme se o tom přesvědčit, pokud se podíváme na indexy řádků obsahující 2 hodnoty - offset na stránce a její délku. Jak vidíte na začátku řádku, záznamy jsou alokovány na konci stránky - například první záznam má offset 8156 bajtů a délku 34 bajtů - proto končí na 8156+34=8192 bajtech - na samém okraji stránky (v našem případě je velikost stránky 8192 bajtů). Když je stránka zaplněna (daty shora a indexy záznamů zdola), server začne zapisovat nové záznamy a verze starých záznamů na nové stránky. Z výše popsaného mechanismu plnění stránek snadno pochopíme, proč odborníci na InterBase důrazně doporučují používat datové stránky velké velikosti (minimálně 4096 bajtů, lépe 8192). Pokud vytvoříme tabulku, jejíž jeden záznam bude poměrně velký (například 10 polí VARCHAR (255)), zabere více než 2550 bajtů. To znamená, že takový záznam bude příliš velký pro stránku malé velikosti (1024 nebo 2048). Je zřejmé, že nutnost načíst několik stránek z disku pro přečtení jediného záznamu práci s databází nezrychlí. Proto se doporučuje při vytváření nebo obnově databáze předefinovat velikost datové stránky, protože výchozí velikost je 1024 bajtů. Právě jsme stručně probrali hlavní typy stránek datových souborů InterBase a jejich funkci. Nyní můžeme přejít na vyšší strukturální úroveň.

ODS

ODS je zkratka pro On-Disk Structure, tedy strukturu dat databáze InterBase na disku. ODS definuje, jak jsou data v databázových souborech organizována. Definice hlavních konstant a datových struktur pro implementaci On-Disk struktury je v souboru ods.h ze sady zdrojových kódů InterBase. ODS se během vývoje InterBase měnila a při práci s konkrétní databází server zjišťuje číslo verze ODS, aby věděl, s čím pracuje. Soubor ods.h nám představuje následující verze On-Disk struktury:

  • ODS 5 byla použita InterBase 3.3 a není podporována vyššími verzemi

  • ODS 6 a ODS 7 nikdy nevyšly

  • ODS 8 je použita InterBase 4.0

  • ODS 9 je použita InterBase 4.5 a vyššími verzemi

  • ODS 10 vyšla s InterBase 6

  • ODS 11 vyšla s InterBase 7.0

Kromě hlavních verzí ODS existují vedlejší verze, které závisí na konkrétní verzi databázového serveru, který je vytvořil. Hlavní čísla verze jsou zapsána v celé části čísla označujícího verzi, vedlejší - ve zlomkové části. Například verze serveru 4.0 vytváří databáze s ODS 8.0 a InterBase 4.2 - 8.2. Přechod mezi vedlejšími verzemi zdola nahoru se provádí automaticky. Například stačí otevřít databázi s ODS 8.0 vytvořenou serverem 4.0 pomocí InterBase 5.6 a ODS této databáze bude mít verzi 8.2. Přechod mezi hlavními verzemi databáze se provádí pouze prostřednictvím zálohy databáze pomocí staré verze a obnovy pomocí nové verze serveru. Proces přechodu mezi verzemi je podrobně popsán v kapitole 1.4 „Migrace“.

Důležitým momentem v implementaci podpory ODS pro verze InterBase 4.x a 5.x je zpětná kompatibilita serverů InterBase 4.x a 5.x s verzí o jednu jednotku nižší, než je implementace konkrétního serveru. InterBase podporuje několik možných ODS a podle své verze ODS při připojení ke konkrétní databázi volí podporu požadované implementace ODS. Mechanismus rozhodování o tom, kterou implementaci podpory ODS zvolit v konkrétním případě, se nazývá Y-Valve ((c) Steve Trenton).

Jednodušeji řečeno, databáze s ODS 8.x odpovídající InterBase 4.0 může být otevřena v InterBase 5.x.

Úplná tabulka kompatibility ODS je uvedena níže:

Verze InterBase Hlavní ODS Vedlejší ODS
4.0/4.1 8.0
4.2 8.2 8.2
5.0/5.1 9.0 8.2
5.5 9.1 8.2
5.6 9.1 8.2
6.0 10.0 9.0/9.1
7.0 11.0 10.0
7.1 11.1 10.0

ODS má zpětnou kompatibilitu. Jinými slovy, server s vyšší verzí a všechny jeho nástroje budou schopny pracovat s databází vytvořenou staršími verzemi serveru, ale ne naopak. Pokud se pokusíte otevřít databázi vytvořenou ve verzi InterBase 6 pomocí InterBase 5.x, obdržíte chybovou zprávu „Unsupported On-disk structure: Found ODS 10, supported ODS 9“.

Popis přechodu mezi verzemi zdola nahoru a naopak viz kapitola „Migrace“.

ODS je velmi důležitá pro záležitosti týkající se zálohování a extrakce databází, stejně jako obnovy poškozených databází. Nástroje pro zálohování gbak a obnovu gfix sledují verzi ODS a jednoduše nebudou fungovat, pokud je verze ODS databáze, které mají sloužit, vyšší než verze v nich implementovaná. To znamená, že gbak ze 4.x nebude schopen vytvořit zálohu databáze vytvořené serverem 5.x, i když naopak to snadné je.

Most mezi fyzickou a logickou strukturou databáze

Obecně jsme probrali fyzickou strukturu databázových souborů. Nyní musíme přejít k logické struktuře databáze. Vytvořme most mezi fyzickou a logickou úrovní reprezentace informací v databázi, aby nedocházelo k oddělení pojmů a mezerám v materiálu. Vše, co je uloženo na různých databázových stránkách, musí být nějakým způsobem organizováno v paměti počítače; data ze souboru databáze musí být převedena na sadu vnitřních objektů a proměnných serveru. Tato sada se podle terminologie Ann Harrisonové nazývá interní obraz databáze [1.. Takže se pokusíme zvážit proces vytváření interního obrazu databáze.

  • Server přečte 1024 bajtů ze začátku souboru, a pokud se skutečně jedná o databázový soubor InterBase, určí velikost stránky této databáze a znovu přečte celou hlavičkovou stránku.

  • Z hlavičky server extrahuje číslo ukazatelové stránky, která ukládá odkazy na datové stránky, čímž definuje tabulku RDB$Pages.

  • Server přejde na tuto ukazatelovou stránku a začne číst informace z odkazovaných datových stránek. Naplní první tabulku RDB$Pages daty. Tato tabulka je něco jako most mezi fyzickými objekty - stránkami databázových souborů - a logickými - tabulkami. Struktura RDB$Pages, stejně jako ostatních systémových tabulek, je v InterBase pevně stanovena.

  • Jakmile server získá data o alokaci stránek podle relací (relace - ve skutečnosti jsou to stejné jako běžné tabulky, a pro zjednodušení si tyto pojmy můžeme mentálně zaměnit), začne InterBase vytvářet datové struktury: nejprve systémové tabulky, omezení a indexy, poté uživatelské objekty.

  • Po inicializaci systémových a uživatelských metadat (tabulky, omezení, indexy a další databázové objekty) vrátí InterBase uživateli, který požádal o otevření databáze, handle této databáze. V handle je identifikátor, který InterBase ukazuje, se kterou databází má pracovat, protože několik uživatelů může pracovat současně, což znamená, že může být otevřeno několik databází.

  • Po těchto operacích je databáze považována za otevřenou a server je připraven vykonávat uživatelské dotazy. Nyní, když je vytvořen určitý most spojující fyzickou a logickou strukturu databáze, můžeme začít studovat zvláštnosti logické struktury.

Logická struktura databáze InterBase

Logická struktura je poněkud vágní pojem, proto se pokusíme zvládnout klíčové myšlenky postupně, s nadějí, že později budou intuitivně jasné. Nejprve se budeme zabývat systémovými tabulkami a jejich obsahem, které se vztahují k logické struktuře databáze. Systémové tabulky popisují systém i uživatelská metadata. Obecně řečeno, termín „metadata“ znamená „data popisující sadu dat“. Předpona „meta“ znamená: „popisuje sadu“. Například metajazyk je jazyk, který popisuje sadu jazyků. Metadata popisují uživatelská data, tedy tabulky, triggery, pohledy, uložené procedury a tak dále - vše, co implementuje pravidla ukládání a zpracování informací, kvůli kterým je tato konkrétní databáze vytvořena.

Při prvním seznámení je docela zábavné zjistit, že všechna metadata - uživatelské tabulky, triggery, pohledy i všechny systémové objekty - jsou uložena ve stejných tabulkách, ze kterých můžete číst a zapisovat data běžnými SQL dotazy. Tyto tabulky se „vizuálně“ liší pouze tím, že jejich názvy začínají na RDB$. Tyto 4 symboly jsou vyhrazeny pro názvy systémových objektů. Žádná uživatelská tabulka, sloupec ani jiný objekt nemá právo mít název začínající těmito symboly. Formálně můžete vytvořit tabulku, jejíž název začíná vyhrazenými symboly, ale dokumentace InterBase to nedoporučuje.

Vyvstává otázka: pokud jsou data o struktuře databáze uložena ve stejných tabulkách jako uživatelská data, kde jsou pak uloženy informace o tabulkách, které popisují tabulky? Klasický příklad problému „slepice a vejce“ - jak mohlo jedno vzniknout dříve než druhé, když jsou vzájemně závislé? Odpověď zní, že systémové tabulky ve svém primitivním stavu jsou pevně zakódovány v počátečních kódech InterBase a jsou automaticky otevírány při vytváření databáze v určitém pořadí. Již jsme mluvili o tabulce RDB$Pages, která porovnává fyzické stránky v databázových souborech s určitými objekty této databáze. Struktura této tabulky je uvedena níže:

Tabulka 5. Systémová tabulka RDB$Pages

Název sloupce Datový typ Popis
RDB$PAGE_NUMBER INTEGER Číslo fyzické stránky
RDB$RELATION_ID SMALLINT Identifikátor tabulky, pro kterou je stránka alokována
RDB$PAGE_SEQUENCE INTEGER Číslo této stránky
RDB$PAGE_TYPE SMALLINT Typ stránky - viz tabulka 3

Každá datová stránka je přiřazena k určité tabulce. Tento vztah je podporován polem RDB$RELATION_ID, kde je uložen odkaz na tabulku. Jak bylo popsáno výše, v procesu vytváření interního obrazu databáze server vytvoří tuto tabulku a naplní ji daty podle stanoveného algoritmu. Abychom byli přesní, v okamžiku vytváření interního obrazu databáze není RDB$Pages tabulkou, ale pouze datovým souborem určitého formátu, který InterBase zná. Podle pevného algoritmu server čte data z tohoto souboru a vytváří tabulku - RDB$Relations - která je důležitá pro celou databázi. Tato tabulka popisuje všechny databázové tabulky. Pokud provedeme SQL dotaz:

SELECT * from RDB$Relations

abychom zjistili, na které tabulky RDB$Relations odkazuje, uvidíme, že obsahuje RDB$Pages i sama sebe. Je zřejmé, že v tomto případě server trochu šidí, dosazuje tyto a další systémové tabulky do RDB$Relations zpětně, čímž je legitimizuje. Zaznamenává je jako „normální“ tabulky, do kterých může přidávat nebo mazat záznamy. Jinými slovy, poskytuje standardní SQL rozhraní pro práci s metadaty.

A může vyvstat docela rozumná otázka - proč by vývojáři InterBase přizpůsobovali svá systémová data uživatelskému rozhraní? Vždyť interní mechanismy přístupu a čtecích operací by byly rychlejší. Samozřejmě, poskytnutí univerzálního mechanismu práce s tabulkami, které popisují metadata, má velký smysl.

Jde o to, že logická struktura databáze se skládá nejen z tabulek, ale také z dalších objektů. V InterBase existují následující objekty:

  • Tabulka

  • Pohled

  • Trigger

  • Computed_field

  • Validace

  • Procedura

  • Expression_index

  • Výjimka

  • Uživatel

  • Pole

  • Index

  • Uživatelem definovaná funkce (UDF)

Zatím neznáme přesně funkci některých objektů, ale víme jistě, že všechny musí být popsány a uloženy v nějaké podobě, která je vhodná pro uživatele i pro přístup z jádra InterBase. Nejlepší by bylo uložit tyto objekty do systémových tabulek. Jejich přidávání a úpravy se provádějí SQL dotazy. Chytré řešení, že? Implementace serveru je zcela oddělena od konkrétní databáze - všechny vzájemné vazby jsou popsány SQL a jeho rozšířeními - jazykem uložených procedur a triggerů.

Takže všechny objekty serveru jsou uloženy v tabulkách. Každý typ objektu má tabulku, která popisuje všechny instance popsané v databázi. Například pro triggery existuje tabulka RDB$Triggers, pro uložené procedury RDB$Procedures, pohledy jsou popsány v tabulce RDB$Relations.

Podívejme se podrobně na strukturu poslední tabulky, která popisuje všechny tabulky a pohledy v databázi. Struktura tabulky RDB$RELATIONS je převzata z Language Reference pro InterBase 6 a je uvedena níže v tabulce 6.

Tabulka 6. Systémová tabulka RDB$Relations

Název sloupce Datový typ Délka Popis
RDB$VIEW_BLR BLOB 80 BLR: pro pohledy obsahuje BLR (Binary Language Representation) dotazu, který InterBase provádí při každém přístupu k pohledu.
RDB$VIEW_SOURCE BLOB 80 Text: pro pohledy obsahuje kód SQL dotazu, který tento pohled implementuje.
RDB$_DESCRIPTION BLOB 80 Uživatelský popis tabulky nebo pohledu
RDB$RELATION_ID SMALLINT Obsahuje interní identifikátor tabulky/pohledu
RDB$SYSTEM_FLAG SMALLINT Definuje typ tabulky: uživatelská data - 0; systémové informace > 0.
RDB$DBKEY_LENGTH SMALLINT Délka db$key
RDB$FORMAT SMALLINT Vyhrazeno pro interní použití InterBase. Obsahuje čítač modifikací metadat pro danou tabulku.
RDB$FIELD_ID SMALLINT Počet polí v tabulce.
RDB$RELATION_NAME CHAR 31 Jedinečný název tabulky.

V popisu této systémové tabulky vidíme zkratku BLR. Abychom pochopili, co to je, uděláme exkurz do SQL. Jak je známo, pohledy, triggery a uložené procedury jsou kód napsaný v rozšíření jazyka SQL (pro každý DBMS server existují jejich vlastní rozšíření). Je blízký lidskému jazyku, což umožňuje snadno v něm vytvářet dotazy. Ale InterBase jej samozřejmě překládá do něčeho „strojovějšího“ - konkrétně do BLR (Binary Language Representation). Jakýkoli dotaz, pohled, trigger, uložená procedura je vždy přeložen do BLR a poté předán jádru InterBase k provedení.

BLR

BLR je speciální jazyk, používaný jako mezistupeň mezi SQL kódem, který píše programátor, a strojovým kódem, který server přijímá. Nikdo nepíše přímo v BLR - to by bylo docela obtížné, protože pro co nejvyšší rychlost běhu se v tomto jazyce používá takzvaný reverzní polský zápis. Zde je malý příklad:

blr_begin,

     blr\_assignment,

        blr\_field, 0, 7, 'D','A','T','E','I','Z','M',

        blr\_variable, 1,0,

     blr\_assignment,

        blr\_field, 0, 4, 'R','A','T','E',

        blr\_variable, 0,0,

     blr\_block,

BLR pro vaše dotazy, procedury, triggery a další triggery je vytvářen speciálním preprocesorem, který je součástí jádra serveru. Jak je ukázáno v tabulce 7, pro pohledy je uložen jejich text (původní) pohled i zkompilovaný pohled, tedy BLR. Při odkazu na jakýkoli objekt, který má BLR, server provádí binární kód objektu a neinterpretuje pokaždé původní text těchto objektů, což umožňuje urychlit provádění složitých dotazů.

Hierarchie objektů v InterBase

Abychom měli jasnou představu o tom, co databázové objekty představují, pokusíme se vytvořit hierarchii databázových objektů podle principu „kdo co obsahuje“. Fyzické stránky databázových souborů jsou první, co musí být zahrnuto do naší hierarchie jako nejnižší úroveň organizace dat. Poté následují tabulky jako základní objekty, které popisují všechny ostatní typy objektů. Tabulky popisují uložené procedury, triggery, vypočítávaná pole, validace, výrazové indexy, výjimky a tak dále. Pozor - pouze popisují! Tabulky obsahují pouze deklarace a definice těchto objektů, a objekty jsou implementovány prostřednictvím BLR. Proto můžeme tabulky znázornit jako rám, který podporuje všechny ostatní databázové objekty. BLR bude na dně rámu jako vrstva implementace, poté triggery, uložené procedury, výrazové indexy a pohledy.

Abychom uklidnili specialisty na vnitřní strukturu InterBase, kteří by mohli namítnout, že BLR mnoha objektů (jako jsou pohledy) je uložen v systémových tabulkách, poznamenáme, že tento vztah je na obrázku docela obtížné vyjádřit, a pro zjednodušení jej vynecháme. Schéma nemá za cíl znovu vytvořit vzájemné závislosti databázových objektů naprosto přesně; pouze ilustruje jejich úzké vzájemné propojení.

Skutečnost, že tyto typy objektů jsou přímo spojeny s BLR, který je implementuje bez jakékoli zprostředkující logiky, je spojuje. Výjimky by měly být vyčleněny zvlášť - představují speciální typy chyb, definované uživatelem. Výjimky jsou zpracovávány na úrovni jádra InterBase, a proto nemají BLR. Takové typy omezení jako kontroly (checks) jsou umístěny nad triggery, protože ve skutečnosti triggery implementují logiku omezení a kontrol.

Hierarchie objektů logické a fyzické struktury databáze je znázorněna na obrázku 2.

Obrázek 10. Objekty logické struktury databáze InterBase

Toto schéma samozřejmě popisuje logickou strukturu a vzájemné propojení objektů v databázi pouze přibližně a dává o ní obecnou představu. Každý, kdo chce studovat strukturu metadat databáze InterBase, může provést reengineering systémových tabulek databáze a zvážit všechny vzájemné vazby mezi jejími objekty, stejně jako se obrátit na dokumentaci a primární kódy InterBase. Tato tabulka ukazuje pouze hlavní databázové objekty. Pojďme stručně popsat hlavní funkce, které tyto objekty v databázi vykonávají.

Tabulky - hlavní objekty obsahující uživatelská a systémová data. Tabulka má jedinečný název a obsahuje sadu pojmenovaných polí. Uživatel může do tabulek ukládat data, získávat je a upravovat. Můžeme říci, že tabulka je podobná běžným papírovým tabulkám kresleným ručně.

Triggery - spustitelné části kódu, používané pro implementaci dodatečných akcí v době datových operací. Triggery se spouštějí před nebo po operacích vložení, úpravy nebo smazání a umožňují realizovat dosazování hodnot do nově vytvářených záznamů a mnoho dalších věcí.

Uložená procedura je výkonný nástroj pro implementaci business logiky na úrovni databáze. Jelikož se provádí na úrovni serveru, pracuje velmi rychle a umožňuje provádět sadu operací nad datovými sadami. Uložené procedury InterBase vracejí standardní SQL datové sady, nad kterými lze provádět všechny SQL operace, včetně sjednocení s jinými tabulkami.

Pohledy jsou zkompilované SQL dotazy, prováděné na serveru. Pohledy umožňují organizovat datové sady a přenést část business logiky na server.

Validace jsou omezení nastavená na hodnoty polí v tabulce. Například můžeme určit, že dané pole bude přijímat pouze kladné hodnoty. Omezení na hodnoty polí jsou implementována triggery a umožňují efektivně kontrolovat referenční integritu na úrovni databáze. Obvykle se omezení používají k tomu, aby se do tabulky nedostaly nesprávné hodnoty.

Uživatelé - InterBase nám umožňuje mít pro práci s databází více uživatelů a rozdělit mezi ně přístupová práva k různým databázovým objektům. Tím můžeme řídit oprávnění k těm či oněm databázovým operacím.

Uživatelem definované funkce (UDF) - funkce definované uživatelem. Je to jedna z nejvýkonnějších schopností InterBase, která nám umožňuje rozšířit standardní SQL rozhraní o vlastní funkce. Například funkce pro práci s řetězci, jako je UPPER (nastavení všech znaků na velká písmena), jsou implementovány ve standardní knihovně UDF, která je součástí sady InterBase. Díky možnosti vytvářet vlastní UDF mohou vývojáři rozšířit funkčnost InterBase prakticky o libovolné funkce. Pro vytváření UDF můžeme použít jakékoli programovací prostředí, které umožňuje vytvářet dynamické knihovny (Visual C++, C++ Builder, Delphi atd.).

Závěr

V této kapitole jsme se poprvé zabývali otázkami implementace ukládání a zpracování dat v databázi InterBase. Bohužel nemůžeme udělat stručný přehled tohoto tématu, aniž bychom se neuchýlili k velkému množství termínů a nepřesných analogií. Pokud bychom popsali fyzickou a logickou strukturu databáze podrobněji, museli bychom se stejně odvolávat na primární kódy InterBase, ale to by byla jiná kniha.

Přesto si myslíme, že by bylo užitečné, aby se každý programátor seznámil s obsahem produktu, který používá každý den.

Bibliografie

  1. „The On-Disk Structure of InterBase" od Ann.W.Harrison

  2. „Space Management in InterBase" od Ann W.Harrison

  3. „Structure of a Data Page" od Paul Beach (S poděkováním Dave Schnepperovi a Deej Bredenbergovi)