Budovanie informačných systémov I. – SQL: Tabuľky a kľúče

Libor Bešenyi  /  24. 08. 2006, 00:00

Dneska si doplníme vedomosti z predchádzajúcej časti. Bližšie sa pozrieme na vytváranie tabuliek a porozprávame s o databázových kľúčoch.

Príloha k článku

Rozšírené vlastnosti tabuliek a jej kľúče

 

Táto časť bude teoreticko-praktická. Bude voľne nadväzovať na posledné dve časti a keďže už máme nejaké základy so syntaxou SQL, teória sa bude efektívnejšie vysvetľovať.

 

predchádzajúcej časti sme sa obmedzili na pomerne zjednodušenú formu vytvorenia tabuľky, ktorú budeme zatiaľ využívať, ale nepopísali sme si jej základne vlastnosti.

 

CREATE TABLE [príkazy] [názov databázy].[názov tabuľky] (

  [názov stĺpca 1] [dátový typ] [príkazy],

  [názov stĺpca 2] [dátový typ] [príkazy],

  …,

  PRIMARY KEY (názov konkrétneho stĺpca)

)

 

Najzákladnejší príkaz, pred názvom o ktorom by sme mali vedieť je práve overovanie existencie. Prečo? Neošetrenie skriptu by mohlo znamenať, že pri upgrade nášho programu sa aplikácia hnusne vysype, ak by neoverovala existenciu objektov.

 

Jedná sa o to, že program môže pracovať bez určitých tabuliek – ak bola narušená štruktúra. Ak však tabuľka neexistuje a mi k nej pridáme napríklad trigger, môže to skončiť veľmi nepekne. Rovnako, ak sa snažíme vytvoriť tabuľku, ktorá už existuje, tiež sa vyhodí chyba. Preto máme niekoľko možnosti, ako tomu predísť:

 

  1. Starú tabuľku vymazať (ako sa dozvieme v ďalšej časti) a novou ju nahradiť.
  2. Ponechať starú a novu nevytvárať.
  3. Upraviť štruktúru starej (o tom tiež neskôr).

 

V prípade, že ju chceme odignorovať, použijeme príkaz IF NOT EXISTS:

 

Obrázok 1 Príklad overenia existencie tabuľky pri vytváraní novej

 

jednej z častí sme si hovorili o akých si kľúčoch, ktoré jednoznačne identifikujú jeden riadok. Tieto kľúče musia byť teda jedinečné a nemôžu obsahovať prázdnu hodnotu NULL (pozri článok) . To sa zabezpečuje inkrementačným príkazom (AUTO_INCREMENT) a jednoznačnou definíciou stĺpca ako primárneho kľúča. Tento primárny kľúč (PK), nie je potrebné pri vkladaní údajov do riadku vypĺňať, o to sa stará systém.

 

Pozn.: Ak niekto pracuje s iným systémom ako MySQL, tak autoinkrementácia sa môže vykonávať prostredníctvom „externých príkazov“, ktoré sa definujú mimo tabuľku a potom sa stĺpcu priradzujú. Oracle pracuje na princípe sekvencii a Inter Base (Firebird) inkrementuje údaje vďaka generátorom (s Firebirdom sa stretneme v druhej časti tohto seriálu a tak sa na to pozrieme bližšie).

 

Teda si vytvorme cvičnú tabuľku, ktorá bude v riadku obsahovať primárny kľúč a nejaký reťazec:

 

CREATE TABLE test2.skuska (

  skuska INT AUTO_INCREMENT PRIMARY KEY,

  retazec VARCHAR(10));

 

Zápis primárneho kľúča pri definícii konkrétneho stĺpca je ekvivalentný s priradzovaním na konci zápisu:

 

CREATE TABLE test2.skuska (

  skuska INT AUTO_INCREMENT,

  retazec VARCHAR(10),

  PRIMARY KEY(skuska));

 

Ak si teraz vyskúšame vkladanie údajov do tabuľky zistíme ako efektívne pracuje inkrementačný stĺpec. Odignorujme preto PK stĺpec (volajme ho identify, niekto ho zvykne označovať ako ID, index) a vložme záznam do tabuľky s následným vypísaním jej obsahu:

 

