Databázy (1) Prednáška 04 Alexander Šimko simko@fmph.uniba.sk
Contents I Množinové operácie UPSERT
Množinové operácie Section 1 Množinové operácie
Množinové operácie Množinové operácie Motivácia Chceme identifikovať používateľov, ktorí majú slovníkové heslo. Chceme zostrojiť slovník tak, aby v ňom boli: používateľské mená a názvy krajín.
Množinové operácie Množinové operácie Syntax dopyt_1 MNOŽINOVÝ_OPERÁTOR dopyt_2 MNOŽINOVÝ_OPERÁTOR: UNION riadky, ktoré vráti dopyt_1 alebo dopyt_2 INTERSECT riadky, ktoré vráti dopyt_1 a zároveň aj dopyt_2 EXCEPT riadky, ktoré vráti dopyt_1 ale nevráti dopyt_2
Množinové operácie UNION Príklad users id name country_id 1 fan123 1 2 johnny 4 3 stellar NULL country id name 1 Slovakia 4 Czech Republic SELECT name FROM users UNION SELECT name FROM countries name fan123 johnny stellar Slovakia Czech Republic
Množinové operácie Množinové operácie Počet a typy stĺpcov sa musia zhodovať SELECT id, name FROM users UNION SELECT name FROM countries ERROR: each UNION query must have the same number of columns SELECT id FROM users UNION SELECT name FROM countries ERROR: UNION types integer and character varying cannot be matched
Množinové operácie Množinové operácie Názvy stĺpcov sa nemusia zhodovať SELECT name FROM users UNION SELECT email FROM users Vezme sa názov sĺpca z prvého dopytu: name fan123 johnny stellar fan123@gmail.com spam@spam.com my@email.ch
Množinové operácie Množinové operácie Vnáranie DOPYT_1 OPERÁTOR_1 DOPYT_2 dopyt môže byť aj zložený z množinových operátorov
Množinové operácie Množinové operácie Vnáranie SELECT name FROM users UNION (SELECT name FROM countries INTERSECT SELECT email FROM users) UNION SELECT name FROM films
Množinové operácie Množinové operácie Ak nepoužijeme zátvorky DOPYT_1 OPERÁTOR_1 DOPYT_2 OPERÁTOR_2 DOPYT_3 je to isté ako (DOPYT_1 OPERÁTOR_1 DOPYT_2) OPERÁTOR_2 DOPYT_3
Množinové operácie Množinové operácie Odstaňujú duplicity a x 1 1 2 2 2 b x 2 2 3 3 SELECT * FROM a UNION SELECT * FROM b x 1 2 3
Množinové operácie Množinové operácie Odstaňujú duplicity a x 1 1 2 2 2 b x 2 2 3 3 SELECT * FROM a INTERSECT SELECT * FROM b x 2
Množinové operácie Množinové operácie Odstaňujú duplicity a x 1 1 2 2 2 b x 2 2 3 3 SELECT * FROM a EXCEPT SELECT * FROM b x 1
Množinové operácie Multimnožinové operácie UNION ALL, INTERSECT ALL, EXCEPT ALL berú do úvaju koľkokrát sa riadok v tabuľke nachádza
Množinové operácie Multimnožinové operácie UNION ALL a x 1 1 2 2 2 b x 2 2 3 3 SELECT * FROM a UNION ALL SELECT * FROM b x 1 1 2 2 2 2 2 3 3
Množinové operácie Multimnožinové operácie INTERSECT ALL a x 1 1 2 2 2 b x 2 2 3 3 SELECT * FROM a INTERSECT ALL SELECT * FROM b x 2 2
Množinové operácie Multimnožinové operácie EXCEPT ALL a x 1 1 2 2 2 b x 2 2 3 3 SELECT * FROM a EXCEPT ALL SELECT * FROM b x 1 1 2
Množinové operácie (Multi)množinové operácie a ORDER BY, LIMIT a OFFSET dopyt_1 OPERÁTOR dopyt_2 ORDER BY výrazy LIMIT limit OFFSET offset 1. vyhodnotí sa dopyt_1, 2. vyhodnotí sa dopyt_2, 3. na výsledky sa aplikuje (multi)množinový operátor 4. výsledok sa usporiada 5. aplikuje sa LIMIT a OFFSET Je to to isté ako: (dopyt_1 OPERÁTOR dopyt_2) ORDER BY výrazy LIMIT limit OFFSET offset
Množinové operácie Množinové operácie a ORDER BY Príklad users id name country_id 1 fan123 1 2 johnny 4 3 stellar NULL countries id name 1 Slovakia 4 Czech Republic SELECT name FROM users UNION SELECT name FROM countries ORDER BY name name Czech Republic fan123 johnny Slovakia stellar
Množinové operácie ORDER BY, LIMIT, OFFSET pred množinovými operáciami SELECT name FROM users ORDER BY name LIMIT 1 UNION SELECT name FROM countries ORDER BY name LIMIT 1 ERROR: syntax error at or near "union"
Množinové operácie ORDER BY, LIMIT, OFFSET pred množinovými operáciami Jednotlivé dopyty musíme uzavrieť do zátvoriek (SELECT name FROM users ORDER BY name LIMIT 1) UNION (SELECT name FROM countries ORDER BY name LIMIT 1)
Množinové operácie (Multi)množinové operátory a NULL hodnoty NULL hodnoty sa považujú za rovnaké (ale iné od nenull hodnôt) (SELECT 1, NULL) UNION (SELECT 1, NULL) UNION (SELECT 1, a )?column??column? 1 NULL 1 a Ak by sa NULL považovali za rôzne, dostali by sme prvý riadok 2x
Množinové operácie (Multi)množinové operátory a NULL hodnoty NULL hodnoty sa považujú za rovnaké (ale iné od nenull hodnôt) (SELECT 1, NULL) INTERSECT ALL (SELECT 1, NULL)?column??column? 1 NULL Ak by sa NULL považovali za rôzne, dostali by sme 0 riadkov
Množinové operácie (Multi)množinové operátory a UPDATE, DELETE, INSERT (Multi)množinové operátory sa dajú použiť iba so SELECTom.
Section 2
Čo to je? Integritné obmedzenie je podmienka, ktorá určuje, čo je konzistentný stav databázy. Databázový systém nepovolí operáciu, ktorá by porušila nejaké integritné obmedzenie
Na čo to je? Zabránime, aby sa nekorektné vstupy od používateľa dostali do databázy Nedovolíme, aby chybná aplikačná logika vložila do databázy nesprávne hodnoty Radšej nech sa aplikácia ukončí a vypíše chybu, než by mala zapísať nekorektné údaje
Dátový typy Dátový typ Na dátový typ stĺpca sa môžeme pozerať ako na integritné obmedzenie: v stĺpci môže byť hodnota iba z daného dátového typu pokus o vloženie hodnoty iného typu zlyhá
NOT NULL NOT NULL CREATE TABLE názov_tabuľky (..., názov_stĺpca typ NOT NULL,... ) Nedovolí stĺpec nastaviť na hodnotu NULL
NOT NULL NOT NULL Príklad CREATE TABLE films ( id serial, name varchar(50), price numeric NOT NULL ) INSERT INTO films (name, price) VALUES ( Bad film, NULL) ERROR: null value in column "price" violates not-null constraint
CHECK CHECK obmedzenie CREATE TABLE názov_tabuľky (..., názov_stĺpca typ [CONSTRAINT názov_obmedzenia] CHECK (booleovský_výraz),... ) Pri akejkoľvek zmene riadku (insert, update) musí byť CHECK obmedzenie splnené. Obmedzenie sa považuje za splnené, ak sa vyhodnotí na: TRUE, alebo NULL
CHECK CHECK obmedzenie Príklad CREATE TABLE films ( id serial, name varchar(50), price numeric CHECK (price >= 0) ) INSERT INTO films (name, price) VALUES ( Bad film, -55) ERROR: new row for relation "films" violates check constraint "films_price_check"
CHECK CHECK obmedzenie Príklad 2 CREATE TABLE films ( id serial, name varchar(50), price numeric CHECK (price >= 0) ) INSERT INTO films (name, price) VALUES ( Good film, NULL) films id name price 1 Good film NULL
CHECK CHECK obmedzenie Prečo tie NULL hodnoty? aby sme mali možnosť stĺpec nevyplniť (NULL hodnota), a CHECK obmedzením kontrolovali iba vyplnené hodnoty na obmedzenie NULL máme predsa NOT NULL
CHECK CHECK obmedzenie na samostatnom riadku CREATE TABLE názov_tabuľky (..., [CONSTRAINT názov_obmedzenia] CHECK (booleovský_výraz),... )
CHECK CHECK obmedzenie na samostatnom riadku Príklad CREATE TABLE films ( id serial, name varchar(50), price numeric CHECK (price >= 0), discounted_price numeric CHECK (discounted_price >= 0), CHECK (price > discounted_price) )
UNIQUE UNIQUE CREATE TABLE názov_tabuľky (..., názov_stĺpca typ [CONSTRAINT názov_obmedzenia] UNIQUE,... ) Nedovolí aby dva riadky v tabuľke mali v stĺpci tú istú hodnotu (porovnáva sa operátorom =).
UNIQUE UNIQUE Príklad CREATE TABLE users ( id serial, name varchar(50), email varchar(50) UNIQUE ) users id name email 1 fan123 fan123@gmail.com INSERT INTO users (name, email) VALUES ( bad, fan123@gmail.com ) ERROR: duplicate key value violates unique constraint "users_email_key"
UNIQUE UNIQUE a NULLy Keďže NULL = NULL neplatí, môžeme mať viac riadkov s NULLami v UNIQUE stĺpci CREATE TABLE users ( id serial, name varchar(50), email varchar(50) UNIQUE ) users id name email 1 fan123 NULL 2 johnny NULL
UNIQUE UNIQUE pre skupinu stĺpcov CREATE TABLE názov_tabuľky (..., [CONSTRAINT názov_obmedzenia] UNIQUE (názov_stĺpca_1,..., názov_stĺpca_n),... ) Nedovolí aby dva riadky v tabuľke mali v daných stĺpcoch tie isté hodnoty, t.j. aby sa n-tice tvorené hodnotami uvedených stĺpcov rovnali (porovnáva sa operátorom =).
UNIQUE UNIQUE pre skupinu stĺpcov Príklad Maximálne jedno hodnotenie pre film a používateľa: CREATE TABLE ratings ( user_id integer, film_id integer, rating integer, UNIQUE (user_id, film_id) )
UNIQUE UNIQUE pre skupinu stĺpcov Príklad ratings user_id film_id rating 1 1 10 1 2 10 INSERT INTO ratings (user_id, film_id, rating) VALUES (1, 1, 9) ERROR: duplicate key value violates unique constraint "ratings_user_id_film_id_key"
UNIQUE UNIQUE pre skupinu stĺpcov a NULLy n-tica obsahujúca NULL sa nerovná žiadnej inej môžeme mať viac riadkov s tými istými hodnotami v UNIQUE stĺpcoch, ak jeden z nich je NULL CREATE TABLE ratings ( user_id integer, film_id integer, rating integer, ) UNIQUE (user_id, film_id) ratings user_id film_id rating 1 NULL 10 1 NULL 9
Kombinovanie integritných obmedzení môžeme kombinovať príklad CREATE TABLE films ( id integer, name varchar(50), price integer CONSTRAINT c1 CHECK(price >= 0) NOT NULL CONSTRAINT c2 UNIQUE )
Primárny kľúč Kľúče tabuľky Kľúč tabuľky je množina stĺpcov, podľa ktorých vieme riadky tabuľky jednoznačne identifikovať. users id name email country_id 1 martin martin.josh@gmail.com 1 2 martin martin124@yahoo.com 4 3 sue whatever@mydomain.com 4 {id} je kľúč, {email} je kľúč, {id, email} je kľúč, {name} neidentifikuje riadky jednoznačne
Primárny kľúč Primárny kľúč tabuľka môže mať viac kľúčov, má zmysel vybrať si jeden kľúč a tento používať v aplikácii na identifikovanie riadkov, takýto kľúč budeme volať primárny kľúč
Primárny kľúč Primárny kľúč Integritné obmedzenie Aj keď si povieme, že {id} je primárny kľúč tabuľky users id name email country_id 1 martin martin.josh@gmail.com 1 2 martin martin124@yahoo.com 4 3 sue whatever@mydomain.com 4 pridaním riadku môže {id} prestať byť kľúčom. users id name email country_id 1 martin martin.josh@gmail.com 1 2 martin martin124@yahoo.com 4 3 sue whatever@mydomain.com 4 3 someone my@email.com 6
Primárny kľúč Primárny kľúč Integritné obmedzenie Syntax CREATE TABLE názov_tabuľky (..., názov_stĺpca typ [CONSTRAINT názov_obmedzenia] PRIMARY KEY,... )
Primárny kľúč Primárny kľúč Integritné obmedzenie Príklad CREATE TABLE users ( id INTEGER PRIMARY KEY, name VARCHAR(100), email VARCHAR(100), country_id INTEGER )
Primárny kľúč Primárny kľúč Integritné obmedzenie Je implementivané ako obmedzenie UNIQUE NOT NULL Može byť ale iba jedno CREATE TABLE users ( id INTEGER PRIMARY KEY, email VARCHAR(100) PRIMARY KEY ) ERROR: multiple primary keys for table "users" are not allowed
Primárny kľúč Zložený primárny kľúč Integritné obmedzenie Syntax CREATE TABLE názov_tabuľky (..., [CONSTRAINT názov_obmedzenia] PRIMARY KEY (názov_stĺpca_1,..., názov_stlĺpca_n), )
Primárny kľúč Zložený primárny kľúč Integritné obmedzenie Príklad CREATE TABLE ratings ( user_id integer, film_id integer, rating integer, PRIMARY KEY (user_id, film_id) )
Cudzí kľúč Cudzí kľúč Cudzí kľúč je množina stĺpcov tabuľky, ktorou sa daná tabuľka odkazuje na primárny kľúč inej tabuľky countries id name 1 Slovakia 4 Czech Republic {id} je primárnym kľúčom tabuľky users users id name email country_id 1 martin martin.josh@gmail.com 1 2 martin martin124@yahoo.com 4 3 sue whatever@mydomain.com 4 {country_id} je cudzím kľúčom tabuľky user a odkazuje na primárny kľúč {id} tabuľky country
Cudzí kľúč Cudzí kľúč Integritné obmedzenie Štandarne nám nič nebráni sa odkazovať na neexistujúci riadok. countries id name 1 Slovakia 4 Czech Republic users id name email country_id 1 martin martin.josh@gmail.com 1 2 martin martin124@yahoo.com 4 3 sue whatever@mydomain.com 5
Cudzí kľúč Cudzí kľúč Integritné obmedzenie Syntax CREATE TABLE názov_tabuľky (..., názov_stĺpca typ [CONSTRAINT názov_obmedzenia] REFERENCES názov_referencovanej_tabuľky [(názov_referencovaného_stĺpca)],... )
Cudzí kľúč Cudzí kľúč Integritné obmedzenie Príklad CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) )
Cudzí kľúč Cudzí kľúč Referencovaný stĺpec musí byť aspoň UNIQUE CREATE TABLE countries ( id INTEGER, name VARCHAR(100) ) CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) ) ERROR: there is no unique constraint matching given keys for referenced table "countries"
Cudzí kľúč Cudzí kľúč Referencovaný stĺpec musí byť aspoň UNIQUE CREATE TABLE countries ( id INTEGER UNIQUE, name VARCHAR(100) ) CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) )
Cudzí kľúč Cudzí kľúč Integeritné obmedzenie Ak referencovaný stĺpec je primárnym kľúčom referencovanej tabuľky, nemusíme ho uviesť. CREATE TABLE countries ( id INTEGER PRIMARY KEY, name VARCHAR(100), ) CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries )
Cudzí kľúč Cudzí kľúč Integritné obmedzenie Teraz po vykonaní príkazu countries id name 1 Slovakia 4 Czech Republic INSERT INTO users (user_id, name, email, country_id) VALUES (4, alice, alice@alice.sk, 5) dostaneme chybu ERROR: DETAIL: insert or update on table "users" violates foreign key constraint "users_country_id_fkey" Key (country_id)=(5) is not present in table "countries"
Cudzí kľúč Cudzí kľúč môže byť NULL Toto prejde bez problémov countries id name 1 Slovakia 4 Czech Republic INSERT INTO users (user_id, name, email, country_id) VALUES (4, alice, alice@alice.sk, NULL)
Cudzí kľúč Zložený cudzí kľúč Integritné obmedzenie Syntax CREATE TABLE názov_tabuľky (..., [CONSTRAINT názov_obmedzenia] FOREIGN KEY (názov_stĺpca_1,..., názov_stĺpca_n) REFERENCES názov_referencovanej_tabuľky [(názov_ref_stĺpca_1,..., názov_ref_stĺpca_n)],... )
Cudzí kľúč Zložený cudzí kľúč Integritné obmedzenie Príklad Majme tabuľku so zloženým primárnym kľúčom (user_id, film_id) ratings user_id film_id name 1 1 10 1 2 8 A chceme vytvoriť tabuľku komentárov hodnotení: CREATE TABLE comments ( comment_id INTEGER PRIMARY KEY, rating_user_id INTEGER, rating_film_id INTEGER, FOREIGN KEY (rating_user_id, rating_film_id) REFERENCES ratings (user_id, film_id), comment VARCHAR(255) )
Cudzí kľúč Cudzí kľúč Referencovať sa musíme na existujúce stĺpce CREATE TABLE countries ( name VARCHAR(100) ) CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) ) ERROR: column "id" referenced in foreign key constraint does not exist
Cudzí kľúč Cudzí kľúč Cyklická závislosť Problém departments department_id department_name manager_id employees employee_id first_name last_name department_id department_id REFERENCES departments(department_id) manager_id REFERENCES employees(employee_id) Keďže tabuľky nemôžeme vytvoriť naraz, doterajší spôsob vytvárania cudzích kľúčov neumožní vytvoriť jeden z cudzích kľúčov
Cudzí kľúč Cudzí kľúč Cyklická závislosť Riešenie vytvor tabuľky bez cudzích kľúčov, cudzie kľúče pridaj pomocou príkazu ALTER TABLE
Cudzí kľúč Cudzí kľúč ALTER TABLE Syntax ALTER TABLE názov_tabuľky ADD [CONSTRAINT názov_obmedzenia] FOREIGN KEY (názov_stĺpca_1,..., názov_stĺpca_n) REFERENCES názov_referencovanej_tabuľky [(názov_ref_stĺpca_1,..., názov_ref_stĺpca_n)]
Cudzí kľúč Cudzí kľúč Cyklická závislosť Riešenie CREATE TABLE employees ( employee_id INTEGER PRIMARY KEY, first_name VARCHAR(100), last_name VARCHAR(100), department_id INTEGER ) CREATE TABLE departments ( department_id INTEGER PRIMARY KEY, department_name VARCHAR(100), manager_id INTEGER REFERENCES employees (employee_id) ) ALTER TABLE employees ADD FOREIGN KEY (department_id) REFERENCES departments (department_id)
Cudzí kľúč Cudzí kľúč Cyklická závislosť Výnimka Referencovaný stĺpec nemusí ešte existovať, ak je to stĺpec tabuľky, ktorú práce vytvárame CREATE TABLE employees ( employee_id INTEGER PRIMARY KEY, first_name VARCHAR(100), last_name VARCHAR(100), manager_id REFERENCES employees(employee_id) ) úspešne prebehne
Cudzí kľúč CREATE script je to postupnosť prevažne CREATE a ALTER príkazov, ktorých cieľom je vytvoríť databázu s požadovanou štruktúrou
Cudzí kľúč Referenčná integrita Existujúce hodnoty Stĺpec môže nadobúdať iba hodnoty, ktoré existujú v referencovanom stĺpci referencovanej tabuľky alebo NULL (to sme si už ukázali)
Cudzí kľúč Referenčná integrita - Manazanie tabuľky Nemôžeme zmazať tabuľku, ak na ňu odkazuje cudzí kľúč inej tabuľky
Cudzí kľúč Referenčná integrita Mazanie tabuľky CREATE TABLE countries ( id INTEGER PRIMARY KEY, name VARCHAR(100) ) CREATE TABLE users ( id INTEGER PRIMARY KEY, name VARCHAR(100), country_id INTEGER REFERENCES countries (country_id) ) DROP TABLE countries ERROR: cannot drop table countries because other objects depend on it
Cudzí kľúč DROP TABLE CASCADE DROP TABLE názov_tabuľky CASCADE Zmaže tabuľku a aj všetky objekty, ktoré na ňu odkazujú: integritné obmedzenia typu cudzí kľúč, pohľady,... Tabuľka samotná, ktorá sa na ňu odkazovala, a aj jej stĺpce ostanú. Zmažú sa len jej integritné obmedzenia.
Cudzí kľúč Referenčná integrita Mazanie riadkov Nemôžeme zmazať riadok, ak na neho odkazuje iný riadok
Cudzí kľúč Referenčná integrita Mazanie riadkov Majme tabuľky countries id name 1 Slovakia 4 Czech Republic Predpokladáme, že country_id REFERENCES countries (id) Po spustení príkazu DELETE FROM countries WHERE id = 1 users id name email country_id 8 martin martin.josh@ 1 9 martin martin124@ 4 dostaneme chybu ERROR: update or delete on table "countries" violates foreign key constraint "users_countries_id_fkey" on table "users" DETAIL: Key (id)=(1) is still referenced from table "users"
Cudzí kľúč ON DELETE Pri vytváraní cudzieho kľúča môžeme stanoviť, čo sa má diať v prípade, že referencovaný riadok zmažeme.... REFERENCES názov_referencovanej_tabuľky [(názov_ref_stĺpca_1,..., názov_ref_stĺpca_n)] ON DELETE názov_akcie názov_akcie môže byť jedno z nasledovných: CASCADE SET NULL SET DEFAULT
Cudzí kľúč ON DELETE CASCADE Zmaže aj riadky odkazujúce na mazaný riadok CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) ON DELETE CASCADE )
Cudzí kľúč ON DELETE CASCADE countries id name 1 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 1 9 martin martin124@ 4 DELETE FROM countries WHERE id = 1 countries id name 4 Czech Republic users id name email country_id 9 martin martin124@ 4
Cudzí kľúč ON DELETE SET NULL Cudzí kľúč v odkazujúcich sa riadkoch nastaví na NULL Ak má cudzí kľúč obmedzenie NOT NULL, dostaneme chybu CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) ON DELETE SET NULL )
Cudzí kľúč ON DELETE SET NULL countries id name 1 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 1 9 martin martin124@ 4 DELETE FROM countries WHERE id = 1 countries id name 4 Czech Republic users id name email country_id 8 martin martin.josh@ NULL 9 martin martin124@ 4
Cudzí kľúč ON DELETE SET DEFAULT cudzí kľúč v odkazujúcich riadkoch nastaví na DEFAULT hodnotu Ak ale DEFAULT hodnota v referencovanej tabuľke neexistuje, dostaneme chybu CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER DEFAULT 4 REFERENCES countries(id) ON DELETE SET DEFAULT )
Cudzí kľúč ON DELETE SET DEFAULT countries id name 1 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 1 9 martin martin124@ 4 DELETE FROM countries WHERE id = 1 countries id name 4 Czech Republic users id name email country_id 8 martin martin.josh@ 4 9 martin martin124@ 4
Cudzí kľúč ON UPDATE Umožňuje povedať, čo sa má stať ak referencovanú hodnotu zmeníme na inú... REFERENCES názov_referencovanej_tabuľky [(názov_ref_stĺpca_1,..., názov_ref_stĺpca_n)] ON UPDATE názov_akcie názov_akcie môže byť jedno z nasledovných: CASCADE SET NULL SET DEFAULT
Cudzí kľúč ON UPDATE CASCADE Zmení cudzie kľúče v referencujúcich sa riadkoch CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) ON UPDATE CASCADE )
Cudzí kľúč ON UPDATE CASCADE countries id name 1 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 1 9 martin martin124@ 4 UPDATE countries SET id = 50 WHERE id = 1 countries id name 50 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 50 9 martin martin124@ 4
Cudzí kľúč ON UPDATE SET NULL Cudzí kľúč v odkazujúcich sa riadkoch nastaví na NULL Ak má cudzí kľúč obmedzenie NOT NULL, dostaneme chybu CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER REFERENCES countries(id) ON UPDATE SET NULL )
Cudzí kľúč ON UPDATE SET NULL countries id name 1 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 1 9 martin martin124@ 4 UPDATE countries SET id = 50 WHERE id = 1 countries id name 50 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ NULL 9 martin martin124@ 4
Cudzí kľúč ON UPDATE SET DEFAULT cudzí kľúč v odkazujúcich riadkoch nastaví na DEFAULT hodnotu Ak ale DEFAULT hodnota v referencovanej tabuľke neexistuje, dostaneme chybu CREATE TABLE users ( id INTEGER, name VARCHAR(100), email VARCHAR(100), country_id INTEGER DEFAULT 4 REFERENCES countries(id) ON UPDATE SET DEFAULT )
Cudzí kľúč ON UPDATE SET DEFAULT countries id name 1 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 1 9 martin martin124@ 4 UPDATE countries SET id = 50 WHERE id = 1 countries id name 50 Slovakia 4 Czech Republic users id name email country_id 8 martin martin.josh@ 4 9 martin martin124@ 4
UPSERT Section 3 UPSERT
UPSERT UPSERT motivácia Chceme uchovávať nastavenia vo formáte kľúč-hodnota. settings key value timeout 30 email admin@domain.org Chceme vložiť riadok pre kľúč timeout, no keď riadok pre tento kľúč už existuje, chceme ho aktualizovať.
UPSERT INSERT ON CONFLICT DO UPDATE INSERT INTO... ON CONFLICT (c_názov_stĺpca_1,..., c_názov_stĺpca_n) DO UPDATE SET názov_stĺpca_1 = výraz_1,... názov_stĺpca_m = výraz_m pokúsi sa o vloženie riadkov ak vloženie neprebehne kvôli porušeniu UNIQUE obmedzenia na daných stĺpcoch, vykoná sa UPDATE na konfliktných riadkoch, riadky, na ktorých konflikt nebol sú nezmenené
UPSERT UPSERT riešenie settings key value timeout 30 email admin@domain.org Predpokladajme, že stĺpec key je UNIQUE. INSERT INTO settings (key, value) VALUES ( timeout, 60 ) ON CONFLICT (key) DO UPDATE SET value = 60 settings key value timeout 60 email admin@domain.org
UPSERT Pseudotabuľka EXCLUDED Na neakceptovaný riadok sa môžeme odkázať pomocou pseudotabuľky EXCLUDED INSERT INTO settings (key, value) VALUES ( timeout, 60 ) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
UPSERT Pseudotabuľka EXCLUDED Vďaka pseudotabuľke EXCLUDED môžeme UPSERTovať viac riadkov naraz INSERT INTO settings (key, value) VALUES ( timeout, 60 ), ( email, admin@newdomain.org ) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
UPSERT Pseudotabuľka EXCLUDED settings key value timeout 30 email admin@domain.org INSERT INTO settings (key, value) VALUES ( timeout, 60 ), ( email, admin@newdomain.org ) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value settings key value timeout 60 email admin@newdomain.org
UPSERT DO UPDATE WHERE podmienka Pomocou WHERE podmineky môžeme ďalej obmedziť, ktoré riadky povolíme aktualizovať INSERT INTO settings (key, value) VALUES ( timeout, 60 ), ( email, admin@newdomain.org ) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value WHERE settings.read_only = FALSE
UPSERT DO UPDATE WHERE podmienka settings key value read_only timeout 30 false email admin@domain.org true INSERT INTO settings (key, value) VALUES ( timeout, 60 ), ( email, admin@newdomain.org ) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value WHERE settings.read_only = FALSE settings key value read_only timeout 60 false email admin@domain.org true
UPSERT INSERT ON CONFLICT DO NOTHING INSERT INTO... ON CONFLICT (c_názov_stĺpca_1,..., c_názov_stĺpca_n) DO NOTHING pokúsi sa o vloženie riadkov ak vloženie neprebehne kvôli porušeniu UNIQUE obmedzenia na daných stĺpcoch, nič sa nedeje a pokračujeme pokusom o vloženie nasledovného riadku čiže konfliktné riadky sa nevložia a príkaz skončí úspechom
UPSERT Koniec Koniec