PostgreSQL (14) - omezení dat (Constraints)
Omezení umožňují přenést na úroveň databáze hlídání hodnot
vkládaných dat. Proč je výhodné je používat se dozví čtenář v tomto
díle seriálu.
3.8.2005 07:00 |
MaReK Olšavský
| Články autora
| přečteno 20353×
S jedním omezením již byl čtenář seznámen. Jedná se o zákaz vložení
prázdné hodnoty do sloupce, který se definoval při vytváření tabulky
direktivou NOT NULL. Vůči této definici existuje i možnost
inverzního "omezení", kdy se položka věty určí direktivou NULL,
což ale neznamená že by tento sloupec mohl obsahovat pouze prázdnou
hodnotu (NULL), ale sloupec se bude chovat tak, že prázná hodnota pro
něj bude výchozí, tj. jedná se v podstatě o definici DEFAULT.
Velmi často je při tvorbě tabulek v databázi vidět duplicitní
definice typu 'NOT NULL DEFAULT hodnota', která zároveň říká, že
hodnota nesmí být prázdná a předepisuje jednu výchozí. Pokud je jednou
zadána defaultní hodnota, je tato použita automaticky, pokud není
vložena jiná, čiže je část definice NOT NULL teoreticky zbytečná.
Omezení 'CHECK'
Check znamená kontrolu hodnoty ve sloupci. Využívá se v (obvykle)
případě, že je potřeba explicitně předepsat rozsah hodnot, kterých může
hodnota ve sloupci nabývat. Vhodný příklad je uveden v původní
dokumentaci a tím je zakázání záporné hodnoty u ceny zboží v katalogu,
v tomto případě je omezen stejným způsobem i stav skladu:
CREATE TABLE produkty( id BIGSERIAL, nazev VARCHAR(255), popis TEXT, sklad_kusu NUMERIC(5,0) CHECK (sklad_kusu > = 0), cena NUMERIC(10,2) CHECK (cena >=0) )
Píše se stejným způsobem, jako výchozí hodnota, nebo omezení NOT
NULL (které ostatně lze pomocí CHECK také přepsat). Na pořadí DEFAULT,
NOT NULL a CHECK v podstatě nezáleží. Způsobů definice kontroly
existuje několik, lze je také zapsat jinam, než přímo za hodnotu, ke
které se vztahuje a lze je provázat mezi sebou. Tyto alternativní
zápisy budou ukázány na několika příkladech, v nichž bude definována
stejná, nebo podobná tabulka, jako v předchozím.
-- Definice s check mimo příslušný typ CREATE TABLE produkty( id BIGSERIAL, nazev VARCHAR(255), popis TEXT, sklad_kusu NUMERIC(5,0), cena NUMERIC(10,2), CHECK (cena >=0), CHECK (sklad_kusu > = 0) )
-- Definice provázaných kontrol CREATE TABLE produkty( id BIGSERIAL, nazev VARCHAR(255), popis TEXT, sklad_kusu NUMERIC(5,0), cena_nakup NUMERIC(10,2), cena_prodej NUMERIC(10,2), CHECK (cena_nakup >=0), CHECK (cena_prodej >=0 AND cena_nakup < cena_prodej), CHECK (sklad_kusu > = 0) )
-- Přepsáni NOT NULL ;-) CREATE TABLE produkty( id BIGSERIAL, nazev VARCHAR(255) CHECK (nazev IS NOT NULL), popis TEXT, sklad_kusu NUMERIC(5,0), cena NUMERIC(10,2), CHECK (cena >=0), CHECK (sklad_kusu > = 0) )
Unikátní hodnota
V mnoha případech je potřeba omezit duplicitu hodnot v jednotlivých
větách, například přihlašovací jména, kódy zboží, ... K vynucení tohoto
na straně serveru je možné použít klauzuli UNIQUE. Unikátní může být
jak hodnota jednoho sloupečku, tak kombinace několika sloupců.
Například v ČR rodné číslo není unikátní identifikátor osoby (existují
duplicity), ale v kombinaci s místem narození a nebo rodným příjmením,
by již jedinečným identifikátorem býti mohl.
-- Unikátní login CREATE TABLE users( id BIGSERIAL, login VARCHAR(255) UNIQUE NOT NULL, heslo CHAR(40) );
-- Totéž jinak CREATE TABLE users( id BIGSERIAL, login VARCHAR(255) NOT NULL, heslo CHAR(40), UNIQUE (login) );
-- Unikátní 3 sloupečky CREATE TABLE user_details( id BIGSERIAL, id_user INTEGER UNIQUE, jmeno VARCHAR(50), prijmeni VARCHAR(100), rodcis NUMERIC(10,0), UNIQUE (jmeno, prijmeni, rodcis) );
--Pokud je potřeba omezení pojmenovat CREATE TABLE users( id BIGSERIAL, login VARCHAR(255) CONSTRAINT neprazdny_login UNIQUE, heslo CHAR(40) );
Primární klíče
Primární klíč jako takový je, technicky vzato, kombinace dvou
omezení, která byla popsána výše, NOT NULL a UNIQUE. Podobně jako
UNIQUE je možné jej definovat hned u definice sloupce, nebo na konci
definice tabulky. Tabulka smí mít pouze jediný primární klíč, byť zde
je menší ústupek vůči SQL normě, která tvrdí, že tabulka musí mít právě
jeden primární klíč. Kombinací NOT NULL a UNIQUE lze mít na tabulce
"nekonečné množství", ale i zde platí, že všeho s mírou, protože udělat
UNIQUE na všechna políčka by mohlo vést k tomu, že brzo bude neschopná
vložení jakýchkoliv dat kvůli konfliktům.
--Vytvoření pro jeden sloupec CREATE TABLE users( id BIGSERIAL, login VARCHAR(255) PRIMARY KEY, heslo CHAR(40) );
--Vytvoření pro několik sloupců CREATE TABLE user_details( id BIGSERIAL, id_user INTEGER UNIQUE, jmeno VARCHAR(50), prijmeni VARCHAR(100), rodcis NUMERIC(10,0), PRIMARY KEY (jmeno, prijmeni, rodcis) );
Cizí klíče
Cizí klíče jsou omezením dat ve sloupci, které pak musí odpovídat
hodnotám ktréhokoliv řádku v jiné tabulce. Jedná se tudíž o vynucení referenční
integrity mezi tabulkami. Zde platí, že závislá tabulka může být
doplněna až poté, co je patřičný záznam v tabulce, na kterou je
odkázáno. Vhodným příkladem využití cizích klíčů je v knihovně vazba
výpůjčka<->kniha, kde cizí klíč ve výpůjčce je referencí na
identifikátor knihy, PgSQL server tudíž nedovolí vložit záznam o
výpůjčce knihy, která není uvedena v databázi. Cizí klíče mohou být
vázány jak na jeden, tak na několik sloupečků.
Kromě vynucení referencí na ostatní tabulky lze pomocí cizích klíčů
relizovat i akce na odkazované tabulce, ačkoliv na to je vhodnější
použít triggery (spouště), které jsou přecijen podstatně flexibilnější.
Klíčové slovo, pomocí nějž se tyto cizí klíče definují se jmenuje
REFERENCES, za které se uvede sloupec (sloupce) s názvem tabulky, na
nichž je vyžadována závislost, případně akce, které se mají provést po
změnách v odkazované tabulce. Akce se definují pomocí klíčových
slov ON DELETE, a ON UPDATE. Pro akce navázané na ON
DELETE a ON UPDATE jsou k dispozici metody RESTRICT (pro zakázání
změny) a CASCADE pro povolení promítnutí změny.
--Vytvoření základních tabulky CREATE TABLE produkty( id BIGSERIAL PRIMARY KEY, jmeno VARCHAR(255), popis TEXT, cena_nakup NUMERIC(10,2) CHECK (cena_nakup>=0), cena_prodej NUMERIC(10,2) CHECK (cena_prodej>=0 AND cena_prodej >=cena_nakup), sklad_kusu NUMERIC(5,0) );
CREATE TABLE kategorie( id BIGSERIAL PRIMARY KEY, jmeno VARCHAR, popis TEXT );
--Vytvoření vazební tabulky s cizími klíči CREATE TABLE produkt_kategorie( id_produkt BIGINT REFERENCES produkty(id) ON DELETE RESTRICT, id_kategorie BIGINT REFERENCES kategorie(id) ON DELETE CASCADE );
V příkladě jsou vytvořeny 3 tabulky, z nichž poslední je jednako
propojovací mezi prvními dvěma a zároveň má pomocí klíčů vynucenu
referenční integritu, aby nebylo možné vložit identifikátory produktů a
kategorií, jež nemají v databázi záznamy. Zároveň jsou na této tabulce
definovány dvě akce, že řádek se nemá rušit, když je smazán referenční
záznam v tabulce produkty a řádek se má smazat, když je smazán řádek v
tabulce kategorie (pochopitelně je v tomto menší chyba, protože
budou-li mazány produkty, zůstanou na ně v databázi neplatná propojení).
Cizí klíče lze definovat i na konci vytváření tabulky, pomocí
klíčových slov FOREIGN KEY (sloupečky) REFERENCES druhá_tabulka
(sloupečky). Definice tabulky detailů produktů by mohla vypadat v
tom případě vypadat takto:
CREATE TABLE produkty_detail( detail_id BIGSERIAL, id BIGINT, hmotnost NUMERIC(5,2), barva INT REFERENCES kody_barev(kod) ON DELETE CASCADE, FOREIGN KEY (id) REFERENCES produkty );
Název tabulky, vůči které se vytváří reference, nemusí nutně
obsahovat i názvy sloupečků, v tom případě se sloupeček, pro který je
omezovací podmínka, v podobě cizího/vynuceného klíče a sloupeček v
referenční tabulce musí jmenovat stejně. V příkladě uvedeném výše,
kdyby se změnil v tabulce kategorie sloupeček id přejmenoval na
id_kategorie, tak by druhý řádek definice tabulky produkt_kategorie
mohl vypadat takto: id_kategorie BIGINT REFERENCES kategorie ON
DELETE CASCADE. Cizí klíče lze definovat pouze proti primárnímu klíči.
Práce s omezeními
Práce s omezeními není nikterak
složitá. Data lze do databáze zadávat v podstatě bez omezení a hlídat
pouze, zda-li server nevrátí chybové hlášení, případně jaké a na něj
teprve reagovat v aplikaci, například zobrazením vstupního formuláře
pro opravu dat. Tento přístup však není z nejvhodnějších, mnohem
systematičtější je kontroly, je-li to možné, provádět na aplikační
vrstvě a z databázové vrstvy, v podstatě pro jistotu, pouze číst
chybová hlášení, zda-li přeci jen nebylo některé omezení porušeno.
Závěr
V tomto díle byla shrnutá
omezení, která může vývojář zadat pro vstupy dat. V příštím díle bude
probrán nástroj, který pomůže udržet integritu dat v databázi a tím
jsou transakce.
Verze pro tisk
|
Příspívat do diskuze mohou pouze registrovaní uživatelé.
|
|

