Politechnika Gdańska, międzywydziałowy kierunek INŻYNIERIA BIOMEDYCZNA. Instrukcja do laboratorium z przedmiotu: Bazy danych. Laboratorium nr 3.

Podobne dokumenty
Politechnika Gdańska, międzywydziałowy kierunek INŻYNIERIA BIOMEDYCZNA. Instrukcja do laboratorium z przedmiotu: Bazy danych. Laboratorium nr 3.

Politechnika Gdańska, międzywydziałowy kierunek INŻYNIERIA BIOMEDYCZNA. Instrukcja do laboratorium z przedmiotu: Bazy danych. Laboratorium nr 2.

Wykład 5. SQL praca z tabelami 2

Paweł Rajba

Laboratorium nr 4. Temat: SQL część II. Polecenia DML

P o d s t a w y j ę z y k a S Q L

Odnawialne Źródła Energii I rok. Tutorial PostgreSQL

Politechnika Gdańska, międzywydziałowy kierunek INŻYNIERIA BIOMEDYCZNA. Instrukcja do laboratorium z przedmiotu: Bazy danych. Laboratorium nr 4.

Język SQL, zajęcia nr 2

Wykład 6. SQL praca z tabelami 3

Ćwiczenia laboratoryjne nr 11 Bazy danych i SQL.

Informatyka (5) SQL. dr inż. Katarzyna Palikowska Katedra Transportu Szynowego p. 4 Hydro

SQL (ang. Structured Query Language)

Bazy danych. Wykład IV SQL - wprowadzenie. Copyrights by Arkadiusz Rzucidło 1

Wykład 05 Bazy danych

Przykłady najlepiej wykonywać od razu na bazie i eksperymentować z nimi.

Język SQL, zajęcia nr 1

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

LAB 3 (część 1 Projektu)

Relacyjne bazy danych. Podstawy SQL

