8. diel - SQLite - Dátové typy, NULL a dynamické typovanie
V predchádzajúcom cvičení, Riešené úlohy k 7. lekcii SQLite, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.
V dnešnom SQLite tutoriáli sa vrátime k dátovým typom a
povieme si niečo o hodnote NULL.
Dátové typy
Hneď na začiatku kurzu sme sa stretli s niekoľkými dátovými typmi.
Vtedy som vám s nimi nechcel motať hlavu. Reč bola o typoch
INTEGER a TEXT. Databáza (u konkrétne SQLite) ich
má síce ešte niekoľko, ale na rozdiel od iných SQL databáz je ich pomerne
málo.
Celé číslo - INTEGER
Podľa veľkosti samotného čísla, ktoré sa ukladá, sa použije 1, 2, 3, 4, 5, 6, 7 alebo 8 bajtov.
Ak hľadáte dátový typ boolean (hodnoty
true/false), tak na ukladanie tejto hodnoty sa
používa tiež INTEGER - 0 = false,
1 = true.
Reálne číslo - REAL
Na ukladanie reálnych čísel sa používa 64 bitov, presnosť je zhruba 15 až 16 čísel a číslo môže nadobúdať hodnoty +-5.0 * 10−324 až +-1.7 * 10308.
Textový reťazec - TEXT
Dátový typ TEXT sa používa na ukladanie reťazcov znakov
podľa použitého kódovania databázy (UTF-8, UTF-16BE or UTF-16LE).
Používa sa taktiež na ukladanie času vo formáte
'rrrr-mm-dd hh:mm:ss.sss', ale dá sa použiť aj dátový typ
INTEGER vo formáte Unix - počet sekúnd od 1. januára 1970 0:00,
alebo typ REAL.
Binárne dáta - BLOB
Všeobecné dáta v binárnom tvare, použitie analogické k typom
TEXT. Umožňujú do databázy ukladať napr. obrázky alebo
zvuky.
Hodnota NULL
Dátové typy v databázach sa trošičku odlišujú od dátových typov, ako
ich poznáme v programovacích jazykoch. Zatiaľ čo napríklad v Céčku môže
mať int hodnoty len nejakých -32.000 až +32.000 a nič okrem
toho, databázový INTEGER môže nadobúdať aj hodnoty
NULL. NULL nemá vôbec nič spoločné s nulou
(0), označuje to, že hodnota nebola ešte
zadaná. Filozofia databáz je takto postavená, nezadané hodnoty
majú východiskovú hodnotu NULL (ak im nenastavíme inú) a
každý dátový typ má okrem hodnôt, ktoré by sme v ňom očakávali,
navyše možnú hodnotu NULL. Datovému typu túto hodnotu môžeme
aj zakázať, viac ďalej.
Ak napr. príkazom INSERT vložíme užívateľa a vyplníme len
niektoré hodnoty, do ďalších hodnôt sa vloží NULL. Skúsme
si to:
INSERT INTO "users" ("first_name", "last_name") VALUES ('Mister', 'Incomplete');
Výsledok:

