Relacja (ang.relation) Po podzieleniu danych na tabele i zdefiniowaniu pól kluczy podstawowych trzeba wprowadzić do systemu bazy danych informacje na temat sposobu poprawnego łączenia powiązanych danych w logiczną całość. W tym celu definiuje się relacje między tabelami. 1. relacja jeden-do-jednego W relacji jeden-do-jednego każdy rekord w tabeli A może mieć tylko jeden dopasowany rekord z tabeli B, i tak samo każdy rekord w tabeli B może mieć tylko jeden dopasowany rekord z tabeli A. Ten typ relacji spotyka się rzadko, ponieważ większość informacji powiązanych w ten sposób byłoby zawartych w jednej tabeli. Relacji jeden-do-jednego można używać do podziału tabeli z wieloma polami, do odizolowania części tabeli ze względów bezpieczeństwa, albo do przechowania informacji odnoszącej się tylko do podzbioru tabeli głównej. Typy relacji
3. Relacja wiele-do-wielu W relacji wiele-do-wielu, rekord w tabeli A może mieć wiele dopasowanych do niego rekordów z tabeli B i tak samo rekord w tabeli B może mieć wiele dopasowanych do niego rekordów z tabeli A. Jest to możliwe tylko przez zdefiniowanie trzeciej tabeli (nazywanej tabelą łącza), której klucz podstawowy składa się z dwóch pól kluczy obcych z tabel A i B. Relacja wiele-do-wielu jest w istocie dwiema relacjami jeden-do-wielu z trzecią tabelą. 2. Relacja jeden-do-wielu Relacja jeden-do-wielu jest najbardziej powszechnym typem relacji. W relacji jeden-do-wielu rekord w tabeli A może mieć wiele dopasowanych do niego rekordów z tabeli B, ale rekord w tabeli B ma tylko jeden dopasowany rekord w tabeli A.
Łączenie poprzez JOIN Składnia polecenia SELECT z klauzulą JOIN jest następująca: SELECT * FROM table1 JOIN table2 ON condition... W przypadku wyświetlania danych z kilku tabel może wystąpić sytuacja, w której kolumny kilku tabel, a nawet same tabele (w przypadku związków rekurencyjnych) będą się powtarzać. W przypadku kolumn problem ten rozwiązywany jest poprzez poprzedzenie ich nazw zakończonej kropką nazwą tabeli, do której należą. (np. Osoby.Imie). W przypadku tabel możemy zastosować klauzulę AS, które zamienia nazwę danej tabeli na inną (np. Osoby AS Rodzice). Jeśli chcemy wyświetlić dane z wielu tabel konieczne jest określenie sposobu łączenia krotek występujących w tych tabelach. W domyślnej postaci tworzony jest bowiem iloczyn kartezjański wszystkich krotek, co zazwyczaj nie jest pożądane. Rozwiązaniem tego problemu może być określenie warunku, który będzie wymagał aby wartości kolumn w dwóch tabelach były identyczne (np. Osoby.PESEL = Adresy.PESEL). To rozwiązanie nie jest jednak doskonałe, gdyż w wyniku zostaną pominięte krotki, których wartość (lub zbiór wartości) dla łączonych atrybutów nie występuje w łączonej tabeli.
condition określa sposób łączenia krotek. Zazwyczaj w warunku będzie wymagało się, żeby wartość kolumny w jednej tabeli była taka sama jak wartość kolumny w innej tabeli (table1.columnA = table2.columnB). Występują trzy wersje klauzuli JOIN: INNER LEFT [OUTER] RIGHT [OUTER] W przypadku INNER JOIN dana krotka zostanie uwzględniona wyłącznie w wypadku, gdy w drugiej tabeli występuje krotka (lub krotki), których wartość dla kolumn określonych w warunku jest taka sama. Klauzula INNER jest opcjonalna (tzn. klauzula JOIN bez modyfikatorów działa jak INNER JOIN). W przypadku LEFT JOIN dana krotka zostanie uwzględniona w wyniku, nawet jeżeli w drugiej tabeli nie będzie krotek, które mogłyby być z nią połączone (dla których były spełniony warunek ON…). W przypadku RIGHT JOIN uwzględniane są krotki z drugiej tabeli, które nie posiadają odpowiedników wśród krotek tabeli pierwszej.
Przykład Tabela Osoby(Imie, Nazwisko, PESEL) Imie Nazwisko PESEL Jan Andrzejewski 345 Jan Wojtkiewicz 123 Wojciech Kowalski 123 Tabela Adresy(PESEL, Ulica, Nr) PESEL Ulica Nr 123 Sobieskiego Zielonego Abecadło 1
Składnia połaczeń pozwala jawnie wskazać relację, której wszystkie krotki mają być zachowane. Dodatkowo składnia pozwala na wykonanie obustronnego połaczenia zewnetrznego. Uwaga! Słowo „OUTER” jest opcjonalne. Połączenia zewnętrzne SELECT nazwa, nazwisko, etat FROM ZESPOLY z LEFT OUTER JOIN pracownicy p ON z.id_zesp = p.id_zesp; SELECT nazwa, nazwisko, etat FROM zespoly z RIGHT OUTER JOIN PRACOWNICY p ON z.id_zesp = p.id_zesp; SELECT nazwa, nazwisko, etat FROM ZESPOLY FULL OUTER JOIN PRACOWNICY USING (id_zesp);
Wiersze z obu relacji nie posiadające odpowiedników spełniających warunek połączenia nie są wyświetlane. W efekcie zespół 50 „Badania operacyjne” nie zostaje wyświetlony. Połączenie zewnętrzne zachowuje wszystkie krotki z wybranej relacji, łącząc je z "wirtualnymi" krotkami z drugiej krotki. "Wirtualne" krotki są wypełnione wartościami pustymi. Połączenie zewnętrzne nazywa się te outer join. SELECT z.id_zesp, z.nazwa, p.nazwisko FROM ZESPOLY z, pracownicy p WHERE p.id_zesp (+) = z.id_zesp; SELECT z.id_zesp, z.nazwa, p.nazwisko FROM zespoly z, PRACOWNICY p WHERE p.id_zesp = z.id_zesp (+);
Połączenia zewnętrzne NAZWISKO ID_ZESP Siekierski 20 Dolny (null) ID_ZESP NAZWA 20 SYSTEMY ROZPROSZONE ? ID_ZESP NAZWA 20 SYSTEMY ROZPROSZONE 50 BADANIA OPERACYJNE (null) NAZWISKO ID_ZESP Siekierski 20 ? (null)
SELECT nazwisko, nazwa FROM pracownicy CROSS JOIN zespoly; NAZWISKO Marecki Janicki Nowicki NAZWA ALGORYTMY BADANIA OPERACYJNE SYSTEMY EKSPERCKIE SYSTEMY ROZPROSZONE ADMINISTRACJA Najprostszym typem połączenia jest tzw. „iloczyn kartezjański” (albo cross-join). W wyniku iloczynu kartezjańskiego powstaje relacja, która zawiera wszystkie atrybuty z obu relacji. Połączenie krzyżowe
„Połączenia zwrotne” (self join) są specjalnym przypadkiem połączeń, w których łączymy tabelę z samą sobą. Połączeniem zwrotnym może być dowolny typ połączenia (wewnętrzne, zewnętrzne, równościowe i nierównościowe), za wyjątkiem połączenia naturalnego, co wynika z faktu, że łączenie równościowe relacji z samą sobą według atrybutów o tej samej nazwie nic nie daje (co najwyżej oryginalną relację). Przykładowym zastosowaniem połączeń zwrotnych może być znajdowanie nazwiska szefa dla każdego pracownika. W relacji PRACOWNICY, dla każdego pracownika pamiętany jest identyfikator pracownika, który jest jego szefem. Aby odnaleźć nazwisko szefa należy połączyć relację PRACOWNICY z samą sobą, stosując warunek połączeniowy ID_PRAC=ID_SZEFA. Połoczenie typu self join
PRACOWNICY ID_PRAC NAZWISKO ID_SZEFA 190 Kotarski Kowalski Nowak 100 PRACOWNICY ID_PRAC NAZWISKO ID_SZEFA 190 Kotarski Kowalski Nowak 100 PRACOWNICY ID_PRAC NAZWISKO ID_SZEFA 190 Kotarski Kowalski Nowak 100
SELECT p.nazwisko AS pracownik, s.nazwisko AS szef FROM pracownicy p JOIN pracownicy s ON p.id_szefa = s.id_prac; PRACOWNIK SZEF Kowalski Nowak Nowak Marecki Nowicki Marecki Janicki Marecki
Imie Nazwisko Osoby.PESEL Adresy.PESEL Ulica Nr Jan Andrzejewski 345 NULL NULL NULL Jan Wojtkiewicz sobieskiego 17 Jan Wojtkiewicz zielonego 15 Wojciech Kowalski sobieskiego 17 Wojciech Kowalski zielonego 15 Dla zapytania: SELECT Imie, Nazwisko, Osoby.PESEL, Adresy.PESEL, Ulica, Nr FROM Osoby JOIN Adresy ON Osoby.PESEL = Adresy.PESEL otrzymamy wynik: Imie Nazwisko Osoby.PESEL Adresy.PESEL Ulica Nr Jan Wojtkiewicz sobieskiego 17 Wojciech Kowalski sobieskiego 17 Jan Wojtkiewicz zielonego 15 Wojciech Kowalski zielonego 15 SELECT Imie, Nazwisko, Osoby.PESEL, Adresy.PESEL, Ulica, Nr FROM Osoby LEFT JOIN Adresy ON Osoby.PESEL = Adresy.PESEL otrzymamy wynik: Dla zapytania:
Imie Nazwisko Osoby.PESEL Adresy.PESEL Ulica Nr Jan Wojtkiewicz sobieskiego 17 Wojciech Kowalski sobieskiego 17 Jan Wojtkiewicz zielonego 15 Wojciech Kowalski zielonego 15 NULL NULL NULL 111 abecadlo 1 SELECT Imie, Nazwisko, Osoby.PESEL, Adresy.PESEL, Ulica, Nr FROM Osoby RIGHT JOIN Adresy ON Osoby.PESEL = Adresy.PESEL Dla zapytania: otrzymamy wynik: