Jak jsme si minule slíbili, dnes si povíme, jak pomocí SQL můžeme založit tabulku, jak ji změnit a zrušit.
Jak jsme si minule slíbili, dnes si povíme, jak pomocí SQL můžeme založit tabulku, jak ji změnit a zrušit. Seznámíme se tak s prvními příkazy spadajícími do kategorie DDL (Data Definition Language).
Na začátku našeho seriálu jsme si uvedli, že název příkazů v SQL je odvozen od odpovídajících výrazů v anglickém jazyce. Chceme-li vytvořit tabulku, použijeme překlad a vyřkneme "magické" CREATE TABLE. Zjednodušená syntaxe tohoto příkazu má následující podobu:
CREATE |
TABLE |
jméno_tabulky |
|
|
|
|
položka |
typ |
[NOT NULL] |
|
|
[,položka |
typ |
[NOT NULL]] ... |
Typů je v
SQL, obdobně jako v dalších programovacích jazycích, celá řada. Mezi nejpoužívanější patří
integer,
decimal,
float,
char,
varchar či
date. Poznamenejme, že vlastnosti (případně včetně názvů) jednotlivých typů mohou být ve vlastních implementacích mírně odlišné a proto doporučuji si zjistit bližší informace (zejména o platnosti rozsahu) v technické dokumentaci. Při volbě typu nezapomínejte na paměťové požadavky - to, co zpočátku vypadá třeba na kilo, může při miliónech záznamů neuvěřitelně narůst.
Za specifikací typu se poprvé setkáváme s pojmem NULL. Tato "hodnota" říká, že v dané položce vlastně žádná hodnota není. Upozorňuji na zásadní rozdíl například od významu nuly (0), která hodnotou je. Ještě jednou tento podstatný rozdíl opakuji - "hodnota" NULL znamená, že v položce žádná hodnota není, tedy (jinými slovy) je prázdná. Klauzule NOT NULL v definici položky nám říká, že v každém řádku musí být hodnota pro daný atribut vyplněna. Pro práci s NULL hodnotami platí určitá pravidla - například v podmínce nepoužíváme zápis ve tvaru položka = NULL, ale položka is NULL. Příkaz na založení naší zkušební tabulky osoby může vypadat takto:
CREATE |
TABLE |
osoby |
|
|
|
jméno |
varchar(30), |
|
|
příjmení |
varchar(30), |
|
|
rodné_číslo |
char(11), |
|
|
datum |
date, |
|
|
počet_dětí |
integer |
Rozhodneme-li se, že chceme mít pro rodné číslo hodnotu vždy vyplněnou, příkaz upravíme přidáním popisované klauzule
NOT NULL:
CREATE |
TABLE |
osoby |
|
|
|
|
jméno |
varchar(30), |
|
|
|
příjmení |
varchar(30), |
|
|
|
rodné_číslo |
char(11) |
NOT NULL, |
|
|
datum |
date, |
|
|
|
počet_dětí |
integer |
|
Příkaz
CREATE TABLE (součástí kterého je v přesné syntaxi možnost definovat jedinečnost, klíče či další logická omezení) bývá jedním z těch, které se od
SQL standardů mírně odlišují. Tím však nechci říci, že by byla nějak radikálně omezena jeho funkčnost, spíše naopak. Mnohdy je umožněno specifikování dalších parametrů týkajících se vlastního uložení dat (například počáteční velikosti zabíraných paměťových bloků). Připomeňme si, že na pořadí atributů v relačním modelu nezáleží - přesto se doporučuje na první pozice umisťovat položky, které budou součástí klíčů či indexů (případná výhoda takového uspořádání však závisí na vnitřních mechanismech konkrétního systému).
Druhým příkazem, který budeme pro práci s definicí tabulky potřebovat, je ALTER TABLE. Vzhledem k jeho určení, kterým je změna definice tabulky, vychází jeho možnosti z příkazu CREATE TABLE. Ukažme si, jaké jsou základní volby:
ALTER |
TABLE |
jméno_tabulky |
|
|
|
|
|
[ADD |
položka |
typ |
[NOT NULL]] ... ¦ |
|
|
[MODIFY |
položka |
typ |
[[NOT] NULL]] ... ¦ |
|
|
[DROP |
položka] ... |
|
|
Význam jednotlivých klauzulí přesně odpovídá anglickým ekvivalentům -
ADD umožní položku přidat,
MODIFY změnit její definici (tedy například typ) a
DROP atribut z tabulky odebrat. Vraťme se ještě k problému
NULL hodnoty - omezení změny na
NOT NULL je logicky možné pouze tehdy, když je hodnota měněné položky vyplněna pro všechny záznamy. Poznamenejme, že některé systémy úpravu na
NOT NULL ani neumožňují (problém lze vyřešit vytvořením nové tabulky a "přehráním" dat). Stejně je na tom i možnost odstranění položky z tabulky (omezení zde ovšem neplyne z hodnot dat jako u
NOT NULL, ale spíše z mnohdy problematické změny použitých fyzických struktur v operační paměti a na záznamovém médiu). Vlastní změna dat se zpravidla neprovádí ihned po vykonání příkazu
ALTER TABLE, ale až při nejbližším použití příkazu
UPDATE.
Pamatujete si, jak jsme v díle věnovaném agregacím přidávali do tabulky osoby novou položku počet_dětí? Příkaz pro tuto změnu by mohl mít následující podobu:
ALTER |
TABLE |
osoby |
|
|
|
|
ADD |
počet_dětí |
integer |
Pokud chceme zrušit naše omezení (použité ve druhém dnešním příkladě na založení tabulky)
NOT NULL na položce
rodné_číslo, použijeme následující zápis:
ALTER |
TABLE |
osoby |
|
|
|
|
MODIFY |
rodné_číslo |
NULL |
Při změně typu dat musíme mít na paměti, že systém musí být schopen na pozadí provést automatickou konverzi mezi typem původním a novým. V opačném případě (například při změně typu z
char na
integer) můžeme očekávat chybové hlášení.
K naší zcela původní verzi tabulky osoby se můžeme vrátit, použijeme-li zápis příkazu ve tvaru:
ALTER |
TABLE |
osoby |
|
|
|
DROP |
počet_dětí |
Velmi často příkaz
ALTER TABLE, obdobně jako příkaz předchozí, umožňuje ovlivnit celou řadu vlastností - bližší podrobnosti jsou však nad rámec tohoto dílu. Na první pohled tyto základní
DDL příkazy vypadají složitěji než například
SELECT. Je a není to pravda - pokud se spokojíme pouze s "jádrem" těchto příkazů (pro učení a zkoušení je to zcela dostačující), nemělo by nám jejich pochopení činit žádné větší problémy.
Pokud jsme si s ukázkovou tabulkou již dostatečně vyhráli, můžeme ji zrušit příkazem DROP TABLE. Rušení čehokoli zpravidla patří mezi nejjednodušší postupy, není proto divu, že syntaxe je velmi triviální:
Příkaz
DROP TABLE bývá často doplněn o možnost současného zrušení referenčních odkazů z ostatních tabulek, ale to již patří do pokročilejších technik.
Na tomto místě bych se ještě jednou vrátil k otázce kompatibility konkrétní implementace SQL se standardy. Pokud Vám některý příklad nefunguje tak jak má, podívejte se do dokumentace na přesnou syntaxi. Odlišnosti však nemusíte chápat jako katastrofu - mnohdy se jedná pouze o drobné nuance. Horší situace nastane ve chvíli, kdy není některá vlastnost podporována vůbec (nejedná se tedy o rozdílnou syntaxi). Pak musíte zjistit, zda se požadavek nedá "opsat" jiným způsobem - pokud ne a uvedenou vlastnost opravdu potřebujete, zvažte, zda nemůžete přejít na jiný systém.
Dosud jsme si ukázali pouze pár příkazů - mohlo by se to zdát málo. Známe však všechny, které potřebujeme k vytvoření jednoduché aplikace (byť opravdu velmi jednoduché a neohrabané). Použití SQL se neustále točí okolo této skupiny příkazů. Příště si povíme něco o slíbených indexech a poprvé se tak podíváme na zoubek (byť z bezpečné vzdálenosti) otázce rychlosti prováděných SQL příkazů.