6. díl - SQLite - Datové typy, NULL a dynamické typování

SQLite SQLite - Datové typy, NULL a dynamické typování

V minulém dílu seriálu tutoriálů o SQLite databázi jsme se dozvěděli něco o řazení a o agregačních funkcích. Dnes se vrátíme k datovým typům a řekneme si něco o hodnotě NULL.

Datové typy

Hned na začátku seriálu jsme se setkali s několika datovými typy. Tehdy jsem vám s nimi nechtěl motat hlavu. Řeč byla o typech INTEGER a TEXT. Databáze (konkrétně zde SQLite) jich má sice ještě několik, ale na rozdíl od jiných SQL databází jich je poměrně málo.

Celé číslo - INTEGER

Dle velikosti samotného čísla, které se ukládá, se použije 1, 2, 3, 4, 5, 6, 7 nebo 8 bajtů.

Pokud hledáte datový typ boolean (hodnoty true/false), tak k ukládání této hodnoty se používá rovněž INTEGER - 0 = false, 1 = true.

Reálné číslo - REAL

K ukládání reálných čísel se používá 64 bitů, přesnost je zhruba 15 až 16 čísel a číslo může nabývat hodnot +-5.0 * 10^−324 až +-1.7 * 10308.

Text

Datový typ TEXT se používá k ukládání řětezců znaků dle použitého kódování databáze (UTF-8, UTF-16BE or UTF-16LE).

Používá se taktéž k ukládání času ve formátu 'rrrr-mm-dd hh:mm:ss.sss', ale jde použít i datový typ INTEGER ve formátu Unix - počet sekund od 1. ledna 1970 0:00, nebo typ REAL.

BLOB

Obecná data v binárním tvaru, použití analogické k typům TEXT. Umožňují do databáze ukládat např. obrázky nebo zvuky.

Hodnota NULL

Datové typy v databázích se malinko odlišují od datových typů, jak je známe v programovacích jazycích. Zatímco třeba v Céčku může mít int hodnoty jen nějakých -32.000 až +32.000 a nic kromě toho, databázový INTEGER může nabývat i hodnoty NULL. NULL nemá vůbec nic společného s nulou (0), označuje to, že hodnota nebyla ještě zadána. Filozofie databází je takto postavena, nezadané hodnoty mají výchozí hodnotu NULL (pokud jim nenastavíme jinou) a každý datový typ má kromě hodnot, které bychom v něm očekávali, navíc možnou hodnotu NULL. Datovému typu tuto hodnotu můžeme i zakázat, více dále.

Pokud např. příkazem INSERT vložíme uživatele a vyplníme jen některé hodnoty, do dalších hodnot se vloží NULL. Zkusme si to:

INSERT INTO "uzivatele" ("jmeno", "prijmeni"`) VALUES ('Pan', 'Neuplny');

Výsledek:

Vložení uživatele s nezadanými hodnotami do SQLite databáze

Přínos hodnoty NULL

Asi se ptáte k čemu hodnota NULL vlastně je? Její přínos je v tom, že poznáme, jestli byla hodnota zadána. Např. při zadávání čísla neexistuje hodnota, podle které bychom poznali, že číslo není zadáno. Kdybychom si k tomuto určili hodnotu nula (0), nevíme, jestli uživatel číslo nezadal nebo zadal právě nulu. NULL mimo jiné i šetří místo v databázi, kde narozdíl od výchozích hodnot nezabírá místo.

NULL na straně aplikace

Již jsme si řekli o tom, že programovací jazyky hodnotu NULL zpravidla nemají (tedy ty staticky typované). V jazycích jako je třeba dynamické PHP nemusíme datový typ vůbec řešit, i když je dobré vědět, že se na NULL můžeme zeptat, když to budeme potřebovat. V jazycích typovaných, jako je třeba Java nebo C#, musíme použít jiné datové typy. V C# můžeme kterýkoli datový typ označit jako NULLovatelný a on pochopí, že v něm může být i NULL. V Javě budeme používat datové typy s velkými písmeny, tedy např. pro čísla místo int použijeme Integer.

Upřesňující informace k datovým typům

K datovým typům (chcete-li ke sloupcům) můžeme uvést několik upřesňujících informací. Již jsme se setkali s AUTO_INCREMENT. Podívejme se na další.

Název Popis
AUTOINCREMENT: Při vkládání řádku dejte této položce hodnotu NULL a systém jí automaticky přidělí hodnotu o 1 větší než dal minulému řádku (přírůstek se teoreticky dá změnit, ale tím se teď nebudeme zatěžovat). Výborná věc pro pohodlnou tvorbu unikátních identifikačních klíčů.
UNIQUE Říká, že nesmí existovat víc řádků, které mají v této položce stejnou hodnotu (s výjimkou hodnoty NULL). Smysl to má pouze u klíčů.
NOT NULL Tahle hodnota nesmí být prázdná - nepůjde do ní vložit hodnota NULL.
PRIMARY KEY Tím se určí, že se tenhle sloupec (v každé tabulce max. jeden) bude používat jako klíč. Vhodné pro nějaké relativně krátké identifikační kódy, podle kterých budeme řádky nejčastěji hledat. Primární klíč je vždy NOT NULL a UNIQUE; i když to nenařídíme, dostane tyhle vlastnosti implicitně.
DEFAULT hodnota Výchozí hodnota, kterou položka dostane, když ji při vkládání řádku neuvedeme. Nefunguje na Texty, Bloby a položky s auto_incrementem.

Nová slova upřesňující datový typ se vkládají za něj, stejně jako tomu bylo u AUTO_INCREMENT. Uveďme si nějaký příklad:

CREATE TABLE "uzivatele" (
        "uzivatele_id" INTEGER PRIMARY KEY AUTOINCREMENT,
        "jmeno" TEXT NOT NULL,
);

Dynamické typování

Naprostá většina SQL databází používá k ukládání statické typování, při vytvoření tabulky zadáte datový typ, který má daný sloupec obsahovat, a datový typ položky se určuje pouze podle toho. SQLite naopak používá dynamické typování, kdy se určuje datový typ podle samotné položky (hodnoty), kterou tam nahráváte. Pojďme si to vyzkoušet.

Připomenu vám strukturu naší tabulky uživatelů

CREATE TABLE "uzivatele" (
        "uzivatele_id" INTEGER PRIMARY KEY AUTOINCREMENT,
        "jmeno" TEXT,
        "prijmeni" TEXT,
        "datum_narozeni" TEXT,
        "pocet_clanku" INTEGER
);

Logicky by neměl jít uložit do sloupce počtu článků nějaký text, takže si zkusíme vložit takovýto záznam:

INSERT INTO "uzivatele" ("pocet_clanku") VALUES ('Mnoho');

Avšak výsledek díky dynamickému typování je takovýto:

Vložení uživatele s textem místo čísla do SQLite databáze

Až na sloupec s parametry INTEGER PRIMARY KEY můžete ukládát co chcete kamkoliv. Možná vás teď napadá, jestli jsme nemohli definovat tabulku takto:

CREATE TABLE "uzivatele" (
        "uzivatele_id" INTEGER PRIMARY KEY AUTOINCREMENT,
        "jmeno",
        "prijmeni",
        "datum_narozeni",
        "pocet_clanku"
);

Ano mohli, je to naprosto validní SQL příkaz v SQLite, avšak doporučuji vám, abyste datové typy definovali a dodržovali, potom víte, v jakém formátu tam ukládat data a v jakém je očekávat třeba ve své aplikaci. Na tento typ se také SQLite pokusí převést data, takže pokud jste sloupec označili jako INTEGER a vložíte do něj '15.0', uloží se číslo 15.

Kompatibilita s ostatními databázemi

V rámci kompatibility s ostatními SQL databázemi mění SQLite podobné datové typy ostatních databází na své vlastní. Naše tabulka uživatelů by se vytvořila v SQLite takto:

CREATE TABLE `uzivatele` (
  `uzivatele_id` int AUTO_INCREMENT,
  `jmeno` varchar(60),
  `prijmeni` varchar(60),
  `datum_narozeni` date,
  `pocet_clanku` int,
  PRIMARY KEY (`uzivatele_id`)
);

Pokud bychom tenhle kód rozběhli na SQLite, tak by byl překvapivě úspěšně proveden, a byl by chápán stejně, jako kdybychom zadali tenhle kód:

CREATE TABLE "uzivatele" (
        "uzivatele_id" INTEGER PRIMARY KEY AUTOINCREMENT,
        "jmeno" TEXT,
        "prijmeni" TEXT,
        "datum_narozeni" TEXT,
        "pocet_clanku" INTEGER
);

Tahle vlastnost vám hodně ulehčí práci, když přecházíte z jiné databáze na SQLite a chcete si přenést i data.

Příště si připravíme tabulky a testovací data pro jednoduchý redakční systém, jako je třeba tady na devbooku. Další díly totiž budeme dělat dotazy přes více tabulek a tzv. poddotazy. Tak bude váš arzenál základních databázových nástrojů kompletní pro tvorbu prakticky jakékoli aplikace :)


 

  Aktivity (1)

Článek pro vás napsal Michal Martinek
Avatar

Jak se ti líbí článek?
Celkem (1 hlasů) :
55555


 



 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!