BAZY DANYCH PostgreSQL. Podstawowe wiadomości Dodatek do instrukcji laboratoryjnej
Spis treści 1. Połączenie z serwerem...4 1.1. SSH, SFTP...4 2. Podstawowe komendy i polecenia w systemie Linux...5 2.1. Polecenia związane z użytkownikami, grupami, loginami i zamykaniem systemu:...5 2.2. Polecenia związane z plikami i katalogami:...8 2.2.1 Polecenia związane z katalogami:...8 2.2.2 Polecenia związane z plikami:...9 2.2.3 Polecenia związane z kopiowaniem i przenoszeniem, plików i katalogów:...9 2.3. Polecenia związane z procesami:...10 2.4. Polecenia związane z pomocą:...11 2.5. Polecenia związane z kompresją i archiwizacją:...11 3. SQL...11 3.1. Relacyjny model danych...12 3.2. Opis formalny modelu relacyjnego...12 3.2.1 Domeny kontra typy danych...13 3.3. Operacje na modelu relacyjnym...13 3.3.1 Relacyjna algebra...13 3.3.2 Relacyjny Calculus...15 3.3.3 Tuple Relational Calculus...15 3.3.4 Relacyjna Algebra - Relacyjny Calculus...15 3.4. Język SQL...15 3.4.1 Select...15 3.4.2 Definicje danych...22 3.4.3 Manipulowanie danymi...24 3.4.4 Zbiory systemowe...24 3.4.5 Wbudowany SQL...24 4. Architektura PostgreSQL...25 5. Rozpoczynamy...25 5.1. Ustawienia środowiska...25 5.2. Aplikacje klienckie PostgreSQL (skrypty)...26 5.3. Aplikacje serwerowe PostgreSQL...26 5.4. Zarządzanie bazą danych...26 5.4.1 Tworzenie bazy danych...26 5.4.2 Dostęp do bazy danych...27 5.4.3 Usunięcie bazy danych...27 5.5. Uruchamiamy Interactive Monitor (psql)...28 5.5.1 Dostępne rozkazy języka SQL...28 5.5.2 Opcje wywołania psql...29 5.5.3 Podstawowe polecenia programu psql...30 5.5.4 Typy danych...31 6. Reguły...33 6.1. Reguły typu SELECT...33 6.2. Reguły typu INSERT...33 6.3. Reguły typu UPDATE...33 6.4. Reguły typu DELETE...34 7. Funkcje i triggery...34 7.1. Funkcje...35 7.1.1 Funkcje SQL...36 7.1.2 Funkcje PL/pgSQL...36 7.1.3 Funkcje PL/PHP...39 7.2. Triggery...39 7.2.1 Dodawanie triggera...39 7.2.2 Modyfikowanie triggera...40 7.2.3 Usuwanie triggera...40 7.2.4 Tworzenie funkcji uruchamianej triggerem...40 8. Przykład użycia psql i języka zapytań...42 8.1. Uruchamiamy monitor psql...42 8.2. Zasady ogólne...43 8.3. Tworzenie tabel...43 8.4. Wstawianie danych do tabeli...43 8.5. Przeglądanie tabeli...43 8.6. Przekierowanie zapytań wybierających...44
8.7. Połączenia tabel...44 8.8. Uaktualnianie danych...44 8.9. Kasowanie danych...45 8.10. Funkcje agregujące...45 9. Zaawansowane właściwości Postgres SQL...46 9.1. Dziedziczenie...46 9.2. Wartości złożone...47 9.3. Tablice...47 9.4. Więcej zaawansowanych właściwości...48 10. Wspomaganie tworzenia interfejsu BD...48 10.1. Funkcje języka C - biblioteka libpq...48 10.1.1 PQconnectdb...49 10.1.2 PQfinish...50 10.1.3 PQstatus...50 10.1.4 PQexec...50 10.1.5 PQresultStatus...50 10.1.6 PQclear...51 10.1.7 PQgetvalue...51 10.2. Funkcje języka PHP...51 10.2.1 pg_connect...53 10.2.2 pg_pconnect...53 10.2.3 pg_close...54 10.2.4 pg_query...54 10.2.5 pg_send_query...54 10.2.6 pg_connection_status...54 10.2.7 pg_result_status...55 10.2.8 pg_fetch_array...55 10.2.9 pg_fetch_assoc...56 10.2.10 pg_fetch_row...56 10.2.11 pg_fetch_object...56 10.2.12 pg_num_rows...56 10.2.13 pg_affected_rows...56
1. Połączenie z serwerem 1.1. SSH, SFTP SSH (Secure Shell) jest to program, który umożliwia logowanie do innych komputerów, kopiowanie plików między komputerami, zdalne wykonywanie poleceń na innych komputerach, łączenie sieci komputerowych za pomocą tzw. tuneli oraz przekazywanie (forwarding) środowiska graficznego X, czyli uruchamianie graficznych aplikacji na zdalnej maszynie i oglądanie ich na swoim komputerze. Logowanie do innych komputerów może być uwierzytelniane hasłem użytkownika, lub wygenerowanym kluczem. Cała transmisja danych pomiędzy komputerami jest szyfrowana. Program ten zastępuje mniej bezpieczne rlogin, rsh, rcp, rdist i telnet. Implementacja OpenSSH w SUSE składa się z dwóch części: klienta ssh, który umożliwia logowanie się na inne maszyny (np. putty) demona sshd, który umożliwia logowanie się do komputera, na którym jest uruchomiony SFTP (ang. Secure File Transfer Protocol) protokół pozbawiony wad, które posiada zwykły FTP. Przesyłając plik dzięki protokołowi FTP uzyskujemy dobre przepływności, ale nie zyskujemy bezpieczeństwa, nasze hasła nie są szyfrowane. Znaczną poprawę bezpieczeństwa przynosi protokół SFTP, który nie wymaga na danym hoście posiadania serwera FTP, wystarczy konto SSH, którego jest on rozszerzeniem, używa jego struktury oraz przez niego się łączy. Korzystanie z kluczy zwiększa bezpieczeństwo, ponieważ złamanie hasła jest prostsze niż uzyskanie dostępu do klucza prywatnego. Poza tym jeśli używasz wielu maszyn, na każdej innego hasła na konto roota czy też inne, ciężko zapamiętać je wszystkie. Kiedy korzystasz z kluczy musisz pamiętać tylko hasło do swojego klucza, albo wcale. PUTTY Pozwala na nawiązywanie połączeń zarówno z serwerami SSH, TELNET jak i XTERM. Program posiada opcję, która umożliwia zapisywanie sesji. Putty jest w stanie także połączyć się z serwerem SSH korzystając z klucza prywatnego, co nie wymaga podawania haseł. PSFTP Program dla nawiązania bezpiecznego połączenia FTP. Otwiera okno konsoli:! uruchomienie polecenia systemowego bye zakończenie sesji SFTP (również exit, quit) cd zmiana zdalnego folderu chmod zmiana atrybutów pliku close zamknięcie sesji bez zatrzymania programu PSFTP del usuń zdalne pliki (również rm) dir listuj zdalne pliki (również ls) get pobierz zdalny plik help wypisz informacje pomocnicze lcd zmiana lokalnego folderu lpwd podaj lokalną ścieżkę mget pobierz naraz wiele plików mv przesuń lub zmień nazwę plików w zdalnym folderze (również ren) open połącz z hostem put wyślij plik na serwer pwd podaj zdalną ścieżkę reget kontynuuj pobieranie plików reput kontynuuj wysyłanie plików rmdir usuń zdalne foldery Łączymy się z serwerem mamma.eti.pg.gda.pl (153.19.51.70), używając przydzielonej nazwy użytkownika i hasła.
2. Podstawowe komendy i polecenia w systemie Linux 2.1. Polecenia związane z użytkownikami, grupami, loginami i zamykaniem systemu: shutdown -Przeznaczenie: zamykanie systemu -Parametry: shutdown [minuty] [informacja dla zalogowanych użytkowników] shutdown - natychmiastowe zamknięcie systemu shutdown now - j/w shutdown 0 (zero) - j/w shutdown 2 - system zamknie się za 2minuty shutdown 2 2minuty do wył. systemu - system zamknie się za 2minuty pokazując komunikat -Opis: to polecenie służy do zamykania systemu, jest możliwość ustawienia tej komendy, żeby zamknęła Linuxa za np. 2 min. powiadamiając zalogowanych użytkowników adduser -Przeznaczenie: dodawanie nowego użytkownika -Parametry:adduser [nazwa użytkownika] adduser jan - dodaje do komputera użytkownika o nazwie(imieniu) jan -Opis: jeśli jesteś zalogowany jako root masz prawo dostępu do tej komendy, jeśli nie jesteś musisz się najpierw przelogować na root'a -Patrz także: [passwd] [newgrp]. newgrp -Przeznaczenie: dodawanie nowej grupy lub przełączanie na inną -Parametry:newgrp [nazwa grupy] newgrp programmers - dodaje nową grupę o nazwie programmers -Opis: jeśli jesteś zalogowany jako root masz prawo dostępu do tworzenia grupy, jeśli nie masz prawo do zmieniania się między nimi -Patrz także: [adduser] passwd -Przeznaczenie: zmiana hasła -Parametry: passwd [użytkownik] adduser - zmienia hasło loginu na którym jesteś zalogowany adduser thomson - zmienia hasło użytkownika thomson, jeśli jesteś zalogowany jako root i nie musisz znać poprzedniego hasła zwykłego użytkownika -Opis: jeśli jesteś zalogowany jako root masz prawo dostępu do tej komendy, jeśli nie jesteś musisz się najpierw przelogować na root'a -Patrz także: [adduser] logout -Przeznaczenie: służy do wylogowania się -Parametry: brak -Opis: po wpisaniu polecenia widzimy napis do zalogowowania się -Patrz także: [adduser] who -Przeznaczenie: sprawdzamy kto jest aktualnie zalogowany -Parametry: who [parametry] who - pokazuje np: root tty01 Dec 13 12:42 who am i - pokazuje nam informacje o naszym loginie -Opis: możesz za pomocą tego polecenia sprawdzić kto jest zalogowany lub "kim" jesteś w systemie -Patrz także: [users] [w] [whoami] users -Przeznaczenie: pokazuje kto jest zalogowany -Parametry: brak -Opis: ta komenda jedynie pokazauje po przecinku nazwy użytkowników zalogowanych w systemie -Patrz także: [who] [w] [whoami]
w -Przeznaczenie: pokazuje kto jest zalogowany -Parametry: brak -Opis: po wpisaniu widzisz napisy : 8:43pm up 13 min, 3 users, load average: 0.07, 0.20, 0.20 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT ^^^a co poszczególne rzeczy oznaczają^^^ 8:43pm - bieżaca godzina (20:43) up 13 min - jak długo pracuje nasz system (13min) 3 users - ilu użytkowników pracuje w systemie load average - obciążenie systemu przez programy USER - identyfikator użytkownika TTY - nazwa terminalu FROM - informacja dodatkowa LOGIN@ - godzina zalogowania IDLE - ile czasu upłynęło od ostatniego naciśnięcia klawisza JCPU - czas zużyty przez wszystkie programy na danym terminalu PCPU - oraz przez wszystkie programy w danym momencie WHAT - nazwa aktywnego procesu -Patrz także: [who] [whoami] [whoami] [users] whoami -Przeznaczenie: sprawdzamy nazwą loginu na którym się zalogowaliśmy -Parametry: brak -Opis: jeśli jesteś zalogowany jako root to wyświetla napis w następnej linijce "root" -Patrz także: [who] [w] [users] mesg -Przeznaczenie: zezwolenie lub nie na przyjmowania komunikatów -Parametry: adduser [Yn] mesg y - możesz otrzymywać wiadomości mesg n - nie możesz otrzymywać wiadomości -Opis: jest to możliwość ustawienia czy do ciebie mają przychodzić komunikaty -Patrz także: [write] [wall] [rwall] [ruser] write -Przeznaczenie: wysyłanie komunikatów -Parametry: write [użytkownik] [wiadomość] write pasternak wiadro - wysłanie wiadomości do użytkownika pasternak, u pasternaka pojawi się tekst: Message from silverstar!root on tty1 at 23:33 wiadro po polsku i ludzku: "Wiadomość od root wysłana o godz. 23:33" i teraz wiadomość: <wiadro>" -Opis: polecenie daje możliwość wysłania komunikaty do wybranej osoby -Patrz także: [mesg] [wall] [rwall] [ruser] wall -Przeznaczenie: wysyłanie komunikatów -Parametry: wall [plik tekstowy] wall mes.txt - wysłanie do wszystkich użytkowników wiadomości z pliku mes.txt -Opis: polecenie daje możliwość wysłania wiadomości do wszystkich osób -Patrz także: [mesg] [write] [rwall] [ruser] rwall -Przeznaczenie: wysyłanie komunikatów -Parametry: wall [plik tekstowy] wall mes.txt - wysłanie do wszystkich sieci wiadomości z pliku mes.txt -Opis: polecenie daje możliwość wysłania wiadomości do wszystkich sieci -Patrz także: [mesg] [write] [wall] [ruser] ruser -Przeznaczenie: wysyłanie komunikatów -Parametry: wall [plik tekstowy] wall mes.txt - wysłanie do wszystkich pracujących w systemie użytkowników wiadomości z pliku mes.txt -Opis: polecenie daje możliwość wysłania wiadomości do wszystkich sieci
-Patrz także: [mesg] [write] [wall] [ruser] talk -Przeznaczenie: interaktywna rozmowa -Parametry: talk [login][@sieć] talk parker - wtedy pokaże się wiadomość No connect yet - brak połączenia Waiting for your party to respond - czekanie na odp. Your party is not logged on - brak partnera w sieci Ringing your party again - ponowne wezwanie Connection established - nawiązano połączenie U odbiorcy pojawi napis Message from Talk_Daemon@kom.net at 23:33 talk: connection requested by root talk: respond with: talk root Czyli jeśli adresat po odczytaniu tego napisze talk root, to połączenie zostanie nawiązane -Opis: możemy nawiązać interaktywny kontakt nie tylko z osoba z naszego komputera, ale tez innego z sieci -Patrz także: [mesg] [write] [wall] [rwall] [ruser] finger -Przeznaczenie: informacja o użytkownikach -Parametry: finger [user] finger - pokaże się nam okienko w rodzaju: LOGIN NAME TTY IDLE WHEN WHERE root root ttyp1 1.01s Jan 20:33 Unknow finger root - pokaże się nam okienko w rodzaju: Login name: root In real life: root Directory: /root Shell: /bin/bash On since Jan 27 20:33:11 on ttyp1 at Unknow No unread mail No Plan. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Jak widać dowiadujemy się jakie są prawdziwe personalia użytkownika (In real life), nazwy jego kartoteki prywatnej (Directory), rodzaj shell'a (Shell), kiedy się załogował (On since), lub kiedy ostatnio był w sieci (Last login), czy dostał/czytał ostatnią paczkę poczty -Opis: Są to szczegółowe informacje o użytkownikach -Patrz także: [who] su -Przeznaczenie: szybka zmiana loginu -Parametry: su [user] su root - zmieniamy się w użytkownika root po podaniu jego hasła -Opis: jeśli jesteśmy jako root nie trzeba podawać hasła -Patrz także: [logout] chmod -Przeznaczenie: zmieniamy parametry pliku -Parametry: chmod [u(user) g(grupa) o(właściciel) a(wszyscy)] [+-] [r(czytanie) w(pisanie) x(uruchamianie)] [nazwa pliku] chmod ugo-rw file - odbieramy prawa dostępu do czytania i modyfikowania pliku właścicielowi, grupie oraz użytkownikom chmod a-rw - j/w chmod a+r - wszyscy mają prawo do czytania pliku chmod a+rwx - wszyscy mają prawo do czytania, zapisywania i uruchamiania pliku -Parametry: chmod [liczba od 000 do 777][nazwa pliku] pierwsza liczba to użytkownik, druga liczba to grupa a trzecia pozostali 0 lub --- brak praw dostępu 1 lub --x wykonywanie
2 lub -w- czytanie 3 lub -wx zapis 4 lub r-- zapis i wykonywanie 5 lub r-x odczyt 6 lub rw- odczyt i zapis 7 lub rwx odczyt, zapis i wykonywanie chmod 777 file - dajemy pełny dostęp właścicielowi, grupie oraz użytkownikom chmod 000 file - zabieramy pełny dostęp właścicielowi, grupie oraz użytkownikom chmod a+r - wszyscy mają prawo do czytania pliku chmod a+rwx - wszyscy mają prawo do czytania, zapisywania i uruchamiania pliku -Opis: są to prawa dostępu dające lub nie prawa do zapisu, czytania i wykonywania, jakie są prawa można zobaczyć wpisując ls l: na początku jest -rwxr--r-- pierwszy znak oznacza plik, katalog..., jeśli zwykły plik to jest minus-, 9 następnych to prawa dostępu 3 pierwsze dla właściciela 3 następne dla grupy a 3 ostatnie dla wszystkich -Patrz także: [write] [wall] [rwall] [ruser] chown -Przeznaczenie: zmieniamy parametry pliku -Parametry: chmod [user] [plik] chown rex doc6 - rex jest właścicielom pliku doc6 chown rex doc* - rex jest właścicielom wszystkich plików w katalogu zaczynających się na doc np. doc5, doc98 chown rex??? - rex jest właścicielom wszystkich plików mających 3 litery np. doc, abc -Opis: jest to możliwość ustawienia właściciela pliku lub plików -Patrz także: [chmod] [chgrp] [newgrp] chgrp -Przeznaczenie: ustawiamy która grupa jest właścicielem pliku pliku -Parametry: chgrp [grupa] [plik] chgrp gracze spis - gracze są właścicielami pliku spis chgrp gracze * - gracze są właścicielami wszystkich plików -Opis: jest to możliwość ustawienia czy d ciebie mają przychodzić komunikaty -Patrz także: [write] [wall] [rwall] [ruser] 2.2. Polecenia związane z plikami i katalogami: 2.2.1 Polecenia związane z katalogami: --ls ---Przeznaczenie: sprawdzanie zawartości katalogu ---Parametry: ls [parametr] [katalog] -- ls - zostaną wyświetlone pliki i katalogi jeden po drugim -- ls -a - zostaną wyświetlone wszystkie pliki (ukryte) i katalogi -- ls -l - zostaną wyświetlone pliki i katalogi w postaci listy ---ls -t - zostaną wyświetlone pliki i katalogi według daty, najpierw wyświetlane są pliki nowsze -- ls -r - zostaną wyświetlone pliki i katalogi według daty, najpierw wyświetlane są pliki starsze ---Opis: jest możliwość łączenia parametrów w postaci ls -al jednak źle będą rozpoznawane ls -a -l ---Patrz także: [dir] -- --dir ---Przeznaczenie: sprawdzanie zawartości katalogu ---Parametry: -brak- ---Opis: to samo po napisaniu ls (bez parametrów) ---Patrz także: [ls] -- --pwd ---Przeznaczenie: sprawdzanie w którym jesteśmy katalogu ---Parametry: -brak- ---Opis: po wpisaniu komendy pokazuje się odpowiedź ---Patrz także: --- --
--cd ---Przeznaczenie: zmiana katalogu ---Parametry: ls [parametr lub katalog] -- cd.. - cofamy się o 1 katalog na dół -- cd../.. - cofamy się o 2 katalogi na dół -- cd gry - otwieramy katalog gry ---cd gry/tetris - otwieramy katalog tetris w katalogu gry -- cd../programy - otwieramy katalog programy w katalogu niżej -- cd /programy - otwieramy katalog programy na samym "dole" -- cd - otwieramy własny katalog ---Opis: jest to możliwość zmieniania aktualnego katalogu ---Patrz także: --- -- --rmdir ---Przeznaczenie: usuwanie katalogu ---Parametry: rmdir [katalog(i)] -- rmdir kat1 - usunięcie katalogu kat1 -- rmdir kat1 kat2 - usunięcie katalogu kat1 i kat2 -- rmdir kat1/kat10 - usunięcie katalogu kat10 w katalogu kat1 ---Opis: jest możliwość usunięcia katalogu, UWAGA katalog musi być pusty ---Patrz także: [mkdir] -- --mkdir ---Przeznaczenie: sprawdzanie zawartości katalogu ---Parametry: mkdir [katalog] -- mkdir kat8 - zostanie utworzony katalog kat8 -- mkdir kat1 gry - zostanie utworzony katalog kat1 i gry -- mkdir gry/nethack - zostanie utworzony katalog gry a w nim utworzony katalog nethack ---Opis: jest możliwość utworzenia katalogu ---Patrz także: --- -- 2.2.2 Polecenia związane z plikami: --cat ---Przeznaczenie: edytowanie tekstu ---Parametry: cat [parametr] [katalog] -- cat >nowy.w - wpisany tekst jest zapisany do pliku nowy.w -- cat nowy.w > dwa - plik nowy.w kopiujemy do pliku dwa ---cat dwa nowy.w >tr3 - plik nowy.w i dwa (złączony jeden po drugim) kopiujemy do tr3 -- cat tr3 > one > two > tree - plik tr3 kopiujemy do one, one do two, two do tree ---Opis: UWAGA przy plikach binarnych grozi ta metoda zawieszeniem terminala lub systemu ---Patrz także: --- -- --rm ---Przeznaczenie: usuwanie pliku ---Parametry: rmdir [plik(i)] -- rmdir plk1 - usunięcie pliku kat1 -- rmdir plk1 plk2 - usunięcie pliku kat1 i kat2 ---Opis: jest możliwość usunięcia pliku ---Patrz także: [rmdir] -- 2.2.3 Polecenia związane z kopiowaniem i przenoszeniem, plików i katalogów: --mv ---Przeznaczenie: przenoszenie plików ---Parametry: mv [plik] [cel] -- mv qfile /tmp - przenosimy plik qfile do katalogu /tmp -- mv f* kat - przenosimy wszystkie pliki zaczynające się literę f do katalogu kat ---Opis: za pomocą tej komendy możemy także zmienić nazwę
---Patrz także: --- -- --cp ---Przeznaczenie: kopiujemy plik ---Parametry: cp [plik/katalog] [cel] -- cp plk1 plik198 - kopiujemy zawartość plk1 do plik198 -- cp plk1 c - kopiujemy zawartość pliku plk1 do c ---Opis: jest możliwość kopiowania plików i katalogów ---Patrz także: [mv] [mvdir] -- --mvdir ---Przeznaczenie: przenoszenie katalogu ---Parametry: mvdir [katalog] [cel] -- mvdir homm3 gry - przenosimy katalog homm3 do gry -- mvdir kosz /tmp - przenosimy katalog kosz do /tmp ---Opis: to polecenie działa podobnie jak mv ---Patrz także: [mv] -- 2.3. Polecenia związane z procesami: ps -Przeznaczenie: sprawdzanie komunikatów -Parametry: ps [parametry] ps - zotanie wyświetlone PID TTY STAT TIME COMMAND 282 1 S 0:02 /bin/login -- root 285 4 S 0:00 (mingetty) 286 5 S 0:00 (mingetty) 287 6 S 0:00 (mingetty) 301 1 S 0:01 (bash) 399 1 R 0:00 ps ps -aux - zotanie wyświetlone USER PID %CPU %MEM SIZE RSS TTY STAT START TIME COMMAND bin 95 0.0 0.6 896 44? S 20:32 0:00 (portmap) news 296 0.0 7.9 1580 516? S 20:33 0:00 /sbin/innd -p5 -r news 300 0.0 0.3 872 24? S 20:33 0:00 (overchan) jasio 283 0.1 11.0 1012 716 2 S 20:33 0:01 /bin/login -- jasio jasio 344 0.1 10.1 1220 656 2 S 20:38 0:01 -bash asia 358 0.2 10.7 1012 700 3 S 20:39 0:01 /bin/login -- asia asia 359 0.1 9.7 1216 632 3 S 20:39 0:00 -bash root 1 0.3 1.6 880 104? S 20:30 0:04 init [...] root 465 0.0 6.2 928 404 1 R 20:53 0:00 ps -aux ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ USER - użytkownik procesu PID - numer identyfikacyjny procesu TTY - procesy związane z naszym terminalem STAT - status procesu o R - proces działający (ang. running) o T - proces zatrzymany (ang. stopped) o P - proces w stanie spoczynku (ang. page wait) o D - proces w stanie spoczynku (ang. disk wait) o S - proces w stanie spoczynku (ang. sleeping) o I - proces w stanie spoczynku (ang. idle) o Z - proces duch (ang. zombie), zakończył się ale nie rozliczył się jeszcze z procesami nadrzędnymi! TIME - jak długo działa proces COMMAND - nazwa programu, której odpowiada proces %CPU - ilość zaangażowania procesora w procesie %MEM - jaka cześć pamięci operacyjnej -Opis: jeśli chcesz zobaczyć kot jakie procesy wykonuje jest to polecenie dla ciebie -Patrz także: [kill]
kill -Przeznaczenie: zabijanie procesów -Parametry:kill [parametr] [PID] kill 200 - zabija proces z numerem 200 (PID) kill -9 200 - jeśli jest oporny i nie che się wyłączyć jest to prawie pewny sposób kill -9-1 - zabija wszystkie procesy kill -9 0 -!!!samobójstwo!!! -Opis: wyłączanie procesów -Patrz także: [ps] 2.4. Polecenia związane z pomocą: help -Przeznaczenie: wyświetla nam wszystkie polecenia w Linuxie -Parametry: -brak- -Opis: wyświetlenie komunikatów dostępnych w systemie -Patrz także: [man] man -Przeznaczenie: pokazuje nam pomoc do programu -Parametry: man [program] man mount - wyświetla pomoc do polecenia mount -Opis: pomoc do konkretnych programów -Patrz także: --- 2.5. Polecenia związane z kompresją i archiwizacją: gzip -Przeznaczenie: kompresuje nam archiwum *.qz -Parametry: gunzip [parametry] [*.gz] gzip arx - tworzy nam zkompresowany plikp arx.gz gzip -d arx.gz - odkompresuje nam archiwum arx.gz -Opis: Można tylko kompresować jeden plik, w przypadku większej ilości trzeba użyć TAR'a -Patrz także: [tar] tar -Przeznaczenie: archiwizuje nam archiwum *.qz -Parametry: tar [parametry] [*.tar] tar -cvf plik* - archiwizuje nam wszystkie pliki do sk.tar tar -xvf - rozarchiwizuje nam wszystkie sk.tar -Opis: TAR nie kompresuje nam plików, żeby były z kompresowane trzeba użyć GZIP'a -Patrz także: --- 3. SQL SQL stał się najpopularniejszym relacyjnym językiem zapytań. Nazwa jest skrótem od Structured Query Language (Strukturalny Język Zapytań). W 1974 r. Donald Chamberlin i inni zdefiniowali SEQUEL (Structured English Query Language). Po raz pierwszy został wprowadzony w prototypie IBM zwanym SEQUEL-XRM w 1974-75 r. W latach 1976-77 powstała poprawiona wersja SEQUEL nazwana SEQUEL/2, a nazwę tą następnie zmieniono na SQL. Nowy prototyp System R wprowadzony przez IBM w 1977 r. obejmował większą część SEQUEL/2 (teraz SQL) jak i wprowadzał wiele zmian do SQL. Sukces i akceptacja pierwszych użytkowników spowodował, że IBM rozpoczęła wprowadzanie pierwszych komercyjnych produktów opartych na technologii Systemu R, zawierających SQL. Przez nastepne lata IBM i inni producenci stworzyli produkty SQL'owe, takie jak: SQL/DS (IBM), DB2 (IBM), ORACLE (Oracle Corp.), DG/SQL (Data General Corp.), and SYBASE (Sybase Inc.). Obecnie SQL jest standardem oficjalnym. W 1982 r. Komitet Baz Danych X3H2 Amerykańskiego Instytutu Standardów ANSI (American National Standards Institute) przedstawił propozycję standardu języka relacyjnego, który zawierał dialekt IBM i został przyjęty w 1986 r. Rok później standard ten został również zaakceptowany przez Międzynarodową Organizację Standaryzacji ISO (International Organization for Standardization). Oryginalna wersja standardu jest nieformalnie nazywana SQL/86. W 1989 r. standard został rozszerzony i znów nieformalnie nazwany SQL/89.
Komitety ISO i ANSI przez wiele lat pracowały nad zdefiniowaniem bardziej rozbudowanej wersji standardu nazwanej SQL2 lub SQL/92. Ta wersja w 1992 r. została przyjęta jako: "International Standard ISO/IEC 9075:1992, Database Language SQL". Podczas pisania tego dokumentu trwały prace nad SQL3, który sprawi że SQL będzie językiem kompletnym, zawierającym np. możliwość tworzenia zapytań krzyżowych. Jest to bardzo złożone zadanie i dlatego nie jest znany czas zakończenia tych prac. 3.1. Relacyjny model danych Jak wspomniano wcześniej, SQL jest językiem relacyjnym. Oznacza to, że jest oparty na relacyjnym modelu danych, opublikowanym po raz pierwszy przez E.F.Codd'a w 1970 roku. Opis formalny modelu relacyjnego przedstawimy później (w rozdziale Opis formalny modelu relacyjnego) ale najpierw musimy spojrzeć na to z bardziej intuicyjnego punktu widzenia. Relacyjna baza danych jest bazą postrzeganą przez użytkowników jako zbiór tabel (i nic więcej tylko tabel). Tabela składa się z wierszy i kolumn, gdzie każdy wiersz reprezentuje rekord, a każda kolumna atrybuty rekordów zawartych w tabeli. Baza danych Suppliers (Dostawcy) i Parts (Produkty) przedstawia przykład bazy składającej się z trzech tabel. SUPPLIER (Dostawca) jest tabelą przechowującą numer (SNO), nazwisko (SNAME) i miasto (CITY) dostawcy. PART (Produkt) jest tabelą przechowującą numer (PNO), nazwę (PNAME) i cenę (PRICE) produktu. SELLS (Sprzedaż) przechowuje informacje o tym, który produkt (PNO) jest sprzedany przez którego dostawcę (SNO). Służy do połączenia pozostałych tabel wzajemnie. Przykład 1-1. Baza danych Dostawcy i Produkty SUPPLIER: SELLS: SNO SNAME CITY SNO PNO ----+---------+-------- -----+----- 1 Smith London 1 1 2 Jones Paris 1 2 3 Adams Vienna 2 4 4 Blake Rome 3 1 3 3 4 2 PART: 4 3 PNO PNAME PRICE 4 4 ----+---------+--------- 1 Screw 10 2 Nut 8 3 Bolt 15 4 Cam 25 Tabele PART i SUPPLIER są encjami a SELLS jest relacją między określonym produktem a dostawcą. Zanim zobaczymy relacje na tabelach przestudiujmy teorię modelu relacyjnego. 3.2. Opis formalny modelu relacyjnego Matematyczna koncepcja przedstawia model relacyjny jako czysto teoretyczną relację, która jest podzbiorem iloczynu kartezjańskiego z listy dziedzin. Stąd bierze się nazwa tego modelu. W rzeczywistości dziedzina, inaczej domena, jest po prostu zbiorem wartości. Na przykład, dziedziną jest zbiór liczb całkowitych lub zbiór łańcuchów znakowych o długości 20 znaków, czy też zbiór liczb rzeczywistych. Iloczyn kartezjański dziedzin D 1, D 2,... D k, zapisany jako D 1 D 2... D k jest zbiorem wszystkich krotek v 1, v 2,... v k, takich jak v 1 D 1, v 2 D 2,... v k D k. Na przykład, gdy mamy k=2, D 1 ={0,1} oraz D 2 ={a,b,c} wtedy D 1 D 2 jest {(0,a),(0,b),(0,c),(1,a),(1,b),(1,c)}. Relacją jest dowolny podzbiór iloczynu kartezjańskiego jednej lub wielu dziedzin: R D 1 D 2... D k. Na przykład {(0,a),(0,b),(1,a)} jest relacją; tzn. zbiorem D 1 D 2 wspomnianym wyżej. Elementy relacji są nazywane krotkami. Każda relacja jakiegoś iloczynu kartezjańskiego D 1 D 2... D k jest zbiorem krotek. Relacja może być przeglądana jak tabela (przypomnij sobie Bazę danych Dostawcy i Produkty, gdzie każda krotka jest przedstawiana jako wiersz, a każda kolumna jest częścią krotki). Nazwy kolumn nazywane atrybutami odgrywają główną rolę w definicji schematu relacji. Schematem relacji R jest dowolny zbiór atrybutów A 1, A 2,... A k. Jest dziedzina D i, dla każdego atrybutu A i, 1 i k, skąd brane są wartości atrybutów. Często schemat relacji zapisuje się w ten sposób: R(A 1, A 2,... A k ).
3.2.1 Domeny kontra typy danych W tym rozdziale często mówiliśmy o dziedzinach (domenach). Formalnie dziedzina jest zbiorem wartości (np. zbiór liczb całkowitych albo rzeczywistych). W terminologii systemów bazodanowych często mówi się o typach danych zamiast o domenach. Gdy zdefiniujemy tabelę możemy zdecydować jakie atrybuty ma zawierać oraz jakiego rodzaju dane będą przechowywane jako wartości opisowe. Dla przykładu wartości SNAME z tabeli SUPPLIER będą ciągami znaków, a SNO będzie przechowywać liczby całkowite. Zdefiniujemy to przypisując typ danych do każdego atrybutu. Typem SNAME będzie VARCHAR(20) (jest to SQL'owy typ dla stringów o długości 20), typem SNO będzie INTEREGER. Przypisując typ musimy także wybrać dziedzinę dla atrybutu. Domeną SNAME jest zbiór łańcuchów o dł. 20, domeną SNO jest zbiór liczb całkowitych. 3.3. Operacje na modelu relacyjnym W poprzednim rozdziale (Opis formalny modelu relacyjnego) poznaliśmy definicje matematyczne modelu relacyjnego. Już wiemy jak przy użyciu modelu relacyjnego są przechowywane dane, ale jeszcze nie wiemy co zrobić aby wyciągnąć informacje z bazy danych. Na przykład ktoś mógłby zapytać o nazwiska dostawców, którzy sprzedają produkt "Screw". W tym celu stosuje się dwa różne sposoby zapisu wyrażeń relacyjnych: Relacyjna algebra która jest zapisem algebraicznym, w którym zapytania są formułowane przy użyciu specjalnych operatorów. Relacyjny Calculus jest zapisem logicznym, polegającym na formułowaniu logicznych warunków, które muszą być spełnione przez zwracane krotki. 3.3.1 Relacyjna algebra Relacyjna algebra została przedstawiona przez E. F. Codd'a w 1972 r. Zawiera zbiór operatorów i relacji: SELECT (σ): wyciąga z relacji krotki spełniające warunek. Niech R będzie tabelą zawierającą atrybut A. σ A=a (R) = {t R, t(a) = a}, gdzie t oznacza krotkę z R, a t(a) oznacza wartość atrybutu A w krotce t. PROJECT (π): wyciąga żądane atrybuty (kolumny) z relacji. Niech R będzie relacją zawierającą atrybut X. π X (R) = {t(x), t R}, gdzie t(x) oznacza wartość atrybutu X krotki t. PRODUCT ( ): tworzy iloczyn kartezjański z dwóch relacji. Niech R tabelą o budowie k 1 i niech S będzie tabelą o budowie k 2. R S jest zbiorem wszystkich k 1 + k 2 krotek gdzie pierwsza k 1 forma krotki z R, a k 2 jest formą krotki z S. UNION ( ): tworzy teoretyczną unię (złączenie) dwóch tabel. Są tabele R i S (o tej samej budowie), złączenie R S jest zbiorem krotek z R lub S albo z obu tabel. INTERSECT ( ): tworzy teoretyczne skrzyżowanie dwóch tabel. Są dane tabele R i S, R S jest zbiorem krotek z R i S. Budowa tabel musi być taka sama. DIFFERENCE ( ): tworzy różnicę dwóch tabel. Niech R i S będą znów dwoma tabelami o tej samej budowie. R - S jest zbiorem krotek z R ale nie z S. JOIN ( ): łączy dwie tabele przez wspólne atrybuty. Niech R będzie tabelą z atrybutami A,B,C i niech S będzie tabelą z atrybutami C,D,E. Jest więc jeden atrybut wspólny dla obu relacji - C. R S = π R.A,R.B,R.C,S.D,S.E (σ R.C=S.C (R S)). Co to oznacza? Na początku liczymy iloczyn kartezjański R S. Potem wybieramy te krotki, których wartości dla wspólnego atrybutu C są równe. Otrzymujemy tabelę zawierającą atrybut C podwójnie, poprawiamy to usuwając powtórzone kolumny. Przykład 1-2. Inner Join Spójrzmy na tabele stworzone dla pokazania kroków niezbędnych do złączenia. Mamy następujące tabele: R: S: A B C C D E ---+---+--- ---+---+--- 1 2 3 3 a b 4 5 6 6 c d 7 8 9
Najpierw liczymy iloczyn kartezjański R S i otrzymujemy: R x S: A B R.C S.C D E ---+---+-----+-----+---+--- 1 2 3 3 a b 1 2 3 6 c d 4 5 6 3 a b 4 5 6 6 c d 7 8 9 3 a b 7 8 9 6 c d Po selekcji σ R.C=S.C (R S) mamy: A B R.C S.C D E ---+---+-----+-----+---+--- 1 2 3 3 a b 4 5 6 6 c d Aby usunąć duplikaty S.C przeprowadzamy następującą operację: π R.A,R.B,R.C,S.D,S.E (σr.c=s.c(r S)) i otrzymaliśmy: A B C D E ---+---+---+---+--- 1 2 3 a b 4 5 6 c d DIVIDE ( ): Niech R będzie tabelą z atrybutami A, B, C, i D, a S niech będzie tabelą z atrybutami C i D. Później definiujemy dzielenie jako: R S = {t: t s S t r R lub tak t r (A,B)=t t r (C,D)=t s }, gdzie t r (x,y) oznacza krotkę tabeli R zawierającą tylko atrybuty x i y. Krotka t zawiera tylko atrybuty A i B relacji R. Dla danych tabel R: S: A B C D C D ---+---+---+--- ---+--- a b c d c d a b e f e f b c e f e d c d e d e f a b d e R S przedstawia się tak A B ---+--- a b e d Przykład 1-3. Zapytanie wykorzystujące algebrę relacyjną. Operatory relacyjne formułujemy aby mieć możliwość wydobycia danych z bazy. Powróćmy teraz do przykładu z poprzedniego rozdziału (Operacje na modelu relacyjnym). Jeśli ktoś chciałby znać nazwy wszystkich dostawców, którzy sprzedają produkt Screw. Takie pytanie przy użyciu algebry relacyjnej może być przedstawione jako następująca operacja: π SUPPLIER.SNAME (σ PART.PNAME='Screw' (SUPPLIER SELLS PART)) Taką operację nazywamy zapytaniem (query). Jeśli zastosujemy powyższe zapytanie do naszych przykładowych tabel (Baza danych Dostawcy i Produkty) otrzymamy następujący wynik: SNAME ------- Smith Adams
3.3.2 Relacyjny Calculus Relacyjny calculus jest oparty na logice pierwszego stopnia. Są dwa warianty relacyjnego calculusa: Domain Relational Calculus (DRC), gdzie wartości zmienne odpowiadają atrybutom krotek. Tuple Relational Calculus (TRC), gdzie wartości zmienne odpowiadają krotkom. My skupimy się na omówieniu wariantu TRC, który jest podstawą większości relacyjnych języków. Szersza dyskusja na ten temat znajduje się w Date, 1994 oraz Ullman, 1988. 3.3.3 Tuple Relational Calculus Zapytania używające TRC mają następującą formę: x(a) : F(x) gdzie x jest zmienną krotką, A jest zbiorem atrybutów i F jest formułą. Wynikowa relacja zawiera wszystkie krotki t(a) zawarte w F(t). Jeśli chcemy odpowiedzi na zapytanie z przykładu Zapytanie z użyciem relacyjnej algebry stosując TRC formułujemy je nastepująco: {x(sname) : x SUPPLIER y SELLS z PART (y(sno)=x(sno) z(pno)=y(pno) z(pname)='screw')} Stosując to zapytanie na przykładzie Bazy danych Dostawcy i Produkty znów otrzymamy taki sam wynik jak w Zapytaniu z użyciem algebry relacyjnej. 3.3.4 Relacyjna Algebra - Relacyjny Calculus Relacyjna algebra i calculus mają te same możliwości wyrazu, tzn. wszystkie zapytania sformułowane przy pomocy relacyjnej algebry mogą być zapisane przy użyciu calculusa i na odwrót. Pierwszy udowodnił to E. F. Codd w 1972 r. Dowód ten jest oparty na algorytmie ("Algorytm redukcji Codd'a"), w którym rozstrzygający warunek relacyjnego calculusa można zredukować do równoznacznego warunku relacyjnej algebry. Więcej na ten temat w Date, 1994 oraz Ullman, 1988. Często mówi się, że języki oparte na calculusie są "wyższego poziomu", ponieważ algebra (częściowo) podaje kolejność operacji, podczas gdy calculus pozostawia kompilatorowi lub interpreterowi stworzenie najefektywniejszego porządku wykonania. 3.4. Język SQL Tak jak w przypadku większości nowoczesnych języków relacyjnych, w SQL'u można sformułować wszystkie zapytania zapisane z użyciem relacyjnej algebry lub calculusa. Istnieją jednak właściwości spoza zakresu relacyjnej algebry i calculusa. Poniżej przedstawiamy cechy SQL, które nie należą do relacyjnej algebry, ani calculusa: Operacje wstawiania, usuwania i modyfikacji danych. Operacje arytmetyczne: W SQL'u można np. stosować operacje arytmetyczne w porównaniach. A < B + 3. Zauważ, że + i inne operatory występują częściej w relacyjnej algebrze, niż w calculusie. Operacje przypisania i wyjścia. Można wyprowadzić na wyjście (ekran, plik) relację stworzoną w zapytaniu albo przypisać nazwę takiej relacji. Funkcje agregujące: Operacje takie jak średnia, suma, maksimum, itd. można stosować do kolumn aby otrzymać jedną liczbę. 3.4.1 Select Najczęściej używanym poleceniem SQL jest SELECT, używane do wybierania danych. Jego składnia jest następująca: SELECT [ ALL DISTINCT [ ON ( expression [,...] ) ] ] * expression [ AS output_name ] [,...] [ INTO [ TEMPORARY TEMP ] [ TABLE ] new_table ] [ FROM from_item [,...] ] [ WHERE condition ]
[ GROUP BY expression [,...] ] [ HAVING condition [,...] ] [ { UNION INTERSECT EXCEPT [ ALL ] } select ] [ ORDER BY expression [ ASC DESC USING operator ] [,...] ] [ FOR UPDATE [ OF class_name [,...] ] ] [ LIMIT { count ALL } [ { OFFSET, } start ]] Teraz zilustrujemy całą składnię polecenia SELECT na różnych przykładach. Tabele użyte w przykładach zdefiniowano w Bazie danych Dostawcy i Produkty. 3.4.1.1 Proste Select'y Podajemy najprostsze przykłady select'ów: Przykład 1-4. Proste zapytanie warunkowe Aby otrzymać wszystkie krotki z tabeli PART, gdzie atrybut PRICE jest większy od 10, sformułujemy takie zapytanie: SELECT * FROM PART WHERE PRICE > 10; i otrzymujemy tabelę: PNO PNAME PRICE -----+---------+-------- 3 Bolt 15 4 Cam 25 Znak "*" w poleceniu SELECT oznacza wszystkie kolumny w tabeli. Jeśli chcielibyśmy wydobyć tylko kolumny PNAME i PRICE z tabeli PART użyjemy takiej formy: SELECT PNAME, PRICE FROM PART WHERE PRICE > 10; W tym wypadku wynikiem będzie: PNAME PRICE --------+-------- Bolt 15 Cam 25 Zauważ, że SELECT odpowiada PROJECT'owi z relacyjnej algebry, a nie SELECT'owi (zobacz Relacyjna Algebra). Warunki w klauzuli WHERE mogą być połączone przy użyciu operatorów logicznych OR, AND lub NOT: SELECT PNAME, PRICE FROM PART WHERE PNAME = 'Bolt' AND (PRICE = 0 OR PRICE <= 15); otrzymamy wynik: PNAME PRICE --------+-------- Bolt 15 Operatory arytmetyczne mogą być używane w liście atrybutów oraz w klauzuli WHERE. Na przykład, jeśli chcemy znać koszt dwóch sztuk produktu, należy zapytać tak: SELECT PNAME, PRICE * 2 AS DOUBLE FROM PART WHERE PRICE * 2 < 50;
i mamy: PNAME DOUBLE --------+--------- Screw 20 Nut 16 Bolt 30 Zauważ, że słowo DOUBLE po słowie kluczowym AS jest nowym tytułem drugiej kolumny. Ten sposób może być użyty dla każdego elementu listy pól do przypisania nowej nazwy dla wynikowej kolumny. Taka nowa nazwa jest często nazywana aliasem. Alias nie może być używany w dalszej części zapytania. 3.4.1.2 Złączenia Następny przykład pokazuje sposób realizacji złączeń w SQL'u. Aby połączyć trzy tabele SUPPLIER, PART i SELLS wg pól wspólnych formułujemy następujące zapytanie: SELECT S.SNAME, P.PNAME FROM SUPPLIER S, PART P, SELLS SE WHERE S.SNO = SE.SNO AND P.PNO = SE.PNO; otrzymujemy następującą tabelę: SNAME PNAME -------+------- Smith Screw Smith Nut Jones Cam Adams Screw Adams Bolt Blake Nut Blake Bolt Blake Cam W klauzuli FROM wprowadzamy alias dla każdej relacji, ponieważ istnieją atrybuty o takich samych nazwach. Teraz możemy rozróżnić wspólne atrybuty poprzedzając je nazwą aliasu i oddzielając kropką. Złączenie przeprowadzane jest w taki sam sposób, jak pokazano w Złączeniu wewnętrznym. Najpierw powstaje iloczyn kartezjański SUPPLIER PART SELLS. Później wybierane są tylko te krotki, które spełniają warunek (np. atrybuty o takich samych wartościach). Innym sposobem na przeprowadzenie złączenia jest użycie składni JOIN: SELECT sname, pname FROM supplier JOIN sells USING (sno) JOIN part USING (pno); daje to taki wynik: SNAME PNAME -------+------- Smith Screw Adams Screw Smith Nut Blake Nut Adams Bolt Blake Bolt Jones Cam Blake Cam (8 rows) Tabela, powstała przy użyciu składni JOIN, zawiera pola podane w klauzuli FROM, a przed WHERE, GROUP BY, albo HAVING. Inne odwołania do tabel, tj. nazwy tabel lub inne klauzule JOIN, mogą być zawarte w klauzuli FROM; należy je rozdzielić przecinkami. Logicznie złączone tabele są takie same jak inne tabele z klauzuli FROM. Istnieją dwa główne typy złączeń SQL - Złączenie krzyżowe (bezwarunkowe) i złączenia warunkowe. Złączenie krzyżowe { T1 } CROSS JOIN { T2 }
Złączenie krzyżowe bierze dwie tabele T1 i T2 mające N i M osobnych wierszy i zwraca złączoną tabelę zawierającą N M wszystkich złączonych wierszy. Dla każdego wiersza R1 z T1, każdy wiersz R2 z T2 jest łączony z R1 i daje w wyniku wiersz JR złączonej tabeli zawierający wszystkie pola z R1 i R2. Złączenie krzyżowe CROSS JOIN jest równoważne poleceniu INNER JOIN ON TRUE. Złączenia warunkowe {T1} [NATURAL] [INNER {LEFT RIGHT FULL} [OUTER]] JOIN { T2 } {ON search_condition USING (join_column_list)} Złączenie warunkowe wprowadza warunki złączenia przez podanie klauzuli NATURAL, ON albo USING. Klauzula ON zawiera warunki złączenia (search_condition) i działa tak jak klauzula WHERE. USING zawiera listę nazw kolumn (oddzielonych przecinkami), które zostaną użyte do złączenia. NATURAL jest skrótem odpowiadającym USING z nazwami wszystkich kolumn z obu tabel. Działaniem ubocznym USING i NATURAL jest zwracanie tylko jednej kopii każdej łączonej kolumny (porównaj to z definicją JOIN z relacyjnej algebry, podaną wcześniej). T1 [ INNER ] JOIN T2 Dla każdego wiersza R1 z T1, złączona tabela ma wiersz dla każdego wiersza z T2, który spełnia warunki złączenia z R1. Uwaga: Słowa INNER i OUTER są opcjonalne dla wszystkich złączeń JOIN. INNER jest domyślne. LEFT, RIGHT oraz FULL dotyczą OUTER JOIN. T1 LEFT [ OUTER ] JOIN T2 Najpierw wykonuje się INNER JOIN. Później dla każdego wiersza z T1, który nie spełnia warunków złączenia z żadnym wierszem z T2, zwracany jest dodatkowo wiersz zawierający wartości NULL w kolumnach z T2. Uwaga: Złączona tabela bezwarunkowo zawiera wiersz dla każdego wiersza z T1. T1 RIGHT [ OUTER ] JOIN T2 Najpierw wykonuje się INNER JOIN. Później dla każdego wiersza z T2, który nie spełnia warunków złączenia z żadnym wierszem z T1, zwracany jest dodatkowo wiersz zawierający wartości NULL w kolumnach z T1. Uwaga: Złączona tabela bezwarunkowo zawiera wiersz dla każdego wiersza z T2. T1 FULL [ OUTER ] JOIN T2 Najpierw wykonuje się INNER JOIN. Później dla każdego wiersza z T1, który nie spełnia warunków złączenia z żadnym wierszem z T2, zwracany jest dodatkowo wiersz z polami NULL w kolumnach z T2. Dodatkowo dla każdego wiersza z T2, który nie spełnia warunków złączenia z żadnym wierszem z T1, zwracany jest wiersz zawierający wartości NULL w kolumnach z T1. Uwaga: Złączona tabela bezwarunkowo zawiera wiersz dla każdego wiersza z T2 oraz dla każdego wiersza z T1. Złączenia wszystkich typów mogą być łączone lub zagnieżdżone, w taki sposób, że jedno lub oba z T 1 i T 2 może być złączoną tabelą. W celu kontroli kolejności wykonania złączeń otacza się je nawiasami, w przeciwnym wypadku są wykonywane od lewej do prawej strony. 3.4.1.3 Funkcje (operatory) agregujące SQL wprowadza funkcje agregujące (tj. AVG, COUNT, SUM, MIN, MAX). Argumentem funkcji jest wyrażenie wykonywane dla każdego wiersza, który spełnia warunki klauzuli WHERE, więc obliczenia są wykonywane na przefiltrowanym zbiorze. Zazwyczaj funkcje zwracają pojedynczy rezultat dla całego polecenia SELECT, ale gdy użyto w zapytaniu grupowania, wtedy obliczenia wykonywane są oddzielnie dla każdej grupy (patrz następny punkt). Przykład 1-5. Funkcje agregujące Jeśli chcemy znać średnią cenę wszystkich produktów z tabeli PART użyjemy następującego zapytania: SELECT AVG(PRICE) AS AVG_PRICE FROM PART; Wynik: AVG_PRICE ----------- 14.5 Jeśli chcemy liczbę części zapiszemy to tak: SELECT COUNT(PNO) FROM PART;
i otrzymamy: COUNT ------- 4 3.4.1.4 Funkcje agregujące i grupowanie SQL pozwala podzielić krotki w tabeli na grupy. Wtedy funkcje agregujące można stosować osobno dla każdej grupy. Grupowania dokonuje się przy pomocy klauzuli GROUP BY z podaniem atrybutów definiujących grupy. Jeśli mamy GROUP BY A1, ⃛, Ak dzielimy relację na grupy tak, że krotki są w tej samej grupie wtedy i tylko wtedy, gdy pasują do wszystkich atrybutów A1, ⃛, Ak. Przykład 1-6. Funkcje agregujące Jeśli chcemy znać liczbę produktów sprzedanych przez każdego dostawcę, zapisujemy zapytanie: SELECT S.SNO, S.SNAME, COUNT(SE.PNO) FROM SUPPLIER S, SELLS SE WHERE S.SNO = SE.SNO GROUP BY S.SNO, S.SNAME; i otrzymujemy: SNO SNAME COUNT -----+-------+------- 1 Smith 2 2 Jones 1 3 Adams 2 4 Blake 3 Teraz zobaczmy jak to się dzieje. Najpierw następuje złączenie tabel SUPPLIER i SELLS: S.SNO S.SNAME SE.PNO -------+---------+-------- 1 Smith 1 1 Smith 2 2 Jones 4 3 Adams 1 3 Adams 3 4 Blake 2 4 Blake 3 4 Blake 4 następnie grupowanie przez umieszczenie razem krotek z pasującymi atrybutami S.SNO i S.SNAME: S.SNO S.SNAME SE.PNO -------+---------+-------- 1 Smith 1 2 -------------------------- 2 Jones 4 -------------------------- 3 Adams 1 3 -------------------------- 4 Blake 2 3 4 W naszym przykładzie mamy cztery grupy i teraz możemy zastosować funkcję COUNT dla każdej grupy otrzymując rezultat podany wcześniej. Zauważ, że zapytanie z GROUP BY i funkcjami agregującymi ma sens, gdy odwołujemy się do atrybutów grupowanych. Inne atrybuty mogą być użyte tylko wewnątrz argumentu funkcji. Inaczej nie będzie unikalnej wartości do połączenia z innymi atrybutami.
Nie ma sensu użycie funkcji na przykład w takiej formie AVG(MAX(sno)), ponieważ SELECT robi tylko jeden przebieg grupowania i agregacji. Można otrzymać wynik tego typu przy użyciu tabeli tymczasowej lub podzapytania z pierwszym stopniem agregacji w klauzuli WHERE. 3.4.1.5 Having Klauzula HAVING działa podobnie do WHERE i jest używana do wybrania tylko grup spełniających warunek przy HAVING. Właściwie WHERE odrzuca niepotrzebne wiersze przed grupowaniem i agregacją, podczas gdy HAVING robi to po grupowaniu. Dlatego WHERE nie może odnosić się do rezultatu funkcji agregujących. Z drugiej strony nie ma sensu zapis warunku HAVING, który nie dotyczy funkcji agregujących. W takim wypadku lepiej zastosować WHERE. Przykład 1-7. Having Jeśli chcemy tylko tych dostawców, którzy sprzedali więcej niż jeden produkt, użyjemy zapytania: SELECT S.SNO, S.SNAME, COUNT(SE.PNO) FROM SUPPLIER S, SELLS SE WHERE S.SNO = SE.SNO GROUP BY S.SNO, S.SNAME HAVING COUNT(SE.PNO) > 1; i otrzymamy: SNO SNAME COUNT -----+-------+------- 1 Smith 2 3 Adams 2 4 Blake 3 3.4.1.6 Podzapytania W klauzulach WHERE oraz HAVING możliwe jest stosowanie podzapytań w miejsce jakichś wartości. W tym wypadku najpierw wykonywane jest podzapytanie. Użycie podzapytań rozszerza możliwości SQL. Przykład 1-8. Podzapytanie Jeśli chcemy znać wszystkie produkty kosztujące więcej od produktu o nazwie 'Screw', użyjmy zapytania: SELECT * FROM PART WHERE PRICE > (SELECT PRICE FROM PART WHERE PNAME='Screw'); Rezultat wygląda następująco: PNO PNAME PRICE -----+---------+-------- 3 Bolt 15 4 Cam 25 Patrząc na powyższe zapytanie zwrócimy uwagę na dwukrotne wystąpienie słowa SELECT. Pierwszy raz na początku zapytania - nazwijmy je zewnętrznym SELECT - i jeszcze raz w klauzuli WHERE, które rozpoczyna zapytanie zagnieżdżone - nazwijmy je wewnętrznym SELECT. Dla każdej krotki zewnętrznego SELECT'a wykonywany jest wewnętrzny SELECT. Po każdym wykonaniu znamy cenę produktu o nazwie 'Screw' i możemy sprawdzić czy nie jest większa od aktualnego produktu. (W tym wypadku wewnętrzne zapytanie jest wykonywane tylko raz, ponieważ nie jest zależne od stanu zapytania zewnętrznego). Jeśli chcemy poznać wszystkich dostawców, którzy nie sprzedają żadnego produktu (np. żeby usunąć ich z bazy) użyjemy : SELECT * FROM SUPPLIER S WHERE NOT EXISTS (SELECT * FROM SELLS SE WHERE SE.SNO = S.SNO); Nasze zapytanie nie zwróci nic, bo w naszej bazie dostawcy sprzedają co najmniej jeden produkt. Zauważ, że użyliśmy S.SNO z zewnętrznego SELECT w klauzuli WHERE wewnętrznego zapytania. W tym wypadku,