Plan bazy: Kod zakładający bazę danych: DROP TABLE noclegi CASCADE; CREATE TABLE noclegi( id_noclegu SERIAL NOT NULL,

Aby uruchomić program klienta i połączyć się z serwerem, należy komendę:

Przykładowa baza danych BIBLIOTEKA

Wykład 8. SQL praca z tabelami 5

CREATE DATABASE ksiegarnia_internetowa DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

BAZA DANYCH SIECI HOTELI

Bazy danych. Polecenia SQL

Relacji między tabelami klucze obce. Schemat bazy danych, wczytanej z pliku create_tables.sql. Klucz obcy jako ograniczenie dla kolumny

Literatura: SQL Ćwiczenia praktyczne Autor: Marcin Lis Wydawnictwo: Helion. Autor: Joanna Karwowska

Wprowadzenie do BD Operacje na bazie i tabelach Co poza zapytaniami? Algebra relacji. Bazy Danych i Systemy informacyjne Wykład 2.

Komunikacja z bazą danych psql

Bazy danych 7. SQL podstawy

Autor: Joanna Karwowska

Relacyjne bazy danych. Podstawy SQL

strukturalny język zapytań używany do tworzenia i modyfikowania baz danych oraz do umieszczania i pobierania danych z baz danych

Wprowadzenie do projektowania i wykorzystania baz danych Relacje

Instrukcje DML INSERT, UPDATE, DELETE. COPY

Podstawy technologii WWW

Bazy Danych i Usługi Sieciowe

3 Przygotowali: mgr inż. Barbara Łukawska, mgr inż. Maciej Lasota

Projektowanie systemów baz danych

Informatyka sem. III studia inżynierskie Transport 2018/19 LAB 2. Lab Backup bazy danych. Tworzenie kopii (backup) bazy danych

Bazy danych i usługi sieciowe

Grupowanie i funkcje agregujące

Bazy danych 10. SQL Widoki

Podstawowe zapytania SELECT (na jednej tabeli)

Struktura drzewa w MySQL. Michał Tyszczenko

Bazy danych. dr inż. Arkadiusz Mirakowski

Bazy danych. Bazy danych. Podstawy języka SQL. Dr inż. Paweł Kasprowski.

Bazy danych 6. Klucze obce. P. F. Góra

Bazy danych. Dr inż. Paweł Kasprowski

Tworzenie tabel. Bazy danych - laboratorium, Hanna Kleban 1

Hurtownia Świętego Mikołaja projekt bazy danych

Wybór EUROPEAN będzie rozpoznawał dzień przed miesiącem, natomiast US miesiąc przed dniem.

D D L S Q L. Co to jest DDL SQL i jakie s jego ą podstawowe polecenia?

Kurs. Podstawy MySQL

Bazy Danych - Instrukcja do Ćwiczenia laboratoryjnego nr 8

BAZY DANYCH. CREATE TABLE dbo.wydzialy (ID INT, Akronim VARCHAR(4) NOT NULL, Wydzial VARCHAR(30) NOT NULL, CONSTRAINT Kluczyk PRIMARY KEY(ID) )

Język DML. Instrukcje DML w różnych implementacjach SQL są bardzo podobne. Podstawowymi instrukcjami DML są: SELECT INSERT UPDATE DELETE

opisuje nazwy kolumn, wyrażenia arytmetyczne, funkcje nazwy tabel lub widoków warunek (wybieranie wierszy)

Ref. 7 - Język SQL - polecenia DDL i DML

Wykład 5: PHP: praca z bazą danych MySQL

Podstawy języka SQL. SQL Structured Query Languagestrukturalny

Podstawy języka SQL. standardy SQL formułowanie zapytań operacje na strukturach danych manipulowanie danymi. Bazy danych s.5-1

Bazy danych SQL Server 2005

Wykład 4. SQL praca z tabelami 1

Bazy danych. Bazy danych. Zapytania SELECT. Dr inż. Paweł Kasprowski.

SQL Server i T-SQL w mgnieniu oka : opanuj język zapytań w 10 minut dziennie / Ben Forta. Gliwice, Spis treści

Tworzenie tabeli przez select CREATE TABLE PRAC2 AS SELECT P.NAZWISKO, Z.NAZWA FROM PRAC P NATURAL JOIN ZESP Z

Rozdział 17. Zarządzanie współbieżnością zadania dodatkowe

Języki programowania wysokiego poziomu. PHP cz.4. Bazy danych

Wstęp 5 Rozdział 1. Podstawy relacyjnych baz danych 9

Systemy GIS Tworzenie zapytań w bazach danych

Bazy Danych. SQL Podstawy języka III: powtórzenie. Krzysztof Regulski WIMiIP, KISiM, B5, pok. 408

Blaski i cienie wyzwalaczy w relacyjnych bazach danych. Mgr inż. Andrzej Ptasznik

Widok Connections po utworzeniu połączenia. Obszar roboczy

Wykład 5 funkcje i procedury pamiętane widoki (perspektywy) wyzwalacze

Programowanie MSQL. show databases; - pokazanie jakie bazy danych są dostępne na koncie

Zadania z SQLa (MS SQL Server)

1. Połączenie z bazą danych. W wybranym edytorze tworzymy plik sqltest.py i umieszczamy w nim poniższy kod. #!/usr/bin/python3 import sqlite3

1 Zaznacz poprawne stwierdzenia dotyczące grup plików (filegroup) możemy określić do której grupy plików trafi

ACESS- zadania z wykorzystaniem poleceń SQL

BAZY DANYCH wprowadzenie do języka SQL. Opracował: dr inż. Piotr Suchomski

Programowanie w SQL procedury i funkcje. UWAGA: Proszę nie zapominać o prefiksowaniu nazw obiektów ciągiem [OLIMP\{nr indeksu}] Funkcje użytkownika

Politechnika Gdańska, międzywydziałowy kierunek INŻYNIERIA BIOMEDYCZNA SKRYPT DO LABORATORIUM BAZY DANYCH. autor: dr inż. Adam Bujnowski.

PHP: bazy danych, SQL, AJAX i JSON

PRZESTRZENNE BAZY DANYCH WYKŁAD 2

77. Modelowanie bazy danych rodzaje połączeń relacyjnych, pojęcie klucza obcego.

Konstruowanie Baz Danych SQL UNION, INTERSECT, EXCEPT

Przestrzenne bazy danych Podstawy języka SQL

Bazy danych dla producenta mebli tapicerowanych. Bartosz Janiak Marcin Sikora Wrocław r.

Bazy danych - Materiały do laboratoriów VIII

Monika Sychla Daniel Smolarek Projekt bazy danych

Instytut Mechaniki i Inżynierii Obliczeniowej fb.com/groups/bazydanychmt/

Paweł Cieśla. Dokumentacja projektu

E.14 Bazy Danych cz. 18 SQL Funkcje, procedury składowane i wyzwalacze

Imię i Nazwisko Data Ocena. Laboratorium 7

Wdrożenie modułu płatności eservice. dla systemu Magento

Transkrypt:

Instrukcja do laboratorium z przedmiotu: Bazy danych Laboratorium nr 3. Metody zarządzania i analizy danych Opracował A. Bujnowski 2010-03-08 Projekt Przygotowanie i realizacja kierunku inżynieria biomedyczna studia międzywydziałowe współfinansowany ze środków Unii Europejskiej w ramach Europejskiego Funduszu Społecznego.

1. Cele laboratorium zapoznanie się z metodami wprowadzania, usuwania i modyfikacji danych. Instrukcje warunkowe. Zapytania złożone i funkcje agregacji 2. Przykładowa baza danych: Jako przykład bazy danych posłuży nam przygotowana uprzednio i nieco zmodyfikowana struktura bazy dla wypożyczalni płyt DVD. Na potrzeby dzisiejszego laboratorium do poprzednio zaprojektowanej struktury tabel dołączymy jeszcze jedną: gatunek oraz dodamy atrybut cena dla każdej płyty. Zakładamy, że płyta należy do jednego gatunku. Kod w języku SQL zakładający bazę danych podana jest poniżej, wytłuszczonym drukiem pokazano zmiany w stosunku do poprzedniej wersji CREATE TABLE klient ( imie varchar(20) not null, nazwisko varchar(40) not null, nr_dowodu char(10), id_klienta serial primary key); CREATE TABLE gatunek( nazwa varchar(30) not null, id_gatunku serial PRIMARY KEY ); CREATE TABLE plyta( tytul varchar(40) not null, numer serial primary key, cena numeric(4,2), gatunek integer REFERENCES gatunek ON DELETE SET NULL ON UPDATE CASCADE); CREATE TABLE wypozyczenie( kto_wypozyczyl int not null REFERENCES klient ON DELETE RESTRICT ON UPDATE RESTRICT, 2

co_wypozyczyl int not null REFERENCES plyta ON DELETE RESTRICT ON UPDATE CASCADE, data_wypozyczenia timestamp default now(), data_zwrotu timestamp, primary key(kto_wypozyczyl, co_wypozyczyl, data_wypozyczenia) ); CREATE TABLE jest_pracownikiem( rabat int, id_klienta int primary key references klient); Dla ujednolicenia sposobu pracy w tym ćwiczeniu, po zalogowaniu do serwera bazy.eti.pg.gda.pl usuń poprzednią bazę poleceniem: dropdb lab2_login gdzie login to Twój login do systemu. Następnie załóż nową bazę o nazwie jak poprzednio poleceniem: createdb lab2_login Teraz przygotuj plik tekstowy z definicją poleceń zakładających bazę danych: mcedit baza3.sql Wypełnij zawartość tego pliku poleceniami z zaprezentowanego wyżej listingu. Połącz się ze swoją bazą danych: psql lab2_login Wczytaj instrukcje z pliku baza1.sql: \i baza3.sql lab2_bujnows=# \i baza3.sql psql:baza3.sql:5: NOTICE: CREATE TABLE will create implicit sequence "klient_id_klienta_seq" for "serial" column "klient.id_klienta" psql:baza3.sql:5: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "klient_pkey" for table "klient" CREATE TABLE psql:baza3.sql:9: NOTICE: CREATE TABLE will create implicit sequence "plyta_numer_seq" for "serial" column "plyta.numer" psql:baza3.sql:9: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "plyta_pkey" for table "plyta" CREATE TABLE psql:baza3.sql:12: ERROR: syntax error at or near "cena" at character 2 3

psql:baza3.sql:19: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "wypozyczenie_pkey" for table "wypozyczenie" CREATE TABLE psql:baza3.sql:23: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "jest_pracownikiem_pkey" for table "jest_pracownikiem" CREATE TABLE psql:baza3.sql:28: NOTICE: CREATE TABLE will create implicit sequence "gatunek_id_gatunku_seq" for "serial" column "gatunek.id_gatunku" psql:baza3.sql:28: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gatunek_pkey" for table "gatunek" CREATE TABLE lab2_bujnows=# W tej chwili struktura Twojej bazy danych jest gotowa do pracy. Na początku poznamy kilka poleceń na uzupełnienie jej danymi. Na początku jednak sprawdź, czy twoja baza przechowuje właściwą strukturę tabel: \d List of relations Schema Name Type Owner --------+------------------------+----------+--------- public gatunek table bujnows public gatunek_id_gatunku_seq sequence bujnows public jest_pracownikiem table bujnows public klient table bujnows public klient_id_klienta_seq sequence bujnows public plyta table bujnows public plyta_numer_seq sequence bujnows public wypozyczenie table bujnows (8 rows) \d klient Table "public.klient" Column Type Modifiers ------------+----------------------- +---------------------------------------------------------------- imie character varying(20) not null nazwisko character varying(40) not null nr_dowodu character(10) id_klienta integer not null default nextval('public.klient_id_klienta_seq'::text) Indexes: "klient_pkey" primary key, btree (id_klienta) \d plyta Table "public.plyta" Column Type Modifiers ---------+----------------------- +---------------------------------------------------------- tytul character varying(40) not null numer integer not null default nextval('public.plyta_numer_seq'::text) cena numeric(4,2) gatunek integer Indexes: 4

"plyta_pkey" primary key, btree (numer) Foreign-key constraints: "$1" FOREIGN KEY (gatunek) REFERENCES gatunek(id_gatunku) \d gatunek Table "public.gatunek" Column Type Modifiers ------------+----------------------- +----------------------------------------------------------------- nazwa character varying(30) not null id_gatunku integer not null default nextval('public.gatunek_id_gatunku_seq'::text) Indexes: "gatunek_pkey" primary key, btree (id_gatunku) \d jest_pracownikiem Table "public.jest_pracownikiem" Column Type Modifiers ------------+---------+----------- rabat integer id_klienta integer not null Indexes: "jest_pracownikiem_pkey" primary key, btree (id_klienta) Foreign-key constraints: "$1" FOREIGN KEY (id_klienta) REFERENCES klient(id_klienta) \d wypozyczenie Table "public.wypozyczenie" Column Type Modifiers ----------------+-----------------------------+------------------------ kto_wypozyczyl integer not null co_wypozyczyl integer not null d_wypozyczenia timestamp without time zone not null default now() d_zwrotu timestamp without time zone Indexes: "wypozyczenie_pkey" primary key, btree (kto_wypozyczyl, co_wypozyczyl, d_wypozyczenia) Foreign-key constraints: "$1" FOREIGN KEY (kto_wypozyczyl) REFERENCES klient(id_klienta) ON UPDATE RESTRICT ON DELETE RESTRICT "$2" FOREIGN KEY (co_wypozyczyl) REFERENCES plyta(numer) ON UPDATE CASCADE ON DELETE RESTRICT Jeżeli którakolwiek z tabel nie została założona lub jej struktura (poza właścicielem tabeli - owner) jest inna niż ta, pokazana w instrukcji dokonaj niezbędnych poprawek. Może się przydać polecenie DROP TABLE lub ALTER TABLE. 3. Wstawianie danych do tabel. Na poprzednich zajęciach wprowadzone instrukcja wprowadzania danych do bazy danych INSERT INTO tabela VALUES. Sprawdźmy jeszcze raz jak zadziałają poniższe instrukcje: 5

INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Jan','Kowalski','DB230398'); Sprawdź również uproszczoną metodę wprowadzania danych do takiej tabeli: INSERT INTO klient VALUES ('Anna','Nowak'); INSERT INTO klient VALUES ('Ewa','Zielińska','DB232343'); Możliwe jest też dodawanie z wymuszeniem własnej wartości id_klienta ale jest to niezalecane. Sprawdź dlaczego. Odpowiedzią niech będzie poniższy fragment kodu: INSERT INTO klient (imie,nazwisko,nr_dowodu,id_klienta) VALUES ('Jan','Kowal','DB130398',1); Powyższe zapytanie nie powiedzie się, gdyż próbujemy użyć istniejącego id_klienta ponownie. INSERT INTO klient (imie,nazwisko,nr_dowodu,id_klienta) VALUES ('Jan','Kowal','DB130398',1); ERROR: duplicate key violates unique constraint "klient_pkey" Ale możemy poprawnie dodać klienta, z innym id_klienta niż już użyte: INSERT INTO klient (imie,nazwisko,nr_dowodu,id_klienta) VALUES ('Janusz','Kowalski','DB210398',4); INSERT INTO klient (imie,nazwisko,nr_dowodu,id_klienta) VALUES ('Janusz','Kowalski','DB210398',4); Problem pojawi się przy próbie dodania nowego klienta z automatycznym id_klienta: INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Maria','Kowalska','DB230300'); lab2_bujnows=# INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Maria','Kowalska','DB230300'); ERROR: duplicate key violates unique constraint "klient_pkey" lab2_bujnows=# select * from klient; imie nazwisko nr_dowodu id_klienta --------+-----------+------------+------------ Jan Kowalski DB230398 1 Anna Nowak 2 Ewa Zielińska DB232343 3 Janusz Kowalski DB210398 4 (4 rows) Ale w tym przypadku ponowne wykonanie tego samego polecenia już zadziała poprawnie (bo system przyjmie id_klienta jako 5): 6