INSERT INTO skuska (

   (retazec)

VALUE

   (“trulo”);

 

SELECT * FROM skuska;

 

Vidíme, že do tabuľky sa vložili oba stĺpce. Pri prázdnej tabuľke a jej prvom zázname je ešte veľmi dobré si uvedomiť jeden podstatný fakt: ID PK sa vždy začína od 1 nie od 0. Možno sa to zdá byť zbytočné, ale nie je – hlavne keď budeme neskôr pracovať s databázou v Delphi.

 

Pridajme si ešte jeden záznam a identify sa znova pripočíta o jedno číslo. Takto nemusíme nijak ošetrovať PK, aby bol jedinečný:

 

Obrázok 2 Príklad autoinkrementácie

 

Tiež  je možné, že nejaký stĺpec nesmie ostať nevyplnený (NULL). Zoberme si absurdný príklad, že nejaká firma rozdáva zamestnancom Fábie rovnakého typu (dohoda s výrobcom) a manažment má Superb. Samozrejme zamestnancov je omnoho viac a v prípade, že ekonómka spracúva knihu jázd, namiesto častého výberu Fábie, odklepne riadok ako prázdny, pričom vie, že databáza si ho doplní o implicitne nastavenú hodnotu. To sa dá nadefinovať ako default hodnota stĺpca:

 

CREATE TABLE test2.kniha_jazd (

  kniha_jazd int AUTO_INCREMENT PRIMARY KEY,

  auto VARCHAR(10) DEFAULT ‘Fabia 1.2’,

  zamestnanec VARCHAR(10) NOT NULL);

 

Tak keď pridáme prázdny riadok, automaticky sa doplní Fábia. V prípade zadania, akéhokoľvek iného riadku, bude práve ten obsah:

 

Obrázok 3 Príklad implicitných hodnôt tabuľky

 

Môže sa však stať aj to, že potrebujeme mať jedinečné hodnoty aj v inom stĺpci, ako v primárnom kľúči. V takomto prípade, by bolo možné tento stĺpec považovať za PK, ale z hľadiska lepšieho prehľadu, my budeme stále používať „stĺpec na viac“. Ostatné stĺpce môžu, ale nemusia byť jedinečné.

 

Ak teda v tabuľke existuje ešte jeden stĺpec, ktorý nemôže obsahovať dve rovnaké hodnoty a nie je primárnym kľúčom, hovoríme, že tento stĺpec obsahuje unikátnu hodnotu – je unique. Typickým príkladom môže byť práve nejaká položka v cenníku firmy, nazvime ju položkou evidencie. Fyzicky počet tovaru na sklade nás nezaujíma, pretože v cenníku neuvedieme predsa desať rovnakých tovarov. Preto táto položka evidencie je jednoznačne určená na tovar. To sa zabezpečí vytvorením napríklad takejto tabuľky:

 

CREATE TABLE test2.PolozkaEvidencie (

  PolozkaEvidencie INT AUTO_INCREMENT PRIMARY KEY,

  Tovar VARCHAR(10) NOT NULL UNIQUE,

  Cena INT NOT NULL);

 

Ak teraz budeme pridávať záznamy, nesmú obsahovať rovnaký názov, pretože databázový systém za nás zisťuje existenciu každého vloženého záznamu a v prípade nájdenia „zakričí“, že sa snažíme vložiť duplikát. A ešte jeden zásadný rozdiel oproti PK a UNIQUE je, že tabuľka môže obsahovať niekoľko „unique“ stĺpcov, pričom môže mať maximálne jeden primárny.

 

Obrázok 4 Príklad tabuľky s unikátnymi hodnotami v stĺpci

 

My však už vieme, že najlepšie by bolo, ak by sme tovar separovali do nejakej z tabuliek. Tam by sme zabezpečili jedinečnosť názvu tovaru a podľa identify by sme tovar dotiahli do tabuľky položky evidencie. Tento spôsob sa nám takmer vnúca pri relačných systémoch. Keďže tovar musíme aj niekde skladovať a jedná sa stále o ten istý tovar, ktorý ponúkame v cenníku, preto by ostatné tabuľky (napríklad skladová karta) niesli redundantné záznamy, prípade by pri skomolení jedného názvu z hľadiska databázy obsahovali iný tovar (bublifuk nie je bubilfuk).

 

Práve preto vznikol pojem relácie (pozri článok). Jedná sa už z nášho hľadiska o myslené prepojenie identify polí. Príkazom select (o ňom neskôr), dokážeme tieto polia prepájať a tak doťahovať záznamy z iných tabuliek (relačne prepojených). Tento model budeme plne využívať v prvej časti.

 

Aby však bol výklad pomerne kompletný, musíme si predstaviť aj druhý pojem a to je referencia. Dalo by sa povedať že sú to pojmy podobné, pretože oba narábajú s prepojeniami tabuliek. Referencia je však „fyzickejším“ prepojením, ako len mysleným. Jedná sa o konkrétny objekt v databáze (podobne ako tabuľka), ktorý udáva presný vzťah medzi poľami dvoch tabuliek. Je to troška komplikovanejšie a preto sa s tým budeme zaoberať asi až v druhej časti seriálu. Znalosťami referencii ale odpadá brutálna práca s databázovými operáciami, ktoré takto budeme ošetrovať zo začiatku sami (ale aspoň si viac budeme vážiť komplikovanejšie techniky a presne budeme vedieť, na akom princípe budú pracovať).

 

Takže ak chceme pridávať referenčný „cudzí“ kľúč do stĺpca - FOREIGN KEY (FK) pridáme ešte názov referencie a celá štruktúra môže vyzerať ako je nižšie naznačené. Podľa toho teda vieme, že aj FK kľúčov môžeme mať viac.

 

CREATE TABLE [príkazy] [názov databázy].[názov tabuľky] (

  [názov stĺpca 1] [dátový typ] [príkazy],

  [názov stĺpca 2] [dátový typ] [príkazy],

  …,

  FOREIGN KEY (názov stĺpca) REFERENCES [názovreferencie](názov stĺpca),

  …,

  PRIMARY KEY (názov konkrétneho stĺpca)

)

 

POZOR: V článku pri tvorbe tabuliek udávam prefix „test2“, jedná sa o názov databázy (pozri predchádzajúci článok) – teda na začiatku som vstúpil / vytvoril databázu test2.

Neprehliadnite: