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

Knihovna IBSurgeon

Datové typy

NOTICE: Tento dokument je kapitolou z knihy „The InterBase World“, kterou napsali Alexey Kovyazin a Serg Vostrikov.

Navzdory tomu, že datové typy jsou podrobně popsány v dokumentaci (viz [1, kapitola 4.), je nutné zvážit řadu pojmů, které budou často používány v následujících kapitolách této knihy. Kromě obecných informací budou také přezkoumány několik příkladů použití datových typů v databázích InterBase a doporučení ohledně jejich použití a konverze. Podrobně zvážíme rozdíly datových typů existující v 1. a 3. databázovém dialektu InterBase.

O datech

Datové typy jsou základními prvky jakéhokoli programovacího jazyka nebo serveru DBMS. InterBase není výjimkou. Když říkáme, že databáze ukládá nějaké informace, musíme si uvědomit, že tyto informace nelze uložit na jedno místo. Naopak; data musí být roztříděna a umístěna na svou „polici“. Datové typy definují, co lze na určitou „polici“ umístit a co ne. Když mluvíme o „polici“, máme na mysli především pole databázových tabulek (viz kapitola „Tabulky. Primární klíče a generátory“ (část 1)), stejně jako proměnné v rámci triggerů a uložených procedur atd. Každý datový typ má sadu operací, které lze provádět nad hodnotami tohoto typu. Proto je důležité zvolit správný datový typ při navrhování databáze. Pomůže to vyhnout se mnoha problémům při vývoji klientských programů. V InterBase existuje 12 datových typů, které mohou uspokojit požadavky vývojáře na ukládání dat. Tyto typy jsou podmíněně rozděleny do následujících 6 skupin:

  • pro ukládání celých čísel - INTEGER a SMALLINT;
  • pro ukládání reálných čísel - FLOAT a DOUBLE PRECISION;
  • pro ukládání čísel s pevnou přesností - NUMERIC a DECIMAL;
  • pro ukládání data, času a časového razítka - DATE, TIME a TIMESTAMP;
  • pro ukládání znaků - CHARACTER (ve zkrácené formě - CHAR) a VARYING CHARACTER (VARCHAR);
  • pro ukládání dynamicky rozšiřitelných dat - BLOB

Kromě toho je možné definovat pole hodnot primitivních typů, tj. všech vyjmenovaných typů kromě BLOB.

Většina datových typů InterBase odpovídá typům definovaným ve standardu SQL92, avšak kromě toho mají své vlastní zvláštnosti - pole primitivních datových typů a BLOB. Pole v InterBase mohou obsahovat sadu dat stejného typu v jednom poli. Například můžeme definovat pole hodnot typu INTEGER. Pole mohou mít několik dimenzí. Datový typ BLOB je dynamicky rozšiřitelný datový typ, jehož název je často dešifrován jako Binary Large OBject. Je třeba říci, že BLOB je vynálezem vývojářů InterBase, který se později rozšířil a usadil ve všech moderních SQL serverech.

Syntaxe definování datových typů

Datové typy se používají pro popis polí v tabulkách, proměnných v triggerách a uložených procedurách. Obecná syntaxe definování všech možných datových typů v InterBase je uvedena níže.

< datatype> =

{SMALLINT | INTEGER | FLOAT | DOUBLE PRECISION}[ ]

| {DATE | TIME | TIMESTAMP} [ ]

| {DECIMAL | NUMERIC} [( precision [, scale])] [ ]

| {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [( int)

[ ] [CHARACTER SET charname]

| {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR}

[VARYING] [( int)] [ ]

| BLOB [SUB_TYPE { int | subtype_name}] [SEGMENT SIZE int]

[CHARACTER SET charname]

| BLOB [(seglen [, subtype])]

Charakteristiky datových typů, jako je velikost, přesnost a rozsah možných hodnot, jsou podrobně popsány v tabulce 4.1 v [1., proto se zde nebudeme opakovat. Nyní stručně přezkoumáme hlavní zvláštnosti datových typů a zaměříme se na jejich možné použití.

Celočíselné typy

SMALLINT a INTEGER se vztahují k celočíselným typům. Měl bych říci, že SMALLINT představuje zmenšenou verzi INTEGER. Jeho délka je 2 bajty na rozdíl od 4 určených pro ukládání INTEGER. Obvykle byste neměli šetřit na místě na disku. Z tohoto důvodu je lepší použít typ INTEGER pro ukládání celočíselných hodnot.

Oblast použití celočíselných typů je zřejmá: jsou nezbytné pro pole obsahující pouze celá čísla - pro ukládání počítadel, čísel atd. Obvykle má typ INTEGER také pole obsahující primární klíče.

Reálné datové typy

Typy FLOAT a DOUBLE PRECISION se vztahují k reálným (nazývají se také číselné typy s plovoucí desetinnou čárkou). Nejprve chci varovat čtenáře před používáním typu FLOAT - jeho přesnost není dostatečná pro ukládání většiny desetinných hodnot. Zvláště se nedoporučuje ukládat do něj peněžní hodnoty - v proměnných typu FLOAT se velmi rychle objevují chyby zaokrouhlování a může to překvapit účetního při provádění výpočtů. Nejlepší způsob, jak ukládat čísla s plovoucí desetinnou čárkou (například v účetních systémech a systémech pro vědecké výpočty) v databázi, je ukládat je do typu DOUBLE PRECISION.

Měli byste vzít v úvahu, že ve 3. dialektu InterBase existuje mechanismus ukládání typů s pevnou délkou bodu 64 bajtů. Tento mechanismus se používá pro ukládání peněžních hodnot. Použití těchto typů poskytuje nejlepší přesnost.

Datové typy s pevným bodem

NUMERIC a DECIMAL se vztahují k těmto datovým typům. Otázka ohledně rozdílu mezi NUMERIC a DECIMAL zaznívá velmi často. Oba tyto typy mají identickou číslicovou kapacitu - od 1 do 18 znaků, identickou přesnost - od nuly do číslicové kapacity.

Připomeňme, že: číslicová kapacita je celkový počet číslic, a přesnost - počet znaků za čárkou.

Nejvtipnější je, že tyto typy se podle dokumentace liší v maximální číslicové kapacitě, ale ve skutečnosti jsou realizovány téměř stejně a není mezi nimi žádný rozdíl.

Můžete to snadno zkontrolovat spuštěním utility isql a provedením níže uvedené sekvence akcí. Vytvoříme tabulku následujícího pohledu:

SQL> CREATE TABLE test (

CON> Num_field NUMERIC(15,2),

CON> Dec_field DECIMAL(15,2));

Poté dáme příkaz k zobrazení struktury tabulky:

SQL> show tables test;

A vidíme následující:

NUM_FIELD NUMERIC(15, 2) Nullable

DEC_FIELD NUMERIC(15, 2) Nullable

Jak vidíte, InterBase informuje, že oba dané sloupce mají typ NUMERIC. Důvody takového chování spočívají v realizaci datových typů s pevným bodem. Jde o to, že InterBase má pouze tři mechanismy pro ukládání jakéhokoli celočíselného výrazu, a všechny typy, ať se nazývají jakkoli, jsou realizovány podle těchto variant.

Zde je tabulka z [1., která ilustruje, jak jsou různé celočíselné typy (tabulka 1.1) ukládány. Jak vidíte, ukládání dat ve 3. dialektu je odlišné pro čísla s velkou číslicovou kapacitou:

Tabulka 1.1. Ukládání čísel s pevným bodem

Číslicová kapacita Dialekt 1 Dialekt 3
od 1 do 4 SMALLINT pro NUMERIC
INTEGER pro DECIMAL
SMALLINT
od 5 do 9 INTEGER INTEGER
od 10 do 18 DOUBLE PRECISION INT64

Nyní můžeme s jistotou říci, jaké jsou hlavní rozdíly mezi typy NUMERIC a DECIMAL: v případě definování pole (nebo proměnné) s malou číslicovou kapacitou (až čtyři) je první ukládán jako 2bajtové celé číslo SMALLINT, a druhý - jako 4bajtové INTEGER. Pokud je tedy číslicová kapacita větší než čtyři, budou typy DECIMAL a NUMERIC ekvivalentní.

Věnujte pozornost rozdílu v realizaci typů s velkou číslicovou kapacitou v prvním a třetím dialektu. V prvním dialektu se číslo s pevným bodem změnilo z celého na reálné, kde byly použity mechanismy zaokrouhlování. Ve třetím dialektu byla tato zvláštnost odstraněna - velká celá čísla jsou skutečně ukládána jako celá čísla - pomocí mechanismu INT64, který může ukládat 64bitová čísla v rozsahu +/-2^32. Proto by bylo lepší ukládat data o peněžních prostředcích v databázích vytvořených s použitím 3. dialektu. Pouze použití mechanismu INT64 zaručí bezpečnost malých peněžních zůstatků.

Typy pro ukládání data a času

Typy pro ukládání data a času se změnily ve verzi InterBase 6.x a jeho klonech ve srovnání s 4.x a 5.x. Abychom se nezamotali do historických pavučin s těmito typy, zvážíme situaci ve verzi InterBase 6. Poté na základě toho stručně zmíníme, co bylo dříve. To je provedeno pro uživatele, kteří stále pracují s ranými verzemi InterBase. Takže v InterBase 6.x existují 3 typy pro ukládání data a času - DATE, TIME a TIMESTAMP.

  • Typ DATE ukládá data s přesností na den. Rozsah možných hodnot - od 1. ledna 100 n. l. do 29. února 32768.
  • Typ TIME ukládá údaje o čase s přesností na desetitisícinu sekundy. Rozsah možných hodnot - od 00:00 do 23:59.9999.
  • Typ TIMESTAMP představuje kombinaci typů DATE a TIME.

Jak pracovat s daty? Pokud jde o práci na úrovni serveru v uložených procedurách nebo triggerách, vše je docela jednoduché - vždy můžeme deklarovat proměnnou požadovaného typu a nastavit ji z tabulek a naopak. Je však nutné přenášet data z databáze do aplikace a zpět. V tomto případě existují dva přístupy: použít knihovny, které používají původní formát dat InterBase pro přístup k objektům těchto typů a převést tento formát na běžné vnitrojazykové typy data/času (příkladem takové knihovny je FIBPlus), nebo použít mechanismus převodu dat na řetězce, vestavěný v InterBase.

Co uděláte, pokud potřebujete vyříznout pouze rok nebo měsíc z úplného data? Budete muset použít skupinu funkcí EXTRACT pro tento účel (dostupnou ve všech klonech InterBase 6.x), která vám umožní extrahovat pouze požadovanou část z data. Tyto funkce se používají následujícím způsobem:

EXTRACT (MONTH FROM DATE_FIELD)

EXTRACT (YEAR FROM DATE_FIELD)

Úplný seznam parametrů ve funkci EXTRACT je následující: YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, WEEKDAY, YEARDAY. Jejich funkce vyplývá z jejich názvu, proto je zde nebudeme interpretovat.

Datové typy pro ukládání textu

V InterBase existují dva typy určené pro ukládání textových informací - CHAR a VARCHAR. Jejich plné názvy - CHARACTER a CHARACTER VARYING, ale není důvod používat dlouhé názvy - dokonce i příkaz Show tables v utilitě isql dává krátké názvy typů.

Abychom definovali pole nebo proměnnou symbolického typu, je nutné zadat v závorkách za názvem typu počet symbolů, které budou použity v definovaném objektu, nebo vynechat počet symbolů - tím se vytvoří pole s délkou 1 symbolu.

CREATE TABLE testCHARLen(

Field1 CHAR(255),

Field2 CHAR);

Při vytvoření této tabulky bude mít Field1 délku 255 symbolů a Field2 - 1 symbol.

Typy CHAR a VARCHAR jsou v mnoha ohledech podobné - oba mohou obsahovat až 32768 symbolů, ale existují určité rozdíly. Ačkoli jsou oba tyto typy ukládány v databázi stejným způsobem, InterBase s nimi pracuje odlišně. Následující příklad to demonstruje:

SQL> create table testCHAR ( c1 char(10), c2 varchar(10));

SQL> insert into testCHAR(c1,c2) values(‘Test’,‘Test’);

SQL> SELECT ‘(’||c1.|’)’, ‘(’||c2.|’)’ from testCHAR;

Ve výsledku získáme následující:

(Test ) (Test)

Jak vidíte, za hodnotou ‘Test’, vybranou z pole c1, byly mezery. To znamená, že při výběru dat z pole typu CHAR je vrácená hodnota doplněna mezerami až do plné délky pole. Je těžké předpokládat, proč je takové chování, které vede k podstatnému růstu síťového provozu (zatížení sítě), nutné. V každém případě je VARCHAR symbolický typ doporučený k použití.

Jednou z hlavních charakteristik symbolického typu je jeho znaková sada - CHARACTER SET. Znaková sada je definována pro celou databázi a používá se ve výchozím nastavení pro všechna symbolická pole, pokud není explicitně znovu definována při vytváření pole. Abychom vytvořili symbolické pole s explicitním uvedením znakové sady, je nutné přidat popis znakové sady do popisu sloupce (v větách CREATE TABLE nebo ALTER TABLE). Znaková sada WIN1251 se obvykle používá pro podporu ruštiny (pokud se chcete dozvědět podrobně o použití ruštiny v InterBase, viz kapitola „Russifikace InterBase“ (část 1)). Zde je příklad tabulky obsahující symbolické pole s explicitně popsanou znakovou sadou WIN1251:

CREATE TABLE TestCHARSET(

Field1 VARCHAR(255),

Field2 VARCHAR(255) CHARACTER SET win1251);

Zde je Field1 pole bez explicitního uvedení znakové sady, proto se pro něj použije znaková sada zadaná při vytváření databáze. U pole Field2 je samozřejmě určeno, že bude ukládat symboly v kódování WIN1251.

Kromě uvedení znakové sady pro symbolická pole můžete také zadat pořadí porovnávání (collation), které definuje, jak budou symboly této datové sady řazeny. Pro ruštinu existují dvě varianty porovnávání - WIN1251 a PXW_CYRL. Další podrobnosti o použití COLLATION ORDER naleznete v kapitole „Rusifikace InterBase".

Úplný seznam znakových sad a COLLATION ORDER pro ně použitých naleznete v dokumentaci [1, kapitola 13..

Pozor! Podle dokumentace k InterBase 6 existují 4 symbolické typy: kromě výše zmíněných datových typů existují ještě 2 další - NCHAR a NCHAR VARYING, avšak stejná dokumentace níže vysvětluje, že poslední dva typy jsou stejné jako CHAR a VARCHAR, pouze s tím rozdílem, že je u nich standardně použita znaková sada ISO8859.1. To znamená, že použití pseudo-typu NCHAR je ve skutečnosti ekvivalentní použití CHAR DEFAULT CHARACTER SET ISO8859.1. Podobně pro NCHAR VARYING, jen místo CHAR se použije VARCHAR. Je zřejmé, že použití těchto pseudo-typů je určeno pro uživatele v západní Evropě a USA, kde je znaková sada ISO8859.1 vytvořena pro podporu jazyků.

Datový typ BLOB

Datový typ BLOB je určen pro ukládání velkého množství dat proměnlivé velikosti. Typ BLOB umožňuje ukládat data, která nelze umístit do polí jiných typů - například obrázky, hudební soubory, video fragmenty atd. Požadavky na definici nejjednoduššího pole typu BLOB v tabulce jsou stejné jako při definici pole jakéhokoli základního typu:

CREATE TABLE testBLOB(

myBlobField BLOB);

Výsledkem bude vytvořeno pole myBlobField, do kterého lze ukládat značně velká data. Navzdory tomu, že se pole BLOB neliší od ostatních způsobem definice, jejich realizace v rámci databáze se velmi liší. Ne-BLOB pole jsou umístěna na datové stránce (viz kapitola „Struktura databáze InterBase" (část 4)) blízko sebe, zatímco na datové stránce je uložen pouze identifikátor BLOB a samotný BLOB je alokován na speciální stránce. Taková datová struktura umožňuje ukládat data nepevné velikosti.

Typ BLOB má možnost definovat sadu několika podtypů a speciálních procedur nazývaných filtry (BLOB filtry) pro práci s těmito podtypy. V InterBase je zabudováno několik předdefinovaných podtypů BLOB. Všechny tyto podtypy mají nezáporná čísla, například podtyp 0 - data nedefinovaného typu, podtyp 1 - text, podtyp 2 - BLR (Binary Language Representation, viz slovník a kapitola „Struktura databáze InterBase") atd. Uživatel může také definovat podtypy BLOB, které mohou mít záporné hodnoty. Filtr lze použít pro každý typ. Převádí pole jednoho podtypu na jiný.

Je třeba poznamenat, že použití BLOB polí je obvykle alternativou k ukládání externích souborů ve vztahu k databázi. Pokud jde o BLOB filtry, používají se poměrně zřídka kvůli orientaci na úzkou kategorii úloh.

Pole (Arrays)

DBMS InterBase byl jedním z prvních, ve kterých se objevila pole. Podpora polí v databázi je rozšířením tradičního relačního modelu. Přítomnost polí umožňuje zjednodušit práci se sadami jednoho datového typu.

Pole je kolekce hodnot jednoho typu, která má společný název a umožňuje přístup k libovolnému prvku pole podle jeho čísla. Pole v InterBase mohou být jednorozměrná a vícerozměrná.

Pro vytvoření pole čísel INTEGER v tabulce by mělo být zapsáno něco jako následující:

CREATE TABLE test(

myOneDimArray INTEGER[12.,

myTwoDimArray INTEGER[5,4.,

myThreeDimArray INTEGER[2,10,8.);

Tím budou vytvořena tři pole typu pole: myOneDimArray - pole obsahující jednorozměrné pole délky 12 čísel, myTwoDimArray obsahující dvourozměrné pole (matici) - 5х4 Integer, a myThreeDimArray - pole obsahující trojrozměrné pole 2х10х8. Je třeba poznamenat, že při takové definici jsou prvky pole číslovány od „jedné", tj. první prvek má číslo 1, druhý - číslo 2 atd. Pokud chce někdo nastavit hranice pole sám, například od 0 do 5, měl by definici pole zadat následujícím způsobem:

myArray INTEGER[0:5.

Pole jsou realizována na základě polí typu BLOB, proto se nemusíte bát, že vícerozměrné pole „znečistí" vaši tabulku velkým množstvím dat: InterBase úhledně alokuje data pole na samostatné stránky pro optimalizaci vstupně-výstupních operací s těmito poli. Jak používat pole? Poskytují pohodlný mechanismus pro ukládání objektů stejného typu. Avšak v 80 % případů místo polí vývojáři preferují ukládání více dat do podřízených (detailních) tabulek, proto se pole v klientských aplikacích DBMS InterBase nepoužívají tak často. Děje se tak proto, že přístupové knihovny dodávané s Delphi a C ++ Builder, jako jsou BDE a IBX, nejsou schopny pracovat s poli. Podle dokumentace k InterBase je možné pracovat s poli pomocí preprocesoru gpre, avšak to není nejpohodlnější způsob pro vývojáře v Delphi/C ++ Builder. Naštěstí knihovna FIBPlus podporuje pole-pole v InterBase. Podrobně si o tom můžete přečíst v kapitole „Speciální schopnosti FIBPlus". Klientská knihovna IBProvider, která umožňuje vytvářet klientské aplikace pro InterBase pomocí vývojových nástrojů společnosti Microsoft, také podporuje práci s poli (viz kapitola „Vývoj klientských aplikací DBMS InterBase pomocí technologie Microsoft OLE DB" (část 3)).

Závěr

Je třeba poznamenat, že o datových typech nelze hovořit bez předbíhání, protože pronikají do všech klíčových oblastí souvisejících s vývojem databázových aplikací. Proto je při čtení této knihy lepší použít danou kapitolu jako rychlou referenci, ke které se můžete kdykoli vrátit, když potřebujete osvěžit základy InterBase.