lab2_bujnows=# INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Maria','Kowalska','DB230300'); INSERT 80519489 1 lab2_bujnows=# select * from klient; imie nazwisko nr_dowodu id_klienta --------+-----------+------------+------------ Jan Kowalski DB230398 1 Anna Nowak 2 Ewa Zielińska DB232343 3 Janusz Kowalski DB210398 4 Maria Kowalska DB230300 5 (5 rows) lab2_bujnows=# Dlatego należy zachowywać ostrożność przy wpisywaniu wartości do kolumn o typie serial lub auto_increment (MySQL). W przypadku konieczności załadowania do bazy danych większej ilości danych przydatne może być wykorzystanie skryptów podobnych do tych, które wykorzystywane były przy zakładaniu bazy danych. Opuść bazę danych (polecenie \q) i wyedytuj plik tekstowy jak załączono poniżej: mcedit klienci.sql INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Adam','Wisniak','AFF456432'); INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Adrian','Wicki','AFF456433'); INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Iwona','Wisniak','AFF456434'); INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Jolanta','Ponicka','AFF456452'); INSERT INTO klient (imie,nazwisko,nr_dowodu) VALUES ('Adam','Brzeski','AFG456432'); INSERT INTO klient(imie,nazwisko,nr_dowodu) VALUES ('Adam','Irenowski','AFF400432'); INSERT INTO klient(imie,nazwisko,nr_dowodu) VALUES ('Jolanta','Wisniak','AFF454432'); Zapisz plik (F2) i opuść edytor (F10). Połącz się ze swoją bazą: psql lab2_login Wczytaj skrypt zewnętrzny poleceniem \i klienci.sql. 7