Vyhledávání software

Vyhledávání článků
28.11.2018 23:56 /František Kučera Prosincový sraz spolku OpenAlt se koná ve středu 5.12.2018 od 16:00 na adrese Zikova 1903/4, Praha 6. Tentokrát navštívíme organizaci CESNET. Na programu jsou dvě přednášky: Distribuované úložiště Ceph (Michal Strnad) a Plně šifrovaný disk na moderním systému (Ondřej Caletka). Následně se přesuneme do některé z nedalekých restaurací, kde budeme pokračovat v diskusi.
Komentářů: 1
12.11.2018 21:28 /Redakce Linuxsoft.cz 22. listopadu 2018 se koná v Praze na Karlově náměstí již pátý ročník konference s tématem Datová centra pro business, která nabídne odpovědi na aktuální a často řešené otázky: Jaké jsou aktuální trendy v oblasti datových center a jak je optimálně využít pro vlastní prospěch? Jak si zajistit odpovídající služby datových center? Podle jakých kritérií vybírat dodavatele služeb? Jak volit vhodné součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně datové centrum spravovat? Jak co nejlépe eliminovat možná rizika? apod. Příznivci LinuxSoftu mohou při registraci uplatnit kód LIN350, který jim přinese zvýhodněné vstupné s 50% slevou.
Přidat komentář
6.11.2018 2:04 /František Kučera Říjnový pražský sraz spolku OpenAlt se koná v listopadu – již tento čtvrtek – 8. 11. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma umění a technologie, IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
4.10.2018 21:30 /Ondřej Čečák LinuxDays 2018 již tento víkend, registrace je otevřená.
Přidat komentář
18.9.2018 23:30 /František Kučera Zářijový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 20. 9. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář
9.9.2018 14:15 /Redakce Linuxsoft.cz 20.9.2018 proběhne v pražském Kongresovém centru Vavruška konference Mobilní řešení pro business.
Návštěvníci si vyslechnou mimo jiné přednášky na témata: Nejdůležitější aktuální trendy v oblasti mobilních technologií, správa a zabezpečení mobilních zařízení ve firmách, jak mobilně přistupovat k informačnímu systému firmy, kdy se vyplatí používat odolná mobilní zařízení nebo jak zabezpečit mobilní komunikaci.
Přidat komentář
12.8.2018 16:58 /František Kučera Srpnový pražský sraz spolku OpenAlt se koná ve čtvrtek – 16. 8. 2018 od 19:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát jsou tématem srazu databáze prezentaci svého projektu si pro nás připravil Standa Dzik. Dále bude prostor, abychom probrali nápady na využití IoT a sítě The Things Network, případně další témata.
Přidat komentář
16.7.2018 1:05 /František Kučera Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.
Přidat komentář
Více ...
Přidat zprávičku
 Poslední diskuze
31.7.2023 14:13 /
Linda Graham iPhone Services
30.11.2022 9:32 /
Kyle McDermott Hosting download unavailable
13.12.2018 10:57 /
Jan Mareš Re: zavináč
2.12.2018 23:56 /
František Kučera Sraz
5.10.2018 17:12 /
Jakub Kuljovsky Re: Jaký kurz a software by jste doporučili pro začínajcího kodéra?
Více ...
|