Prínos hodnoty NULL
Asi sa pýtate na čo hodnota NULL vlastne je? Jej prínos je v
tom, že spoznáme, či bola hodnota zadaná. Napr. pri zadávaní čísla
neexistuje hodnota, podľa ktorej by sme poznali, že číslo nie je zadané.
Keby sme si k tomuto určili hodnotu nula (0), nevieme, či
používateľ číslo nezadal alebo zadal práve nulu. NULL okrem
iného aj šetrí miesto v databáze, kde na rozdiel od východiskových hodnôt
nezaberá miesto.
NULL na strane aplikácie
Už sme si povedali o tom, že programovacie jazyky hodnotu NULL
spravidla nemajú (teda tie staticky typované). V jazykoch ako napríklad
dynamické PHP nemusíme dátový typ vôbec riešiť, aj keď je dobré
vedieť, že sa na NULL môžeme opýtať, keď to budeme
potrebovať. V typovaných jazykoch, ako je napríklad Java alebo C#, musíme
použiť iné dátové typy. V C# môžeme ktorýkoľvek dátový typ označiť
ako NULLovateľný a on pochopí, že v ňom môže byť aj NULL. V
Jave budeme používať dátové typy s veľkými písmenami, teda napr. pre
čísla namiesto int použijeme Integer.
Upresňujúce informácie k dátovým typom
K dátovým typom (ak chcete k stĺpcom) môžeme uviesť niekoľko
upresňujúcich informácií. Už sme sa stretli s AUTO_INCREMENT.
Pozrime sa na ďalšie:
| Názov | Popis |
|---|---|
| AUTOINCREMENT | Pri vkladaní riadku dajte tejto položke hodnotu NULL a
systém jej automaticky pridelí hodnotu o 1 väčšiu ako dal
minulému riadku (prírastok sa teoreticky dá zmeniť, ale tým sa teraz
nebudeme zaťažovať). Výborná vec na pohodlnú tvorbu unikátnych
identifikačných kľúčov. |
| UNIQUE | Hovorí, že nesmie existovať viac riadkov, ktoré majú v tejto položke
rovnakú hodnotu (s výnimkou hodnoty NULL). Zmysel to má iba pri
kľúčoch. |
| NOT NULL | Táto hodnota nesmie byť prázdna - nepôjde do nej vložiť hodnota
NULL. |
| PRIMARY KEY | Tým sa určí, že sa tento stĺpec (v každej tabuľke max. jeden) bude
používať ako kľúč. Vhodné pre nejaké relatívne krátke identifikačné
kódy, podľa ktorých budeme riadky najčastejšie hľadať. Primárny kľúč
je vždy NOT NULL a UNIQUE; aj keď to nenariadime,
dostane tieto vlastnosti implicitne. |
| DEFAULT hodnota | Predvolená hodnota, ktorú položka dostane, keď ju pri vkladaní riadka
neuvedieme. Nefunguje u typů TEXT, BLOB a u
položiek, koté majú nastavený AUTOINCREMENT. |
Nové slová upresňujúce dátový typ sa vkladajú zaň, rovnako ako to
bolo pri AUTOINCREMENT. Uveďme si nejaký príklad:
CREATE TABLE "users" ( "user_id" INTEGER PRIMARY KEY AUTOINCREMENT, "first_name" TEXT NOT NULL, );
Dynamické typovanie
Prevažná väčšina SQL databáz používa na ukladanie statické typovanie, pri vytvorení tabuľky zadáte dátový typ, ktorý má daný stĺpec obsahovať, a dátový typ položky sa určuje iba podľa toho. SQLite naopak používa dynamické typovanie, kedy sa určuje dátový typ podľa samotnej položky (hodnoty), ktorú tam nahrávate. Poďme si to vyskúšať.
Pripomeniem vám štruktúru našej tabuľky užívateľov
CREATE TABLE "users" ( "user_id" INTEGER PRIMARY KEY AUTOINCREMENT, "first_name" TEXT, "last_name" TEXT, "birth_date" TEXT, "article_count" INTEGER );
Logicky by nemalo byť možné uložiť do stĺpca počtu článkov nejaký text, takže si skúsime vložiť takýto záznam:
INSERT INTO "users" ("article_count") VALUES ('A lot');
Avšak výsledok je vďaka dynamickému typovaniu takýto:

Až na stĺpec s parametrami INTEGER PRIMARY KEY môžeme v
SQLite ukladať ukladať akýkoľvek typ hodnoty do akéhokoľvek stĺpca.
Možno vás teraz napadá, či sme nemohli definovať tabuľku takto:
CREATE TABLE "users" ( "user_id" INTEGER PRIMARY KEY AUTOINCREMENT, "first_name", "last_name", "birth_date", "article_count" );
Áno mohli, je to úplne validný SQL príkaz v SQLite, avšak odporúčam
vám, aby ste dátové typy definovali a dodržiavali, potom viete, v akom
formáte tam ukladať dáta a v akom ich očakávať vo svojej aplikácii. Na
tento typ sa tiež SQLite pokúsi previesť dáta, takže ak ste stĺpec
označili ako INTEGER a vložíte doň 15.0, uloží
sa číslo 15.
Kompatibilita s ostatnými databázami
V rámci kompatibility s ostatnými SQL databázami mení SQLite podobné dátové typy ostatných databáz na svoje vlastné. Naša tabuľka užívateľov by sa vytvorila v SQL takto:
CREATE TABLE `users` ( `user_id` int AUTO_INCREMENT, `first_name` varchar(60), `last_name` varchar(60), `birth_date` date, `article_count` int, PRIMARY KEY (`user_id`) );
Ak by sme tento kód rozbehli na SQLite, tak by bol prekvapivo úspešne vykonaný a bol by chápaný rovnako, ako keby sme zadali tento kód:
CREATE TABLE "users" ( "user_id" INTEGER PRIMARY KEY AUTOINCREMENT, "first_name" TEXT, "last_name" TEXT, "birth_date" TEXT, "article_count" INTEGER );
Táto vlastnosť nám veľmi uľahčí prácu, keď prechádzame z inej databázy na SQLite a chceme si preniesť aj dáta.
V nasledujúcom kvíze, Kvíz - Export, import, radenie a dátové typy v SQLite, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