lab2_bujnows=# \i klienci.sql INSERT 80519490 1 INSERT 80519491 1 INSERT 80519492 1 INSERT 80519493 1 INSERT 80519494 1 INSERT 80519495 1 INSERT 80519496 1 lab2_bujnows=# select * from klient; imie nazwisko nr_dowodu id_klienta ---------+-----------+------------+------------ Jan Kowalski DB230398 1 Anna Nowak 2 Ewa Zielińska DB232343 3 Janusz Kowalski DB210398 4 Maria Kowalska DB230300 5 Adam Wisniak AFF456432 6 Adrian Wicki AFF456433 7 Iwona Wisniak AFF456434 8 Jolanta Ponicka AFF456452 9 Adam Brzeski AFG456432 10 Adam Irenowski AFF400432 11 Jolanta Wisniak AFF454432 12 (12 rows) Jak widać możliwe jest stosunkowo szybkie wczytywanie takich danych. Czasami jednak problematyczne może okazać się wyświetlanie potwierdzeń wczytywanych danych, lub konieczność przygotowania pliku z kompletną składnią w SQL-u. Większość systemów zarządzania bazami danych przychodzi tutaj z pomocą udostępniając interfejs do pobierania danych z pliku. Plik powinien być jednak odpowiednio sformatowany. W PostgreSQL poleceniem takim jest \copy: Copy działa w obie strony pozwala na eksport danych z tabeli do pliku (COPY TO) i z pliku do tabeli (COPY FROM). W tej chwili zajmiemy się tylko importem danych do bazy danych. Plik, który zawiera dane do wgrania powinien być odpowiednio przygotowany. Wgrywając dane do tabeli musi on składać się z wierszy, z których każde pole zawiera dokładnie taką samą ilość separatorów pól. Dwa kolejne separatory pól oznaczają wartość typu NULL. Ostatnia linia nie może składać się z pustych znaków itd. Domyślnym separatorem pól jest znak tabulacji, zaś wierszy znak końca linii. Przygotujmy zatem kilka plików wsadowych do wypełnienia gatunków i płyt: W tym celu opuść bazę danych (\q) i przygotuj pliki: mcedit gatunki.txt Zawartość pliku: komedia dramat musical kreskowka thriller sensacyjny przygodowy 8

historyczny fantasy mcedit plyty.txt Zawartość pliku: Shrek 15 Piraci z Karaibow 20 Calineczka 15 Szeregowiec Dolot 10 Constantine 20 Hellboy 15 UWAGA! Ważne jest aby w pliku plyty.txt pomiędzy tytułem a ceną cisnąć TAB a nie kilka spacji!!! Teraz spróbuj wczytać tak przygotowane dane z pliku. lab2_bujnows=# \copy gatunek(nazwa) from gatunki.txt lab2_bujnows=# select * from gatunek; nazwa id_gatunku -------------+------------ komedia 1 dramat 2 musical 3 kreskówka 4 thriller 5 sensacyjny 6 przygodowy 7 historyczny 8 fantasy 9 (8 rows) lab2_bujnows=# lab2_bujnows=# \copy plyta(tytul,cena) from plyty.txt lab2_bujnows=# select * from plyta; tytul numer cena gatunek -------------------+-------+-------+--------- Shrek 1 15.00 Piraci z Karaibów 2 20.00 Calineczka 3 15.00 Szeregowiec Dolot 4 10.00 Constantine 5 20.00 Hellboy 6 15.00 (6 rows) 4. Aktualizacja danych w tabeli. W tak przygotowanej bazie danych pojawili się klienci, płyty i gatunki. lab2_bujnows=# select * from klient; 9

imie nazwisko nr_dowodu id_klienta ---------+-----------+------------+------------ Jan Kowalski DB230398 1 Anna Nowak 2 Ewa Zielińska DB232343 3 Janusz Kowalski DB210398 4 Maria Kowalska DB230300 5 Adam Wisniak AFF456432 6 Adrian Wicki AFF456433 7 Iwona Wisniak AFF456434 8 Jolanta Ponicka AFF456452 9 Adam Brzeski AFG456432 10 Adam Irenowski AFF400432 11 Jolanta Wisniak AFF454432 12 (12 rows) lab2_bujnows=# select * from plyta; tytul numer cena gatunek -------------------+-------+-------+--------- Shrek 1 15.00 Piraci z Karaibów 2 20.00 Calineczka 3 15.00 Szeregowiec Dolot 4 10.00 Constantine 5 20.00 Hellboy 6 15.00 (6 rows) lab2_bujnows=# select * from gatunek; nazwa id_gatunku -------------+------------ komedia 1 dramat 2 musical 3 kreskówka 4 thriller 5 sensacyjny 6 przygodowy 7 historyczny 8 fantasy 9 (9 rows) lab2_bujnows=# Płyty nie osiadają przypisanych gatunków. Spróbujmy zatem przypisać gatunki do płyt. Dokonamy tego przy pomocy polecenia UPDATE. Ustawmy zatem gatunek komedia dla płyty Shrek. To co trzeba zrobić to sprawdzić id gatunku dla komedii i wpisać to do bazy danych: lab2_bujnows=# select * from gatunek; nazwa id_gatunku -------------+------------ komedia 1 dramat 2 musical 3 10

kreskówka 4 thriller 5 sensacyjny 6 przygodowy 7 historyczny 8 fantasy 9 (9 rows) lab2_bujnows=# select * from gatunek where nazwa='komedia'; nazwa id_gatunku ---------+------------ komedia 1 (1 row) lab2_bujnows=# update plyta set gatunek=1 where tytul='shrek'; UPDATE 1 lab2_bujnows=# select * from plyta; tytul numer cena gatunek -------------------+-------+-------+--------- Piraci z Karaibów 2 20.00 Calineczka 3 15.00 Szeregowiec Dolot 4 10.00 Constantine 5 20.00 Hellboy 6 15.00 Shrek 1 15.00 1 (6 rows) lab2_bujnows=# Aby wykonać to zadanie musieliśmy wykonać dwa zapytania w pierwszym (SELECT) należało sprawdzić id_gatunku dla komedii i drugie polecenie jest faktycznym uzupełnieniem danych (UPDATE). Można zapisać to przy pomocy pojedynczego zapytania. Sprawdźmy to: update plyta set gatunek=(select id_gatunku from gatunek where nazwa = 'kreskowka') where tytul = 'Calineczka'; W podobny sposób przypisz wszystkie filmy do gatunków: Piraci z Karaibów przygodowy Szeregowiec Dolot kreskówka Constantine - thriller Hellboy - fantasy Zastanów się czy w podobny sposób nie da się zapisać wypożyczeń poleceniem INSERT. Spróbuj zapisać akcję wypożyczenia płyty o tytule Constantine dla pana Jana Kowalskiego. W podobny sposób wypożycz płyty użytkownikom: Adrian Wicki : Hellboy Iwona Wisniak : Szeregowiec Dolot Jolanta Ponicka : Constantine Operatory w SQL 11

W języku SQL istnieje szereg operatorów warunkowych do używania z klauzulą WHERE. Są to: Operatory logiczne AND i OR, używane do połączenia warunków. Przykład : SELECT * FROM klient where id_klienta > 5 AND id_klienta < 10; Operatory porównania: > (większe), < (mniejsze), <= (mniejsze lub równe), >= (większe lub równe), <> (różne) W przypadku ciągów tekstowych można wyróżnić operator LIKE, który pozwala na używanie znaków typu wildcard. Znaki te to '_' - zastępuje dowolny jeden znak oraz '%' - zastępuje dowolny ciąg znaków. Przykład: SELECT * FROM klient WHERE imię LIKE 'Ja%'; Operator BETWEEN.. AND - poznamy go poprzez przykład użycia: SELECT * FROM klient where id_klienta BETWEEN 3 AND 7; Operator IN() pozwala wybrać elementy z listy do porównania wartości: SELECT * FROM klient WERE id IN(3,5,9); SELECT * FROM klient WERE imie IN('Jan','Janina'); Operator IS pozwal na sprawdzenie, czy dana wartość jest NULL lub nie jest: SELECT * FROM wypozyczenie WHERE data_zwrotu IS NULL; SELECT * FROM wypozyczenie WHERE data_zwrotu IS NOT NULL; Operatory i klauzulę WHERE można stosować w instrukcjach SELECT, UPDATE lub DELETE do wybierania zakresu rekordów na których dokonywane będą przewidziane operacje. Dzięki operatorom AND i OR można budować bardzo wyszukane warunki. Zapytania złożone i widoki. Przypomnijmy sobie zapytania złożone z wielu tabel, które przerabialiśmy podczas ostatnich zajęć. Utrwalmy te zapytania w formie widoków. SELECT k.imie, k.nazwisko, p.tytul,w.data_wypozyczenia, w.data_zwrotu FROM klient k, wypozyczenie w, plyta p 12

WHERE k.id_klienta = w.kto_wypozyczyl AND p.numer = w.co_wypozyczyl; SELECT k.imie, k.nazwisko, p.tytul,w.data_wypozyczenia, w.data_zwrotu FROM klient k LEFT JOIN wypozyczenie w ON k.id_klienta = w.kto_wypozyczyl LEFT JOIN plyta p ON p.numer = w.co_wypozyczyl; oraz SELECT k.imie, k.nazwisko, p.tytul,w.data_wypozyczenia, w.data_zwrotu FROM klient k JOIN wypozyczenie w ON k.id_klienta = w.kto_wypozyczyl RIGHT JOIN plyta p ON p.numer = w.co_wypozyczyl; Ale struktura naszej Bazy danych jest dalece bardziej rozbudowana niż spróbujmy zastem wyświetlić zdecydowanie więcej danych. Zanim jednak to uczynimy dodajmy kila rekordów do tablicy jest pracownikiem. Pracownicy w naszej wypożyczalni to Jan Kowalski przysługuje mu rabat 50 % i Adam Brzeski z rabatem 40 %. Zatem dodajmy odpowiednie wpisy do tabeli jest_pracownikiem: INSERT INTO jest_pracownikiem(rabat,id_klienta) VALUES((SELECT id_klienta from klient where imie='jan' AND nazwisko = 'Kowalski'),50); Podobnie zrób dla pana Adama Brzeskiego z rabatem 40%. Teraz przepisz zapytanie w taki sposób, żeby pokazało tabelę wynikową w postaci: imię nazwisko tytuł gatunek data_wypozyczenia data_zwrotu cena rabat Łatwo zauważyć, że w pojedynczym zapytaniu z wykorzystaniem klauzuli WHERE jako warunku łączącego tabele. W wyniku tak postawionego zapytania otrzymamy jedynie wiersze dla wszystkich wypożyczonych płyt które mają gatunek i są wypożyczone przez klienta będącego pracownikiem: SELECT k.imie, k.nazwisko, p.tytul, g.nazwa, w.data_wypozyczenia, w.data_zwrotu, p.cena, j.rabat FROM klient k, plyta p, gatunek g, wypozyczenie w, jest_pracownikiem j WHERE k.id_klienta = w.kto_wypozyczyl and p.numer = w.co_wypozyczyl and k.id_klienta = j.id_klienta and p.gatunek = g.id_gatunku; 13

Przyjrzyjmy się instrukcji warunkowej po klauzuli where: k.id_klienta = w.kto_wypozyczyl and (prawdziwe dla wszystkich wypożyczeń) p.numer = w.co_wypozyczyl and (prawdziwe dla wszystkich wypożyczeń) k.id_klienta = j.id_klienta and (prawdziwe tylko dla pracowników) p.gatunek = g.id_gatunku;(prawdziwe tylko dla płyt z wypełnionym gatunkiem) Widać zatem, że część zapytania z komentarzem na czerwono znacznie ograniczy ilość wyświetlanych wyników. Musimy zatem skorzystać z innej postaci połączenia tabel przy pomocy JOIN. Sprawdźmy zatem jak zadziała połączenie join dla tych 5 tabel: SELECT k.imie, k.nazwisko, p.tytul, g.nazwa, w.data_wypozyczenia, w.data_zwrotu, p.cena, j.rabat FROM jest_pracownikiem j JOIN klient k ON k.id_klienta = j.id_klienta JOIN wypozyczenie w ON k.id_klienta = w.kto_wypozyczyl JOIN plyta p ON p.numer = w.co_wypozyczyl JOIN gatunek g ON p.gatunek = g.id_gatunku; Jak to działa i jaka jest kolejność złączeń? Sprawdźmy to na następującym rysunku, gdzie odpowiednio j oznacza tabelę jest_pracownikiem, k tabelę klient, w tabelę wypozyczeie, p tabelę plyta i g tabelę gatunek: j k w j g Kolejne owale oznaczają tutaj kolejność łączeń. Jako pierwsze połączenie występuje tutaj połączenie klienta z jest_pracownikiem. Tabela jest_pracownikiem występuje po lewej stronie związku, ale powinniśmy w wyniku zapytania wyświetlić wszystkich klientów nawet jeśli nie są pracownikami. Chronimy zatem prawą stronę związku tabel klient i jest_pracownikiem. Sprawdźmy jak zadziała ta część zapytania: SELECT k.imie, k.nazwisko, j.rabat from jest_pracownikiem j JOIN klient k ON k.id_klienta = j.id_klienta; SELECT k.imie, k.nazwisko, j.rabat from jest_pracownikiem j RIGHT JOIN klient k ON k.id_klienta = j.id_klienta; Następną w kolejności złączeń tabelą jest wypożyczenie dołączmy ją do poprzedniego zapytania: 14

SELECT k.imie, k.nazwisko, j.rabat, w.data_wypozyczenia, w.data_zwrotu from jest_pracownikiem j RIGHT JOIN klient k ON k.id_klienta = j.id_klienta JOIN wypozyczenie w ON w.kto_wypozyczyl = k.id_klienta; Łatwo zauważyć, że taki JOIN zepsuje wynik RIGHT JOIN'a z poprzedniego zapytania. Ponieważ to co chcemy chronić jest po lewej stronie związku musimy skorzystać z LEFT JOIN w kolejnym złączeniu. Sprawdźmy to: SELECT k.imie, k.nazwisko, j.rabat, w.data_wypozyczenia, w.data_zwrotu from jest_pracownikiem j RIGHT JOIN klient k ON k.id_klienta = j.id_klienta LEFT JOIN wypozyczenie w ON w.kto_wypozyczyl = k.id_klienta; Podobnie dołączmy płytę i gatunek: SELECT k.imie, k.nazwisko, p.tytul, g.nazwa, w.data_wypozyczenia, w.data_zwrotu, p.cena, j.rabat FROM jest_pracownikiem j RIGHT JOIN klient k ON k.id_klienta = j.id_klienta LEFT JOIN wypozyczenie w ON k.id_klienta = w.kto_wypozyczyl LEFT JOIN plyta p ON p.numer = w.co_wypozyczyl LEFT JOIN gatunek g ON p.gatunek = g.id_gatunku; Utrwalmy podobne do powyższego zapytanie w formie widoku: CREATE VIEW raport1 AS SELECT k.imie ' ' k.nazwisko, p.tytul, g.nazwa, w.data_wypozyczenia, w.data_zwrotu, p.cena, j.rabat FROM jest_pracownikiem j RIGHT JOIN klient k ON k.id_klienta = j.id_klienta LEFT JOIN wypozyczenie w ON k.id_klienta = w.kto_wypozyczyl LEFT JOIN plyta p ON p.numer = w.co_wypozyczyl LEFT JOIN gatunek g ON p.gatunek = g.id_gatunku; Użyliśmy tutaj operatora łączenia ciągów znaków. Pozwala to na połączenie np. imienia i nazwiska klienta tak, aby znalazły się w jednej kolumnie. Dodatkowo wymuszamy zmianę nazwy wyświetlanej kolumny dyrektywą AS. Funkcje agregacji W poprzednim ćwiczeniu pokazana została funkcja, dzięki której można dokonać połączenia ciągu znaków. Istnieje szereg innych funkcji min matematycznych. Sprawdźmy działanie niektórych z 15

nich: SELECT 2+2; SELECT sin(1); SELECT log(numer) FROM plyta; SELECT sin(cena) FROM plyta; Ale istnieją także inne funkcje: SELECT count(*) FROM gatunek; SELECT count(imie) FROM klient; SELECT max(id_klienta) FROM klient; SELECT min(id_klienta) FROM klient; SELECT avg(id_klienta) FROM klient; Te funkcje w odróżnieniu od poprzednich zwracają pojedynczy wynik a operują na grupach krotek. Funkcje takie noszą miano funkcji agregacji, gdyż dokonują analizy na grupie krotek. Gdy wykonamy funkcję sin(id_klienta) to zwróci ona tyle wyników na ilu krotkach się ona wykonała, natomiast funkcje takie jak max(), min(), avg(), variance(), stdev() czy count() zwrócą pojedynczy wynik. Z tymi funkcjami związana jest dodatkowa klauzula zapytania SELECT : GROUP BY. GROUP BY powoduje przestawienie wyników w taki sposób, aby stanowiły one przegrupowaną tabelę względem kryterium. Na tak przegrupowanej tabeli możliwe jest wykonywanie funkcji agregacji i dalsza analiza wyników. Przykładowo chcemy dokonać statystycznego zestawienia imion występujących w tabeli klient: SELECT imię, count(imie) FROM klient GROUP BY imię; Z klauzulą GOUP BY związana jest klauzula HAVING, która działa tak samo jak WHERE dla normalnej wersji SELECT: SELECT imię, count(imie) FROM klient GROUP BY imię HAVING imię < 'J'; W ramach laboratorium pokazane zostały metody manipulowania danymi, operatory, zapytania złożone, funkcje agregacji, klauzula GROUP BY oraz możliwość utrwalania zapytań w formie widoków. Na następnych zajęciach wprowadzone zostaną szerzej funkcje i pokazane metody dalszej analizy danych oraz transakcje. Kopie zapasowe i odzyskiwanie danych W PostgreSQL możliwe jest wykonanie kopii zapasowej bazy danych. Można tego dokonać przy pomocy polecenia systemowego pg_dump nazwabazy. W wyniku działania tego polecenia na 16

ekranie terminala pojawi się kod SQL, który pozwoli na ponowne założenie bazy danych. Przykład: Opuść bazę danych (\q) pg_dump lab2_login Teraz przekierujmy wynik działania polecenia do pliku: pg_dump lab2_login > lab2_login_dump.sql możesz teraz podejrzeć zawartość tego pliku np. przy pomocy edytora mcedit: mcedit lab2_login_dump.sql W tym miejscu połącz się za swoją bazą ponownie i poćwicz usuwanie danych. Spróbuj skasować płyty, gatunki i wypożyczenia. Teraz możliwe będzie odtworzenie tej bazy danych przy pomocy polecenia psql: Usuńmy bazę danych: dropdb lab2_login stwórzmy ją na nowo (będzie pusta) : createdb lab2_login sprawdźmy, że jest pusta: psql lab2_login \d No relations found \i lab2_login_dump.sql \d SELECT * FROM klient; Widać, że nasza baza odzyskała postać i dane z pliku. 17