Bazy danych Wykł. prof. W. Khadzhynov p. 310 _____________________________________________________________ _________ Literatura: 1. Arkadiusz Jakubowski. Podstawy SQL, Helion, 2001. 2. Marcin Szeliga. ABC języka SQL, Helion, 2002. 3. Ben Forta. Poznaj SQL, SAMS Pub, 2000. 4. Janusz Graf. ACCESS 97, Helion, 2000. 5. Kopertowska M., Jaroszewski Ł. Ćwiczenia z bazy danych ACCESS 97 , Mikom 6. M.Muraszkieicz, H.Rybiński. Bazy danych, Akademicka Oficyna Wydawnicza PLJ, Warszawa, 1998. 7. C.J.Date. Wprowadzenie do systemów baz danych, Klasyka Informatyki,Wydawnictwa Naukowo-Techniczne, Warszawa, 2000. 8. Maria Chałon. Systemy baz danych. Wprowadzenie, Oficyna Wydawnicza Politechniki Wrocławskiej,Wrocław 2001. BAZY DANYCH Treść Wstęp do baz danych .................................................................................... 5 Systemy informacyjne .................................................................................................. 5 Systemy plików ............................................................................................................ 7 Bazy danych. Głównie pojęcia i definicji. .................................................................... 14 Architektura baz danych............................................................................ 20 Trzywarstwowa architektura ANSI.............................................................................. 20 Kategorie użytkowników BD ....................................................................................... 24 Klasyfikacja modelów danych .................................................................................... 24 Logiczne modele danych ............................................................................ 28 Model hierarchiczny (hierarchical model) ................................................................... 28 Sieciowy model danych (network model) ................................................................... 31 Relacyjny model danych (Relation model) ................................................................. 32 Główne definicje..................................................................................................................... 32 Operacje nad relacjami (algebra relacji) .............................................................................. 41 Definicje języka SQL .................................................................................................. 52 Typy danych języka SQL ........................................................................................... 53 Tworzenie tabeli ..................................................................................................................... 54 Wartość pusta NULL .............................................................................................................. 54 Instrukcja DQL ( Data Query Language) SELECT ..................................................... 54 Zapytania SELECT do wielu tabel ......................................................................................... 60 Funkcji agregujące, klauzuli HAVING i ORDER BY w instrukcji SELECT. ......................... 62 Włożone instrukcje SELECT .................................................................................................. 65 Funkcje daty .............................................................................................................. 67 Funkcje tekstowe ....................................................................................................... 68 Funkcje matematyczne .............................................................................................. 70 Funkcje konwersji ...................................................................................................... 72 Instrukcja INSERT ................................................................................................................. 72 Instrukcja DELETE ................................................................................................................ 73 Instrukcja UPDATE ............................................................................................................... 74 Instrukcje DDL (Data Definition Language ) ............................................................... 74 Instrukcja CREATE TABLE ................................................................................................... 74 Instrukcja DROP TABLE ....................................................................................................... 75 Instrukcja ALTER TABLE ...................................................................................................... 75 Stworzenia tabel wirtualnych – widoków (perspektyw) ......................................................... 77 Stworzenie indeksów .............................................................................................................. 78 Zapamiętane procedury (Stored Procedure) oraz funkcje .......................................... 80 Instrukcji sterowania dostępu do danych .................................................................... 83 Instrukcja GRANT .................................................................................................................. 84 Instrukcja REVOKE ............................................................................................................... 84 Wykorzystywanie transakcji w SQL ............................................................................ 85 Automatyczne zatwierdzanie transakcji ................................................................................. 88 Instrukcja BEGIN ................................................................................................................... 88 Instrukcja COMMIT ............................................................................................................... 89 Instrukcja ROLLBACK........................................................................................................... 89 Instrukcje SAVEPOINT, ROLLBACK TO SAVEPOINT ........................................................ 89 Zanurzony SQL (Embedded SQL) ............................................................................. 91 Cykl życiowy bazy danych (Life cycle of the database) .............................................. 95 2 BAZY DANYCH Normalizacja relacji .................................................................................................. 100 Pierwsza forma normalna (1NF) ......................................................................................... 100 Druga forma normalna (2NF) ............................................................................................. 103 Trzecia forma normalna (3NF) ............................................................................................ 106 Projektowanie modelu konceptualnego .................................................................... 111 Przekształcenie ER – modelu (modelu infologicznego) do modelu relacyjnego (modelu fizycznego) ............................................................................................................... 119 Przykład projektowania bazy danych ....................................................................... 123 Etap planowania projektu bazy danych ............................................................................... 123 Etap projektowania bazy danych ........................................................................................ 126 Utrzymanie integralności bazy danych ..................................................................... 129 Ograniczenia obowiązkowej obecności danych ................................................................... 129 Ograniczenia wartości atrybutów ........................................................................................ 130 Integralność encji (entity integrity) ...................................................................................... 130 Warunek UNIQUE ............................................................................................................... 131 Integralność odwołań (referential integrity) ........................................................................ 131 Dostęp do baz danych ............................................................................... 132 Standard ODBC (Open Database Connectivity) ....................................................... 132 Uniwersalne strategii dostępu ................................................................................. 135 Dostęp w Jawie przez JDBC - sterownik .................................................................. 140 Przykład stworzenia tablicy w aplikacji JAVA ..................................................................... 143 Przykład konstruowania zapytań do bazy danych w aplikacji Java ................................... 144 Rozproszone systemy danych .................................................................. 147 Modeli rozproszonych funkcji ................................................................................... 148 Serwer plików ....................................................................................................................... 151 Zdalny dostęp do danych ...................................................................................................... 153 Serwery bazy danych ............................................................................................................ 154 Serwer aplikacji ................................................................................................................... 156 Modeli rozproszonych danych .................................................................................. 157 Architektura Oracle Network Computing Architekture (NCA) .................................... 161 Struktury plików wykorzystywane dla przechowania informacji w bazach danych ........................................................................................... 163 Struktury plików dla metod szeregowego dostępu .................................................... 164 Struktury plików dla metod dostępu bezpośredniego (dowolnego) ........................... 168 Metody mieszające ............................................................................................................... 168 Struktury plików dla metod indeksowanych ......................................................................... 173 Zarządzanie transakcjami ....................................................................... 181 Cechy transakcji....................................................................................................... 181 Anomalne historii przetwarzania transakcji ............................................................. 185 1. Nieodtwarzalne historie przetwarzania. .......................................................................... 186 2. Historie przetwarzania z kaskadą odrzuceń..................................................................... 187 3. Historie przetwarzania z anomalią powtórnego czytania. ............................................... 188 4. Historie przetwarzania z fantomami. ............................................................................... 188 Przetwarzanie transakcji na różnych poziomach izolacji .......................................... 189 Czytanie danych z transakcji nie zatwierdzonych (poziom izolacji 0) ................................. 189 Zakaz czytania danych z transakcji nie zatwierdzonych (poziom izolacji 1). ...................... 190 Zakaz czytania i zapisywania danych w transakcjach nie zatwierdzonych (poziom izolacji 2). .............................................................................................................................................. 191 Historie szeregowalne (poziom izolacji 3) ........................................................................... 191 3 BAZY DANYCH Szeregowalność transakcji ...................................................................................... 193 Zarządzanie transakcjami w języku SQL .................................................................. 196 Metody sterowania współbieżnością transakcji na różnych poziomach izolacji......... 200 Metody blokowania danych.................................................................................................. 200 Algorytm blokowania dwufazowego..................................................................................... 202 Zakleszczenia transakcji....................................................................................................... 206 Metody znaczników czasowych. ........................................................................................... 208 Odtwarzanie bazy danych ........................................................................................ 209 Odtwarzanie bazy danych przy uszkodzeniach pamięci ulotnej ........................................... 210 Odtwarzanie bazy danych przy uszkodzeniach pamięci trwałej .......................................... 214 Pytania kontrolne po kursu „Bazy danych” dla studentów studiów wieczorowych............................................................................................. 216 Pytania kontrolne po kursu „Bazy danych” dla studentów studiów dziennych ................................................................................................... 217 4 BAZY DANYCH Wstęp do baz danych Historia programowania komputerów zawiera dwa główne kierunki swojego rozwoju: Wykonanie złożonych obliczeń inżynierskich, które nie można wykonać w ogóle bez komputerów; Wykorzystanie komputerów w automatyzowanych systemach informacyjnych. Rozwój pierwszego kierunku sprzyjał stworzeniu metod oraz algorytmów numerycznych. Główną cechą tego zakresu są złożone algorytmy oraz metody obróbki danych i proste struktury danych, które trzeba obrabiać. Drugi kierunek bezpośrednio dotyczy tematu niniejszego kursu i jest związany z wykorzystaniem komputerów dla magazynowania danych mających złożone struktury. Ten kierunek powstał późnej pierwszego, ponieważ wcześniej nie było dużych i niezawodnych komputerów dla realizacji tych zadań. Teraz jest to najważniejszym kierunkiem w rozwoju informatyki, ponieważ wartość danych często dużo przekracza wartość współczesnych superkomputerów. Systemy informacyjne Systemy informacyjne (SI) – to są oprogramowanie (Software), sprzętowe (Hardware) oraz organizacyjne (Organizational) zasoby, oraz resursy informacyjne, które pozwalają wypełnić zbiór, przetwarzanie (processing), magazynowanie (Data storage) i rozpowszechnienie informacji wewnątrz organizacji. Informatyka jest dziedziną o charakterze interdyscyplinarnym. Główne zakresy zastosowania Systemów informacyjnych: Przyjęcie decyzji Handel Finanse Banki Energetyka Transport Produkcja. Główne komponenty typowego systemu informacyjnego (rys.1): 1. Zasoby zabezpieczenia SI 2. Magazyn informacyjny (Information storage) 3. Personel projektantów (developers) i użytkowników 5 BAZY DANYCH Chief ... Dep(A) Dep(B) Dep(N) Informations system documents paper Electronic Out Enter Fig. 1 6 BAZY DANYCH Zasoby zabezpieczenia SI: Organizacyjne Prawnicze Programowe Sprzętowe Wymogi do magazynów informacyjnych(Data Store): niezawodne magazynowanie danych o wielkiej objętości wykonanie różnych przetwarzań informacji szybkie wyszukiwanie informacji wygodny interfejs dla użytkowników Główne sposoby istnienia Magazynów informacyjnych: Twarde kopii (papierowe) Systemy plików ( na dyskach twardych i dyskietkach) Bazy danych Mieszane. Systemy plików Systemy plików są pierwszymi zasobami automatyzacji komputerowej. Plikiem nazywamy sekwencję rekordów, która ma imię i jest przechowywana w zewnętrznej pamięci komputera. Plik może być wykorzystywany przez jedna lub kilka aplikacji. Aplikacja - to jest program, przeznaczony dla automatyzacji funkcji i zadań systemu informacyjnego . Aplikacji składają oprogramowanie systemu informacyjnego. Miejsce systemu informacyjnego we współczesnym zakładzie umownie pokazano na rys 1. Dostęp do pliku z aplikacji urzeczywistni się za pomocą systemu sterowania plikami, który jest częścią systemu operacyjnego. Każda aplikacja wykorzystuje następny zestaw operacji: Stworzyć plik (Create File) Otworzyć plik (Open File) Zamknąć plik (Close File) Odczytać rekord (Read record) Zapisać rekord (Write record). Przykład magazynowania informacji przy pomocy systemu plików pokazany jest na rysunku 2. Tu umownie przedstawiona struktura zakładu pracy, mającego kilka oddziałów (departamentów). W każdym oddziale wykonują się zadania informacyjne, związane z działalnością zakładu. 7 BAZY DANYCH Zadaniom informacyjnym odpowiadają aplikacji. Każda aplikacja ma dostęp do jednego lub wielu plików. Aplikacji mogą wspólnie korzystać z pewnych plików. Pliki mogą być przekazywane innym oddziałom, jeśli tego potrzebują wymagania funkcjonalne. Przy magazynowaniu informacji przez system plików, każda aplikacja powinna „znać” z dokładnością do 1 bita strukturę rekordów odpowiedniego pliku. To wymaganie związane jest ze specyfiką działania systemów operacyjnych. Główne wady systemów plików: Izolowanie danych Dublowanie danych Zależność od danych Niekompatybilność plików Rozpatrzymy każdą z tych wad. Izolowanie danych. Powstaje, kiedy dane są izolowane w osobnych plikach. Dostęp do nich jest utrudniony. Na przykład (rys.3), dla stworzenia pliku Kontrakty (Contracts) w departamencie C trzeba zmodyfikować plik Wynajęci potencjalne (Renters), który jest stworzony w departamencie A, oraz zmodyfikować plik Nieruchomości (Property for 8 BAZY DANYCH Company Dep. (A) . . . Dep.(N) . . . User Application User Application 1. Data entry 2. Output of reports 1. Data entry 2. Output of reports Support Definition of files of files Support Definition of files of files . . . Files of a dep. N Files of a dep. A fig 2. 9 BAZY DANYCH Dep.A ... ... Renters Dep.B ... Property for Rent ... Dep.C Processing Contrakts Fig.3. 10 BAZY DANYCH Rent), który jest stworzony w departamencie B. Te pliki, zgodnie z wymogami funkcjonalnymi, są stworzone i obsługiwane, w innych departamentach. Wszystkie te pliki powinny mieć najbardziej aktualne informację, inaczej plik Kontrakty będzie błędny. I tu powstaje problem: departament C nie jest odpowiedzialnym za uaktualnienie informacji w departamentach A i B. W praktyce w departamencie C muszą być stworzone wszystkie potrzebne pliki. Sytuacja pogarsza się tym, że takich plików staje dużo. Skutkiem tego jest decentralizowana praca z danymi, kiedy pliki danych muszą mieć kopie w różnych departamentach. Dublowanie danych. Dublowanie jest skutkiem izolowania danych, prowadzi do nieekonomicznego zastosowania sprzętu oraz do naruszenia integralności danych. Ta sytuacja polega na tym, że te same dane w różnych departamentach mogą być sprzecznymi. Na przykład, zmiany danych o pracownikach mogą być wykonane tylko w departamencie A. W innych kopiach tego pliku, w innych departamentach pewny czas będzie zostawać stara informacja. Ten przykład pokazano na rys. 4. Departament E tu dubluje wszystkie dane innych departamentów. Zależność od danych. Fizyczna struktura rekordów plików i sposoby dostępu do nich muszą być wyznaczone we wszystkich aplikacjach, które używają te pliki. Jakakolwiek zmiana struktury rekordów w pliku potrzebuje, oprócz stworzenia nowego pliku i kopiowania do niego wszystkich rekordów, również wprowadzenia zmian we wszystkich aplikacjach, które mają dostęp do tego pliku. Ta sytuacja jest pokazana na rys. 5. Tu trzeba zmienić długość dwóch rekordów w pliku, mającego związki z wielu aplikacjami. Na rysunku pokazano kroki, które trzeba wykonać. Niekompatybilność plików. Różne aplikacje mogą być zaprogramowane w różnych językach programowania, poza tym różne systemy programowania mają różne formaty danych. Skutkiem tego jest sytuacja, że pliki, stworzone w różnych systemach programowania będą niekompatybilne.. Ta sytuacja jest pokazana na rys. 6. Główne przyczyny wad systemów plików : 1. Definicja danych zlokalizowana w aplikacjach, i nie jest przechowywana osobnie od nich. 2. Bezpośredni dostęp do danych dokona się bezpośrednio z poziomu aplikacji, a nie z poziomu jednorodnych metod dostępu. 11 BAZY DANYCH DataArea of department A DataArea of department B DataArea of department E DataArea of department C DataArea of department D Fig. 4 12 BAZY DANYCH Application 1 . . . Application N ... Char (40) Adres Char (50) Name ... Property for Rent 1.Create new File 2.Create "File Copy Application" 3.Change Applications 1-N ... Char (44) Adres Char (60) Name ... Property for Rent Fig.5 13 BAZY DANYCH Bazy danych. Głównie pojęcia i definicji. Baza danych to jest wspólnie wykorzystywany zbiór logicznie połączonych danych, przeznaczony dla zadowolenia informacyjnych potrzeb organizacji oraz reprezentujący bieżący stan obiektów informacyjnych . System zarządzania bazą danych (SZBD) (Data Base Management System – DBMS) to jest zbiór językowych zasobów i aplikacji, przeznaczonych do stworzenia oraz wspólnego wykorzystania informacyjnych obiektów przez wielu użytkowników. Z tych definicji wynika , że BD jest korporacyjnym informacyjnym resursem. Konstrukcja magazynów informacyjnych przy pomocy BD pokazana jest na rys.7. Tu wszystkie aplikacje odwołują się do wspólnego resursu informacyjnego wykorzystując jedyny wspólny interfejs z SZBD (DBMS). Aplikacje użytkownika tu nie definiują dane, nie dokonują również bezpośredniego dostępu do danych, jak to było w systemach plików. Wszystkie operacje współdziałania z SZBD (DBMS) składają się z realizacji zapytań sformalizowanych: wprowadzenie czy modyfikacja danych lub otrzymanie raportów (reports). Taka konstrukcja magazynów informacyjnych nie ma wad, które były w systemach plików. Rozpatrzymy bardziej szczegółowo wyznaczone wyżej pojęcia. SZBD (DBMS) – to jest oprogramowanie, które użytkownicy mogą definiować, tworzyć, podtrzymywać (support) BD, a również mieć dostęp do danych. Dlatego SZBD (DBMS) składa się z dwóch komponentów (rys.8): Języka definicji danych (Data Definition Language -DDL); Języka manipulacji danymi (Data Manipulation Language – DML). Baza danych istnieje w systemie plików systemu operacyjnego. W systemie plików BD ma następujące obszary: obszar danych obszar metadanych (Metadata). Obszar danych - to są pliki z rekordami zawierającymi informacje główne. Obszar metadanych zawiera pliki, które zawierają informacje o strukturze danych, połączeniach logicznych, prawach dostępu użytkowników, ich fizycznego rozmieszczenia. 14 BAZY DANYCH Współdziałanie tych komponentów pokazano na rys.9. 15 BAZY DANYCH Company . . . Department (A) Department (N) . . . User Application 1. Data entry 2. Output of reports User Application 1. Data entry 2. Output of reports . . . Database Management System (DBMS) Fig. 7. Database Files 16 BAZY DANYCH Podstawową cechą systemów baz danych jest to, że dane i związane z nimi programy (aplikacje) są od siebie oddzielone. DBMS - to program uruchamiany w pamięci wewnętrznej komputera i kontrolowany przez odpowiedni system operacyjny. Baza danych jest przechowywana w systemie plików. DBMS działa jako interfejs między aplikacjami i bazą danych. Ten interfejs realizuje się przez DDL i DML. Dostęp do BD realizuje wewnętrzny (internal) interfejs do systemów plików. DBMS realizuje następujące funkcje wewnętrzne: Dodawanie nowych plików do bazy danych; Usuwanie plików z bazy danych; Modyfikowanie struktury istniejących plików; Uzupełnienie nowymi danymi istniejących plików; Aktualizacja danych w istniejących plikach; Usuwanie danych z istniejących plików; Wykorzystanie danych z istniejących plików przez różne aplikacje; Tworzenie i monitorowanie użytkowników BD; Ograniczenie dostępu do plików w BD; Monitorowanie działania BD. Użytkownik nie ma bezpośredniego dostępu do tych funkcji. DBMS sama aktualizuje te funkcji. Główne przewagi BD nad systemami plików : Brak zbytecznych danych (Redundant data) Integralność danych (kompatybilność) Wspólne wykorzystanie Bezpieczeństwo danych Podtrzymywanie (Support) danych Niezależność (Independence) od aplikacji 17 BAZY DANYCH DBMS DDL (Data DML Definition (Data Manupulation Language Language) ) Database Files Data dictionary Files Meta-data ... Data Files Fig.8 18 BAZY DANYCH ... User Application DBMS DBMS - Interface DDL (Data Definition Languare) DML (Data Manupulation Languare) Internal Database-File System Interface Files System Data dictionary fig. 4 ... Metadata Fig.9 Data 19 BAZY DANYCH Równoległy dostęp różnych aplikacji Skuteczna obsługa Główne wady BD: Duże wymagania do komputerów; Duże koszty; Potrzeba w doświadczonych specjalistach; Wrażliwość na sytuacje awaryjne; Architektura baz danych Trzywarstwowa architektura ANSI Powinna być jedyna koncepcja przy tworzeniu wszystkich baz danych. Koncepcja musi zapewnić przewagi bazy danych przed systemami plików. Ta koncepcja musi być odpowiednia do standardów światowych. Tym standardem jest trzech poziomowy model ANSI (American National Standarts Institute). Rozpatrzymy ten standard. On zawiera 3 poziomy (rys. 10): 1. Zewnętrzny (External Level) 2. Pojęciowy (Conceptual Level) 3. Wewnętrzny lub fizyczny (Internal Level, Phisycal Level). Zewnętrzny poziom (External Level) - odzwierciedla specyficzne definicje każdego użytkownika (i ego aplikacji) na strukturę danych. Każda aplikacja ma dostęp i przetwarza tylko te dane, które są jej potrzebne. Na przykład, system podziału prac na firmie wykorzystuje wiadomości o kwalifikacji pracownika. Dla tego systemu nie potrzebne są dane o np. wynagrodzeniu pracownika, ego adresie, numerze telefonu itd. Te wiadomości interesują oddział kadrów i kwestura. Pojęciowy poziom (Conceptual Level) – BD prezentowana w postaci schematu konceptualnego, który jednoczy dane zewnętrznego poziomu z których korzystają wszystkie użytkownicy z ich aplikacjami. Pojęciowy poziom – to jest ogólny model przedmiotów rozważań (universe of discourse), które wyznaczają wszystkie obiekty bazy danych. Ten model nie bierze pod uwagę kwestii fizycznej realizacji danych. Wewnętrzny (fizyczny) poziom (Internal Level , Phisycal Level). Wyznacza jak dane będą przechowywane w pamięci zewnętrznej. Trzywarstwowa architektura umożliwia logiczną i fizyczną niezależność danych. Logiczna niezależność – umożliwia zmianę jakiejkolwiek aplikacji bez potrzeby zmian w innych aplikacjach. 20 BAZY DANYCH ... User 1 User 2 view 1 view 2 User n ... view n External level Conceptual shema Conceptual level Internal shema Internal level fig.10 Files of Data Base 21 BAZY DANYCH Fizyczna niezależność - podaje możliwość przeniesienia informacji na inne plikowe systemy, komputery, dyski itd., przy czym wszystkie aplikacje zostają użytecznymi. Na rys.11 umownie przedstawiono niezależność warstwową. User Application ... view view 1 2 External level ... view n Logical data independence Conceptual shema Conceptual level Physical data independence Internal shema Internal level fig.11 22 BAZY DANYCH View 1 Sno FName LName Age Salary View 2 Staff_No LName BNo Conceptual level Staff_No FName LName DOB Salary BNo Internal level Struct STAFF { int Staff_No; int Branch_No; char FName [20]; char LName [20]; struct date Date_of_Birth; float Salary; struct STAFF *next; }; index Staf_No; Index Branch_No; fig.12 23 BAZY DANYCH Na rys.12 jest przedstawiony przykład opisy bazy danych na trzech warstwach. Dwa użytkownika mają różne schematy bazy danych na poziomie zewnętrznym. Konceptualny schemat na poziomie pojęciowym (Conceptual Level) jednoczy wszystkie schematy poziomu zewnętrznego. Na wewnętrznym (fizycznym) poziomie powstają opisy struktury plików oraz ich rekordów. Wewnętrzne opisy – to wynik pracy zasobów DBMS. Użytkownicy nie mają bezpośrednio dostępu do tych zasobów. Kategorie użytkowników BD Użytkownicy końcowe (Users) – to jest główna kategoria użytkowników, dla których stwarza się baza danych. Ta kategoria zawiera kierowników i wykonawców, które nie są specjalistami w zakresie informatyki. Współpraca użytkowników końcowych z BD jest możliwa za pomocą aplikacji lub języka zapytań – kwerend (query). Administratorzy bazy danych (DB Administrators) – grupa osób, odpowiedzialna za jedną lub więcej baz danych podtrzymywanych przez pewien DBMS. Administrator BD tworzy bazę danych oraz dba o jej spójność, integralność i bezpieczeństwo. Nadaje przywileje i prawa do korzystania z bazy danych dla poszczególnych użytkowników. Dla dostępu do danych administratorzy wykorzystają język definicji danych (DDL). Projektanci aplikacji (Programmers) – ta grupa istnieje tylko przy projektowaniu BD. Projektanci pracują tylko z tą częścią informacji, która potrzebna dla oznaczonej aplikacji. Dla dostępu do danych wykorzystują język manipulowania danymi (DML). Współdziałanie tych gryp z narzędziami DBMS pokazane jest na rys.13. Klasyfikacja modelów danych Zasadniczym pojęciem w koncepcji baz danych są kategorie „dane” oraz „model”. Dane – to jest zbiór wartości, parametrów, które charakteryzują rzeczywisty obiekt. Na przykład: Join Bull, Floryda, 30$. Te dane nie dają żadnej informacji , jeżeli nie pokazane ich związki. Model danych – to jest kategoria, która odzwierciedla związki danych między sobą oraz ich stosunki do obiektów świata rzeczywistego. Istnieje dużo różnych modeli danych. Ich klasyfikacja pokazana jest na rys. 14. Tu modeli są podzielone na trzy główne grupy: Infologiczne; Datalogiczne; 24 BAZY DANYCH Fizyczne. Infologiczne modele przeznaczone są dla opisu bazy danych na poziomach zewnętrznym i pojęciowym. Cechą szczególną tych modeli jest to, że one nie odwzorowują wewnętrzną strukturę danych, odwzorowują natomiast semantykę danych. Ta grupa modelów zawiera model „Encja – związek” które będziemy studiować. Datalogiczne modele (Logiczne modele) odwzorowują semantykę oraz wewnętrzną strukturę danych. Mogą być zastosowywane na zewnętrznym czy pojęciowym poziomach. Ta grupa zawiera: Model dokumentalny (documental model) - to jest model danych, który pozwala przedstawiać cały dokument jak jednostkę informacyjną. Model hierarchiczny(hierarchikal model) - to jest model danych, w którym dopuszczalnymi strukturami danych są struktury hierarche (drzewa) . Model sieciowy (network model), to jest model danych, w którym związki asocjacyjne pomiędzy danymi są reprezentowane poprzez powiązania wskaźnikowe. Model relacyjny (relation model), to jest model danych, oparty o pojęcie relacji, zaproponowany przez E.F.Codda z IBM w 1970 r. Fizyczne modele - to modele oparte na strukturach plikowych albo na innych sposobach. 25 BAZY DANYCH Programmer User DBMS Applications Query Preprocessor DML Object code DB Administrator Shema DB Processor of query DDL compiler DataBase controller Dictionary controller Filles System System buffers DataBase fig.13 26 BAZY DANYCH Models of data InfoLogical models Models of Entity link DataLogical models Physical models Documental models File structures Hierarchical models Segment page organization Network models Relational models fig. 14 27 BAZY DANYCH W niniejszym kursie Baz Danych będziemy studiować także i relacyjne modeli, ze względu na to, że współczesne technologie projektowania baz danych na 90% używają właśnie te modele. Logiczne modele danych Model hierarchiczny (hierarchical model) Model hierarchiczny to jest model danych, łączące wszystkie rekordy we wspólnej strukturze drzewa. Na korzeniu drzewa (hierarchii) znajduje się jeden typ rekordu, który ma 0 czy wiele typów rekordów podległych. Każdy typ podległy może mieć też 0 lub wiele innych typów rekordów podległych. Jakikolwiek rekord, oprócz korzeniowego, może mieć tylko jeden rekord macierzysty (parent record). Przykład modelu hierarchicznego pokazany na rys.16. Główne komponenty informacyjne w modelu hierarchicznym są następne: Pole danych (data field) to jest minimalny, niepodzielny element danych, który jest dostępny dla użytkownika przez DBMS. Typ segmentu (type of a segment) to jest zbiór rekordów homogenicznych, które mają jedno imię i identyczne pola danych. Egzemplarz segmentu (albo po-prostu segment) (Copy of a segment) - to jest zbiór wartości pól, które składają jeden rekord. Na rys.16 pokazany przykład modelu hierarchicznego bazy danych klientów. Tu są kilka typów segmentów. Typ segmentu „Client” jest korzeniowym. Każdy egzemplarz segmentu „Client” jest związany z jednym albo z wielu egzemplarzami segmentu „Order”. Podobnie każdy egzemplarz segmentu „Order” może być związany z egzemplarzami segmentów „Product” i „Trade agent”. Każdy rekord (segment) zawiera odpowiednie pola. Przykład pól dla segmentu „Client” pokazany jest na rys.16. Pomiędzy segmentami w modelach hierarchicznych może być definiowany związek „jeden-do-wielu” czy „jeden–do–jednego”. Rekord, odpowiadający elementu „jeden” tego związku - jest macierzysty, a elementu „wielu” jest podległy. W modelach hierarchicznych dla każdego rekordu może być tylko jeden rekord macierzysty, przy czym każdy rekord, może być macierzystym dla wielu rekordów. W pokazanym na rys 16 schemacie bazy danych niemożliwe równoczesne istnienie związków („Order” - > „Trade agent”) oraz („Trade agent” - > ”Order”). Poszukiwania informacji pro ordery, które są związane z pewnym agentem , jest niemożliwe. 28 BAZY DANYCH Model hierarchiczny był pierwszym modelem danych i wiąże się z systemem IMS firmy IBM. Wady modelów hierarchicznych: 1. Niemożliwym jest przechowywanie rekordów, które nie mają rekordów macierzystych. Na przykład, skasowanie jednego rekordu segmentu typu „Client” skasuje związane z nim rekordy „Order”, :Product” i „Trade agent”. Dla nowych egzemplarzy segmentu typu „Client” trzeba wielokrotnie te rekordy stwarzać. 2. Niemożliwym jest realizacja związków typu „wiele do wielu”, na przykład związek („Product” -> „Order”) jest niedopuszczalny. 29 BAZY DANYCH Client Types of segments Order Product Trade agent Client Name Adress Phone Account Fields of a segment fig. 16 30 BAZY DANYCH Trade agent Agent-Ord ers Client Client Orders Order Order Products Product Orders Product Order 1..N Product 1..N Product Set - "Order Products" Order Set - " ProductOrders" fig. 17 Sieciowy model danych (network model) Sieciowy model danych to jest model danych, w którym związki asocjacyjne pomiędzy danymi są reprezentowane poprzez powiązania wskaźnikowe. Struktura danych tworzy więc graf, chyli sieć. 31 BAZY DANYCH Pomiędzy dowolnymi rekordami w modelach sieciowych może być zdefiniowany związek „jeden-do-wielu” za pomocą obiektu „Set”. Poprzedni przykład bazy danych będzie mieć strukturę, która jest przestawiona na rys. 17. Tu niema ograniczeń na ilość rekordów macierzystych. Żeby realizować związek typu „wiele-do-wielu”, trzeba definiować dwa obiekty „Set”, jak to jest pokazano na rys.17. Model sieciowy stanowił istotny postęp w stosunku do modelu hierarchicznego . Jego podstawowymi wadami są: 1. Obniżenie poziomu programowania do drugorzędnych szczegółów organizacji danych (koncepcja wskaźników) 2. Niski stopień niezależności danych od programów i na odwrót. Relacyjny model danych (Relation model) Główne definicje Relacyjny model danych – to jest ideologia informatyczna dotycząca organizacji baz danych, oparta o pojęcie matematyczne relacji i zaproponowana przez E.F.Codda z IBM w 1970 r. Definicja. N – wymiarowa relacja – to jest podzbiór iloczynu kartezjańskiego D D ... D 1 2 pewnych N zbiorów D , D ,..., D ( N 1 ) . 1 2 N Wyrażenie matematyczne relacji ma następny wygląd: R D D ... D 1 gdzie 2 D D 1 2 ... D N N , - iloczyn kartezjański . D , D ,..., D Źródłowe zbiory 1 domeny (Domains). 2 N mają jeszcze nazwę dziedziny czyli Iloczyn kartezjański – to jest komplet wszystkich możliwych kombinacji, każda z których zawiera N elementów (komórek), oraz każdy element której należy do swej domeny. Rozpatrzymy przykład przedstawiony na rys. 18. Iloczyn kartezjański zawiera 18 trójek. Każda trójka – to są następne elementy: 1. Nazwisko studenta 32 BAZY DANYCH 2. Nazwisko dyscypliny 3. Ewentualna ocena na egzaminie D 1 D 2 D 3 R ґ = {Johns, Smith,Berg} = {C++, Java} = {3, 4, 5} D 1 ґ D <Johns,c++,5> <Johns,java,4> <Smith,c++,3> <Berg,java,5> 2 ґ D 3 <Johns,c++,3> <Johns,c++,4> <Johns,c++,5> <Johns,java,3> <Johns,java,4> <Johns,java,5> <Smith,c++,3> <Smith,c++,4> ... <Berg,java,5> fig.18 33 BAZY DANYCH Sytuacja rzeczywista polega na tym, że każdej dyscyplinie dla każdego studenta może odpowiadać tylko jedna ocena, albo w ogóle nie być oceny, jeśli egzaminu jeszcze nie było. Relacja R na rys.18 odwzorowuje tą sytuację i zawiera tylko 4 wiersze tablicy. Relacja jest podstawowym pojęciem relacyjnego modelu danych, jednakże w ramach tego modelu ona ma nieco inne znaczenie równoważne – to jest tablica, która ma kolumny, odpowiadające domenom, a wiersze – to są komplety z N liczb, gdzie N – ilość komórek w wierszu. Wejście domeny w tablice nazywa się atrybutem (attribute) relacji. Jedna domena może kilka razy wchodzić do tablicy pod różnymi atrybutami. Na przykład, (R=Nazwisko_Studenta,Ocena_praktycznych_zajęć,Ocena_na_egzaminie) – drugi i trzeci atrybuty są połączone z domeną OCENY_W_UCZELNIE (3,4,5). Atrybut - to jest kolumna relacji (tablicy), która ma nazwę. Wiersze relacji (tablicy) mają w literaturze jeszcze następne nazwy: krotki, rekordy, zapisy (cortege). Konkretną wartością atrybutu w rekordzie jest pole rekordu. Ilość atrybutów w relacji (tablicy) jest stopień relacji (degree). Liczba kardynalna - to jest ilość rekordów pewnej relacji. Schemat relacji - to jest mający swoje imię zbiór imion atrybutów. Każdy atrybut w tym schemacie pokazuje jedną domenę, z której on jest związany . Wyrażenie matematyczne schematu relacji R ma następny wygląd: S R S R A1 , A2 ,... AN , Ai : Di Na rys. 19 jest pokazany następny schemat relacji: (Name, Discipline, Ball), D D D : : Name : 1 , Discipline 2 , Ball 3; Wartości atrybutów domen mają następny wygląd: D D D 1= {Johns, Smith, Berg}; 2 = {C++, Java}; = {3, 4, 5}. Definicja 3 34 BAZY DANYCH Schematy dwóch relacji są równoznacznymi, kiedy one mają identyczne stopnie oraz identyczne sekwencje atrybutów. To znaczy, że na identycznych pozycjach w różnych schematach znajdują się atrybuty z tych samych domen. Równoznaczność schematów relacji nie oznacza równoznaczność samych relacji. 35 BAZY DANYCH <Johns,c++,5> <Johns,java,4> <Smith,c++,3> <Berg,java,5> Atributs R Discipline Ball Johns c++ 5 Johns java 4 Smith c++ 3 Berg java 5 Cortege Cardinality Name Degree fig.19 36 BAZY DANYCH Na przykład, rozpatrzymy schematy relacji R, R1 oraz R2 dotyczące poprzedniego przykładu: S R1 (FirstName, The programming language, Rating), FirstName : D1 , The programming language Rating : S R2 Name D 3 : D2 , . ( Name , Rating , Discipline ) : D1 , Discipline : D2 , D Rating : 3. Dla tych schematów prawidłowymi są następne równości : S R S R1 , S R S R2 , S R1 S R2 . Własności relacji: Każda relacja ma unikalne (oryginalne) imię; nie istnieje dwóch relacji, mających tą same imię; Każda komórka relacji zawiera tylko jedną niepodzielną wartość Każdy atrybut relacji ma unikalne imię, nie istnieją dwóch atrybutów w jednej relacji, mających jednakowe imiona Każdy rekord w relacji jest unikalnym, nie istnieją dwóch identycznych rekordów w tej samej relacji Dwie relacje są równe, kiedy one mają równe wartości liczb kardynalnych oraz każdy rekord jednej relacji ma odpowiednią kopię w drugiej. Kolejność rekordów w relacji nie przeszkadza porównaniu różnych relacji. Model relacyjny - to jest zbiór połączonych pomiędzy sobą relacji, które odwzorowują niektórą dziedzinę przedmiotową . Dla określenia związków relacji pomiędzy sobą, wszystkie relacje powinny zawierać atrybuty , które są połączone tymi związkami w różnych relacjach. 37 BAZY DANYCH Klucz pierwotny (klucz główny) (primery key) relacji - to jest atrybut, czy zbiór minimalny atrybutów, których wartości identyfikują unikalne wszystkie rekordy relacji. Klucz obcy (foreign key) - to jest atrybut relacji, którego wartość jest wartością klucza pierwotnego (primery key) pewnej innej relacji. Rozpatrzymy przykład przedstawiony na rys. 20. Skonstruujemy model relacyjny, który zawiera dwie relacji: „Students” oraz „Students group”. To znaczy połączymy te tablicy w taki sposób, żeby było możliwe poszukiwanie informacji 38 BAZY DANYCH PRIMARY KEY R = Student's group GNum GSpeciality GDepartment ... ... ... ef01 Informatika Elektronica ep03 Programing Elektronica ... ... ... me03 Construction ... Mechanics ... R = Students PaspNum Name StGruppe ... ... ... Pl09867 Johnson ef01 AL06709 Smith ef01 AI67099 Berg me03 ... ... Fig.20 ... FOREIGN KEY 39 BAZY DANYCH w modelu bazy. Pomiędzy relacją „Students group” i relacją „Students” związek logiczny ma typ „jeden–do–wielu”, bowiem jakakolwiek grupa może mieć wiele studentów, a każdy student musi znajdować się tylko w jednej grupie. W relacji „Student” kluczem pierwotnym jest atrybut „PaspNum”, ponieważ numer legitymacji jest unikalnym dla identyfikacji każdego studenta. W relacji „Students group” kluczem pierwotnym jest „Gnum” (numer grupy), ponieważ w Uczelni nie może być grup z identycznymi numerami. Do relacji „Students” jest dodany atrybut „StGruppe”, który jest kluczem obcym tej relacji. Ten klucz łączy relacji „Students” oraz „Students group”. W pole „StGruppe” każdego rekordu relacji „Students” jest zapisana pewna wartość klucza pierwotnego relacji „Students group”. Klucz alternatywny - to jest klucz, który składa się z jednego lub kilku atrybutów, które jednoznaczne identyfikują rekordy w relacji, ale nie są wybrane przez klucz pierwotnym. Atrybut kluczowy – to jest atrybut, który jest częścią klucza pierwotnego, klucza alternatywnego lub klucza obcego. Zależność funkcyjna pomiędzy atrybutami relacji – to jest związek pomiędzy atrybutami A i B, gdzie każda wartość atrybutu A jest skojarzona z dokładnie jedną wartością atrybutu B. Wyrażenie matematyczne schematu relacji R ma następny wygląd: AB – A implikuje B. W ogóle A oraz B mogą zawierać grupy atrybutów. Rozpatrzymy przykład na rys. 20. W relacji „ Students group” są następne zależności funkcyjne: GNum Gspeciality GNum GDepartment Gspeciality GDepartment. Innych zależności funkcyjnych w tej relacji nie ma. Np. wartości atrybutu „GDepartment” nie mogą określać dokładnie wartości atrybutów „Gnum”, bowiem każdej wartości atrybutu GDepartment” mogą odpowiadać wiele wartości „Gnum”. W przykładzie na rys.19 istnieją zależności funkcyjne pomiędzy grupami atrybutów: (Name)(Discipline) Ball. Determinanta zależności funkcyjnej – to jest atrybut lub grupa atrybutów, która znajduje się w lewej części implikacji. Jako przykład na rys. 19 determinanta zawiera dwa atrybuty: (Name) oraz (Discipline). W relacji „Students” na rys 20 są następne zależności funkcyjne: 40 BAZY DANYCH (PaspNum, Name) (StGruppe) (PaspNum) (StGruppe). Całkowita zależność funkcyjna – to jest zależność funkcyjna, determinanta której nie zawiera zbytecznych atrybutów. W nadanych wyżej zależności funkcyjnych pierwsza nie jest całkowitą, a druga jest całkowita. Zależność tranzytywna - to jest zależność funkcyjna pomiędzy atrybutami, mająca taki wygląd: AB oraz BC. Zależność tranzytywna zawiera zależności funkcyjne pomiędzy atrybutami, które nie są kluczami. W przykładzie na rys. 20 w relacji „Students group” istnieją następne zależności tranzytywne: (Gnum) (Gspeciality) (Gspeciality) (GDepartment). Operacje nad relacjami (algebra relacji) Podstawowe założenia modelu relacyjnego są następne : Struktury danych w bazie danych są relacjami w sensie matematycznym, w których elementy rekordów (pola) są „atomami” (niepodzielne); Użytkownik lub programista aplikacyjny nie będzie miał możliwości zajmowania się szczegółami reprezentacji danych; Przetwarzanie danych odbywa się w językach bardzo wysokiego poziomu, posiadających syntaksy matematyczne (język SQL) , podstawą których jest algebra relacji; Relacje w bazie danych są wolne od anomalii aktualizacyjnych związanych z zależnościami funkcyjnymi (i innymi). Algebra relacji – to jest język operacji, które tworzą z zapamiętanych relacji nowe relacje poprzez zastosowanie operatorów algebraicznych, określanych jako selekcja (selection), projekcja (projection), iloczyn kartezjański, łączenie (join), suma zbiorów (union) i innych. Rozpatrzymy następne główne operatory algebry relacji. 1.Selekcja (selection) – to jest operator algebry relacji, który tworzy nową relację (R2) poprzez wybranie z wejściowej relacji (R1) wierszy spełniających pewien warunek (zwany predykatem). Wyrażenie matematyczne selekcji ma następny wygląd: R2 = SELECT (R1) {(cond) [{and / or} (cond)] [,…]} Dla wyjaśnienia formatów instrukcji wykorzystujemy notacje Bekusa (Backus Form). Główne elementy tej notacji są następujące: [xxx] – nie obowiązkowa obecność elementu w instrukcji {xxx} - obowiązkowa obecność elementu w instrukcji 41 BAZY DANYCH / - potrzeba wyboru jednego z kilku elementów rozdzielonych znakiem „/” … - nie obowiązkowa możliwość powtórzenia konstrukcji. Predykat (cond) zawiera pewien warunek w postaci wyrażenia logicznego, które jest określone na atrybutach relacji. To wyrażenie może mieć wartości „true” lub „false”. Rekordy (krótki), na atrybutach których to wyrażenie logiczne ma wartość „true”, wchodzą do ostatecznej relacji R2. Przykład. W modelu relacyjnym (rys. 20) trzeba wyznaczyć spis wszystkich studentów, które uczą się w grupie (ef01). Rozwiązanie: R = SELECT (Students)(StGruppe= „ef01”) 2. Projekcja (Projection) – to jest operator algebry relacji, który pozwala z zadanej relacji (R1) stworzyć nową relację (R2) o zmniejszonej liczbie kolumn. Z wynikowego zbioru rekordów nowej relacji są automatycznie wykluczone wiersze - duplikaty. Wyrażenie matematyczne projekcji ma następny wygląd: R2 = project (R1) (a1,a2,…aN), gdzie a1,a2,…aN – są nazwy atrybutów, które muszą być wyprodukowane z relacji R1 do relacji R2. Przykład. Mamy następny schemat relacji, zawierający dane o pracownikach zakładu: S Sno, Fname, Lname, Address, Tel _ No, Position, Sex, DOB , Salary , Bno Staff Trzeba otrzymać listę wszystkich pracowników zakładu, z zaznaczeniem wynagrodzenia każdego pracownika. Rozwiązanie: R = project (Staff) (Sno,Fname,Lname,Salary). 3.Iloczyn kartezjański (Cartesian produkt) – to jest operator, pozwalający z dwóch zadanych relacji (R1) oraz (R2) stworzyć nową relację (R3), wierszy której jest operacja konkatenacji każdej wierszy (R1) z każdej wierszą (R2). Ten operator ma dwie wchodzące relacji (R1) , (R2) oraz rezultat (R3). Przypuszczamy, że relacja (R1) ma I rekordów i N atrybutów, a relacja (R2) ma J rekordów i M atrybutów, wtedy ostateczna relacja (R3) będzie mieć (I x M) rekordów, oraz (N x M) atrybutów. Wyrażenie matematyczne iloczynu kartezjańskiego ma następny wygląd: R3 =(R1) product (R2). Popatrzymy następny przykład. Baza danych Uczelni zawiera relacji (R1) oraz (R2) z takimi schematami: 42 BAZY DANYCH Gr, Speciality , Fakulty 1.) S StGroup 2.) S Students PaspNum, Name, SGr Pierwsza relacja zawiera wszystkie grupy studentów Uczelni z takimi atrybutami: Gr – numer grupy, Speciality – specjalność wykształcenia. Fakulty – Widział Uczelni, gdzie jest ta grupa. Druga relacja zawiera spis wszystkich studentów Uczelni z takimi atrybutami: PaspNum – numer legitymacji (indeks), Name – nazwisko studenta, SGr – numer grupy. Trzeba skonstruować relację zawierające : nazwisko studenta , dani legitymacji, Widział wykształcenia. Schemat nowej relacji musi mieć następny wygląd: S PaspNum, Name, Faculty NEW Relacji R1 oraz R2 z danymi są pokazane na rys.21. Na tym rys. Jest pokazany także rezultat iloczynu kartezjańskiego tych relacji: R3 = (R1) product (R2). Analiza wierszy relacji R3 pokasuje, że niektóre z tych wierszy nie mają sensu. Na przykład, nie mają sensu wierszy : 2,3,4, 6,7,8. Wiersza np. 2 jest otrzymana za pomocą konkatenacji wierszy 1 z relacji R1, mający wartość atrybutu: Gr =Pr01 , z wierszą 2 relacji R2, mający inny kod grupy studentów : SGr = MP22. 43 BAZY DANYCH (R1) StGroup (R2) Students Gr Speciality Faculty PaspNum Name SGr Pr01 Programing Elektronica pl09867 Jonson Pr01 Mp22 MicProcess Elektronica al06709 Smith Mp22 Cn32 Constructor Mechanika ok90187 Berg Cn32 R3 = (R1) product (R2) Faculty Name SGr Pr01 Programing Elektronica pl09867 Jonson Pr01 Pr01 Programing Elektronica al06709 Smith Mp22 Pr01 Programing Elektronica ok90187 Berg Cn32 Mp22 MicProcess Elektronica pl09867 Jonson Pr01 Mp22 MicProcess Elektronica al06709 Smith Mp22 Mp22 MicProcess Elektronica ok90187 Berg Cn32 Cn32 Constructor Mechanika pl09867 Jonson Pr01 Cn32 Constructor Mechanika al06709 Smith Mp22 Cn32 Constructor Mechanika ok90187 Berg Cn32 Gr Speciality PaspNum fig.21 44 BAZY DANYCH R4 = select (R3) ( Gr = SGr) Name SGr Pr01 Programing Elektronica pl09867 Jonson Pr01 Mp22 MicProcess Elektronica al06709 Smith Mp22 Cn32 Constructor Mechanika ok90187 Berg Cn32 Gr Speciality Faculty PaspNum R5 = project (R4) (PaspNum,Name,Faculty). PaspNum Name Faculty pl09867 Jonson Elektronica al06709 Smith Elektronica ok90187 Berg Mechanika fig.22 45 BAZY DANYCH Żeby wyeliminować niepożądane wierszy, trzeba wykorzystać operator selekcji: R4 = select (R3) ( Gr = SGr) Relacja R4 zawiera tylko te wierszy, gdzie wartości Gr oraz SGr są identyczne. Relacja R4 zawiera zbyteczne atrybuty, dlatego realizujemy operację projekcji: R5 = project (R4) (PaspNum,Name,Faculty). Rezultat odwzorowania relacji R5 jest pokazany na rys. 22. Wszystkie operacji algebry relacyjnej dla tego przykładu mają następny wygląd: R3 = (R1) product (R2) R4 = select (R3) ( Gr = SGr) R5 = project (R4) (PaspNum,Name,Faculty). Ćwiczenie: Otrzymać relację, która odwzorowuje z relacji (R1) oraz(R2) spis studentów Wydziału Elektroniki. 4. Suma zbiorów (Union) – to jest operator, pozwalający z dwóch zadanych relacji (R1) oraz (R2) stworzyć nową relację (R3), która zawiera wszystkie wierszy (R1) oraz (R2). Schematy relacji (R1) oraz (R2) powinni być równoznaczni, tzn., że one muszą mieć identyczne stopnie oraz identyczne konsekwentności atrybutów, i na identycznych pozycjach w różnych schematach powinny być atrybuty z tych samych domen. Dla relacji (R1) z ilością wierszy – I, relacji (R2) z ilością wierszy – J, będziemy mieć relację (R3) z ilością wierszy (I+J), jeżeli w relacjach (R1) oraz (R2) nie będą identycznych wierszy. Wyrażenie matematyczne Sumy zbiorów ma następny wygląd: R3 =(R1) union (R2). Przykład. Zadano 3 relacje R1,R2,R3, mające równoznaczne schematy: S Students PaspNum, Name, SGr Każda z tych relacji odwzorowuje dane o studentach jednego Wydziału. Uczelnia ma trzy wydziały. Trzeba skonstruować relację, która odwzorowuje dane o wszystkich studentach Uczelni. Rozwiązanie: R4 = (R1) union (R2) R5 = (R4) union ( R3). 46 BAZY DANYCH 5.Różnica relacji (Set difference) – to jest operator, pozwalający z dwóch relacji R1 i R2 stworzyć nową relację R3 zawierającą wszystkie wiersze R1, których nie zawiera relacja R2. Schematy relacji (R1) oraz (R2) powinny być równoznaczne, tzn., że one muszą mieć identyczne stopnie oraz identyczne konsekwentności atrybutów, i na identycznych pozycjach w różnych schematach powinny być atrybuty z tych samych domen. Wyrażenie matematyczne Różnica relacji ma następny wygląd: R3 =(R1) difference (R2). Przykład. W bazie danych fabryki, zawierającej 3 oddziały fabryczne, są zadane relacji: R1 – spis artykułów, które produkuje oddział fabryczny #1, R2 - spis artykułów, które produkuje oddział fabryczny #2, R3 - spis artykułów, które produkuje oddział fabryczny #3. Przy pomocy algebry relacji skonstruować nową relacje, zawierającą artykuły unikalne, produkowane w oddziałach fabrycznych. Rozwiązanie: R4 = (R1) difference (R2) – to jest spis artykułów, które produkuje oddział fabryczny #1 oraz jednocześnie nie produkuje oddział fabryczny #2. R5 = (R4) difference (R3) - to jest spis artykułów, które produkuje oddział fabryczny #1 oraz jednocześnie nie produkują oddziały fabryczne #2 i #3. Ćwiczenia: 1).Otrzymać resztę relacji, dla innych oddziałów fabrycznych. 2).Wymyślić inne przykłady. 6.Przecięcie (iloczyn) relacji (Intersection) – to jest operator, pozwalający z dwóch relacji : R1 oraz R2 , stworzyć nową relację R3, zawierającą wszystkie wierszy R1, które są jednocześnie obecne w relacji R2. Schematy relacji (R1) oraz (R2) powinny być równoznaczne, tzn., że one muszą mieć identyczne stopnie oraz identyczne konsekwentności atrybutów, i na identycznych pozycjach w różnych schematach powinny być atrybuty z tych samych domen. Wyrażenie matematyczne Przecięcie relacji ma następny wygląd: R3 =(R1) intersection (R2). Operacja Przecięcie relacji ma związek z operacją Różnica relacji. Na przykład: R3 = (R1) difference (R2) R4 = (R1) difference (R3) R4 = (R1) intersection (R2) Ćwiczenia:1) Udowodnić te równości 2) Wymyślić przykłady dla tej operacji. 47 BAZY DANYCH 7. Łączenie relacji (Join) – to jest operator, pozwalający z dwóch relacji: R1 oraz R2 , stworzyć nową relację R3, wiersze której są otrzymane poprzez łączenie wierszy relacji R1 i R2. Ten sposób cechuje się pewnym warunkiem (zwanym predykatem). Wyrażenie matematyczne dla łączenia relacji ma następny wygląd: R3 = Join (R1) (R2) {(cond) [{and / or} (cond)] [,…]} Predykat (cond) zawiera pewien warunek w postaci wyrażenia logicznego, które jest określone na atrybutach relacji. To wyrażenie może przyjmować wartości prawda („true”) lub falsz („false”). Rekordy (krótki) relacji R1 i R3 na atrybutach których ten wyraz logiczny ma wartość „true”, wchodzą do wynikowej relacji R3 jako jedyny rekord. Predykat „cond” ma następny wygląd: R. . A R . B , COND = gdzie: Ai oraz i 1 B i 2 i są atrybutami relacji R1 oraz R2 , - jest operatorem porównania : ( <, >, , , , =). Przykład. W bazie danych fabryki są zadane relacje, schematy których mają następną postać: S (R1) = (DetailCode, DetailName, Material); S(R2) = (DetailCode, Shop). Relacja R1 zawiera spis wszystkich artykułów wytwarzanych na fabryce z ich parametrami. Relacja R2 zawiera kody artykułów produkowanych we wszystkich oddziałach fabrycznych. Trzeba skonstruować relację, która zawiera nazwy wszystkich artykułów wytwarzanych w oddziału fabrycznym „Shop#1”. Rozwiązanie: 1) Tworzymy relację, która odwzorowuje wszystkie artykuły z ich parametrami, wytwarzane we wszystkich oddziałach fabrycznych: R3 = join (R1) (R2) (R1.DetailCode = R2.DetailCode) Schemat relacji R3 ma następny wygląd: S (R3) = (DetailCode, DetailName, Material, Shop); 2) Zastosowujemy operator selekcji do relacji R3, żeby otrzymać dane tylko dla oddziału fabrycznego „Shop#1”: R4 = selection (R3) (Shop = „Shop#1”). Schemat relacji R4 jest identyczny do schematu relacji R3: S(R4) = S(R3). Relacja R4 zawiera tylko wszystkie artykuły dla oddziału fabrycznego „Shop#1”. 48 BAZY DANYCH 3) Zastosowujemy operator projekcji do relacji R4, żeby otrzymać dane tylko o nazwach artykułów: R5 = project (R4)( DetailName). Schemat relacji R5 ma następny wygląd: S (R5) = (DetailName). Ostateczna sekwencja operatorów algebry relacji dla tego przykładu ma następny wygląd: R3 = join (R1) (R2) (R1.DetailCode = R2.DetailCode) R4 = selection (R3) (Shop = „Shop#1”) R5 = project (R4)( DetailName). 8. Łączenie naturalne relacji (Natural Join) Dla łączenia relacji można nie tylko definiować warunki połączeń w predykacie COND, lecz zastosowywać połączenie domyślne. Połączenia domyślne są oparte na atrybuty, które mają identyczne nazwy w różnych relacjach oraz potrzebują zamiast JOIN operatora NATURAL JOIN. Predykat COND jest zbędny. Poprzedni przykład można zapisać tak: R3 = NaturalJoin (R1) (R2) R4 = selection (R3) (Shop = „Shop#1”) R5 = project (R4)( DetailName). 9. Dzielenie relacji (division) . Przypuszczamy, że relacja R1 jest wyznaczona na zbiorze atrybutów A, a relacja R2 jest wyznaczona na zbiorze atrybutów B. Przy czym B jest podzbiór A: B A. Rozpatrzymy podzbiór atrybutów C, które nie wchodzą do B, lecz wchodzą do A: C= A-B. Rezultatem dzielenia relacji R1 przez relację R2 jest nowa relacja R3, która jest wyznaczona na podzbiorze atrybutów C, a wartości atrybutów relacji R3 odpowiadają wartości atrybutów relacji R1 w kombinacji wszystkich wierszy relacji R2. Wyrażenie matematyczne dla operacji dzielenia relacji ma następny wygląd: R3 = (R1) division (R2). Popatrzymy te pojęcia na przykładzie pokazanym na rys.23. 49 BAZY DANYCH A={C,B}; C=A-B; R3=(R1) division (R2) R1 C a a b b c BґA R2 B 1 2 1 2 2 B 1 2 C a b ? fig.23 50 BAZY DANYCH Zbiór atrybutów relacji R1 zawiera dwa atrybuty - C i B: A= {C, B}. Relacja R2 zawiera jeden atrybut B, który jest podzbiorem A: B A. Relacja R3 zawiera tylko jeden atrybut C. Kombinacja wierszy relacji R2 składa z dwóch rekordów, mających wartości B: 1 & 2. Tej kombinacji wierszy w relacji R1 odpowiadają dwa komplety wierszy relacji R1: pierwsza para wierszy, oraz druga para wierszy. Ostatni wiersz relacji R1 nie odpowiada kombinacji wierszy relacji R2. Pierwszemu kompletu wierszy relacji R1 odpowiada wartość „a” atrybutu C, która jest włączona to relacji R3. Drugiemu kompletu wierszy relacji R1 odpowiada wartość „b” atrybutu C, która też jest włączona to relacji R3. Relacja R3 jest rezultatem dzielenia relacji R1 przez relację R2. Przykład. W bazie danych fabryki są zadane relacje, schematy których mają następną postać: S (R1) = (DetailCode, DetailName); S(R2) = (DetailCode, DetailName, Shop). Relacja R1 zawiera spis wszystkich artykułów wytwarzanych we wszystkich oddziałach fabryki. Relacja R2 zawiera kody artykułów wytwarzanych we wszystkich oddziałach fabrycznych. Trzeba skonstruować relację R3, która wyznacza spis oddziałów fabrycznych, wytwarzających wszystkie artykuły. Rozwiązanie: R3 = (R2) division (R1). Zadanie: Baza danych banku zawiera relacje R1 oraz R2 zadane następnymi schematami: S(R1) =(ClientName, BranchNumber,AccountNumber,Rest,Credit); S(R2) = (BranchNumber,Area). Domeny tych relacji mają następne znaczenia: ClientName – nazwisko klienta, BranchNumber – numer filii banku, AccountNumber – numer konta klienta, Rest – reszta pieniędzy klienta (stan konta), Credit – suma kredytu, który otrzymał klient, Area – region, gdzie się znajduje filia banku. Trzeba za pomocą operatorów algebry relacyjnej wyznaczyć: 1. Filii, klienci których mają konta z resztą Rest >1000$ 2. Klientów, który mają konta we wszystkich filiach banku 3. Spis filii, w których ma konta zadany klient 51 BAZY DANYCH 4. Filii, w których są klienci mające resztę =0 5. Filii, w których są klienci, mające kredyty dwukrotnie większe od ich reszty. Język SQL (Structured Query Language) Definicje języka SQL Relacyjny system bazy danych przechowuje wszystkie dane w tabelach. Każda tabela zawiera dane na konkretny temat, np. dane o klientach, dane o pracownikach, towarach itp. System zarządzania bazą danych (SZBD, ang. nazwa DBMS) zarządza tymi danymi, pozwala na szybsze ich wyszukanie i optymalne zorganizowanie. Tabela składa się z wierszy (lub rekordów) i kolumn (lub atrybutów). Wiersze w tabeli są przechowywane w dowolnej kolejności. Dla każdego wiersza każda z kolumn posiada jedno pole z wartością. Wszystkie wartości w kolumnie są tego samego typu. Każda tabela musi mieć unikatową nazwę. SQL jest ratyfikowany jako standard języka relacyjnych baz danych. Wszystkie DBMS powinny więc opierać się na ten standard. SQL jest zaimplementowany w takich systemach baz danych (DBMS), jak: DB2, Oracle, InterBase, MySQL, dBase, Sybase, Informix, Paradox ta in. Na skutek tego systemy informacyjne można przenosić na inne platformy baz danych. SQL jest przeznaczony do: Tworzenia baz danych oraz różnych tabel z kompletnym opisem ich struktur; Realizacji operacji nad danymi w tabelach - wstawianie (insert), aktualizacja (updating), usuwanie (deleting) z tabel ; Realizacji zapytań oraz transformacji danych. SQL zawiera następnie grupy instrukcji: instrukcje DDL (Data Definition Language ) – są wyznaczone dla definicji struktur danych bazy danych; instrukcje DML (Data Manipulatuion Language) - są wyznaczone dla manipulowania danymi w bazie danych; instrukcja DQL ( Data Query Language) - jest główną instrukcją SQL – „SELECT”- I jest przyznaczona dla konstruowania zapytań ; instrukcje DCL ( Data Control Language) – są wyznaczone dla kontroli dostępu do danych. Język SQL nie zawiera zwykłych instrukcji sterowania – IF … THEN …, DO …WHILE i in. Z SQL można korzystać na różne sposoby: 52 BAZY DANYCH 1. Interaktywne wpisanie operatorów SQL bezpośrednio z klawiatury do programu dialogowego DBMS; 2. Wpisanie operatorów SQL bezpośrednio do programu użytkownika. System oprogramowania w temu wypadku musi mieć jeden z dwóch standardów: zanurzony SQL(embedded SQL) lub dynamiczny SQL (dinamik SQL) ; 3. Za pomocą transakcji, czyli krótkich sekwencji instrukcji SQL, które wykonują synchroniczne transformacje w tabelach jednej czy wielu baz danych. Typy danych języka SQL W różnych systemach relacyjnych baz danych inaczej nazywają się typy danych. Jednak ich zakres i typ jest często identyczny. Każdy system relacyjnych baz danych posiada w swojej dokumentacji sekcje, opisującą typy danych używanych w tym systemie. Standard SQL zawiera następne typy danych: Znakowe typy danych: CHARACTER (n) ( CHAR(n)) – to jest typ znakowy , gdzie n - jest liczba długości ciągu znaków; VARCHAR (n) – to jest typ ciągów znaków, mających regulowane długości; LONG VARCHAR – to jest typ danych dla reprezentacji tekstu nieustrukturowanego (nieuporządkowanego), mającego dużą długość ; Numeryczne typy danych: NUMERIC (n,m) – to jest typ precyzyjny, gdzie n – to długość ogólna liczby, m – ilość znaków z prawa od przecinka; INTEGER (INT) – to jest typ całkowity; SMALLINT - to jest typ całkowity liczb małego diapazonu; FLOAT – to jest typ liczb precyzyjnych w postaci zmiennoprzecinkowej; DOUBLE - to jest typ liczb z precyzją podwójną w postaci zmiennoprzecinkowej; BINARY – to jest typ bitowy; Typy danych daty i czasu: DATE – to jest data kalendarza; TIME – to jest czas; TIME STAMP to jest „data kalendarza + czas”. 53 BAZY DANYCH Tworzenie tabeli Tworzenie tabeli polega na definiowaniu jej kolumn. Dla każdej kolumny należy określić nazwę kolumny, typ danych i długość (w zależności od typu) oraz to, czy jest dozwolone pozostawienie wartości pustej w kolumnie. Przykład 0. create table EMPLOYEE_TBL (Emp_Id char(9) not null, EMP_NAME varchar(20) not null, EMP_ST_ADDR varchar(20) not null, EMP_CITY varchar(15) not null, EMP_ZIP numeric(5) not null, EMP_PHONE numeric(10) , primary key (Emp_Id)); Usuwanie tabeli z bazy danych dokonywa Instrukcją DROP TABLE DROP TABLE EMPLOYEE_TBL; Wartość pusta NULL Wartość NULL - to wartość nieokreślona, która może zostać użyta w każdym polu tabeli niezależnie od typu kolumny. Wartość NULL jest różna od zera lub od spacji. Przy konstruowaniu tabeli poleceniem CREATE TABLE w poprzednim przykładzie określiliśmy dla pewnych kolumn parametr NOT NULL. Oznacza to, że przy wstawianiu nowych wierszy musimy określić wartości dla tych kolumn, nie mogą one być wartościami NULL. Definicja kolumny w poleceniu CREATE TABLE pozostawiona bez NOT NULL określa, że dozwolone jest wstawienie do tej kolumny wartości NULL. Instrukcja DQL ( Data Query Language) SELECT Instrukcja jest przeznaczona dla korzystania z danych jednej czy z wielu tabel bazy danych. Rezultatem instrukcji SELECT jest nowy zbiór danych. Ta instrukcja odpowiada następnym operatorom algebry relacyjnej: SELECTION, PROJECTION oraz JOIN. Instrukcja SELECT zawiera kilka klauzul. Każda klauzula pisze się z nowej linii. W końcu ostatniej klauzuli stawi się „ ; ” Dla przedstawienia formatów instrukcji korzystamy z notacji Bekusa (Backus Form). Główne elementy tej notacji: [xxx] – nie obowiązkowa obecność elementu w instrukcji {xxx} - obowiązkowa obecność elementu w instrukcji / - niezbędność wyboru jednego z kilku elementów, rozdzielonych „/” 54 BAZY DANYCH … - możliwość powtórzenia konstrukcji. Format instrukcji SELECT: SELECT [ DISTINCT/ALL] { */ [column_expression [AS new_name]] [,…]} FROM table_name [alias] [,…] [WHERE condition] [GROUP BY column_list] [HAVING condition] [ORDER BY column_list]; Wykorzystane oznaczenia: Słowo kluczowe ALL oznacza, że zbiór ostateczny zawiera wszystkie rekordy zadowalające warunkom zapytania. Ten zbiór zawiera rekordy, które są powtarzane. Słowo kluczowe DISTINCT wyłącza powtarzanie rekordów. Element „ * ” oznacza tu, że wszystkie kolumny wszystkich tabel będą włączone do zbioru ostatecznego. Wyrażenie WHERE condition wyznacza warunki włączenia rekordów do formowania zbioru ostatecznego. Warunek condition jest konstruowany jako wyrażenie logiczne przy pomocy operatorów AND, OR, NOT. Są używane również operatory porównania: =, <, >, <=, >=, < >. column_expression – to nazwa kolumny w tabeli, lub wyrażenie zawierające nazwy kolumn. table_name – to jest nazwa tabeli istniejącej w bazie danych, do której chcemy mieć dostęp. alias – to jest skrócona nazwa tej samej tabeli. Procedura wykonania instrukcji SELECT polega na realizacji klauzul FROM, WHERE, GROUP BY, HAVING i ORDER BY w następnej kolejności: 1. FROM – określić nazwę (nazwy) tablicy (tablic), która jest potrzebna(i) dla formowania zbioru ostatecznego. 2. WHERE – włączyć filtracje rekordów tabel. Warunki tej filtracji są wyznaczone w wyrażeniu WHERE condition. 3. GROUP BY – sformować grupy rekordów, mających identyczne wartości w kolumnach tabeli, nazwa której jest podana w wyrażeniu tej instrukcji. 4. HAVING – wykorzystać filtracje grupy rekordów. Warunek (warunki) tej filtracji jest wyznaczony w wyrażeniu instrukcji. 55 BAZY DANYCH 5. ORDER BY – sformować rozkaz wyników ostatecznego zbioru. Rozkaz jest zadany w wyrażeniu tej instrukcji. Przykład 1. W bazie danych znajduje się tabela z atrybutami: Staff (Cno,Fname,Lname,Address,Tel_No,Sex,Dob,Salary,Bno). Otrzymać listę adresów klientów. Rozwiązanie: SELECT Cno,Fname,Lname,Address FROM Staff; Przykład 2. W bazie danych uczelni znajduje się tabela z atrybutami : GruppeD(Gnum, Gspeciality,Gdepartment) Otrzymać wykaz wszystkich specjalności danej uczelni. Rozwiązanie: SELECT DISTINCT Gspeciality FROM GruppeD; Słowo kluczowe DISTINCT usuwa z tablicy powtarzające się rekordy. Przykład 3. W bazie danych (przykład 1) otrzymać listę pracowników posortowaną według kwot wynagrodzenia. Staff (Cno,Fname,Lname,Address,Tel_No,Sex,Dob,Salary,Bno ) Rozwiązanie: SELECT Cno,Fname,Lname, Salary FROM Staff ORDER BY Salary ASC; Klauzula ORDER BY sortuje wszystkie rekordy odpowiednio do argumentów: ASC (rosnąco), i DESC (malejąco). Przykład 4. Z bazy danych (przykład 1) otrzymać listę pracowników, posortowaną z początku malejąco według kwot wynagrodzenia, a potem według nazwisk. Rozwiązanie: SELECT Cno,Fname,Lname, Salary FROM Staff ORDER BY Salary DESC, Lname ASC; W instrukcji SELECT mogą być wyznaczone wyliczone kolumny. Te kolumny są fizycznie nieobecne w bazie danych, lecz one powstają w wyniku operacji matematycznych na istniejących kolumnach tablic. Przykład 5. W bazie danych (przykład 1) otrzymać raport o przeciętnym miesięcznym wynagrodzeniu. Rozwiązanie: SELECT Cno,Fname,Lname, Salary /12 AS monthly_salary FROM Staff; 56 BAZY DANYCH Salary /12 jest atrybutem wyliczonym. Atrybut Salary fizycznie obecny w tabeli, i powinien mieć format liczbowy (żeby można było realizować operacje matematyczne). W danym przykładzie w słowie kluczowym AS podana jest nowa nazwa kolumny monthly_salary tablicy zbioru ostatecznego. Ta nazwa może być wykorzystana w dalszych obliczeniach. Przykład 6. W bazie danych (przykład 1) otrzymać listę pracowników z wynagrodzeniem > 10000$. Rozwiązanie: SELECT Cno,Fname,Lname, Salary FROM Staff WHERE Salary>10000; Przykład 7. W sytuacji z poprzedniego przykładu otrzymać listę pracowników z wynagrodzeniem >6000$ i <12000$. Rozwiązanie: SELECT Cno,Fname,Lname, Salary FROM Staff WHERE (Salary>6000) AND (Salary<12000); W klauzuli WHERE mogą występować następne operatory (predykaty): LIKE BEETWEN/NOT BEETWEN IS NULL/ IS NOT NULL Przy pomocy LIKE można polecić poszukiwanie według wzorca. Na przykład, trzeba skonstruować zapytania dla otrzymania listy pracowników, nazwiska których zaczynają się z „Co”. Klauzula WHERE dla przykładu 7 wygląda następująco: WHERE Lname LIKE ‘Co%’; Operator BETWEEN pozwała zamienić klauzulę WHERE w przykładzie 7 w sposób następujący: SELECT Cno,Fname,Lname, Salary FROM Staff WHERE Salary BETWEEN 6000 AND 12000; Operator NOT BETWEEN wybiera dane nie wchodzące do zaznaczonego przedziału: SELECT Cno,Fname,Lname, Salary FROM Staff WHERE Salary NOT BETWEEN 6000 AND 12000; Operator NOT NULL wybiera rekordy, które mają wyznaczone wartości w kolumnach. Na przykład , trzeba skonstruować zapytania dla otrzymania 57 BAZY DANYCH listy pracowników, dochód których jest wyznaczony. Klauzula WHERE dla przykładu 7 będzie mieć następną postać: WHERE Salary IS NOT NULL; Rozpatrzymy przykłady konstruowania zapytań do kilku tabel bazy danych. Przykład 8. Baza danych uczelni ma następne tablice: Gruppe (GCod, SpecCod); Speciality (SpecCod, SpecName); Discipline (DiscCod,DiscName); CorrTable (SpecCod, DiscCod). Trzeba skonstruować SQL zapytanie dla formowania listy przedmiotów, z których składa się plan kształcenia grupy ef22. Związki (relacje) tych tablic są pokazane na rys. 24. Dla formowania zapytania trzeba w nim połączyć te tablice. Połączenia można realizować za pomocą klauzuli WHERE. Omówimy szczegółowo przedstawione na rys.24 tablice oraz ich połączenia. W tabeli Grupy każdemu kodu grupy studentów odpowiada kod specjalności kształcenia. W tej tabeli atrybut Gcod jest kluczem głównym, czyli kluczem pierwotnym (primary key). Kluczem głównym w tabele Speciality jest atrybut SpecCod. Każdej wartości klucza głównego odpowiada nazwa specjalności. Te dwie tabeli są połączone przez swoje atrybuty SpecCod. Tabela CorrTable ustala zależności pomiędzy tabelami Speciality oraz Discipline. Kluczem głównym w tabeli CorrTable jest zespól atrybutów SpecCod oraz DiscCod. 58 BAZY DANYCH Primary key Gruppe GCod SpecCod ... ... ef22 0513 ... ... Speciality SpecCod SpecName ... ... 0513 Microprocessors ... ... CorrTable SpecCod DiscCod ... ... 0513 2002 ... ... 0513 2006 ... ... Primary key Discipline DiscCod DiscName ... ... 2002 C++ ... ... 2006 Java fig.24 59 BAZY DANYCH Rozwiązanie: SELECT S.SpecName, D.DiscName FROM Gruppe G, Speciality S, Discipline D, CorrTable C WHERE (G.GCod= 'ef22') AND SpecCod=S.SpecCod)AND(S.SpecCod = C. SpecCod) (C.DiscCod=D.DiscCod)) ORDER BY D.DiscCod; Skutkiem tego zapytania będzie, na przykład, następna tablica: ((G. AND Zapytania SELECT do wielu tabel Poprzednie przykłady wykorzystywali dla połączenia tabel wyrażenia warunkowe w klauzuli WHERE. W standardzie SQL istnieją również inne sposoby połączenia tabel za pomocą operatorów (predykatów) w klauzuli FROM. Przykład 9. Otrzymać z tabel Gruppe oraz Speciality listę zawierającą kody grup wraz z nazwami specjalności kształcenia . Rozwiązanie: SELECT G.GCod, S.SpecName FROM Gruppe G JOIN Speciality S ON G. SpecCod =S. SpecCod ORDER BY G.GCod ; W danym przypadku w klauzuli FROM znajduje się operator JOIN, który deklaruje połączenia dwóch tabel. Warunki tego połączenia są zdefiniowane za pomocą operatora ON. Oprócz tego w klauzuli FROM są zadane: alias G dla tablicy Gruppe oraz alias S dla tablicy Speciality. Dla połączenia tabel można nie tylko definiować warunki połączeń w operatorze ON, lecz zastosowywać połączenie domyślne. Połączenia domyślne są oparte na atrybuty, które mają identyczne nazwy w różnych tabelach, a potrzebują zamiast JOIN operatora NATURAL JOIN. Poprzedni przykład można przedstawić następującą: SELECT G.GCod, S.SpecName FROM Gruppe G NATURAL JOIN Speciality S 60 BAZY DANYCH ORDER BY G.GCod ; Przykład 8 też można zapisać inaczej: SELECT S.SpecName, D.DiscName FROM (Gruppe G JOIN Speciality S ON G.SpecCod = S.SpecCod) JOIN (Discipline D JOIN CorrTable C ON D. DiscCod = C. DiscCod) ON S.SpecCod= C.SpecCod WHERE G.GCod= 'ef22' ORDER BY D.DiscCod; Operatory JOIN oraz NATURAL JOIN wykonują połączenia wewnętrzne tablic (INNER JOIN). To znaczy, że dane z dwóch tabel kombinują się za pomocą par związanych rekordów, w których wartości porównywanych kolumn są równe. Jeśli rekord jednej tablicy nie znajduje odpowiednika w drugiej, ten rekord nie zostanie włączony do zbioru ostatecznego. Istnieją przypadki, kiedy taki rekordy trzeba włączyć do zbioru ostatecznego. Na przykład, niech w tablicy Gruppe z przykładu 8 znajduje się rekord (AT01, 1313). Ale w tablicy Speciality nie ma żadnego rekordu, kolumna SpecCod którego ma wartość 1313. Oznacza to, że istnieje grupa studencka AT01, mająca kod specjalności 1313, któremu jednak nie została wyznaczona nazwa specjalności. To jest błąd integralności (poprawności) danych. Operatory JOIN oraz NATURAL JOIN nie znajdują błędów w danych (integralności i/lub poprawności). Standard ISO (International Standart Organisation) wyznacza możliwość realizacji „połączeń zewnętrznych” tablic bazy danych, które dostarczają do zbioru ostatecznego inne rekordy, które nie odpowiadają warunkom połączeń. Wartości niektórych atrybutów w tych rekordach zostają nie wyznaczone. Połączenia zewnętrzne zawierają trzy różne typy: Lewe połączenie zewnętrzne (LEFT OUTER JOIN) Prawe połączenie zewnętrzne (RIGHT OUTER JOIN) Pełne połączenie zewnętrzne (FULL OUTER JOIN) – jest dostępne nie we wszystkich realizacjach standardu SQL. Przy lewym połączeniu zewnętrznym do zbioru ostatecznego oprócz rekordów, które zadowalają warunkom połączeń, dodają się rekordy z pierwszej (lewej) tablicy, które nie zadowalają tym warunkom. Przy prawym połączeniu zewnętrznym do zbioru ostatecznego oprócz rekordów, które zadowalają warunkom połączeń , dodają się rekordy z drugiej (prawej) tablicy, które nie zadowalają tym warunkom. Przy pełnym połączeniu zewnętrznym do zbioru ostatecznego oprócz rekordów, które zadowalają warunkom połączeń , dodają się rekordy z 61 BAZY DANYCH pierwszej (lewej) oraz z drugiej (prawej) tablicy, które nie zadowalają tym warunkom. Przykład 10. W bazie danych Wydziału Elektroniki są 3 tablicy. Tabela R1 jest przeznaczona dla przechowania rezultatów egzaminów: R1(Number, Lname, Discipline, Estimation). Tabela R2 zawiera spis wszystkich studentów, które studiują na Wydziale: R2(LegNum, Lname, Grupe). Tabela R3 zawiera wszystkie dyscypliny (przedmioty), które są wyznaczone dla egzaminów we wszystkich grupach: R3(Num,Grupe, Discipline). Trzeba otrzymać wykaz rezultatów sesji akademickiej. Dla studentów, którzy nie byli obecni na egzaminach, trzeba w tym wykazie zaznaczyć nazwisko, nazwę dyscypliny, a wartość oceny zostawić nie wyznaczoną. Rozwiązanie: SELECT R2.Lname, R3.Discipline, R1.Estimation FROM (R2 NATURAL JOIN R3) LEFT OUTER JOIN R1 ON ((R1.lname = R2.lname) AND (R1.Discipline = R3.Discipline)) ORDER BY R2.lname; Przykład 11. Baza danych uczelni (patrz przykład 9), ma następne tablice : Gruppe (GCod, SpecCod) Speciality (SpecCod, SpecName), Trzeba otrzymać listę zawierającą kody grup z nazwami specjalności kształcenia oraz wszystkie specjalności uczelni. Rozwiązanie: SELECT G.gcod,S.SpecName FROM (Gruppe G right outer JOIN Speciality S ON G.SpecCod = S.SpecCod); Funkcji agregujące, klauzuli HAVING i ORDER BY w instrukcji SELECT. Funkcji agregujące pozwalają obliczyć niektóre wartości dla rekordów oraz kolumn zbioru ostatecznego wyznaczonego instrukcją SELECT. Istnieją 5 typów funkcji agregujących: 1. COUNT – ta funkcja zwraca ilość rekordów zbioru ostatecznego; 2. SUM - ta funkcja zwraca sumę wartości w wyznaczonej kolumnie; 3. AVG - ta funkcja zwraca wartość średnią w wyznaczonej kolumnie; 4. MIN - ta funkcja zwraca wartość minimalną w wyznaczonej kolumnie; 5. MAX - ta funkcja zwraca wartość maksymalną w wyznaczonej kolumnie. 62 BAZY DANYCH Funkcja COUNT może być zastosowana do rekordów, mających nie liczbowe wartości atrybutów, reszta funkcji agregujących mogą być zastosowane tylko do kolumn mających wartości liczbowe. Funkcja agregująca COUNT może mieć następne formaty: COUNT (Atribut Name) COUNT (*) Format pierwszy COUNT pozwala obliczyć ilość rekordów zbioru ostatecznego instrukcji SELECT, mających wartości „nie NULL” w kolumnie, wyznaczonej przez „Atribut Name”. NULL – to jest nie określona wartość atrybutu. UWAGA. Wartość nie określona nie jest wartością zerową!!! Format drugi COUNT pozwala obliczyć ilość wszystkich rekordów. Przykład 12. Baza danych uczelni (patrz przykład 9), ma następną tablicę : Speciality (SpecCod, SpecName), Trzeba obliczyć ilość wszystkich specjalności na Uczelni oraz ilość grup na różnych specjalnościach. Rozwiązanie 1. Określić ilości wszystkich specjalności na Uczelni: SELECT count (s.SpecCod) FROM Speciality S ; Baza danych uczelni ma następną tablicę : GruppeD (GNum, Gspeciality, Gdepartment) Określić ilości grup na różnych specjalnościach: Rozwiązanie 2. SELECT Gspeciality, count (Gspeciality) FROM GruppeD group by Gspeciality Funkcje agregujące można stosować nie tylko do wszystkich rekordów zbioru ostatecznego, lecz do oddzielnych grup tego zbioru. W tym celu trzeba wykorzystać te funkcje razem z klauzulami GROUP BY oraz HAVING. W tym przypadku klauzula GROUP BY najpierw realizuję swoje funkcje grupujące, a potem przy pomocy funkcji agregujących obliczają się sumy w każdej grupie. Przykład 13. W bazie danych firmy handlowej istnieją następne tablice: Orders (orderno,orderdate,custid,ordertotal) Customer(custid,lastname,firstname,address). Pierwsza tabela zawiera listę zamówień wszystkich klientów z odpowiednimi atrybutami: Orderno – numer zamówienia 63 BAZY DANYCH Orderdate – data zamówienia Custid – kod klienta, który złożył zamówienie Ordertotal – cena zamówienia. B drugiej tabeli są dane o klientach z następnymi atrybutami: Custid – kod klienta Lastname – nazwisko klienta Firstname – imię klienta Addres – adres firmy klienta. Trzeba ustalić ilość zamówień złożonych przez każdego klienta oraz ich sumy. Rozwiązanie: SELECT custid, count(*), SUM(ordertotal) FROM ORDERS GROUP BY custid ORDER BY custid; Klauzula GROUP BY jest niezbędną dla wykonania obliczeń w grupach rekordów przy pomocy funkcji agregujących. Wszystkie atrybuty, wykorzystane w instrukcji SELECT, muszą być w klauzuli GROUP BY. Jeśli chcemy, żeby zbiór ostateczny w przykładzie 13 zawierał jeszcze i nazwiska klientów, musimy połączyć tablice customer oraz orders: SELECT customer.lastname, customer.firstname, orders.custid, count(*), SUM(orders.ordertotal) FROM customer NATURAL JOIN orders GROUP BY orders.custid, customer.lastname, customer.firstname ORDER BY orders.custid; Klauzula HAVING ogranicza działanie ORDER BY. Ta klauzula jest analogiczna do klauzuli WHERE, tzn. zawiera warunki potrzebne dla włączenia rekordów do zbioru ostatecznego. W przeciwieństwie do WHERE warunki w HAVING mogą zawierać funkcji agregujące. Przykład 14. Do zadania z przykładu 13 dodamy nowe wymogi – otrzymać listę klientów, którzy złożyli więcej niż trzy zamówienia. Rozwiązanie: SELECT customer.lastname, customer.firstname, orders.custid, count(*), SUM(orders.ordertotal) FROM customer NATURAL JOIN orders 64 BAZY DANYCH GROUP BY orders.custid,customer.lastname, customer.firstname HAVING COUNT(*) > 3 ORDER BY orders.custid; Przykład 15. Do zadania z przykładu 13 dodamy nowe wymogi – otrzymać listę klientów, którzy zamówili na kwotę większą od 5000$. Rozwiązanie: SELECT customer.lastname, customer.firstname, orders.custid, count(*), SUM(orders.ordertotal) FROM customer NATURAL JOIN orders GROUP BY orders.custid,customer.lastname, customer.firstname HAVING SUM(orders.ordertotal)>5000 ORDER BY orders.custid; Włożone instrukcje SELECT Standard SQL zezwala na użycie jednej konstrukcji zapytania SELECT wewnątrz konstrukcji innego zapytania SELECT. W tym przypadku zewnętrzna konstrukcja SELECT wykorzysta wyniki wewnętrznej. Wewnętrzna konstrukcja może być użyta: w klauzulach SELECT, WHERE czy HAVING instrukcji zewnętrznej; w instrukcjach INSERT, UPDATE, DELETE języka DML (Data Manipulatuion Language). Przykład 16. Baza danych firmy handlowej zawiera tabelę z danymi o swoich pracownikach : Staff(cno,fname,lname,position,salary) Atrybuty tej tabeli: Cno – numer unikalny pracownika; Fname , lname – nazwisko, imię; Position – stanowisko; Salary – wynagrodzenie. Trzeba skonstruować zapytanie SQL dla otrzymania zbioru ostatecznego, zawierającego dane o pracownikach, wynagrodzenia których są większe od wynagrodzenia przeciętnego w firmie. Oprócz tego trzeba otrzymać wysokość tej nadpłaty dla każdego pracownika. Rozwiązanie: SELECT cno,fname,position,salary,salary - (SELECT avg(salary) FROM staff) FROM staff WHERE salary >(SELECT avg(salary) FROM staff); 65 BAZY DANYCH W tym przykładzie zapytanie włożone SELECT będzie wykorzystane dwukrotnie. Za każdym razem zapytanie włożone sformuje listę z jednym rekordem i z jednym polem. To pole zawiera wartość przeciętną wynagrodzenia, otrzymaną przy pomocy funkcji agregującej AVG. Jeśli wynikiem zapytania włożonego SELECT jest jeden rekord z jednym polem, takie zapytanie włożone SELECT nazywa się skalarnym. Jeśli wynikiem zapytania włożonego SELECT jest jeden rekord z wieloma polami, zapytanie włożone SELECT nazywa się rekordowym. Jeśli wynikiem zapytania włożonego SELECT jest tablica rekordów, zapytanie włożone SELECT nazywa się tabelkowym (tabulared). Przy pomocy zapytań włożonych SELECT można otrzymywać decyzji analogicznie, jak przy łączeniu tabel. Przykład 17. Zgodnie z przykładem 13, baza danych firmy handlowej zawiera następne tablice: Orders (orderno,orderdate,custid,ordertotal) Customer(custid,lastname,firstname,address). Trzeba przy pomocy zapytań włożonych SELECT otrzymać listę klientów, którzy złożyli zamówienia. Rozwiązanie: SELECT customer.custid, customer.lastname, customer.firstname FROM customer WHERE customer.custid IN (SELECT DISTINCT orders.custid FROM orders) ORDER BY customer.lastname,customer.firstname; Połączenia tabel będzie zorganizowane przy pomocy słowa kluczowego IN z odpowiednim wyrażeniem (SELECT…) . Słowo kluczowe DISTINCT wyklucza dublowanie rekordów listy utworzonej po wykonaniu wewnętrznej instrukcji SELECT. Przykład 18. W poprzednim przykładzie przy pomocy zapytań włożonych SELECT otrzymać listę klientów, którzy nie złożyli zamówień. Rozwiązanie: SELECT customer.custid, customer.lastname, customer.firstname FROM customer WHERE customer.custid NOT IN (SELECT DISTINCT orders.custid 66 BAZY DANYCH FROM orders) ORDER BY customer.lastname,customer.firstname; W tym przykładzie lista wewnętrzna jest otrzymana analogiczne do poprzedniego przykładu, ale były wykorzystane słowa kluczowe NOT IN (SELECT…). Główne regule konstruowania zapytań włożonych SELECT: Zapytania włożone SELECT muszą być w nawiasach okrągłych. Zapytania włożone SELECT może zawierać tylko jedną kolumnę w wyrażeniu głównego słowa kluczowego SELECT. Konstrukcja włożonego zapytania SELECT nie może zawierać klauzulę ORDER BY. Zamiast ORDER BY można wykorzystywać GROUP BY. Zapytania włożone SELECT, które wróci kilka rekordów z danymi, można wykorzystywać tylko w operatorach typu „IN”. Nie można wykorzystywać operator BETWEEN zawierający włożoną konstrukcję SELECT. Zapytania włożone SELECT może zawierać operator BETWEEN. Funkcje daty Funkcja YEAR pozwala odczyta rok z pełnego formatu daty. Funkcja MONTH pozwala odczyta miesiąc z pełnego formatu daty. Funkcja DAY pozwala odczyta dzień z pełnego formatu daty. Funkcja CURRENT DATE zwraca bieżącą datę. Funkcja Dateadd doda wyznaczoną wartość do daty. Przykład 18-1. Baza danych firmy handlowej zawiera tabelę z danymi o swoich pracownikach : Staff(cno,fname,lname,position,salary,DOB) Trzeba skonstruować zapytanie SQL dla otrzymania spisu pracowników z datami ich urodzenia. Tabela musi mieć kolumny : Rok, Miesiąc oraz Dzień. Rozwiązanie: SELECT cno,fname,DOB, YEAR(DOB) as Rok, MONTH(DOB) as Miesiac, Day(DOB) as Dzien FROM staff; Przykład 18-2. W poprzednim przykładzie trzeba skonstruować zapytanie SQL, które wyświetla kolumny : numer(cno), nazwisko((fname), data urodzenia(DBO) oraz wiek pracownika. Rozwiązanie: SELECT cno, fname, DOB, YEAR(CURRENT DATE)-YEAR(DOB) as Wiek FROM staff; 67 BAZY DANYCH Działanie funkcji Dateadd powoduje obliczenie wyniku zmiany daty(podanej jako trzeci parametr) o określoną poprzez drugi parametr liczbę jednostek. Typ jednostki podaje się jako pierwszy parametr. Mogą bić następnie typy jednostek: YEAR, MONTH, DAY. Przykład 18-3. W poprzednim przykładzie trzeba skonstruować zapytanie SQL, które wyświetla kolumny numer(cno), nazwisko((fname), data urodzenia(DBO) oraz datę upływania 30 lat. Rozwiązanie: SELECT cno, fname, DOB, year(Dateadd(year,30, DOB)) as Rok, MONTH(Dateadd(year,30, DOB)) as Miesiac, DAY(Dateadd(year,30, DOB)) as Dzien FROM staff; Przykład 18-4. Baza danych firmy handlowej zawiera następne tablice: Orders (orderno,orderdate,custid,ordertotal). Customer(custid,lastname,firstname,address). Trzeba wyznaczyć dla zamawiania każdego klienta daty ich realizacji. Zamawiania muszą być realizowane za trzy miesięcy od daty zamawiania. Rozwiązanie: SELECT customer.lastname as Klient, orders.orderno as Zamowianie, orders.orderdate as DataZam, DAY( (Dateadd(month,3, orderdate))) as DZIEN, MONTH( (Dateadd(month,3, orderdate))) as MIESIAC, YEAR( (Dateadd(month,3, orderdate))) as ROK FROM customer NATURAL JOIN orders ORDER BY orders.custid; Funkcje tekstowe Argumentem funkcji tekstowych są ciągi znaków (dane typu text, char, vchar lub memo). Typ danych zwracanych przez funkcje tekstowe jest podstawa do ich dalszego podziału: wyróżniamy funkcje tekstowe zwracające wartość znakową I funkcje tekstowe zwracające wartość numeryczną. Funkcje LOWER(), LCASE() . Wynikiem działania tych funkcji jest ciąg znaków podany jako argument, ale składający się wyłącznie z małych liter. Za pomocą tej funkcji wszystkie wielkie litery argumentu zostaną zamienione na małe. Przykład 18-5. Trzeba wyświetlić nazwiska wszystkich klientów za pomocą małych liter z tabeli CUSTOMER przykładu 18-4. 68 BAZY DANYCH Rozwiązanie: SELECT LCASE(customer.lastname) as Klient FROM customer; Funkcje UPPER(), UCASE(). Wynikiem działania tych funkcji jest ciąg znaków podany jako argument, ale składający się wyłącznie z wielkich liter. Za pomocą tej funkcji wszystkie małe litery argumentu zostaną zamienione na wielkie. Przykład 18-6. Trzeba poszeregować nazwiska wszystkich klientów alfabetycznie według ich nazwisk bez względu na wielość użytych liter z tabeli CUSTOMER przykładu 18-4. Rozwiązanie: SELECT customer.lastname, UCASE(customer.lastname) as Klient FROM customer ORDER BY UCASE(customer.lastname); Funkcje LEFT(), RIGHT(), LTRIM(), RTRIM(),TRIM() Za pomocą funkcji LEFT() z podanego jako argument ciągu znaków zostanie wycięta określona liczba znaków, zaczynając od lewej strony. Przykład 18-7. Trzeba wyświetlić siedem pierwszych znaków(liter lub znaków specjalnych, takich jak spacja) nazwiska klientów tabeli CUSTOMER przykładu 18-4. Rozwiązanie: SELECT customer.lastname, LEFT(customer.lastname,7) as skrot FROM customer; Za pomocą funkcji RIGHT()z podanego jako argument ciągu znaków zostanie wycięta określona liczba znaków, zaczynając od prawej strony. Przykład 18-8. Trzeba wyświetlić cztery ostatnie znaki z nazwiska klientów tabeli CUSTOMER przykładu 18-4. Rozwiązanie: SELECT customer.lastname, RIGHT(customer.lastname,4) as skrot FROM customer; Za pomocą funkcji LTRIM() z podanego ciągu znaków zostaną usunięte spacji z lewa. Na przykład: SELECT LTRIM (' wyrazenie popredzone i zakonczone spacjami '); Za pomocą funkcji RTRIM() z podanego ciągu znaków zostaną usunięte spacji z prawa. Za pomocą funkcji TRIM() z podanego ciągu znaków zostaną usunięte spacji z lewa i z prawa. Na przykład: SELECT customer.lastname, TRIM(customer.lastname) FROM customer; Funkcja SUBSTR() 69 BAZY DANYCH W wyniku działania funkcji SUBSTR() zostanie zwrócona określona liczba znaków z łańcucha tekstowego, począwszy od podanej pozycji. Jeżeli nie padamy liczby znaków do usunięcia, usuwane są wszystkie znaki występujące po pozycji określonej przez drugi parametr. Podanie ujemnej wartości drugiego parametru spowoduje, że znaki będą liczone od prawej do lewej. Następna instrukcja wyświetli słowo ‘funkcja?’: SELECT SUBSTR ('co to ma byc za funkcja? ',16,9); Funkcja LENGTH() Funkcja LENGTH() jako wynik zwraca długość ciągu znaków podanego jako parametr jej wywołania. Jeżeli wywołamy funkcję z ciągiem znaków mającym wartość NULL, funkcja zwróci wartość NULL. Przykład 18-9. Trzeba wyświetlić z tabeli CUSTOMER adresy klientów, które mają krótkie nazwiska(mniej 7 liter). Rozwiązanie: SELECT LastName, ADDRESS from Customer WHERE LENGTH(LastName)<7; Funkcja SIMILAR() Funkcja SIMILAR() jako wynik zwraca wartość od 0 do 100, która jest procent identyczności dwóch ciągów znaków podanych jako parametry jej wywołania. Przykład działania funkcji SIMILAR(): SELECT SIMILAR ( 'string-expr1', 'string-expr2' ); Funkcje matematyczne Funkcja ROUND() Działanie funkcji ROUND() powoduje zaokrąglenie liczby do określonej liczby cyfr po przecinku. Pierwszy parametr jest liczbą do zaokrąglenia, drugi jest liczba pozycji do ilu chcemy zaokrąglić. Przykład działania funkcji ROUND(): SELECT ROUND(3.1418281828,3) as Pi; Funkcja ABS() Wynikiem działania funkcji ABS() jest wartość bezwzględna liczby (liczba bez znaku). Jako parametr podaje się liczbę, której wartość bezwzględną należy obliczyć. Przykład działania funkcji ABS(): SELECT abs(-124) Funkcja CEILING () Wynikiem działania funkcji CEILING () jest najmniejsza liczba całkowita większa lub równa liczbie podanej jako argument funkcji. Przykład działania funkcji CEILING (): 70 BAZY DANYCH SELECT CEILING ( 124.1) Funkcja FLOOR () Działanie funkcji FLOOR() powoduje zwrócenie największej lub równej liczbie podanej jako argument funkcji. Przykład działania funkcji FLOOR(): SELECT FLOOR ( 124.9) Funkcja SQRT() W wyniku działania funkcji SQRT() zwrócony zostanie pierwiastek kwadratowy z liczby podanej jako parametr wywołania. Przykład działania funkcji SQRT(): SELECT SQRT ( 225) Funkcja POWER() Funkcja POWER() sprawia, że liczba podana jako pierwszy parametr zostanie podniesiona do potęgi podanej jako drugi parametr. Wartości drugiego parametru mogą być mniejsze niż zero. Przykład działania funkcji POWER(): SELECT Power ( 2,7) Funkcja EXP() Wynikiem działania funkcji EXP() jest wartość e=2.7118281828 do potęgi podanej jako parametr. Stała e=2.7118281828 jest podstawą logarytmów naturalnych. Przykład działania funkcji EXP(): SELECT EXP (7) Funkcja LOG() Funkcja LOG() jest przeciwną do funkcji EXP(). Za pomocą funkcji LOG() podana zostanie wartość logarytmu liczby przy podstawie e=2.7118281828. Przykład działania funkcji LOG(): SELECT LOG (1096.63) Funkcja MOD() Funkcja MOD() zwraca jako wynik wartości reszty po podzieleniu liczby podanej jako pierwszy parametr przez dzielnik podany jako drugi parametr wywołania funkcji. Przykład działania funkcji MOD(): SELECT MOD(5,3) Funkcje trygonometryczne: SIN(),COS(),TAN() W wyniku działania funkcji SIN(), COS() I TAN() zwrócona zostanie wartość odpowiednich funkcji trygonometrycznych dla parametru będącego kątem w radianach. Przykład działania funkcji SIN(): SELECT SIN(PI()/6); Funkcja PI() w tym wyrażeniu zwraca wartość PI=3.141592…. 71 BAZY DANYCH Funkcje konwersji Te funkcje pozwala skonwertować dane jednego wyznaczonego typy do danych innego typu. Funkcje konwersji wykorzystują się w operacjach porównania danych różnych typów. Funkcja ASCII() W wyniku działania funkcji ASCII() kod ASCII znaku podanego jako parametr wywołania zostaje zwrócony. Jeżeli jako parametr podamy ciąg znaków, za pomocą tej funkcji zostanie obliczony kod ASCII pierwszego znaku w ciągu. Przykład działania funkcji ASCII(): SELECT ASCII('A') AS "Kod ASCII" Funkcja CHAR() Działanie funkcji CHAR() jest przeciwieństwem działania funkcji ASCII() zamiast zamiany tekstu na liczbę dokonuje się konwersja liczby na odpowiadający jej znak kodu ASCII. Przykład działania funkcji CHAR(): SELECT CHAR (65) Funkcja BYTE_LENGTH () Za dopomogą funkcji BYTE_LENGTH () można wyznaczyć ilość bajtów argumentu, który ma tekstowy typ. Przykład działania funkcji BYTE_LENGTH (): SELECT Lastname, BYTE_LENGTH (Lastname) FROM Customer Zapytania SELECT pobierają informacje z bazy danych, ale nie zmieniają danych. Instrukcje DML służą do wpisywania, usuwania oraz uaktualniania danych w bazie danych. Zestaw instrukcji DML zawiera następne instrukcji: INSERT DELETE UPDATE. Instrukcja INSERT Instrukcja INSERT wstawia do tablicy rekordy. Przykład 19. Stworzyć nową tabelę, dodać do niej rekord i wyświetlić treść nowej tablicy. Rozwiązanie: CREATE TABLE temp1 (custid char(4), ordertotal integer); Przy pomocy danego wyrażenia jest tworzona nowa tabela , mająca nazwę „temp1” z dwoma kolumnami : „custid” oraz „ordertotal”. 72 BAZY DANYCH Wstawiamy do tej tablicy nowy rekord: INSERT INTO temp1 Values (‘A1’, 2); Wyświetlamy wynik na ekranie monitora: SELECT * FROM temp1; Instrukcja INSERT może zawierać instrukcje włożone SELECT. Przykład 20. Wprowadzić do tablicy „temp1”, stworzonej w przykładzie 19, wartości ostatecznych kwot zamówień każdego klienta z tablicy „orders” . Rozwiązanie: INSERT INTO temp1 (custid, ordertotal) SELECT custid, SUM(ordertotal) FROM orders GROUP BY custid; Podajemy wynik na ekran monitora: SELECT * FROM temp1 ORDER BY custid; Instrukcja włożona SELECT formuje listę wewnętrzną , zawierającą rekordy z sumami cen zamówień każdego klienta. Wartości tych cen znajdują się w polach „ordertotal” listy wewnętrznej. Potem instrukcja INSERT wstawia te wartości do tablicy „temp1”. Instrukcja DELETE Zapytanie DELETE usuwa jeden lub więcej rekordów z tablicy. Przykład 21. Usuwanie jednego rekordu z tablicy. Usunąć z tablicy rekord z kodem custid='A12'. Rozwiązanie: DELETE FROM temp1 WHERE temp1.custid='A12'; Wynik podać na ekran: SELECT * FROM temp1 ORDER BY temp1.custid; Przykład 21-a. Usuwanie wielu rekordów z tablicy. Usunąć z tablicy rekordy z kodami ordertotal < 4000. Rozwiązanie: DELETE FROM temp1 WHERE temp1.ordertotal < 4000; Wynik podać na ekran: SELECT * FROM temp1 ORDER BY temp1.ordertotal; 73 BAZY DANYCH Instrukcja UPDATE Aktualizuje jeden czy więcej rekordów w tabeli. Przykład 22. Aktualizacja jednego rekordu w tabeli. Trzeba zmodyfikować wartość atrybutu „custid” z 14 na 9999. Rozwiązanie: UPDATE temp1 SET custid = '9999' WHERE custid = 'a14'; Podajemy wynik na ekran: SELECT * FROM temp1 ORDER BY custid; Przykład 23. Aktualizacja wielu rekordów w tabeli. Zwiększyć wszystkie wartości „ordertotal” o 10% . Rozwiązanie: UPDATE temp1 SET ordertotal =ordertotal*1.1; Podajemy wynik na ekran: SELECT * FROM temp1 ORDER BY custid; Instrukcje DDL (Data Definition Language ) Zestaw instrukcji DDL zawiera następne instrukcje: CREATE TABLE DROP TABLE ALTER TABLE CREATE VIEW ALTER VIEW DROP VIEW CREATE INDEX DROP INDEX Instrukcja CREATE TABLE Formuje nowe tabele w bazie danych. Przykład 24. Stworzyć tabele pracowników firmy. Rozwiązanie: if exists(select 1 from sys.systable where table_name='Employee_tbl' and table_type='BASE') then drop table Employee_tbl end if; create table Employee_tbl ( 74 BAZY DANYCH Emp_Id varchar(9) not null, Last_Name varchar(15) not null, First_Name varchar(15) not null, Middle_Name varchar(15), Addres varchar(30) not null, City varchar(15) not null, State varchar(2) not null, ZIP numeric(5) not null, Phone varchar(10), Pager varchar(10), primary key (Emp_Id) ); Przykład 25. Stworzyć tabele dla prz.19. Rozwiązanie: CREATE TABLE temp1 (custid char(4), ordertotal numeric(5,2)); Instrukcja DROP TABLE Ta instrukcja usuwa tabelę z bazy danych. Przykład 26. DROP TABLE temp1; DROP TABLE Employee_tbl; Instrukcja ALTER TABLE Za pomocą instrukcji ALTER TABLE możemy zmienić definicje istniejącej tablicy oraz zmienić nazwy kolumn lub tablicy. Obowiązkowym parametrem instrukcji jest nazwa modyfikowanej tabeli. Instrukcja ALTER TABLE może zawierać następnie klauzule i opcji: ADD NULL/NOT NULL RENAME DROP CONSTRAINT. Klauzula ADD pozwala na dodawanie nowych kolumn lub nowych warunków integralności. Przykład 26 a. Baza danych uczelni zawiera następnie tabeli: Gruppe (GCod, SpecCod); 75 BAZY DANYCH Speciality (SpecCod, SpecName); Discipline (DiscCod,DiscName); CorrTable (SpecCod, DiscCod). Trzeba dodać do tabelę SPECIALITY nowe atrybuty : „Promoter specjalności” oraz „Katedra”. Także dodać warunki integralności odwołań. ALTER TABLE SPECIALITY ADD ( PROMOTER Char (20) NULL, KATEDRA Char(30) NULL); ALTER TABLE GRUPPE ADD CONSTRAINT foreign key FK_GRUPPE_SPECIALITY_SPECCOD (SPECCOD) references SPECIALITY (SPECCOD) on update restrict on delete restrict; ALTER TABLE CORRTABLE ADD CONSTRAINT foreign key FK_CORRTABLE_SPECIALITY_SPECCOD (SPECCOD) references SPECIALITY (SPECCOD) on update restrict on delete restrict; ALTER TABLE CORRTABLE ADD CONSTRAINT foreign key FK_CORRTABLE_DISCIPLINE_DISCCOD (DISCCOD) references DISCIPLINE (DISCCOD) on update restrict on delete restrict; Opcja NULL /NOT NULL użyta po definicji kolumny określa czy wartości przechowywane w tych kolumnach mogą przyjmować wartość NULL. Klauzula MODIFY pozwala na zmianę typu I rozmiaru danych przechowywanych w poszczególnych kolumnach. Na przykład, trzeba zwiększyć rozmiary istniejących kolumn: ALTER TABLE SPECIALITY MODIFY PROMOTER Char (45), MODIFY KATEDRA Char(50) ; Klauzula RENAME pozwala zmienić nazwy zdefiniowanych kolumn. Aby przemianować kolumnę „PROMOTER” do „PROFESOR”, należy wykonać instrukcję: 76 BAZY DANYCH ALTER TABLE SPECIALITY RENAME PROMOTER TO PROFESOR; Klauzula DROP usuwa kolumny oraz warunki integralności (Kluczy pierwotny oraz obcy) z tabel bazy danych. Następna grupa instrukcji usuwa wszystkie zmiany przykładu 26a: ALTER TABLE SPECIALITY DROP PROFESOR; ALTER TABLE SPECIALITY DROP KATEDRA; ALTER TABLE GRUPPE DROP FOREIGN KEY FK_GRUPPE_SPECIALITY_SPECCOD; ALTER TABLE CORRTABLE DROP FOREIGN KEY FK_CORRTABLE_SPECIALITY_SPECCOD; ALTER TABLE CORRTABLE DROP FOREIGN KEY FK_CORRTABLE_DISCIPLINE_DISCCOD; Stworzenia tabel wirtualnych – widoków (perspektyw) Tabela wirtualna – widok (w innych źródłach - perspektywa) - powstaje w wyniku wykonania dynamicznych operacji relacyjnych nad tabelami bazy danych dla otrzymania nowej relacji. Nowa relacja nie istnieje fizycznie w bazie danych, nie jest umieszczona na dysku, istnieje tylko w RAM. Tabela wirtualna jest doprowadzona przy pomocy procedur bazy danych do postaci tablicy zwyczajnej dla użytkownika. Perspektywa jest funkcją, odwzorowującą zapamiętane dane w dane wirtualne, i z punktu widzenia użytkownika to są te same dane. Dla pracy z tabelami wirtualnymi użytkownik może wykorzystać wszystkie metody dotyczące pracy z tabelami zwykłymi. Przykład 27. Z trzech tabel bazy danych uczelni stworzyć jedną tabelę, którą zawiera pola (speccod, specname, disccod ,discname). Rozwiązanie: if exists(select 1 from sys.systable where table_name='spec_disc' and table_type='View') then drop View spec_disc end if; CREATE VIEW spec_disc AS SELECT Gruppe.Gcod, speciality.speccod, speciality.specname, 77 BAZY DANYCH discipline.disccod, discipline.discname FROM Gruppe ,corrtable, discipline, speciality WHERE (Gruppe.SpecCod = Speciality.SpecCod) and ( corrtable.disccod = discipline. disccod ) and ( corrtable.speccod = speciality.speccod ); Wyświetlamy tabelę: select * from spec_disc Order by Gcod; Przewagi wykorzystania tabel wirtualnych: Dla konstruowania złożonych zapytań administrator bazy danych powinien stworzyć tabele wirtualną tylko jeden raz. Następne zapytania SELECT do tej tablicy już nie będą zawierali zapytań włożonych. Administrator bazy danych może zabezpieczyć dostęp do atrybutów tabel dla użytkowników nieupoważnionych. Stworzenie indeksów Obecność indeksu w tablicach pozwala przyspieszyć poszukiwania w bazie danych. Instrukcja stworzenia indeksu ma następny format : CREATE [UNIQUE] INDEX <Index_Name> ON <Table_Name> (<Column_Name>,...) Ta instrukcja tworzy indeks, mający nazwę Index_Name dla tablicy Table_Name według kolumn, lista których jest podana w nawiasach. W przypadku użycia parametru UNIQUE , DBMS będzie sprawdzać wartości każdego z indeksów na unikalność. Indeksy są potrzebne dla kluczy pierwotnych, dzięki którym będzie zorganizowany dostęp do danych przy operacjach połączenia dwóch czy wielu tabel. Oprócz tego indeksy są potrzebne dla bardzo częstych odwołań do bazy danych. Przykład 28. Stworzyć indeks dla tabeli pracowników firmy po nazwiskach pracowników. Dla tworzenia tabeli pracowników wykorzystamy następny kod SQL: if exists(select 1 from sys.systable where table_name='Employee_tbl' and table_type='BASE') then drop table Employee_tbl end if; create table Employee_tbl ( 78 BAZY DANYCH Emp_Id varchar(9) Last_Name varchar(15) First_Name varchar(15) Middle_Name varchar(15), Addres varchar(30) City varchar(15) State varchar(2) ZIP numeric(5) Phone varchar(10), Pager varchar(10), primary key (Emp_Id) ); not null, not null, not null, not null, not null, not null, not null, Dla uzupełnienia tabeli wykorzystamy następny kod SQL: insert into employee_tbl values ('311549902', 'STEPHENS', 'TINA', 'DAWN', 'RR 3 BOX 17A', 'GREENWOOD', 'IN', '47890', '3178784465', NULL); insert into employee_tbl values ('442346889', 'PLEW', 'LINDA', 'CAROL', '3301 BEACON', 'INDIANOPOLIS', 'IN', '46224', '3178784465', NULL); insert into employee_tbl values ('213764555', 'GLASS', 'BRANDON', 'SCOTT', '1710 MAIN ST', 'WHITELAND', 'IN', '47885', '3178984321', '3175709980'); insert into employee_tbl values ('313782439', 'GLASS', 'JACOB', NULL, '3789 WHITE RIVER BLVD', 'INDIANOPOLIS', 'IN', '45734', '3175457676', '3175709980'); insert into employee_tbl values ('220984332', 'WALLACE', 'MARIAN', NULL, '7889 KEYSTONE AVE', 'INDIANOPOLIS', 'IN', '46741', '317332986', NULL); insert into employee_tbl values ('443679012', 'SPURGEON', 'TIFFANY', NULL, '5 GEORGE COURT', 'INDIANOPOLIS', 'IN', '46234', '317569007', NULL); Dla tworzenia indeksu po nazwiskach pracowników firmy wykorzystamy następny kod SQL: 79 BAZY DANYCH CREATE INDEX Index_Last_Name ON EMPLOYEE_TBL (Last_Name); Obecność tego indeksu pozwala na skuteczne poszukiwanie pracowników po ich nazwiskach. Na przykład: SELECT * FROM Employee_tbl Order by Last_Name; W oknie statystyki ISQL mamy komunikat: PLAN> EMPLOYEE_TBL (Index_Last_Name); To znaczy, że poszukiwania rekordów było przez indeks z nazwiskom Index_Last_Name. Dla usuwania indeksu wykorzystuje się instrukcja: DROP INDEX Index_Last_Name; Dla usuwania tabeli wykorzystamy instrukcje: Drop Table Employee_tbl; Zapamiętane procedury (Stored Procedure) oraz funkcje Zapamiętana procedura (procedury przechowywane) to jest zbiór instrukcji SQL, który jest zapamiętany w bazie danych dla powtarzalnego wykorzystania. Zapamiętana procedura jest przechowywana w bazie danych w kompilowanym wyglądzie i jest gotowa dla uruchomienia przez użytkownika bazy danych. Ważną cechą jest możliwość uruchomienia zapamiętaną procedurę z jakikolwiek aplikacji, które jest stworzona w jakikolwiek systemu oprogramowania (C++, Java, DELPHI, PowerBuilder, itp.) . System oprogramowania w temu wypadku musi mieć jeden z dwóch standardów SQL: zanurzony SQL(embedded SQL) lub dynamiczny SQL (dinamik SQL). Zapamiętaną funkcją, która wróci jedną lub wiele wartości, nazywa się zapamiętaną procedurą. Przy wołaniu, procedurom i funkcjom mogą być przekazane parametry, które będzie wykorzystywane dla obliczeń. Dla funkcji oprócz tego trzeba przekazać parametry, która funkcją musi wrócić. Pojęcia procedur oraz funkcji są identyczne, ale istnieją różnie syntaksy instrukcji dla ich stworzenia. Format instrukcji dla stworzenia procedury ma następny wygląd: CREATE PROCEDURE [owner.] procedure-name ([parameter,...]) ... { ... compound-statement } Wykorzystane oznaczenia: owner – imię właściciela stwarzającego procedurę; procedure-name – imię procedury; parameter – parametr procedury; 80 BAZY DANYCH compound-statement - tekst z kodami procedury. Każdy parametr (parameter) procedury musi mieć następny format: parameter_mode parameter-name data-type Tu parameter_mode wyznacza typ parametru procedury i może mieć jedną z wartości (IN|OUT|INOUT), które oznaczają : IN – wejściowy parametr; OUT – wyjściowy parametr; INOUT – równocześnie wejściowy oraz wyjściowy parametr; parameter-name – imię parametru, data-type typ danych parametru. Przykład 28 a. Trzeba stworzyć zapamiętaną procedurę dla administratora bazy danych, która wyświetli z tabeli Staff ilość pracowników, pensja których jest w wyznaczonym zasięgu. Zasięg musi być zadany przez parametry n1, w2, mających typ integer. Rezultat musi być otrzymany w parametrze tek_count . Rozwiązanie: CREATE procedure "DBA".PROBA (in n1 integer,in w2 integer, out tek_count integer) /* parameters,... */ on exception resume /*umożliwia wykonanie w wypadku błędu*/ begin select(select "count"(Cno) from Staff where Salary not between n1 and w2) into tek_count end Dla czytania rezultatów trzeba wywołanie procedury z aplikacji, która jest stworzona w środowisku systemu oprogramowania, mającego zanurzony lub dynamiczny SQL. Sprawdzić działanie procedury w środowisku SQL serwera SYBASE SQL ANYWHERE można za dopomogą następnego koda: % % % Ensure our test variables do not already exist SET OPTION On_error = 'continue'; CREATE VARIABLE "tek_count" integer; % % Execute the procedure CALL "DBA"."PROBA"(6000, 12000, "tek_count" ); % % View the output variables SELECT "tek_count" FROM DUMMY; % Rezultat procedury pisze się do systemnej tabeli DUMMY, która ma tylko jedną kolumnę. Ostatnia instrukcja SELECT czyta wyjściowy parametr 81 BAZY DANYCH tek_count. Procedury mogą bez ograniczeń wywoływać inne procedury oraz funkcje. Format instrukcji dla stworzenia funkcji ma następny wygląd: CREATE FUNCTION [creator.]"func_name" (parameters,... ) RETURNS /* return type */ BEGIN DECLARE /*return name */ /* return type */; ... compound-statement RETURN (return name); END Wykorzystane oznaczenia: creator – imię użytkownika, właściciela funkcji; func_name – imię funkcji; parameter – parametr funkcji w formacie: IN parameter-name parametr-type compound-statement - tekst z kodami funkcji; return type – typ parametru, który funkcja musi wrócić; /*return name */ /* return type */ - imię funkcji oraz typ tego imię. Przykład 28 b. Trzeba stworzyć funkcję, która dokonywa połączenia przekazanych ją znakowych parametrów i wraca rezultat w wyglądu jednego rekordu. Rozwiazanie CREATE function fullname(in firstname char(30),in lastname char(30)) returns char(61) begin declare "name" char(61); set "name"=firstname||' '||lastname; return("name") end Skonstruujemy zapytanie SQL, które będzie zawierać imię i nazwisko klientów tablicy CUSTOMER oraz wykorzystać funkcję fullname: SELECT fullname( "firstname", "lastname" ) FROM Customer; Istnieje specjalny typ zapamiętanej procedury, który ma nazwisko tryger. Tryger uruchomi się automatyczne (spontaniczne), niezależnie od normalnego przebiegu sterowania aplikacji użytkownika, przez określone zdarzenie zachodzące w bazie danych, np. aktualizację pewnej danej, upłynięcie pewnego czasu, itp. Tryger jest połączony z jednej czy wielu operacjami modyfikacji jednej tabeli. 82 BAZY DANYCH Zapamiętanej procedury są przekompilowane przez bazę danych, dzięki temu wykonywane są znaczne szybciej niż tradycyjnie używane polecenia SQL-owe. Dodatkowo kod procedury znajduje się wewnątrz bazy danych i nie trzeba przesyłać go przez sieć. W związku z tym, w przypadku dużych procedur(a taki zwykle spotykamy w praktyce), następuje zmniejszenie generowanego ruchu w sieci. Instrukcji sterowania dostępu do danych Każda DBMS musi zawierać mechanizm gwarantujący dostęp do baz danych tylko tych użytkowników, które mają dozwalanie od administratora bazy danych. Język SQL zawiera instrukcji GRANT oraz REVOKE dla zabezpieczenia danych. Ten mechanizm wykorzysta identyfikatory użytkowników oraz ich przywileje. Identyfikatorem użytkownika nazywa się identyfikator SQL, który jest wykorzystany dla oznaczenia użytkownika bazy danych. Ten identyfikator rejestruje się przez administratora bazy danych (DBA). Każdy identyfikator jest połączony ze swoim hasłem. Każdy operator lub instrukcja SQL wykonują się od użytkownika, mającego swoje imię. Identyfikator użytkownika dozwala wyznaczyć obiekty bazy danych, z którymi może pracować użytkownik. Każdy obiekt, który jest stworzony w środowisku SQL, ma swego właściciela. Przywileje to są akcji, które użytkownik może wykonywać z daną tabelę czy widokom (tabelę wirtualną) bazy danych. Standard ISO zawiera następny zbiór przywileje: SELECT – to jest prawo wybierać dani z tabeli; INSERT - to jest prawo wstawiać do tabeli nowe rekordy; UPDATE - to jest prawo modyfikować dani w tabeli; DELETE - to jest prawo usuwać rekordy z tabeli; REFERENCES - to jest prawo odwołać do tabeli w zapytaniach SQL dla połączenia z innymi tabelami oraz dla utrzymania integralności odwołań. Przywileje INSERT oraz UPDATE mogą dotyczą się do oddzielnych kolumn tabeli. W temu wypadku użytkownik może modyfikować wartości tych kolumn, no nic nie może modyfikować wartości innych kolumn. Użytkownik za dopomogą instrukcji CREATE TABLE stworzy nową tabelę oraz automatyczne powstaje ją właścicielem. Stosowne tej tabeli on ma wszystkie przywileje. Inne użytkownicy nie mają dostęp do tej tabeli. Właściciel tabeli może wyznaczyć prawa innych użytkowników do tabeli za dopomogą instrukcji GRANT. Rezygnować przywileje właściciel tabeli może za dopomogą instrukcji REVOKE. 83 BAZY DANYCH Instrukcja GRANT Instrukcja GRANT ma następny format: GRANT { pivilege_list / ALL PRIVILEGES} ON object_name TO {authorization_id_list /PUBLIC} {WITH GRANT OPTION} W tym formacie są następne parametry: pivilege_list – to jest lista przywilejów standardu ISO; ALL PRIVILEGES – oznacza, że właściciel obiektu odda wszystkie swoje prawa; object_name – to jest nazwa obiektu (tabeli czy widoku) ; authorization_id_list – to jest lista identyfikatorów użytkowników; PUBLIC oznacza, że właściciel obiektu odda prawa wszystkim użytkowników; klauzula WITH GRANT OPTION pozwala wszystkim użytkownikom, które są ukazane w authorization_id_list oddawać swoje prawa. Przykład 29. Oddać prawa czytania i modyfikacji danych tabeli DISCIPLINE użytkowniku z identyfikatorem „had”( identyfikator tego użytkownika musi być stworzony przez administrator): Rozwiązanie: GRANT SELECT,UPDATE ON DISCIPLINE TO had Instrukcja REVOKE Ta instrukcja wykorzysta dla odmiany przywilejów który byli ustaleni przez instrukcji GRANT. Instrukcja REVOKE ma następny format: REVOKE [GRANT OPTION FOR] {privilege_list / ALL PRIVILEGES} ON object_name FROM { authorization_id_list / PUBLIC} W tym formacie są następne parametry: Klauzula GRANT OPTION FOR unieważni opcję WITH GRANT OPTION , która jest ustalona w instrukcji GRANT. privilege_list - to jest lista przywilejów którą unieważni instrukcja REVOKE; object_name – to jest nazwa obiektu (tabeli czy widoku) ; 84 BAZY DANYCH authorization_id_list – to jest lista identyfikatorów użytkowników; PUBLIC oznacza, że właściciel obiektu unieważni prawa wszystkim użytkowników. Przykład 30. Unieważnić prawa modyfikacji danych z tabeli DISCIPLINE użytkowniku z identyfikatorem „had”. Rozwiązanie: REVOKE UPDATE ON DISCIPLINE FROM had Wykorzystywanie transakcji w SQL Jakakolwiek baza danych tak długo jest przydatna, jak długo znajdują się w niej wyłącznie prawdziwe informacje. Wynika z tego, że im częściej zmieniają się opisywane obiekty, tym częściej musimy aktualizować zawartość bazy danych. Sytuacje komplikuje fakt, że bazy danych w większości są aplikacjami sieciowymi. Dostęp do danych oraz możliwość ich modyfikacji muszą być zapewnione jednocześnie wielu użytkownikom. Podstawowym sposobem zachowania integralności danych jest przetwarzanie ich w częściach noszących nazwę transakcji. Transakcja to jest operacja zmiany stanu bazy danych, składającą się z wielu operacji aktualizacji (INSERT, UPDATE, DELETE) wierszy w tabelach. Transakcja to jest seria zmian wprowadzonych do bazy danych i traktowanych przez DBMS jako pojedyncza zmiana. Transakcja może składać się z pojedynczej instrukcji, lub z wielu instrukcji. Istotną cechą transakcji jest to, że zmiany wprowadzane przez nie do bazy danych są trwale zapisywane tylko wtedy, gdy wykonane zostaną wszystkie wchodzące w skład transakcji instrukcje. Działanie takie ma szczególne znaczenie, ponieważ pozwala zachować integralność bazy danych w sytuacji, gdy w trakcie wykonywania transakcji nastąpi awaria systemu, zerwania połączenia itp. Przypuśćmy, że modyfikujemy dane o pracownikach firmy. Postanowiliśmy podnieść pensje wszystkich osób o 10%. W tym celu odczytujemy aktualną wysokość pensji, dodajemy do niej 10% I tak zmienioną wartość zapisujemy z powrotem do bazy. Załóżmy dodatkowo, że w bazie przechowywana jest wyłącznie informacja o aktualnej wysokości pensji każdego z pracowników. W trakcie wykonywania instrukcji serwer bazodanowy został nagle wyłączony. Po ponownym uruchomieniu sprawdzamy wysokość pensji współpracowników i odkrywamy, że część danych została zmieniona. W przypadku tabeli zawierającej kilkaset wierszy możemy mieć poważne 85 BAZY DANYCH problemy z określeniem, którym pracownikom podnieśliśmy już pensje, a którym dopiero zamierzamy to zrobić. Aby zapobiec takim problemom, powinniśmy zdefiniować instrukcje zmieniającą wypłatę wszystkim osobom jako jedną transakcję – wtedy albo DBMS zmodyfikowałby wszystkie rekordy, albo w wypadku wystąpienia niespodziewanej awarii – zostawił wszystkie rekordy nie zmienione. 86 BAZY DANYCH 1 faza Transaction BEGIN TRANSACTION INSERT ... UPDATE ... DELETE ... ... Temporary Buffer ROLLBACK 2 faza COMMIT Cancellation of changes Registration of changes in the table Return to the previous condition of the tables Fig. 24_a 87 BAZY DANYCH Przetwarzanie transakcji przebiega w dwóch fazach (Rys.24-a). Pierwsza z nich to inicjalizacja, rozpoczęcie transakcji. Po zainicjalizowaniu transakcji wszystkie kolejne wyrażenia SQL traktowane są jako część transakcji, aż do momentu jej zakończenia. Transakcję rozpoczyna wykonanie pierwszej instrukcji DML zmieniające stan bazy. Początek fazy 1 blokuje wszystkie inne zapytania do bazy danych. Druga faza jest zatwierdzenie lub wycofanie transakcji. Jest ono równoznaczne z jej zakończeniem i sprawia, że wszelkie wprowadzone przez nią modyfikacje są na stałe zapisywane lub anulowane w bazie danych. Do momentu, kiedy transakcja nie zostanie zatwierdzona, wprowadzone przez nią zmiany nie są widoczne dla innych użytkowników korzystających z tej samej bazy danych. Transakcja może zostać zakończona poprzez: Jawne jej zatwierdzenie instrukcją COMMIT; zmiany zostają nieodwracalnie wprowadzone do bazy; Jawne jej wycofanie instrukcją ROLLBACK; zmiany zostają odrzucone, a baza wraca do stanu z przed rozpoczęcia transakcji; Wykonanie instrukcji DDL (CREATE TABLE, ALTER TABLE, DROP TABLE); zmiany zostają nieodwracalnie wprowadzone do bazy; Skuteczne zakończenie sesji, w ramach której rozpoczęliśmy transakcje; zmiany zostają wprowadzone niby była instrukcja COMMIT; Przetwarzanie sesji (np. w wyniku awarii zasilania lub sieci); zmiany zostają odrzucone niby była instrukcja ROLLBACK. Automatyczne zatwierdzanie transakcji Większość DBMS posiada specjalny tryb pracy (ang Autocommit mode), w którym każde wykonanie zapytania powoduje automatyczne zatwierdzenie transakcji. Do włączenia trybu Autocommit w serwerze SQL SYBASE ANYWHERE służy następujące polecenie: SET OPTION auto_commit = 'on' ; Dla wyłączenia tego trybu służy następujące polecenie: SET OPTION auto_commit = 'off' ; Instrukcja BEGIN Format: BEGIN TRANSACTION Ta instrukcja jest przeznaczona dla jawnego rozpoczęcia transakcji. 88 BAZY DANYCH Instrukcja COMMIT Format: COMMIT; Wykonanie instrukcji powoduje: Zakończenie transakcji, Zatwierdzenie zmian w bazie danych, Usunięcie wszystkich założonych blokad i punktów zachowania, Udostępnienie zmian innym użytkownikom bazy. Instrukcja ROLLBACK Format: ROLLBACK; Wykonanie instrukcji powoduje: Zakończenie transakcji, Wycofanie wszystkich zmian, które byli dokonane od rozpoczęcia transakcji, Usunięcie wszystkich założonych blokad i punktów zachowania. Instrukcje SAVEPOINT, ROLLBACK TO SAVEPOINT Transakcje składające się z dużej liczby poleceń lub modyfikujące dużą liczbę wierszy warto podzielić na kilka mniejszych części, Większość DBMS pozwala na definiowanie w ramach transakcji tzw. Punktów kontrolnych lub punktów zachowania. Aby określić punkt kontrolny, należy wykonać instrukcję z następnym formatem: SAVEPOINT savepoint-name; Wprowadzenie punktu zachowania umożliwia częściowe wycofanie rozpoczętej transakcji. Dzięki temu zmiany wprowadzone przed punktem kontrolnym nie zostają utracone. O ile zdefiniowaliśmy punkt kontrolny, możemy wycofać część zmian wprowadzonych w ramach transakcji. W tym celu należy wykonać instrukcję: ROLLBACK TO SAVEPOINT savepoint-name; Przykład 31. Dla pokazywania działania transakcji z instrukcją ROLLBACK realizujemy następne kroki. 1. Stworzymy tabelę TEMPTRANSACTION z dwoma atrybutami (custid, ordertotal) w których muszą być identyfikatory klientów oraz sumy artykułów, które są zamawiane tymi klientami z tabeli ORDERS. CREATE TABLE temptransaction (custid char(4) Primary key, ordertotal integer); 2. Stworzymy transakcję dla uzupełnienia tabeli TEMPTRANSACTION. 89 BAZY DANYCH BEGIN TRANSACTION INSERT INTO temptransaction (custid, ordertotal) SELECT custid, SUM(ordertotal) FROM orders GROUP BY custid; 3. Wyświetlimy dani tabeli. SELECT * FROM temptransaction; Tabela TEMPTRANSACTION musi być uzupełniona danymi. 4. Spędzamy wycofywanie transakcję. ROLLBACK; 5. Wyświetlimy dani tabeli TEMPTRANSACTION po wycofywaniu transakcję. SELECT * FROM temptransaction; Tabela TEMPTRANSACTION jest pusta. Przykład 32. Dla pokazywania działania transakcji z instrukcją COMMIT realizujemy następne kroki. 1. Usuwamy tabelę TEMPTRANSACTION : DROP TABLE temptransaction; 2. Stworzymy tabelę TEMPTRANSACTION z dwoma atrybutami (custid, ordertotal) w których muszą być identyfikatory klientów oraz sumy artykułów, które są zamawiane tymi klientami z tabeli ORDERS. CREATE TABLE temptransaction (custid char(4) Primary key, ordertotal integer); 3. Stworzymy transakcję dla uzupełnienia tabeli TEMPTRANSACTION. BEGIN TRANSACTION INSERT INTO temptransaction (custid, ordertotal) SELECT custid, SUM(ordertotal) FROM orders GROUP BY custid; 4.Wyświetlimy dani tabeli. SELECT * FROM temptransaction; Tabela TEMPTRANSACTION musi być uzupełniona danymi. 6. Zatwierdzimy transakcję. COMMIT; 7. Wyświetlimy dani tabeli. SELECT * 90 BAZY DANYCH FROM temptransaction; Tabela TEMPTRANSACTION musi być uzupełniona danymi. Przykład 33. Dla pokazywania działania transakcji z instrukcją SAVEPOINT oraz ROLLBACK TO SAVEPOINT Wykorzystamy tabelę TEMPTRANSACTION, która jest uzupełniona danymi z poprzedniego przykładu. Realizujemy następne kroki. 1. Stworzymy następny kod dla usuwania rekordów z tabeli: SAVEPOINT SP1; DELETE FROM TEMPTRANSACTION WHERE CUSTID='a12'; SAVEPOINT SP2; DELETE FROM TEMPTRANSACTION WHERE CUSTID='a13'; SAVEPOINT SP3; DELETE FROM TEMPTRANSACTION WHERE CUSTID='a14'; SAVEPOINT SP4; DELETE FROM TEMPTRANSACTION WHERE CUSTID='a15'; SAVEPOINT SP5; DELETE FROM TEMPTRANSACTION WHERE CUSTID='a16'; 2. Wyświetlimy dani tabeli. SELECT * FROM temptransaction; Tabela nie zawiera rekordy z identyfikatorami : 'a12',’a13', 'a14', 'a15', 'a16'. 3. Spędzamy wycofywanie transakcję. ROLLBACK TO SAVEPOINT SP2; Tabela znów zawiera rekordy z identyfikatorami :’a13', 'a14', 'a15', 'a16', ale nie zawiera rekord z identyfikatorem 'a12'. Zanurzony SQL (Embedded SQL) Język SQL jest przeznaczony dla dostępu do baz danych. Dostęp może być urzeczywistni się w dwóch następnych trybach: Interaktywny dostęp przez ISQL Bezpośredni dostęp z aplikacji użytkownika. Taka dualność tworzy następnie zalety: Wszystkie możliwości instrukcji interaktywnych SQL są dostępnie przy oprogramowaniu aplikacji. W trybie interaktywnym jest możliwe usuwać błędy głównych algorytmów obrabiania informacji, które potem można wstawiać do aplikacji użytkownika. Standard SQL-2 jest językiem wszystkich baz danych, ale on nie jest językiem programowania. On nie zawiera taki instrukcji sterowania programem jako „IF …THEN”, „DO… WHILE” i in. Oprócz tego język 91 BAZY DANYCH SQL nie może definiować wewnętrznie zmienni, analizować warunki logiczne oraz zmieniać przebieg programu w zależności od tych warunków. W ogóle SQL jest językiem, który wykorzysta się tylko dla sterowania bazami danych. Dla tworzenia aplikacji wykorzystają się inne języki (np. C++, Pascal, ADA) oraz systemy oprogramowania (np. PowerBuilder, Delphi). W tych językach oraz systemach konstrukcje języka SQL są używane wewnątrz konstrukcji języka głównego. Język główny nazywa się językiem – gospodarzem (host language), a wewnętrzna konstrukcja SQL nazywa się zanurzonym SQL (embedded SQL). Technologia przetwarzania programu w tych wypadkach zakłada istnienie prekompilatora SQL, który zamieni instrukcje SQL na sekwencje instrukcji języka głównego, odwołujących do interfejsu bazy danych. Interfejs bazy danych ma nazwisko: „sterownik” (driver). Zanurzony SQL wykorzysta dla zapytań oraz dla manipulacji danymi mechanizm transakcji. Standard ISO zawiera następnie operatory zanurzonego SQL: CONNECT – ten operator połączy aplikację do bazy danych. Ten operator odpowiada opcji CONNECT serwera SQL. DISCONNECT – wyłączy aplikację użytkownika od bazy danych. Ten operator odpowiada opcji DISCONNECT serwera SQL. EXECUTE – ten operator uruchomi zapamiętaną procedurę, w niektórych realizacjach skrót „EXEC” jest niezbędny dla uruchomienia wszystkich operatorów zanurzonego SQL (np. C++) . INSERT – wstawia do tablicy bazy danych rekordy. DELETE – usuwa rekordy z tabeli bazy danych. UPDATE – modyfikuje rekordy tabel bazy danych. SELECT – czyta jeden rekord z tabel(i) bazy danych. COMMIT – ten operator pozwala urzeczywistni wszystkie zmiany w bazie danych. ROLLBACK - ten operator spędza wycofywanie wszystkich zmian w bazie danych. DECLARE – ten operator definiuje kursor bazy danych. Kursor to jest wskaźnik w zbiorze ostatecznym zapytania SQL do bazy danych. Ten zbiór jest otrzymany za dopomogą instrukcji SQL „SELECT”, która jest opisana w operatorze DECLARE. Kursor pozwala przesunięcie po rekordach bazy danych. OPEN – ten operator uruchomi zapytanie SELECT, które jest opisane w operatorze DECLARE. Wskaźnik kursora po operatorze OPEN jest ustalony przed pierwszym rekordem tabeli zbioru ostatecznego. 92 BAZY DANYCH FETCH – ten operator czyta dani w zmieni aplikacji. Po operatorze FETCH wskaźnik kursora jest ustalony do następnego rekordu zbioru ostatecznego. CLOSE – ten operator zamyka kursor. Przykład realizacji zanurzonego SQL w języku C++. Ten program modyfikuje rekord tabeli EMPLOYEE bazy danych BAZA_FIRMY. /*The following is a very simple example of an Embedded SQL program.*/ #include <stdio.h> EXEC SQL INCLUDE SQLCA; main() { db_init( &sqlca ); EXEC SQL WHENEVER SQLERROR GOTO error; EXEC SQL CONNECT DATABASE “baza_firmy” USER "dba" IDENTIFIED BY "sql"; EXEC SQL UPDATE employee SET emp_lname = 'Plankton' WHERE emp_id = 195; EXEC SQL COMMIT; EXEC SQL DISCONNECT; db_fini( &sqlca ); return( 0 ); error: printf( "update unsuccessful -- sqlcode = %ld.n", sqlca.sqlcode ); return( -1 ); } W tym przykładzie klauzula EXEC SQL INCLUDE SQLCA; połączy definicje wszystkich zmiennych oraz struktur SQLCA (SQL Communication Area) do programu. SQLCA to jest obszar pamięci , który jest wykorzystywany dla : informacji pro połączenia z bazą danych; otrzymania statystyki opracowania transakcji; otrzymania komunikatów pro błędy z bazy danych. Funkcja db_init( &sqlca ); 93 BAZY DANYCH inicjalizuje SQLCA dla roboty z bazą danych. Klauzula EXEC SQL WHENEVER SQLERROR GOTO error; tworzy pułapkę dla błędów, które mogą być przy realizacji transakcji. Przykład programu z jednorekordowym zapytaniem SQL. Ten program zaprasza tabelny numer pracownika oraz wyświetli ego dani. #include <stdio.h> #include <stdlib.h> EXEC SQL INCLUDE SQLA; main () { EXEC SQL BEGIN DECLARE SECTION; char staff_no[6]; /* tabelny numer pracownika char first_name[16]; /* nazwisko pracownika*/ char last_name[16]; /*imię pracownika*/ char address[51]; /* adres firmy */ char branch_no[4] /* numer filii firmy */ EXEC SQL END DECLARE SECTION; /* Połączenie do bazy danych*/ EXEC SQL CONNECT DATABASE "baza_firmy" USER "dba" IDENTIFIED BY "sql"; If (sqlca.sqlcode <0) exit (-1); /* zapytania tabelnego numeru pracownika */ printf ("Enter staff number: "); scanf("%s", staff_no); EXEC SQL SELECT fname, lname, address, bno INTO :first_name, :last_name, :address, branch_no FROM staff WHERE sno = :staff_no; /* analiza zakończenia programu oraz wyprowadzania rezultatów */ if (sqlca.sqlcode = = 0) { printf (" First name: %s\n", first_name); printf (" Last name: %s\n", last_name); printf (" Address: %s\n", address); printf (" Branch number: %s\n", branch_no); } else if (sqlca.sqlcode = = 100) 94 BAZY DANYCH printf ("No staff member with specified number\n"); else printf ("SQL error %d\n, sqlca.sqlcode); /* wyłączenie od bazy danych */ EXEC SQL DISCONNECT; } Projektowanie baz danych Cykl życiowy bazy danych (Life cycle of the database) Cykl życia bazy danych to jest diagram pokazujący fazy stworzenia oraz życia objektów bazy danych pod kątem roli bazy danych w systemie informacyjnem. Główne etapy cyklu życiowego bazy danych są pokazane na rys. 25. Przyjrzyjmy się dokładnie tym etapom. Do etapu „Planowanie projektu bazy danych” (Planning of development of DB) wchodzą działania przygotowawcze, dzięki którym powinny być realizowane kolejne etapy. Ten etap zawiera: Określenie procesów biznesowych, czyli opracowanie modeli opisujących daną dziedzinę przedmiotową. Tu można wyróżnić komponenty informacyjne, opisujące zewnętrzny poziom bazy danych dla każdego użytkownika oraz zakres działania organizacji. 95 BAZY DANYCH Planning of development of DB DataBase designing Choice of DBMS Conceptual designing Physical designing Creation of the prototypes Development of applications Implementation Testing Maintenance and support fig. 25 96 BAZY DANYCH Werbalny opis korporacyjnego modelu danych, który jest agregacją (zawiera) wszystkich danych dla wszystkich użytkowników oraz zakresów działania organizacji. Reguły tworzenia nazw dla danych różnego typu w słowniku danych. Słownik danych jest repozytorium zawierającym opis danych, które mogą być używane w wielu aplikacjach. Wyznaczenie wymóg do całej bazy danych oraz do konkretnych grup danych. Etap „Projektowanie bazy danych” (DataBase Designing) jest głównym etapem projektowania. On zawiera następne podetapy : Projektowanie konceptualnego modelu danych (Conceptual Designing) Projektowanie fizycznego modelu danych (Physical designing, Logical Designing) Istnieją dwie różne metody projektowania baz danych: metoda wspinająca oraz metoda schodząca. Metoda wspinająca zaczyna się z szczegółowej definicji atrybutów danych, grupowania tych atrybutów w tablice, normalizacji danych (termin normalizacja danych wyjaśnimy późnej) . Ta metoda ma sens dla małych baz danych (dziesiątki tabel). Kiedy tabel mało ich treści są oczywiste. Kiedy tabel w bazie danych są dużo, stosuje się metoda schodząca. Dane w tej metodzie agregują się w encji. Potem definiują związki pomiędzy encjamy, i specyfikują się same encje. Podetap „Projektowanie konceptualnego modelu danych” (Conceptual Designing) zawiera etapy tworzenia modelu, nie zależnego od: Typu DBMS; Realizacji fizycznej DBMS; Aplikacji użytkownika; Języków programowania; Systemu operacyjnego i typu komputera . Podetap „Projektowanie fizycznego modelu danych” (Physical designing, Logical Designing) zawiera następne etapy: Dostosowanie modelu konceptualnego do konkretnego DBMS; Przekształcenie modelu konceptualnego do modelu fizycznego (w niektórych źródłach model fizyczny nazywają modelem logicznym); Normalizacja modelu fizycznego. Model fizyczny jest inwariantny (niezależny) od : Aplikacji użytkownika; 97 BAZY DANYCH Języków programowania; Systemu operacyjnego i typu komputera . Związek pomiędzy modelem konceptualnym a modelem fizycznym jest pokazany na rys.26. Model fizyczny nie jest inwariantny od typu DBMS. Na podetapie projektowania fizycznego modelu możemy wybrać jeden z trzech następnych modeli danych dla realizacji DBMS: Hierarchiczny Sieciowy Relacyjny. W przypadku wyboru modelu relacyjnego tworzy się dodatkowo kod SQL (dla generacji tabel w DBMS). Etap wybór DBMS (Choice of DBMS) trzeba rozpoczynać po wykonaniu podetapu „Projektowanie konceptualnego modelu danych” (Conceptual Designing). Na tym etapie projektant razem z klientem muszą podjąć decyzję o typie realizacji DBMS, oraz o konkretnym DBMS z tego typu. Ten etap jest koniecznym dla rozpoczęcia podetapu „Projektowania fizycznego modelu danych” (Phisical Designing). Etap opracowania aplikacji (Development of applications) polega na zaprojektowaniu interfejsu tak z użytkownikiem, jak i z bazą danych. Ten etap realizuje się równolegle z etapem oprogramowania bazy danych (DataBase Designing). Mechanizmy dostępu aplikacji do baz danych opracowują na testowych bazach danych, mających interfejs dostępu analogiczny interfejsu głównej bazy danych. Etap „Stworzenia prototypu” (Creation of the Prototypes) polega na stworzeniu pewnej wersji bazy danych oraz aplikacji. Prototyp może zawierać tylko część trybów pracy oraz funkcji systemu informacyjnego. Prototyp pełni funkcję „sprzężenia zwrotnego” między klientem a projektantem (czyli klient testuje aplikację i decyduje, które funkcje mu odpowiadają, a które nie). Wskutek tego klient uczestniczy w projekcie. Etap „Realizacja” (Implementation) polega na stworzeniu wersji ostatecznej bazy danych oraz aplikacji. Na tym etapie opracowana baza danych uzupełnia się danymi z plików oraz dokumentów papierowych. Etap „Testowanie”(Testing) zawiera testowanie aplikacji i bazy danych w celu wykrycia błędów. Etap „Eksploatacja oraz utrzymanie” (Maintenance and support) zawiera ciągłą aktualizację bazy danych, poszukiwanie nowych wymóg, które są potrzebne dla jej skutecznej pracy. Dlatego proces projektowania systemu informacyjnego jest iteracyjny. Wymienione etapy mogą się powtarzać. Każda iteracja określa warunki dla następnego projektowania. 98 BAZY DANYCH Conceptual designing Conceptual model DBMS typ Phisical designing Phisical model fig. 26 99 BAZY DANYCH Normalizacja relacji Pierwsza forma normalna (1NF) Nie normalizowana baza danych może zawierać dane, które są skoncentrowane równocześnie w wielu tablicach czy w wielu wierszy jednej tablicy (dane powtarzające się). Powtarzanie danych jest niebezpieczne dla poprawności działania i integralności bazy danych. Normalizacja to jest proces usunięcia powtarzanych informacji w bazie danych. Normalizacja zawiera konsekwentne przekształcania struktur danych do pewnego określonego formatu. Ten proces obejmuje: eliminacje powtarzalnych atrybutów poprzez zastąpienie ich odrębnymi relacjami; „spłaszczanie” (uproszczenie) struktury danych poprzez eliminacje atrybutów złożonych; utworzenie nowych tablic w celu zastąpienia (uproszczenia) niektórych związków; ustalenie pierwotnych (głównych) i obcych kluczy relacji, które reprezentują związki semantyczne; wyeliminowanie niepożądanych zależności (np. funkcyjnych) pomiędzy kolumnami relacji poprzez wprowadzenie nowych relacji. Normalizacja wykonuje się na etapie projektowania modelu fizycznego danych (Phisical Designing). Normalizacja zawiera określone kroki, na których otrzymają się formy normalne. Indeks każdego kroku odpowiada poziomu formy. Proces normalizacji jest włożony. To znaczy, że każda forma normalna bardziej wysokiego poziomu zawiera wszystkie formy, mające mniej wysokie poziomy. Teoria relacji zawiera pięć form normalizacji od 1NF do 5NF. Na praktyce, w wielu wypadkach, dostatnio normalizować do formy 3NF. Rozpatrzymy przykład relacji R, która ma następną strukturę R(OrdNum,OrdDate,CustNum, CustName, CustAddr, InvNum, InvAddr, ProdNum, ProdDescr, ProdQuant, ProdDisk): 100 BAZY DANYCH Tab 0. R Ord Nu m Ord Cus Cust Dat t Name e Nu m 1109 20/1 L09 N.Jaks 0/ on 200 1 1208 21/1 M9 0/ 7 200 1 … … Cust Addr USA, Sun Franci sko … Avenu … V.Gaus Poland s , Krako w … … … Inv Num Inv Prod Prod Addr Descr Num In809 0 Bank of Ame r. New Jork … Bank An09 87 100 10 201 Pentium 40 3 MsBoard 40 300 … Printer … 10 … 9 Pentium 3 HardDis k … Modem … 12 15 50 12 … 30 … … 10 … 100 Gdan 097 ski … … … Prod Prod Quan Disk t 450 Ta relacja może być modelem zewnętrznego poziomu bazy danych (external level), który odwzorowuje zdanie wyznaczonych pracowników firmy handlowej na bazę danych swojej firmy. Objaśnienie atrybutów tej relacji są przedstawione poniżej: OrdNum – (Order Number) – numer zamówienia dla dostawy towarów klientom; OrdDate – (Order Date) – data zamówienia; CustNum – (Customer Number) – numer identyfikacyjny klienta jednoznaczne wyznaczający klienta, np. numer legitymacji, paszportu; CustName – (Customer Name)- nazwisko klienta; CustAddr – (Customer Address) –adres klienta ; InvNum – (Invoice Number)- numer konta klienta w banku; InvAddr – (Invoice Address) – adres banku, gdzie się znajduje konto klienta; ProdNum - (Product Number) – kod produktu dostarczonego do klienta (wszystkie gatunki produkcji są klasyfikowane za pomocą tych kodów); 101 15 BAZY DANYCH ProdDescr – (Product Description) – nazwa produktu dostarczonego do klienta; ProdQuant – (Product Quantity) – ilość produktów w zamówieniu; ProdDisk – (Product Diskount) - zniżka w %. Ta tabela odwzorowuje reprezentacje głównej kategorii użytkowników bazy danych. Użytkownikami tej bazy są klienci oraz pracownicy firmy handlowej. Każdy użytkownik myśli, że dane w bazie są połączone w sposób pokazany w tablicy oraz przechowują się w niej. Dla użytkownika jest to schemat zewnętrzny bazy danych. Z punktu widzenia projektanta oraz teorii relacji sposób przechowania danych w tablicy R jest bardzo zły. Przede wszystkim zwrócimy uwagę na ostatnie 4 kolumny tablicy dla wszystkich jej wierszy (rekordów), gdzie mamy kilka wartości atrybutów połączonych z jednym zamówieniem. To znaczy, że każdemu zamówieniu klienta odpowiadają różne towary dla dostawy. Definicja pierwszej formy normalnej(1NF): Relacja odpowiada do pierwszej formy normalnej(1NF), jeśli na skrzyżowaniu każdej kolumny i wiersza (czyli w każdej komórce tablicy) znajduje się tylko jedna wartość atrybutu. Tabela R nie odpowiada tym wymogom. Tabelę R można doprowadzić do pierwszej formy normalnej, jeśli dodać do opisu każdego towaru informację powtarzającą się w pierwszych 7 kolumnach. W tym przypadku atrybut „OrdNum” nie zmoże być kluczem pierwotnym (głównym), ponieważ w tabeli pojawia się wiersze powtarzające się, dla tego do tabeli R trzeba dodać jeszcze jedną kolumnę LineNum(numer linii). Zespół atrybutów OrdNum oraz LineNum będzie kluczem pierwotnym. 102 BAZY DANYCH Tab 1. R1 Ord Nu m Line Num 1109 1 2 Ord Date 20/1 0/ 2001 Cus Cust t Name Nu m L09 N.Jak son ... n 1208 1 2 … ... m ... 21/1 0/ 2001 … M9 7 V.Ga uss … Cust Addr Inv Num Inv Prod Prod Addr Descr Num USA, Sun Franci sko … Avenu … Poland , Krako w … In809 0 Bank of Ame r. New Jork … Bank … An09 87 100 201 Pentium 40 3 MsBoard 40 300 … Printer … 10 Pentium 3 HardDis k … Modem … 12 100 Gdan 097 ski … … … Prod Quan t 450 Sformułujemy regułę 1 - przetwarzania tablicy do pierwszej formy normalnej: Żeby usunąć wiele wartości danych w komórce tabeli, trzeba stworzyć nowe wierszy dla każdej danej tej komórki. Nowe wiersze w innych polach atrybutów muszą zawierać taki same dani. W nowej tabeli trzeba wyznaczyć(lub dodać) atrybuty, wyznaczające klucz pierwotny. Gdyby wszystkie tabele bazy danych spełniały pierwsza postać normalną, to relacje typy JEDEN-DO-WIELE byłyby określone zawsze pomiędzy kilkoma tabelami (nigdy w obrębie jednej tabeli), a relacja typu JEDEN-DOJEDEN mogłaby się zawierać w jednej tabeli. Ale ta decyzja ma następne błędy: W tabeli R1 okaże się dużo informacji zbytecznych, bowiem informacja w pierwszych 7 kolumnach będzie często powtarzać się w różnych wierszach. Druga forma normalna (2NF) Definicja drugiej formy normalnej(2NF): 103 50 … 30 … BAZY DANYCH Relacja odpowiada drugiej formie normalnej(2NF), jeśli ona odpowiada pierwszej formie normalnej(1NF) oraz każdy atrybut, który nie wchodzi do klucza pierwotnego zależy funkcyjne od klucza pierwotnego i nie zależy od jego części. Zależność funkcyjna (Functional dependency) to jest ograniczenie integralności relacji, stwierdzające, że każda z wartości atrybutu A jest skojarzona z dokładnie jedną wartością atrybutu B w tej relacji. Jest to zapisane w postaci A B . Na przykład, wartość atrybutu „NR_PRACOWNIKA” wyznacza dokładnie wartość atrybutu „NAZWISKO”: NR_PRACOWNIKA NAZWISKO. Rozpatrzymy relacje R1 w celu sprawdzenia, czy one odpowiadają drugiej formie normalnej. Kluczem pierwotnym w relacji R1 jest zespół atrybutów (OrdNum,LineNum). Wyznaczymy zależności funkcyjne pomiędzy atrybutem OrdNum, który jest częścią klucza pierwotnego, i innymi atrybutami tabeli R1: OrdNum OrdDate; OrdNum CustNum; OrdNum CustName; OrdNum CustAddr; OrdNum InvNum; OrdNum InvAddr. Inne atrybuty są funkcyjne zależnymi od pełnego klucza pierwotnego: (OrdNum,LineNum) ProdNum; (OrdNum,LineNum) ProdDescr; (OrdNum,LineNum) ProdQuant; (OrdNum,LineNum) ProdDisk. To znaczy, że relacja R1 nie odpowiada wymogom drugiej formy normalnej, ponieważ atrybuty OrderData, CustNun, CustName, CustAddr, InvNum oraz InvAddr są funkcyjnie zależne tylko od numeru zamawiania klienta (OrdNum) . Sformułujemy regułę 2 - przekształcenia tablicy do drugiej formy normalnej: Żeby relacja odpowiadała wymogom drugiej formy normalnej, trzeba wszystkie atrybuty, które są zależne funkcyjnie od atrybutu, który jest częścią klucza pierwotnego, przenieść do nowej tablicy. Ta tabela powinna mieć swój klucz pierwotny oraz tabela stara musi mieć klucz obcy dla związku z tabelą nową. Rezultat zastosowania tej reguły jest pokazany w Tab. 2 oraz Tab.3. Tab.2 104 BAZY DANYCH R11 Ord Num … 1109 Ord Date … 20/10/01 Cust Num L09 Cust Name … N.Jakson 1208 21/10/01 M97 V.Gauss … … … Cust Addr … USA, Sun Francisko … Avenu… Poland, Krakow … Inv Num … In8090 Inv Addr … Bank of Amer. New Jork… An0987 Bank Gdanski … … Tab.3. Ord Num … 1109 1109 1109 ... 1208 1208 1208 … Line Num … 1 2 3 … 1 2 3 … Prod Num 100 201 300 100 097 450 R12 Prod Descr … Pentium 3 MsBoard Printer … Pentium 3 HardDisk Modem … Prod Quant … 40 40 10 … 12 50 30 … Prod Disk … 10 15 9 … 10 12 10 … Tą regułę trzeba konsekwentnie zastosować dla każdej tablicy bazy danych, dopóki wszystkie tablicę będą odpowiadać wymogom drugiej formy normalnej. Początkowa relacja R jest przekształcona do dwóch nowych relacji: R11(OrdNum, OrdDate, CustNum, CustName, CustAddr, InvNum, InvAddr); R12(OrdNum, LineNum, ProdNum, ProductDescript, ProductQuantity, ProductDiskount). 105 BAZY DANYCH Do tablicy R12 jest dodany atrybut dodatkowy – LineNum - który wyznacza numer rekordu w dokumencie zamówienia. W relacji R12 kluczem pierwotnym jest kompozycja atrybutów (OrdNum,LineNum), natomiast kluczem obcym jest – OrdNum. Początkowa relacja R może być otrzymana z relacji R11 i R12 przy pomocy operacji połączenia według wartości atrybutu OrdNum. Na przykład: SELECT R11.OrdNum, R11.OrdDate, R11.CustNum, R11.CustAddr, R11.InvNum, R11.InvAddr, R12.ProdNum, R12.ProdDescr, R12.prodQuant, R12.ProdDisk FROM R11,R12 WHERE R11.OrdNum = R12.OrdNum GROUP BY R11.OrdNum ORDER BY R12.LineNum ; Reprezentacja relacji R w postaci dwóch relacji R11 i R12 pozwala uniknąć dublowania niektórych danych w bazie. Trzecia forma normalna (3NF) Relacja odpowiada trzeciej formie normalnej (3NF), jeżeli ona znajduje się w drugiej formie normalnej (2NF) oraz nie zawiera tranzytywnych zależności funkcyjnych. Zależność tranzytywna - to jest zależność funkcyjna pomiędzy atrybutami, mająca taki wygląd: AB oraz BC. Zależność tranzytywna zawiera zależności funkcyjne pomiędzy atrybutami, które nie są kluczami. Relacja R11 nie odpowiada wymogom trzeciej formy normalnej. Ta relacja zawiera następne zależności tranzytywne : OrdNum CustNum CustNum CustName CustNum CustAddr OrdNum InvNum InvNum InvAddr. Atrybut OrdNum jest kluczem, który wchodzi do wszystkich zależności funkcyjnych z atrybutami tablicy R11. Oprócz tego adres banku jest funkcyjnie zależny od numeru konta klienta w tym banku oraz dani klienta są zależne od identyfikatora klienta. Relacja R12 także nie odpowiada wymogom trzeciej formy normalnej. Ta relacja zawiera następne zależności tranzytywne : (OrdNum, LineNum) ProdNum 106 BAZY DANYCH ProdNum ProdDescr ProdNum ProdDisk Sformułujemy regułę 3 - przetwarzania tablicy do trzeciej formy normalnej: W celu doprowadzenia relacji do trzeciej formy normalnej trzeba wszystkie atrybuty, które znajdują się w zależności tranzytywnej, przenieść do nowej tablicy. Ta tablica powinna mieć swój klucz pierwotny oraz klucz obcy dla związku z tabelą starą. Rezultatem zastosowania tej reguły są nowe relacje R111, R112, R113 – otrzymane z relacji R11, oraz R121 i R122 - otrzymane z relacji R12: R111(OrdNum, OrdDate, CustNum, InvNum); R112(InvNum, InvAddr). R113 (CustNum, CustName, CustAddr); R121(OrdNum,LineNum, ProdNum, ProdQuant); R122(ProdNum, ProdDescr, ProdDisk). Podane wyżej relacje odpowiadają wymogom trzeciej formy normalnej . W relacji R122 atrybut ProdNum jest kluczem pierwotnym. Mający ta samą nazwę atrybut w relacji R121 jest kluczem obcym wykorzystywanym dla związku pomiędzy R121 oraz R122. Analogiczne jest wykorzystywany atrybut CustNum w relacjach R113 i R111 oraz atrybut InvNum w relacjach R112 i R111. Ostatecznym wynikiem normalizacji bazy danych zadanej przy pomocy relacji R, są następnie relacje: Tab 4. R111 OrdNum OrdDate CustNum InvNum 1109 20/10/2001 L09 In8090 … … … … 1208 21/10/2001 M97 An0987 … … … … Tab 5. R112 InvNum In8090 … An0987 … InvAddr Bank of Amer. New Jork… … New Jork Sity Bank… … 107 BAZY DANYCH Tab. 6. CustNum L09 … M97 … R113 CustName CustAddr N.Jakson USA, Sun Francisko… Avenu… … … V.Gauss RP, Krakow … … Tab 7. OrdNum 1109 1109 1109 … 1208 1208 1208 … LineNum 1 2 3 … 1 2 3 … R121 ProdNum 100 201 300 … 100 097 450 … ProdQuant 40 40 10 … 12 50 30 … Tab.8. R122 ProdNum … 097 100 201 300 450 … ProdDescr … HardDisk Pentium 3 MsBoard Printer Modem … ProdDisk … 12 10 15 9 10 … Graficzne algorytm normalizacji można przedstawić w postaci drzewa binarnego na rys.26a. Zależność funkcyjna typu: A ->>B oznacza, że atrybut A wyznacza jednoznaczne zbiór atrybutów B . 108 BAZY DANYCH Na początku normalizacji mieliśmy tylko jedną relację (tablicę) R. Mimo to, że ilość tabel została zwiększona, baza danych ma nieduże rozmiary, bowiem atrybuty w różnych tabelach nie powtarzają się. Oprócz tego, te tablice podtrzymują integralność bazy danych. Np. zakładamy, że zmienił się adres klienta. W tym wypadku zmiany trzeba zrobić tylko jeden raz w jednej tablicy R113. W przypadku jednej nie normalizowanej tabeli R, zmiany trzeba było by zrobić we wszystkich rekordach zamówień, które ma klient. Sytuacja analogiczna w przypadku zmian zniżek cen na produkcję. W nie normalizowanej tabeli R trzeba byłoby dokonać zmiany dla atrybutu ProdDisk we wszystkich rekordach zamówień dla wszystkich klientów. W bazie normalizowanej zmianę tego atrybutu trzeba zrobić tylko w jednym rekordzie tabeli R122. Zadanie: Zapisać kod SQL dla otrzymania relacji R z relacji, otrzymanych w trzeciej formie normalnej. 109 BAZY DANYCH R(OrdNum,OrderDate,CustNum, CustAddr,InvNum,InvAddr, ProdNum,ProdDescr,ProdQuant,ProdDisk) 1NF R1 (OrdNum, LineNum)->>(Atybuty R) 2NF R11 OrdNum->>(Atrybuty R1) R111 (OrdNum )->>(OrderDate, CustNum,InvNum) R112 (InvNum)->>(InvAddr) R12 (OrdNum,LineNum) ->> (Atrybuty R1) 3NF R121 (OrdNum,LineNum)>>(ProdNum,ProdQua nt) R113 (CustNum)>>(CustName,CustAdd) R122 (ProdNum)->> (ProdDescr,ProdDisk) Fig 26 a 110 BAZY DANYCH Projektowanie modelu konceptualnego Model konceptualny (infologiczny) stworzą się na drugim etapie projektowania bazy danych, czyli po zakończeniu etapu planowania projektu bazy danych. Skutkiem poprzedniego etapu jest opis werbalny problemu. Na etapie projektowania modelu konceptualnego trzeba opis werbalny przekształcić do opisu formalnego. Model konceptualny zawiera opis dziedziny problemu (problem domain), który będzie zrozumiałym tak dla specjalistów z baz danych, jak również dla użytkowników. Relacyjny model danych nie reprezentuje w sposób wizualny semantykę dziedziny problemu i potrzebuje specjalnej wiedzy. Standardem modelu konceptualnego jest ERD - diagram P.Chena (Entity – Relationship Diagram), w literaturze spotykamy też inne nazwy: diagram „encja –związek” albo „ER-model”. Główne pojęcia i kategorie ER-modelu. Encja (ang. Entity) – to jest grupa obiektów o podobnych własnościach, która ma nazwę i którą można i warto wyróżnić w modelowanej rzeczywistości, np. Pracownik, Dział, Kierownik, Pomieszczenie. W odróżnieniu od obiektu, encja nie jest kojarzona z metodami. Encja ma unikalną nazwę i zbiór atrybutów. Stosownie do relacyjnych baz danych ten zbiór atrybutów przedstawia jedną tabelę. Atrybut – nazwana własność lub wartość przypisana do encji. Na przykład, encja „Pracownik” może mieć następny zbiór atrybutów: „ Numer identyfikacyjny”, „Nazwisko”, „Imię”, „ Ilość dzieci”, itd. Klucz – to jest atrybut lub zbiór atrybutów, który jednoznacznie identyfikuje konkretny egzemplarz encji. Dla encji „Pracownik” kluczem jest atrybut „ Numer identyfikacyjny”. Egzemplarz encji (lub rekord) - to jest komplet (zbiór) wszystkich atrybutów odpowiadających jednemu kluczowi. Ten komplet nazywa się rekordem encji. Miedzy oddzielnymi encjami mogą istnieć związki. Związek (asocjacja) to jest binarna kategoria deklarująca powiązanie asocjacyjne pomiędzy encjami. Na przykład, encja „Pracownik” ma powiązanie asocjacyjne z encją „ Dział”. Ten związek ma nazwę „Pracuje”. Związki (asocjacji) mogą istnieć tak pomiędzy różnymi encjami, jak również pomiędzy rekordami tej samej encji. W przypadku ostatnim związki nazywają się rekursywnymi. 111 BAZY DANYCH Związek może mieć własną nazwę oraz nazwy swoich roli. Rola odwzorowuje interpretację związku z punktu widzenia encji, która jest połączona tym związkiem. Wiele firm-producentów DBMS wykorzystują oznaczenia graficzne encji jako prostokątów, wewnątrz których są podane nazwy encji oraz ich atrybuty. Przykłady różnych typów związków pomiędzy encjami są pokazane na rys.27. Tu umownie nie pokazane atrybuty tych encji. Rozpatrzymy te związki: (A---B). Związek pomiędzy encjami A i B jest zależnym (dependent), jeżeli egzemplarzy encji B nie mogą istnieć niezależnie (samodzielnie) bez egzemplarzy encji A. W związku zależnym dowolnemu egzemplarzowi z encji B odpowiada tylko jeden egzemplarz z encji A. Dla oznaczenia graficznego tej zależności stosuje się trójkąt przy encji B. Ponieważ egzemplarzowi encji A mogą odpowiadać wiele egzemplarzy encji B, trójkąt jest połączony z encją B za pomocą trzech kreseczek. Na rys.27 ta sytuacja oznaczona za pomocą skrótów (1,1) około B oraz (1..n) około A. Kreska pozioma przecinająca ten związek, oznacza obowiązkową obecność minimum jednego egzemplarza tej encji, około której znajduje się kreska. Jeżeli obecność encji nie jest obowiązkowa, na miejscu kreski będzie krążek. Kiedy związek pomiędzy encjami będzie mieć typ „jeden – do – jednego”(1:1) trójkąt będzie połączony z encją B za pomocą jednej kreski. (C—D). Związki niezależne mogą być różnych typów. Pomiędzy encjami C i D związek jest niezależny, mający typ „wiele - do – wielu” (M:M). To znaczy, że każdemu egzemplarzowi encji C może odpowiadać wiele egzemplarzy encji D, i odwrotnie: każdemu egzemplarzowi encji D może odpowiadać wiele egzemplarzy encji C. Obecność minimum jednego egzemplarza encji C i D jest obowiązkowa. (E—F). Pomiędzy encjami E i F związek jest niezależny, mający typ „jeden – do – wielu”(1:M). Związki pomiędzy encjami nie są obowiązkowe, o czym mówią skróty(0..n) oraz (0,1). To znaczy, że dowolnemu egzemplarzowi encji E może odpowiadać wiele, jeden lub zero egzemplarzy encji F, natomiast dowolnemu egzemplarzowi encji F może odpowiadać jeden albo zero egzemplarzy encji E. (G—R). Pomiędzy encjami G oraz R związek jest niezależny, mający typ „jeden – do – jednego” (1:1). Związki pomiędzy encjami nie są obowiązkowe, o czym mówią skróty (0,1). To znaczy, że dowolnemu egzemplarzowi encji G może odpowiadać jeden albo zero egzemplarzy encji R i odwrotnie. 112 BAZY DANYCH (M---N). Pomiędzy encjami M oraz N związek jest niezależny, mający typ „jeden – do – jednego”(1:1). Związki pomiędzy encjami są obowiązkowe, o czym mówią skróty (1,1). To znaczy, że dowolnemu egzemplarzowi encji G obowiązkowo odpowiada jeden egzemplarz encji R, i odwrotnie dowolnemu egzemplarzowi encji R obowiązkowo odpowiada jeden egzemplarz encji G. (O---Q). Pomiędzy encjami O oraz Q związek jest niezależny, mający typ „jeden – do – wielu”(1:M). Związki pomiędzy encjami są obowiązkowe, o czym mówią skróty(1..n) oraz (1,1). To znaczy, że dowolnemu egzemplarzowi encji O może 113 BAZY DANYCH A C E G 1..n 1..n 0,1 0..n 1,1 1..n 0,1 0,1 B D M F o R S 1,1 1,1 1..n 1,1 1,1 0,1 N Q T fig.27 114 BAZY DANYCH odpowiadać jeden albo wiele egzemplarzy encji Q, natomiast dowolnemu egzemplarzowi encji Q odpowiada jeden egzemplarz encji O. (S---T). Pomiędzy encjami S i T związek jest niezależnym, mającym typ „jeden – do – jednego” (1:1). Ten związek obowiązkowo potrzebuje obecność egzemplarza encji T dla każdego istniejącego egzemplarza encji S, natomiast dla dowolnego egzemplarza encji T nie obowiązkowa obecność egzemplarza encji S. Przykład modelu konceptualnego, zawierającego dwie encje - „the Teacher” (Wykładowca) oraz „Student” są pokazane na rys. 28. Pomiędzy tymi encjami istnieją dwa typy związków: „ Degree designing” (Projektowanie dyplomowe) „ The Lectures” (Wykłady). Każdy związek ma różne nazwy roli obok każdej encji. Rozpatrzymy związek „Degree designing” (Projektowanie dyplomowe): Ze strony encji „ Student” rola oznacza (i ma odpowiednią nazwę) „ Writes the diploma under the direction” (Pisze dyplom z promotorem). Ze strony encji „the Teacher”(Wykładowca) rola oznacza (i ma odpowiednią nazwę) „Supervises” (kieruje studentem). Wykładowca może być promotorem u wielu studentów, natomiast każdy student może mieć tylko jednego promotora, dla tego ten związek ma typ „jeden - do - wielu”. Związek „The Lectures” (Wykłady) pomiędzy encjami ma typ „wiele - do wielu” (M:M), ponieważ wykładowcy wykładają wielu studentom, a studenci przychodzą na wykłady do wielu wykładowców. Przykład modelu konceptualnego biblioteki jest pokazany na rys.29. On zawiera 4 typy encji: Książki (Books) Egzemplarze książki (Copies of the book) Katalog systematyczny (Classifikation directory) Czytelnicy (The readers). Encja Książki (Books) zawiera pełny opis książki, która jest wydana z biblioteki. Każda książka może mieć wiele egzemplarzy, które są wydawane czytelnikom, dlatego związek pomiędzy encjami „Books” oraz „Copies of the book” jest zależny. To znaczy, że egzemplarz książki nie może istnieć bez odpowiedniego rekordu w encji „Books”. Każda książka jest opisana w katalogu tematycznym, przy czym ona może być opisana w różnych katalogach. Dlatego związek pomiędzy encjami „Books” oraz „Classification directory” ma typ „wiele - do - wielu” (M:M). 115 BAZY DANYCH Fig.28 Egzemplarze książek wydają się czytelnikom. Każdy czytelnik może wypożyczyć wiele książek, może również w ogólne nie wypożyczać ich. To znaczy, że związek pomiędzy encjami „The readers” oraz „Copies of the book” ma typ „jeden – do – wielu” (1:M). Krążki na tym związku oznaczają, że egzemplarz encji może być nieobecnym. ER- model podtrzymuje kategoryzacje encji. To oznacza, że podobno do systemów obiektowych, encja może być nadklasą dla innych encji (tzn. być dla tych encji klasą macierzystą). Przy czym encje potomne zawierają wszystkie cechy encji macierzystych. Dla reprezentacji graficznej kategoryzacji encji stosują specjalny element graficzny „jednostkę – dyskryminator”. Na rys. 30 jest pokazany fragment bazy danych 116 BAZY DANYCH Fig.29 117 BAZY DANYCH Tests KOD I Autor VA30 Type VA10 Quest_answers SQL_Tests DB_Name VA15 Amount_quest SI Discipline VA15 Ball SI Data DT Analytical_tasks TaskName VA15 Amount_at SI fig.30 118 BAZY DANYCH testów sprawdzających wiedzę studenta. Tu jest encja macierzysta „Tests”, która zawiera ogólne dla każdego testu własności (kod testu, autor testu, typ testu). Podklasami tej encji mogą być różne konkretne testy, z różnymi własnościami. Przekształcenie ER – modelu (modelu infologicznego) do modelu relacyjnego (modelu fizycznego) Istnieją formalne reguły dla przekształcenia istniejącego ER – modelu do modelu relacyjnego. Na podstawie tych reguł opracowują CASE – narzędzia dla projektowania baz danych. CASE-narzędzia, zgodnie z tymi regułami, pozwalają tworzyć konceptualne ER – modele, tabeli baz danych dla modelu fizycznego oraz kod SQL dla wybranego środowiska bazy danych. Wymienimy te reguły: 1. Każda encja przekształca się do relacji (tabeli) modelu relacyjnego. Przy czym, nazwy encji i ich atrybutów z ER - modelu trzeba przypisać odpowiednim relacjom oraz ich atrybutom w modelu relacyjnym. Spacje w nazwach zamieniają się symbolem „ _” . 2. Dla każdego atrybutu modelu relacyjnego wyznacza się odpowiedni dla wybranego DBMS typ danych. 3. Klucz encji ER – modelu będzie kluczem pierwotnym w relacji (tabeli) modelu relacyjnego. Atrybuty modelu relacyjnego, które wchodzą do klucza pierwotnego, otrzymają własność „ obowiązkowa obecność” (wartość NOT NULL). 4. Do atrybutów każdej relacji modelu relacyjnego, która odpowiada encji zależnej ER – modelu, dodaje się atrybut (czy zbiór atrybutów), który(e) formuje klucz encji niezależnej tego ER – modelu. W relacji, która odpowiada encji zależnej, dodany atrybut (czy zbiór atrybutów) zostaje kluczem obcym (FOREIGN KEY). 5. Dla przetwarzania związków z nieobowiązkową obecnością atrybutów, które odpowiadają kluczowi obcemu (FOREIGN KEY), wartości tych atrybutów trzeba ustawić w (NULL). Przy obecności obowiązkowej wartość tych atrybutów trzeba ustawić w (NOT NULL). 6. Dla realizacji kategoryzacji encji przy przekształceniu do modelu relacyjnego można otrzymać kilka wariantów tego przekształcenia. Wariant pierwszy – tworzy się jedna relacja, a do niej włączają się wszystkie atrybuty macierzystych oraz potomnych encji. Wariant drugi – twarzą się relacje dla każdej encji: nadklasa oraz podklasa. W relacji 119 BAZY DANYCH encji podklasy włączają się atrybuty kluczowe nadklasy, które też deklarują się jako klucze. 7. Dla realizacji każdego związku w modelu relacyjnym, do każdej relacji trzeba dodać atrybuty kluczowe innej encji, która jest połączona tym związkiem. 8. Dla realizacji związków „wiele – do – wielu” (M:M) trzeba stworzyć nową relację , która zawiera wszystkie atrybuty kluczowe dwóch encji. Przykład przetwarzania modelu konceptualnego „Biblioteka” do modelu fizycznego jest pokazany na rys.31. Przykład przetwarzania modelu konceptualnego „Testy” do modelu fizycznego jest pokazany na rys.32. 120 BAZY DANYCH The readers Num_document Last_name First_name Birth_date Sex Phone_home Phone_office VARCHAR(10) <pk> VARCHAR(20) VARCHAR(10) DATE VARCHAR(1) VARCHAR(10) VARCHAR(10) Books ISBN Name Autor Publishing City Year Amount of pages VARCHAR(12) <pk> VARCHAR(30) VARCHAR(15) VARCHAR(15) VARCHAR(15) DATE NUMBER Num_document = Num_document Copies of the book ISBN = ISBN ISBN = ISBN ISBN Num_inv Num_document Is_or_not Capture_date Return_date VARCHAR(12) <pk,fk1> VARCHAR(10) <pk> VARCHAR(10) <fk2> BINARY(1) DATE DATE Is connected Code_knowiedges VARCHAR(10) <pk,fk2> ISBN VARCHAR(12) <pk,fk1> Code_knowiedges = Code_knowiedges Classification directory Code_knowiedges VARCHAR(10) <pk> Name_knowledges VARCHAR(20) fig31 121 BAZY DANYCH Tests KOD INTEGER <pk> Autor VARCHAR(30) Type VARCHAR(10) KOD = KOD KOD = KOD KOD = KOD Quest_answers SQL_Tests KOD INTEGER DB_Name VARCHAR(15) Amount_quest SMALLINT KOD Discipline Ball Data INTEGER <pk,fk> VARCHAR(15) SMALLINT DATETIME Analytical_tasks KOD INTEGER <pk,fk> TaskName VARCHAR(15) Amount_at SMALLINT fig.32 122 BAZY DANYCH Przykład projektowania bazy danych Etap planowania projektu bazy danych Opracowanie modeli zewnętrznego poziomu bazy danych. Baza danych musi zawierać dani pro tematy projektów dyplomowych Wydziału Elektroniki. Zewnętrzny poziom bazy danych składają następne komponenty informacyjne : Tematy prac dyplomowych Zakresy tematów Dyplomanci (Studenci studiów inżynierskich oraz magisterskich) Promotorzy prac dyplomowych Recenzenci prac dyplomowych. Określenie procesów biznesowych modeli: Przy stworzeniu nowego tematu promotor czyta poprzednią informację z bazy danych pro wszystkie tematy w wyznaczonym zakresie dziedziny przedmiotową. Przy zatwierdzeniu nowego tematu kancelaria dziekanatu wnosi dani do bazy danych pro ten temat. Przy wyboru tematu student czyta informacje pro wszystkie tematy oraz ich promotorów w wyznaczonym zakresie dziedziny przedmiotową. Dziekanat wnosi dani pro studenta przy zatwierdzeniu wykonawcą tematu. Promotor czyta dani pro recenzentów przy poszukiwaniu recenzenta danego tematu. Z punktu wzoru użytkownika dani muszą być połączone w taki sposób: Temat Grupy atrybutów bazy danych Zakres Dyplomant Promotor Recenzent Werbalny opis modelu danych. Użytkownikami bazy danych są : Dziekanat Promotorzy oraz recenzenci prac dyplomowych Studenci Wydziału Elektroniki oraz innych wydziałów Uczelni. Baza musi zawierać dane pro: tematy prac dyplomowych, wykonawców, 123 BAZY DANYCH zakresy tematów, daty zgłoszenia tematów katedrą, daty wydania tematów wykonawcą, daty obrony tematów, dyplomantów, promotorów, daty zgłoszenia tematów promotorem, daty wydania recenzji, recenzentów, opisy zgłoszonych tematów, plany realizacji tematów, itp. Słownik danych : Nazwisko atrybutu Id_temat Nazw_t Data_zl Data_wyd Data_obr Opis_pr Plan_pr literat Nazwisko atrybutu Id_zakr Nazwa_zakr Nazwisko atrybutu Id_dypl Nazwisko_d Imie_d kierunek specjal Temat Opis atrybutu Identyfikator tematu Nazwisko tematu Data zgłoszenia tematu Data wydania tematu Data obrony projektu Opis projektu Plan projektu Literatura Zakres Opis atrybutu Identyfikator zakresu Nazwisko zakresu tematu Format danych liczbowy Tekstowy (30) data data data Tekstowy (120) Tekstowy (120) Tekstowy (120) Format danych liczbowy Tekstowy (40) Dyplomant Opis atrybutu Identyfikator dyplomanta Nazwisko dyplomanta Imię dyplomanta Kierunek studiów dyplomanta Specjalność studiów Format danych liczbowy Tekstowy (30) Tekstowy (30) Tekstowy (40) Tekstowy (30) 124 BAZY DANYCH Kurs_t Adres_d Telefon_d Data_ur Miej_ur dyplomanta Kurs studiów dyplomanta Adres mieszkania dyplomanta Telefon dyplomanta Data urodzenia dyplomanta Miejsce urodzenia dyplomanta Nazwisko atrybutu Id_pr Nazwisko_p Imie_p St_nauk katedra Nr_pokoju Data_pr Promoter Opis atrybutu Identyfikator pracownika Nazwisko pracownika Imię pracownika Stopień naukowy Katedra Numer pokoju Data recenzji promotorem Format danych liczbowy Tekstowy (30) Tekstowy (30) Tekstowy (30) Tekstowy (40) Tekstowy (10) data Nazwisko atrybutu Id_pr Nazwisko_p Imie_p St_nauk katedra Nr_pokoju Data_pr Recenzent Opis atrybutu Identyfikator pracownika Nazwisko pracownika Imię pracownika Stopień naukowy Katedra Numer pokoju Data recenzji recenzentem Format danych liczbowy Tekstowy (30) Tekstowy (30) Tekstowy (30) Tekstowy (40) Tekstowy (10) data Tekstowy (30) Tekstowy (60) Tekstowy (12) data Tekstowy (30) Reguły tworzenia nazw danych. Nazwy nowych danych składają się z pierwszych trzech liter – nazw tabeli oraz z nazw nowego atrybut przez symbol „_”. Na przykład: Rec_newatrybut. Wyznaczenie wymóg do całej bazy danych oraz do konkretnych grup danych. Baza danych nie może zawierać powtarzających atrybutów. Wszystkie zmiany dokonywają się tylko w jednym miejsce jednego atrybutu. 125 BAZY DANYCH Etap projektowania bazy danych Normalizacja Rezultat normalizacji: Zakresy Id_zakr Nazw a_zakr N VA40 tematy id_temat nazw _t data_w yd data_zl data_obr opis_pr plan_pr literat Dyplomanci Id_dypl Nazw isko_d imie_d kierunek specjal kurs_t adres_d telefon_d Data_ur Miej_ur N A30 D D D VA120 VA120 VA120 N VA30 VA30 VA40 VA30 VA30 VA60 VA12 D VA30 rezenzenty data_rez D pracow nicy promouter data_pr D id_pr nazw isko_p imie_p st_nauk katedra nr_pokoju N VA30 VA30 VA30 VA40 VA10 126 BAZY DANYCH Projektowanie modelu konceptualnego Rezultat: Zakresy Id_zakr N Nazw a_zakr VA40 tematy id_temat nazw _t data_w yd data_zl data_obr opis_pr plan_pr literat N A30 D D D VA120 VA120 VA120 Dyplomanci 0..n zakresy tematow 0,1 0,1 tenatu dyplomow 1..1 rezenzent tematu1..1 1,1 rezenzenty Id_dypl Nazw isko_d imie_d kierunek specjal kurs_t adres_d telefon_d Data_ur Miej_ur N VA30 VA30 VA40 VA30 VA30 VA60 VA12 D VA30 data_rez D 1,1 0..1 rezenzent jest pracow nikem promouter tematu 0..n 1..1 pracow nicy promouter data_pr D 0..1 promouter iest pracow nikem 0..n id_pr nazw isko_p imie_p st_nauk katedra nr_pokoju N VA30 VA30 VA30 VA40 VA10 127 BAZY DANYCH Projektowanie modelu fizycznego Rezultat: Zakresy Id_zakr numeric <pk> Nazw a_zakr varchar(40) Id_zakr = Id_zakr tematy id_temat Id_zakr Id_dypl nazw _t data_w yd data_zl data_obr opis_pr plan_pr literat numeric <pk> numeric <fk1> numeric <fk2> char(30) date date date varchar(120) varchar(120) varchar(120) Dyplomanci Id_dypl = Id_dypl id_temat = id_temat id_temat = id_temat rezenzenty id_temat numeric <pk,fk1> id_pr numeric <fk2> data_rez date id_temat = id_temat Id_dypl id_temat Nazw isko_d imie_d kierunek specjal kurs_t adres_d telefon_d Data_ur Miej_ur numeric <pk> numeric <fk> varchar(30) varchar(30) varchar(40) varchar(30) varchar(30) varchar(60) varchar(12) date varchar(30) id_pr = id_pr pracow nicy promouter id_temat numeric <pk,fk1> id_pr numeric <fk2> data_pr date id_pr = id_pr id_pr nazw isko_p imie_p st_nauk katedra nr_pokoju numeric <pk> varchar(30) varchar(30) varchar(30) varchar(40) varchar(10) 128 BAZY DANYCH Utrzymanie integralności bazy danych Integralność (integrity) łączy w sobie formalną poprawność bazy danych i procesów przetwarzania, poprawność fizycznej organizacji danych, zgodność ze schematem bazy danych, zgodność z ograniczeniami integralności oraz z regułami dostępu. Integralność nie oznacza, ze baza danych prawidłowo odwzorowuje sytuację i procesy opisanego przez nią świata zewnętrznego. Odpowiednim terminem tu jest spójność (consistency). Rozpatrzymy model logiczny bazy danych „Biblioteka”. Model odwzorowuje rzeczywisty proces otrzymania czytelnikiem książki i jej zwracania. Ten proces podtrzymuje się za pomocą atrybutów encji: „Copies of the book” (Egzemplarzy książek), „The readers” (Czytelnicy) oraz związków pomiędzy encjami. Jeżeli czytelnik wypożyczył książkę, to w tabeli „Copies of the book” w rekordzie odpowiadającemu temu egzemplarzowi, powinna być ustawiona wartość „False” w polu „Is_or_not”, co oznacza nieobecność egzemplarza książki w bibliotece. Poza tym, w polu „Num_document” powinien być wpisany numer legitymacji (indeksu) czytelnika. Jeżeli pole „Is_or_not” ma wartość („False”), a pole „Num_document” nie zawiera numeru legitymacji czytelnika, to oznacza niepoprawność bazy danych. Modele danych powinny mieć środki dla utrzymania integralności. Utrzymanie integralności zawiera środki wyznaczające ograniczenia, które są potrzebne dla koordynacji wartości atrybutów różnych tabel. Istnieją następne typy ograniczeń, które wykorzystują się dla utrzymania integralności: obowiązkowa obecność danych; wartość atrybutów; integralność encji (entity integrity); integralność odwołań (referential integrity); Wszystkie ograniczenia określają się w instrukcjach CREATE oraz ALTER TABLE języka SQL. Ograniczenia obowiązkowej obecności danych Te ograniczenia potrzebują, żeby w każdym rekordzie tabeli była obecna konkretna wartość dla atrybutu wyznaczonego. Na przykład, w encji „Staff” 129 BAZY DANYCH (Personel) dla każdego rekordu powinien być wyznaczony atrybut „Position” (Stanowisko): CREATE TABLE "Staff" ( Num varchar(12), Last_name varchar(20), First_name varchar(10), Birth_date date, Position varchar(10) NOT NULL, Sex varchar(1) ); Ograniczenia wartości atrybutów Te ograniczenia wyznaczają dopuszczalne wartości atrybutów. Każda kolumna w tabeli może mieć wartość z dopuszczalnego zbioru wartości. Ten zbiór może być zadany w warunku CHEK: create table "Staff" ( Num varchar(12), Last_name varchar(20), First_name varchar(10), Birth_date date, Position varchar(10) NOT NULL, Sex varchar(1) NOT NULL CHECK ( Sex IN (‘M’,’F’)) ); Integralność encji (entity integrity) Każda tabela w bazie normalizowanej powinna mieć klucz pierwotny (główny), który powinien być unikalnym w każdym rekordzie. Ta integralność może być zadana za pomocą „primary key…” oraz „not null” : create table Books ( ISBN varchar(12), Name varchar(30), Autor varchar(15), Publishing varchar(15), City varchar(15), Year date, "Amount of pages" numeric, primary key (ISBN) ); Jeżeli danej kolumnie nałożyliśmy warunek primary key, DBMS automatycznie nałoży jej warunki not null i unique. 130 BAZY DANYCH Warunek UNIQUE Za pomocą warunku UNIQUE definiujemy tzw. Klucz unikalny tabeli. W kolumnach, na których nałożymy ten warunek, DBMS będzie przechowywał wyłącznie niepowtarzalne (unikalne) wartości. W ramach jednej tabeli można zdefiniować dowolną liczbę warunków UNIQUE. Aby utworzyć tabelę TYP, napiszemy : CREATE TABLE TYP ( ID_TYPU Integer PRIMARY KEY, NAZWA Char(50) UNIQUE, OPIS VARCHAR(100)); W tabeli TYP nie mogą znajdować się rekordy z nie ustaloną wartością dla kolumny NAZWA. Integralność odwołań (referential integrity) Klucz obcy - to jedna lub więcej kolumn tabeli odwołujących się do kolumny lub kolumn klucza pierwotnego (głównego) w innej tabeli. Klucze obce są wykorzystywane do utrzymania integralności referencyjnej (integralności odwołań) w bazie danych. Tworząc klucz obcy, definiujemy związek między tabelą klucza pierwotnego i tabelą klucza obcego. Związek taki powstaje podczas połączenia kolumn tych samych typów danych z każdej tabeli. Łączenie tabel przy pomocy łączenie odpowiednich kolumn chroni dane z tabeli klucza obcego przez „osieroceniem”, jakie mogłoby nastąpić w wyniku usunięcia odpowiadających im danych z tabeli klucza pierwotnego. Definiowanie kluczy obcych jest po prostu sposobem łączenia danych przechowywanych w różnych tabelach bazy danych. W relacyjnych bazach danych integralność odwołań dotyczy sytuacji, kiedy tablica A zawiera klucz obcy (foreign key) będący równocześnie kluczem pierwotnym tablicy B. Warunek integralności odwołań ustala, że dla każdego wiersza tablicy A musi istnieć taki wiersz w tablicy B, że wartości kluczy obcego i pierwotnego są jednakowe. Np. dla każdej wartości kolumny „ISBN”( klucz obcy) w tablicy „Copies_of_the_book” musi istnieć taka sama wartość w kolumnie„ISBN”( klucz pierwotny) tablicy „Books”. Deklarować klucz obcy można tak: CREATE TABLE "Copies of the book" ( ISBN varchar(12) not null, Num_inv varchar(10) not null, Num_document varchar(10), Is_or_not binary(1), Capture_date date, 131 BAZY DANYCH Return_date date, PRIMARY KEY (ISBN, Num_inv) ); ALTER TABLE "Copies of the book" ADD FOREIGN KEY "FK_COPIES O_INCLUDES_BOOKS" (ISBN) REFERENCES BOOKS (ISBN) ON UPDATE RESTRICT ON DELETE RESTRICT; _____________________________________________________________ W tablicy „Copies of the book", która jest stworzona w instrukcji CREATE TABLE za pomocą klauzuli ALTER TABLE deklaruje się klucz obcy: ADD FOREIGN KEY "FK_COPIES O_INCLUDES_BOOKS" (ISBN), który jest połączony z kluczem pierwotnym tablicy „Books”: REFERENCES Books (ISBN). Predykat „ON UPDATE RESTRICT” anuluje uaktualnienia wartości (ISBN) w kolumnie macierzystej, jeżeli na nią odwołają się rekordy tablic potomnych. Predykat „ON DELETE RESTRICT” anuluje skasowanie wartości (ISBN) w kolumnie macierzystej, jeżeli na nią odwołają się rekordy tablic potomnych. Jeżeli ostatnie dwie frazy wyznaczyć tak: ON DELETE CASCADE ON UPDATE CASCADE, to w pierwszym przypadku będą skasowane wszystkie połączone w tablicach rekordy. W przypadku drugim będą uaktualnione wszystkie połączone w tablicach rekordy. Takie możliwości mają nie wszystkie środowiska DBMS. Dostęp do baz danych Standard ODBC (Open Database Connectivity) Różne DBMS mogą realizować różne wersje SQL dla realizacji języków definicji danych (DDL) i manipulacji danymi (DML). Interfejsy bezpośredniego dostępu do tych DBMS, stworzone przez różnych producentów, też mogą się różnić. Wskutek tego konsekwentności zapytań SQL do różnych baz danych, różnych serwerów SQL mogą też się różnić. To znaczy, np., że dla bazy danych w środowisku „ORACLE” trzeba konstruować inne konsekwentności zapytań SQL niż dla tej samej bazy w środowisku „INFORMIX”. 132 BAZY DANYCH W celu usunięcia tej wady firma MICROSOFT w 1992r opracowała standard ODBC (Open Database Connectivity). Technologia ODBC wprowadza jedyny interfejs dostępu do różnych typów baz danych. Język SQL jest wykorzystywany jako główny uniwersalny dialekt wszystkich baz danych. Standard ODBC pozwala realizować technologię „Klient – Serwer”, która realizuje główne operacji przetwarzania danych na serwerze, a klient tylko otrzymuje rezultaty. Architektura ODBC jest pokazana na rys. 33. Aplikacje nie są połączone z konkretnym interfejsem jakikolwiek DBMS, a realizują jedyny standard zapytań do menedżera ODBC – sterowników (ODBC-drivers). Menedżer ODBC podłącza potrzebny ODBC – sterownik, Application 1 Application 2 ... Application N The manager of drivers ODBC Driver ODBC ACCESS Source of data ODBC ACCESS Driver ODBC SYBASE Source of data ODBC SYBASE ... Driver ODBC ORACLE Source of data ODBC ORACLE ... Fig. 33 133 BAZY DANYCH który jest stworzony przez producenta konkretnej DBMS. Dla podłączenia ODBC – sterownika trzeba stworzyć profile ODBC w trybie (Source ODBC…) panelu sterowania systemu operacyjnego. Teraz istnieją ponad 50 typów ODBC – sterowników dla różnych DBMS. Standard ODBS pozwala realizować zapytania SQL bezpośrednio z programów użytkownika. W tym celu można wykorzystywać dynamiczny SQL. Na rys 34. jest pokazany schemat pracy różnych narzędzi programowych przy realizacji architektury „ Klient – Serwer” w sieci lokalnej. Aplikacja na Client application Client MS Windows ODBC driver manager ODBC driver local data text ODBC driver DBMS-2 ODBC driver DBMS-1 Server 1 DBMS - 1 File System Net Driver Net Driver Local Disk LocalNet Server 2 DBMS - 2 Net Driver Fig. 34 134 BAZY DANYCH stancji klienta realizuje zapytania do baz danych przez ODBC Manager. Zapytania mogą być dla lokalnej bazy danych lub do baz danych umieszczonych na innych serwerach sieci lokalnej. Na rys.34 są pokazane trasy wszystkich zapytań. Główne wady technologii dostępu do baz danych przez ODBC: Aplikacje są przystosowane do platformy MS Windows Wzrasta czas obróbki zapytań dzięki dodatkowej warstwie programówJest potrzebna uprzednia instalacja ODBC – sterownika, profile ODBC dla każdej stacji. Parametry tej instalacji jest statyczne i użytkownik nie może ich zmienić. Uniwersalne strategii dostępu Technologia ODBC firmy Microsoft zaopatrzy ogólny interfejs dostępu do baz danych, które są kompatybilne przez SQL. Każda baza danych mająca interfejs ODBC zawiera sterownik (driver) , który realizuje bezpośrednio ten interfejs. Interfejs zawiera bibliotekę funkcji specjalnych napisanych w języku C++ . Zastosowanie tej biblioteki może być wadą przy realizacji dostępu aplikacji stworzonych w innym środowisku języków oprogramowania. Żeby usuwać te wady różne producenci stwarzają specjalne komponenty obiektowe dostępu do baz danych. Przykład komponentów firmy Microsoft jest pokazany na rys. 35. Obiektowy model DAO (Data Access Objects) jest przeznaczony w środowiskach Microsoft Access oraz Visual C++. DAO zawiera obiekty baz danych (component DataBase), obiekty tabel(component TableDef), obiekty definicji kwerend (component QueryDef), obiekty rezultatów zapytań do bazy danych (component RecordSet) oraz inne obiekty. Model DAO jest przeznaczony przede wszystkim dla dostępu do baz danych Access. Ten model nie odpowiada wszystkim standardom oraz specyfikacjom SQL . Ten model teraz jest zamieniony nowym modelem RDO (Remote Data Obiekt). RDO wchodzi do Visual Basica, Visual FoxPro oraz do Microsoft SQL Servera. Firma Microsoft zaproponowała zbiór obiektów OLE DB( Object Linking and Embedding for DataBase), który pozwala aplikacjom wykorzystywać oraz sterować danymi w bazach danych przez swoje obiekty. Technologia OLE DB gwarantuje dostęp do jakikolwiek baz danych włącznie nie relacyjne modeli danych. Oprócz tego przez OLE DB można udostępnić do plikowych oraz pocztowych systemów, graficznych plików, innych obiektów stworzonych w różnych aplikacjach. Technologia OLE DB jest obiektowo - orientowana specyfikacja na podstawie C++ API. 135 BAZY DANYCH User Aplication DAO (RDO) ADO OLE DB ODBC DB SQL Fig 35 Technologia ADO (Active Data Obiects) to jest rozwiązanie technologii ASP dostępu do baz danych, które jest realizowane we WWW serwerze IIS (Internet Information Server) firmy Microsoft. Technologia ADO zawiera wszystkie lepsze cechy technologii RDO oraz DAO i musi zamienić te ostanie technologii. Technologia ADO zawiera następne funkcje: Stworzenia niezależnych obiektów baz danych Wsparcie zapamiętanych procedur baz danych Stworzenia kursorów dostępu do danych Wsparcie mechanizmów transakcji. Głównymi zaletami technologii ADO są nie komplikowane wykorzystanie, prędkość, małe obciągi RAM oraz disku. 136 BAZY DANYCH Model obiektowy ADO zawiera 6 głównych klasy obiektów (rys. 36): CONNECTION COMMAND PARAMETERS RECORDSET FIELDS ERRORS. Obiekt CONNECTION połączy związek pomiędzy aplikację oraz źródłem danych. Utworzenia takiego połączenia zawsze jest pierwszym etapem obsługi bazy. Ten obiekt pozwala także uruchomić instrukcje SQL. Dla zachowywania rezultatów instrukcji trzeba stworzyć obiekt klasy RECORDSET. Klasa CONNECTION zawiera następne metody: Open( ) , Close( ) – połączenie lub wyłączenia ze źródłem danych Execute( ) – uruchomienie instrukcji dla wyznaczonego połączenia BeginTrans( ), CommitTrans( ) oraz RollbackTrans( ) – sterowanie transakcjami dla danego połączenia. Obiekt COMMAND zawiera instrukcję SQL lub wywołanie zapamiętanej procedury. Ten obiekt może mieć kolekcję parametrów, które mogą być zadane przez obiekty klasy PARAMETER. Klasa COMMAND zawiera następne metody: Execute( ) – uruchomianie instrukcji dla danego połączenia CreateParameter( ) – tworzenie nowego parametru(obiektu klasy PARAMETER) Kolekcja PARAMETERS zawiera wszystkie parametry, które są wykorzystywane razem z danym obiektem COMMAND. Parametry te są przechowywane w obiektach klasy PARAMETER. Klasa PARAMETERS zawiera następne metody: Append(), Delete() – dodawanie (usuwanie) parametru dla danej kolekcji Item() – wywołanie wyznaczonego obiektu PARAMETR Refresh() – wywołanie informacji pro parametry właściciela zapamiętanej procedury. 137 BAZY DANYCH Connect Open() Execute( ) BeginTrans() CommitTrans( ) RollbackTrans ( ) Errors Error Command Execute ( ) CreateParametr () Parameters Recordset BOF EOF RecordCount MoveFirst ( ) MoveLast ( ) MoveNext () MovePrevious () Move() AddNew () UpDate () Delete () Open() Close() Append ( ) Delete ( ) Item () Refresh () Parameter Fields Fig 36 Field 138 BAZY DANYCH Obiekt RECORDSET pozwala na operowania danymi przechowywanymi w tabeli. Obiekt ten zawiera zbiór rekordów pobranych z tabeli. Pozwala on na odczytywanie danych przechowanych w tabeli, modyfikowanie ich oraz gromadzenie informacji, jakie mają być dodane do bazy. Aktualne analizowany rekord oraz jego położenie względem pozostałych rekordów zbioru określane przez kursor bazy danych. Kursor to jest obiekt zawierający rezultat polecenia do bazy danych. Przy stworzeniu obiektu RECORDSET wskaźnik rekordu bieżącego kursora odwzorowuje pierwszy rekord zbioru, a atrybuty BOF oraz EOF otrzymają wartości FALSE. Kiedy zbiór jest pusty atrybut RecordCount otrzyma wartość 0 (zero), lecz BOF oraz EOF – wartości TRUE. Klasa RECORDSET zawiera następne metody: MoveFirst(), MoveLast(), MoveNext(), MovePrevious() oraz Move() – przesuwają wskaźnik rekordu bieżącego. Obiektami RECORDSET są kursory, które mogą być sterowanymi tylko w jednym kierunku lub w dwóch kierunkach zbioru rekordów. W przypadku jednokierunkowego kursora można przechodzić jedynie do następnego rekordu zbioru, nie istnieje możliwości cofania się do poprzedniego wiersza lub przeskakiwania o kilka rekordów do przodu lub do tylu zbioru. Tutaj może być wykorzystywana tylko metoda MoveNext(). Dla wyznaczenia końca lub początku rekordów trzeba wykorzystać atrybuty BOF oraz EOF obiektu RECORDSET. AddNew(), Update() oraz Delete() – dodawanie nowych rekordów, aktualizacja oraz usuwanie istniejących rekordów, które jest związane z obiektem REKORDSET. Open(), oraz Close() – uruchomienie (Zamknięcie ) kursora, który reprezentuje rezultaty instrukcji, która jest poprzednio stworzona przez obiekt COMMAND. Metoda Open() odsyła na już stworzony obiekt CONNECT. Każdy obiekt RECORDSET zawiera kolekcję FILDS, która są zbiorem obiektów klasy FIELD. Każdy obiekt FIELD reprezentuje jedną kolumnę tabeli danych. Na każdy obiekt FIELD w kolekcji FIELDS można odwalać przez nazwę lub liczbę numeryczną. Kolekcja ERRORS jest stworzona dla zachowywania informacji pro jakikolwiek błędy. Obiekt ERROR reprezentuje błąd wygenerowany przez źródło danych. Kolekcja ERRORS jest używana w sytuacji, gdy jedno wywołanie metody może wygenerować większą ilość błędów. Przy stworzeniu obiektu RECORDSET można wykorzystać dwa typy kursorów: jednokierunkowy lub dwukierunkowy. Podczas wywołania metody Open() obiektu RECORDSET domyślnie tworzony jest kursor 139 BAZY DANYCH jednokierunkowy. Kursor tego typu jest najbardziej efektywny, jednak oferuje ograniczone możliwości poszukiwania się po zbiorze rekordów . Dwukierunkowe kursory zawierają następne typy: Statyczny. Wyniki wykonania zapytania są przechowywane w tabeli tymczasowej, której wierszy nie są modyfikowane w momencie, gdy kursor jest otwarty. Zbiór kluczy. Kursory tego typu zapisują w tymczasowej bazie danych klucze wszystkich wierszy zwróconych w wyniku wykonania polecenia. Dzięki przechowywaniu jedynie kluczy, wszelkie modyfikację rekordów wykonane w czasie gdy kursor jest otwarty, będą zauważane. Dynamiczny. W przypadku użycia kursora dynamicznego za każdym razem, gdy zażądamy nowego rekordu, polecenie określające zawartość zwracanych wyników jest ponownie wykonywane. Oznacza to, że wszelkie modyfikacje wprowadzane w tabeli bazy danych będą widoczne, a co więcej, dodanie nowego rekordu może mieć wpływ na zawartość wynikowego zbioru rekordów. Dostęp w Jawie przez JDBC - sterownik Java, jako nowoczesny język programowania, posiada m.in. możliwości związane z podłączeniem się i operowaniem na bazach danych. Jednak założeniem projektantów Javy było stworzenie języka, którego kod byłby przenośny między różnymi systemami operacyjnymi. Taką przenośność posiada Java w dziedzinie zastosowań aplikacji bazodanowych. Java także wykorzysta technologię ODBC. Została ona realizowana jako interfejs niezależny od architektury bazy danych i ma nazwisko JDBC (ang. Java DataBase Connectivity). JDBC jest pomostem pomiędzy przestrzeniami bazy danych, mającą sterownik ODBC, i aplikacji, napisanej w języku Java. Interfejs ten operuje na poziomie SQL. Dzięki JDBC aplikacje bazodanowe napisane w Javie są niezależne od sprzętu oraz stosowanej bazy danych. Niezależność od systemu operacyjnego zapewnia sama Java. Struktura JDBC jest pokazana na rys. 37. Głównym elementem JDBC jest sterownik (driver). Sterownikiem JDBC, łączącym aplikację z konkretną bazą danych, nazywa się zestaw klas, które implementują interfejs ODBC. Zadaniem JDBC jest ukrycie przez programista wszelkich specyficznych własności bazy danych. Dzięki temu programista może skupić się wyłączne na swojej aplikacji, nie wdając się w szczegóły związane z obsługą używanej przez niego bazy danych. Aby umożliwić niezależność od platformy, JDBC udostępnia menedżera sterowników ODBC, który dynamiczne zarządza różnymi obiektami 140 BAZY DANYCH sterowników. Obiekty te będą wykorzystywać zapytania do bazy danych. Kolejność dostępu do bazy danych zawiera następne czyności: 1. Załadować do pamięci potrzebny sterownik JDBC. To można zdarzyć następnym sposobem: Class.forName ("sun. jdbc.odbc.JdbcOdbcDriver") Argumentem metody forName() jest obiekt typu STRING. Jest on nazwa klasy sterownika wraz z nazwą pakietu, który trzeba załadować. Po załadowaniu sterownik staje się dostępnym dla aplikacji. 2. Zdarzyć połączenie z bazą danych. Dla połączenia z bazą danych wykorzystają konstrukcję : DriverManager.getConnection(url,user,password) Pierwszy parametr w metodzie getConnection() to URL do bazy danych. Pozwala on na identyfikację bazy danych w taki sposób, że możliwe jest załadowanie do pamięci odpowiedniego sterownika ODBC i uzyskanie połączenia z bazą. Drugi i trzeci parametry oznaczają odpowiednio nazwę użytkownika bazy danych i hasło dostępu do niej. Jeżeli baza danych nie potrzebuje identyfikatora oraz hasła, drugi oraz trzeci parametry są nieobecne. Standartowa składnia URL–a jest następująca: jdbc:<subprotokół>:<subnazwa>. JDBC – to typ protokółu, subprotokół określa nazwę wykorzystanego sterownika (w tym wypadku – ODBC), subnazwa jest nazwą identyfikującą bazę danych, nazwa profilu ODBC. Przykład połączenia z bazą danych: Connection con; String url = "jdbc:odbc:biblio"; … con = DriverManager.getConnection(url); 3. Wykonać zapytanie SQL do bazy danych. Dla wykonania zapytania SQL do bazy danych, analizując rys. 37, mamy do wyboru jeden z interfejsów: Statement, PreparedStatement lub CallableStatement. Wszystkie trzy służą zasadniczo jednemu: wykonaniu zapytania SQL-owego. Tworzenie obiektów z grupy Statement ma następującą postać: Statement stmt; stmt = con.createStatement(); Obiektu Statement używamy do wykonania zapytań SQL. Rezultaty zapytania są przechowywane w obiektu ResultSet: String query; // wiersz operatora SQL query = "SELECT …FROM…WHERE…”; ResultSet rs; // pole dla rezultatu zapytania SQL rs = stmt.executeQuery(query); 141 BAZY DANYCH Struktura JDBC ResultSet ResultSet ResultSet Statement PreparedStatement CallableStatement Connection DriverManager Oracle Driver JDBC-ODBC Driver ... ODBC Driver BD BD BD Fig 37 142 BAZY DANYCH 4.Wywolać dani z zbioru skutecznego. Obiekt ResultSet reprezentuje wynik zapytania SQL i zawiera zbiór rekordów z danymi. Stosując metodę next() tego obiektu, możemy mieć dostęp do wszystkich danych: more = rs.next(); Zatem stosując metodę getXXX(nazwa_pola) trzeba zdarzyć dostęp do danych bieżącego rekordu. Na przykład: While (rs.next()) { Int x = rs.getInt (‘pole1’); String s =rs.getString (‘pole2’); Float f = rs.getFloat (‘pole3’); } Podczas działania aplikacji bazodanowej mogą wystąpić różnego rodzaju sytuacje powodujące, że określone operacje na bazie zakończą się niepowodzeniem. Dlatego ważne jest, aby aplikacja potrafiła obsłużyć tego typu zdarzenia. Pomocny okazuje się mechanizm obsługi wyjątków. W takich przypadkach wykorzystujemy klasę SQLException. Przykład stworzenia tablicy w aplikacji JAVA //---------------------------------------------------------------------------------package jdbc; import java.sql.*; // Stworzenie tablicy w bazie danych biblio. // Najpierw trzeba stworzyć ODBC profile // bazy danych biblio. // Do tej bazy aplikacja umieszczona poniżej dodaje nową tabelę SKLEP public class JdbcCreateTable { public static void main(String args[]) { String url = "jdbc:odbc:biblio"; Connection con; String createString; createString = "create table SKLEP " + "(SKL_NAME varchar(32), " + "SkL_ID int, " + "SKL_ADDR varchar(32), " + 143 BAZY DANYCH "SKL_INV varchar(32))"; Statement stmt; try { // Uruchomienie ODBC – sterownika (brydża Java – ODBC) Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch(java.lang.ClassNotFoundException e) { System.err.print("ClassNotFoundException: "); System.err.println(e.getMessage()); } try { // Realizujemy połączenie z bazą biblio con = DriverManager.getConnection(url); //tworzymy obiekt Statement dla przeniesienia SQL instrukcji stmt = con.createStatement(); // uruchomienie instrukcji stmt.executeUpdate(createString); // usunięcie objektów stmt.close(); con.close(); } catch(SQLException ex) { System.err.println("SQLException: " + ex.getMessage()); } } } //---------------------------------------------------------------------------------Przykład konstruowania zapytań do bazy danych w aplikacji Java //---------------------------------------------------------------------------------import java.sql.*; // Wykorzystanie pakietu Jdbc w bazie danych biblio // Najpierw trzeba stworzyć ODBC profile //bazy danych biblio public class JdbcExample { // Deklaruje się obiekt połączenia z bazą danych static Connection dbcon; 144 BAZY DANYCH /* Podprogram główny*/ public static void main(String args[]) throws Exception { // Uruchomienie ODBC – sterownika (brydża Java – ODBC) Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); // otworzenie bazy danych open (); // Odwzorowanie wszystkich wierszy w bazie select ("And Authors.Au_ID < 20 )"); // Uaktualnienie rekordów oraz formowanie rezultatu update (); // zamknięcie bazy danych close(); } /* otworzyć połączenie z bazą danych */ static void open() throws SQLException { /* Zadać imię źródła ODBC, nazwiska użytkownika i hasła String dsn = "jdbc:odbc:biblio"; String user = ""; String password = ""; /* Uruchomienie menedżera sterownika dla połączenia dbcon = DriverManager.getConnection(dsn,user,password); /* Domyślnie fiksacja transakcji jest dokonywana automatycznie, dla tego funkcja AutoCommit() jest odłączona */ dbcon.setAutoCommit(false); } /* określenie wszystkich czekających na zakończenie transakcji oraz zamknięcie bazy danych */ static void close() throws SQLException { dbcon.commit(); dbcon.close(); } /* Otrzymanie zapytań SQL z klauzulą WHERE*/ static void select(String whereClause) throws SQLException { Statement stmt; //Obiekt operatora SQL String query; // wiersz operatora SQL ResultSet rs; // pole dla rezultatu zapytania SQL String pr; boolean more; // przełącznik "wiersze dodatkowe są obecne” /* Przygotowanie zapytania SQL , konstruowanie operatora SQL, wypełnienie zapytania SQL */ 145 BAZY DANYCH //query = "SELECT Authors.Author FROM Authors WHERE (Au_ID < 20 // );"; query = "SELECT Authors.Author, Titles.Title, Publishers.`Company Name` "; query = query + "FROM Authors, `Title Author`, Titles, Publishers "; query = query + "WHERE (Authors.Au_ID = `Title Author`.Au_ID AND "; query = query + "`Title Author`.ISBN = Titles.ISBN AND "; query = query + "Titles.PubID = Publishers.PubID " + whereClause; stmt = dbcon.createStatement(); rs = stmt.executeQuery(query); /* sprawdzenie obecności wierszy, które będą zwrócone */ more = rs.next(); if (!more) { System.out.println("No rows found"); return; } /* Cykl dla obróbki wierzy, które są wybrane */ while (more) { pr = rs.getString("Author"); System.out.println("Autor: " + pr); pr = rs.getString("Title"); System.out.println("Title: " + pr); pr = rs.getString("Company Name"); System.out.println("Publishers: " + pr); System.out.println(""); more = rs.next(); } rs.close(); stmt.close(); } /* Otrzymanie zapytań SQL bez klauzuli WHERE*/ static void select() throws SQLException { select(""); } } 146 BAZY DANYCH Rozproszone systemy danych Coraz ważniejsze miejsce w istniejących systemach komputerowych zajmują systemy rozproszone (ang. Distributed system). System rozproszony jest zbiorem samodzielnych komputerów wraz z urządzeniami peryferyjnymi, bazami danych, połączonymi za pomocą sieci, na których zainstalowane jest rozproszone oprogramowanie systemowe. Użytkownicy takiego systemu powinni go odbierać jako jedno zintegrowane środowisko. Fakt rozproszenia powinien być tu niezauważalny lub przezroczystym dla użytkownika. Do zainteresowania się systemami rozproszonymi przyczynił się szybki rozwój sieci rozległych. Potencjalna gama zastosowania systemów rozproszonych jest bardzo szeroka. Duże koncerny posiadające swoje oddziały w wielu krajach, giełdy, banki, linie lotnicze opierają swoje działanie na posiadaniu rozproszonego systemu komputerowego. Powstanie wydajnych systemów sieciowych oraz rozproszonych systemów operacyjnych dało możliwość budowania rozproszonych systemów baz danych. Podstawę tych systemów stanowią specjalizowane serwery baz danych, mające możliwość wymiany danych z innymi serwerami. Przykład rozproszonej bazy danych jest pokazany na rys. 1. Zamiast Server 1 BD Server 2 Server 3 NET BD BD FIG 37_1. 147 BAZY DANYCH jednego centralnego serwera bazy danych (mainfrejma) są realizowane serwery w różnych filiach firmy. Sieciowe połączenia pozwalają współdziałanie filii pomiędzy sobą. Z tego przykładu rozproszony system bazy danych - to zbiór lokalnych baz danych stanowiących całość w sensie jednego modelu danych i koordynacji wykonywanych transakcji. W zależności od przedmiotu rozproszenia istnieje rozproszenie funkcji oraz rozproszenie danych. Modeli rozproszonych funkcji Mówiąc o rozproszeniu funkcji mają na myśli separację funkcjonalną między danymi i mechanizmami zarządzania nimi, czyli serwerem a aplikacjami użytkowników, które pobierają wymagane dane poprzez wysyłanie do serwera zapytań. Model obrazujący separację ma nazwisko „Klient – Serwer”. „Klient – Serwer” to jest architektura komputerów lub oprogramowania, charakteryzująca się podziałem na część określaną jako serwer, której zadaniem jest realizacja usług (np. dostępu do bazy danych) i część określaną jako klient, która zleca te usługi. Główną cechą modelu Klient – Serwer jest rozdzielenie funkcji aplikacji bazodanowej na następne grupy: 1. Funkcji wpisania oraz odwzorowania danych – logika prezentacyjna (Prezentation Logic) 2. Funkcji, które wyznaczają główne algorytmy działania aplikacji- logika biznesowa - (Business Logic) 3. Funkcji sterujące danymi (SZBD,DBMS) Logika prezentacyjna jest częścią aplikacji, która odwzorowuje rezultat działania aplikacji na monitorze użytkownika. Ona zawiera wszystkie formy, które użytkownik musi uzupełniać oraz otrzymać na ekranie w czasie działania aplikacji. Głównymi zadaniami logiki prezentacyjnej są następne: Tworzenie przedstawień na ekranie monitora Czytania oraz wpisanie informacji w formy na ekranie monitora Sterowanie ekranem monitora Obsługa zdarzeń (myszy oraz klawiatury). Logika biznesowa to jest kod programu, który realizuje algorytmy zadań aplikacji. Ten kod może być napisany przez różne języki oprogramowania oraz CASE narzędzia, np. : C++, Borland C++ Builder, PowerBuilder, Java, Visual Basic i in. Funkcji sterujące danymi - to są System Zarządzania Bazą Danych(SZBD) (Database Manager System, DBMS). SZBD steruje bezpośrednio danymi. 148 BAZY DANYCH Wszystkie te funkcje mogą być realizowane za pomocą architektury centralizowanej oraz architektury decentralizowanej. W pierwszym wypadku 5 grup funkcji są w jednym komputerowym środowisku pod sterowaniem jednego systemu operacyjnego. To jest najmniej efektywny sposób realizacji modelu Klient – Serwer. W architekturze decentralizowanej wszystkie grupy funkcji mogą być różnymi sposobami rozproszone pomiędzy serwerem oraz klientem. Zwykle serwer realizuje w oddzielnym środowisku ( to znaczy na oddzielnym komputerze oraz w systemu operacyjnym) dostęp do centralnej bazy danych, zaś po stronie klienta znajduje się obsługa interfejsu użytkownika. Architektura klient – serwer znacznie podnosi ogólną wydajność systemu i dostępność bazy danych. Istnieje wiele odmian tej architektury, które w różnym stopniu spełniają te kryteria. Na rys.37_2 jest pokazany diagram klasyfikacyjny podziału głównych funkcji aplikacji bazodanowych dla różnych typów modelów klient – serwer. Głównymi takimi typami są następne: Rozproszona prezentacja (presentation) Zdalna prezentacja (Remote presentation) Rozproszona logika biznesowa (Distribution business logic) Zdalne zarządzanie danymi (Remote Data Management) lub Zdalny dostęp do danych (Remote Data Access, RDA) Rozproszone zarządzanie danymi (Distributed Data Management ) . 149 BAZY DANYCH Aplication komponents Presentation logic Business logic DataBase Management Distribution presentation (DP) Client Server Remote presentation (RP) Client Server Distributed business logic (DBL) Client Server Remote date management (RDM) Client Server Distributed data management (DDM) Client Server Fig. 37_2 150 BAZY DANYCH Gdy komponenty klienta oraz komponenty serwera realizują się na dwóch oddzielnych platformach komputerowych, mających swoje systemy operacyjne, mówią pro „dwóch poziomowy model klient – serwer”. Rozpatrzymy następne typy realizacji modelów klient - serwer, które często są wykorzystywane w praktyce: serwer plików (File Serwer,FS) zdalny dostęp do danych (Remote Data Access, RDA) serwer baz danych serwer aplikacji. Serwer plików Shemat modelu serwera plików jest pokazany na rys. 37_3. Komponent klienta serwera plików zawiera: logikę prezentacyjną, logikę biznesową, logikę manipulowania danymi. Wszystkie pliki bazy danych w tym modelu są lokalizowane na serwerze, lecz mechanizm sterowania wszystkimi resursami informacyjnymi jest lokalizowany na kliencie. Klient odwoła do serwera przez instrukcje plikowe dla otrzymania potrzebnych plików lub oddzielnych bloków tych plików. Informacja pro treść tabel oraz plikach, które zawierają te tabeli dysponuje się „Meta baza”. Zaletą tego modelu jest podział aplikacji bazodanowej na dwa paralelny procesy. Serwer może obsługiwać wiele klientów, które odwołają do serwera z zapytaniami. DBMS musi być na kliencie. Algorytm realizacji zapytania klienta polega w następnym. 1. DBMS transformuje zapytanie do bazy danych w konsekwentność plikowych instrukcji. 2. Każda instrukcja plikowa powoduje posyłanie bloku informacji z serwera do klienta. 3. DBMS na stronie klienta analizuje otrzymaną informację. 4. Gdy w tym bloku nie znajduje się potrzebny rezultat, formuje się nową instrukcję oraz przejście do p.1. 5. Inaczej, gdy blok zawiera potrzebną informację - koniec algorytmu. Wady Serwera plików: Duży sieciowy trafik, który jest rezultatem przesyłania zbytecznych danych w blokach Ograniczona spektra operacji manipulowania danymi, która jest wyznaczona tylko plikowymi instrukcjami Nieobecność zasobów bezpieczeństwa dostępem. 151 BAZY DANYCH files commands File System Client Server Presentation Logic DB Business Logic Data bloks DBMS Meta Base Fig. 37_3 152 BAZY DANYCH Zdalny dostęp do danych Schemat modelu zdalnego dostępu do danych (Remote Data Access, RDA) jest pokazany na rys. 34_4. Baza danych oraz DBMS są zachowywane na serwerze. Strona klienta zawiera logikę prezentacyjną oraz logikę biznesową. SQL Query Client Presentation Logic Server Business Logic DBMS Results of queries DB Fig. 37_4 153 BAZY DANYCH Klient posyła zapytania w kodach SQL do serwera i otrzyma konkretne rezultaty tych zapytań. Zalety tego modelu: Mały sieciowy trafik w porównaniu z modelem serwera plików. Serwer wykonuje funkcje przetwarzania danych, zapytań oraz transakcji do DBMS paralelne z procesami na stronie klienta. Unifikacja interfejsu „klient – serwer”, go standardem jest język SQL. Wady tego modelu: Każdy klient musi zawierać logikę biznesową oraz logikę prezentacyjną, dlatego ten model nazywają się „Modelem z tłustym klientem”(fat client). Przy dużej ilości klientów trzeba dublować kody aplikacji na każdej stacji klienta. W sieci mogą istnieć dużo powtarzalnych procesów, które dublują logikę biznesową. Te powtarzalne procesy powiększają trafik sieci. Serwer jest elementem pasywnym. Kontrola spójności danych musi być realizowana przez logikę biznesową każdego klienta. Serwery bazy danych Call of stored procedures Server Client Stored procedures Presentation Logic Triggers Business Logic DBMS Results DB Triggers Stored procedures Fig. 37_5 154 BAZY DANYCH Żeby usuwać wady modelu zdalnego dostępu trzeba realizować następne warunki: Baza danych musi realizować niektóre regule logiki biznesową (business rules). Np. fabryka może normalne pracować gdy na składzie jest ilość wyznaczona detali lub materiałów dla produkcji. Musi być stała kontrola za stanem bazy danych. Przy osiąganiu jakikolwiek parametrem wartości wyznaczonej trzeba formować reakcję logiki biznesową. Np. przy zmniejszeniu zapasów towarów niżej normy dopuszczalnej trzeba automatyczne formować zamawianie dostarczanie. Baza danych musi podtrzymać domenie typy danych (lub typy danych użytkownika). Struktura serwera bazy danych jest pokazana na rys. 37_5. W tym modelu logika biznesowa jest podzielona pomiędzy klientem oraz serwerem. Na serwerze logika biznesowa jest realizowana przez zapamiętane procedury. Te procedury jest przechowywane w pamięci DBMS. Strona klienta odwoła do serwera z instrukcją SQL po uruchomianiu tej procedury . Serwer uruchomi tą procedurę oraz prowadzi wszystkie zmiany w bazie danych. Potem serwer wraca do klienta rezultaty, które jest relewantne zapytaniu klienta. Kontrola za stanem bazy danych realizuje się na stronie serwera przez mechanizm trygerów . Tryger to jest program umieszczany w wyglądzie bytów w pamięci bazy danych. Uruchomianie trygeru jest powodowane spontaniczne( niezależnie od normalnego przebiegu sterowania aplikacji) przez określone zdarzenia zachodzące w bazie danych, np. aktualizację pewnej danej, uplynięcie pewnego czasu, itp. Trygery oraz zapamiętane procedury mogą realizować regule logiki biznesową. Tryger może wywołać zapamiętaną procedurę. Tryger jest wywołany z pamięci przez DBMS serwera. Model serwera bazy danych jest realizowany takimi producentami: Oracle, Informix, Ingres, Sybase, Microsoft(MS SQL Serwer). W tym modelu serwer jest zawsze aktywnym. Serwer może samodzielne inicjować przetwarzanie danych. Ten model ma jeszcze nazwisko „model z chudym klientem” (Thin client). Serwer obsługowa paralelne mnóstwo klientów oraz realizuje następne funkcji: Monitorowanie zdarzeń, które są związane z trygerami Automatyczne uruchomianie trygerów przez określone zdarzenia zachodzące w bazie danych Uruchomianie zapamiętanych procedur 155 BAZY DANYCH Powrót potrzebnych danych do klienta. Wady modelu serwera baz danych: Wymogi do wydajności sprzętu, gdzie będzie zainstalowany serwer. Serwer aplikacji Model serwera aplikacji jest trzywarstwowy, zawiera dodatkową warstwę pomiędzy klientem a serwerem. Schemat tego modelu jest pokazany na rys. 37_6. Call of procedures DataBase Server Application Server Client Stored procedures Triggers Presentation Logic Business Logic DBMS Results DB Triggers Stored procedures Fig. 37_6 W tym modelu istnieje następny podział funkcji aplikacji bazodanowych: Warstwa klienta zawiera logikę prezentacyjną oraz funkcje komunikacyjne (na rys. nie pokazane) dla dostępu do sieci Warstwa serwera aplikacji zawiera ogólne funkcje logiki biznesowej. Serwer aplikacji zbiera zlecenia od klientów, realizuje logikę biznesową, wysyła zlecenia do serwera baz danych, zbiera wyniki tych zleceń i przekazuje je w odpowiedniej formie do klientów. Warstwa serwera baz danych zawiera tylko funkcje DBMS, które utrzymają integralność bazy danych oraz spójność. 156 BAZY DANYCH Modeli rozproszonych danych Rozproszenie pozwala przede wszystkim na odwzorowanie struktur organizacji, dla której system został zaprojektowany, umożliwia większą kontrolę nad danymi w miejscu ich wprowadzania i użytkowania. W rozproszonych systemach baz danych występuje rozłożenie danych poprzez ich fragmentację lub replikację do różnych konfiguracji. sprzętowych i programistycznych umieszczonych w różnych węzłach sieci. Fragmentacja to jest podział relację lub tabel bazy danych na części, które nazywają się fragmentami. Fragmentacja może znacznie podnieść wydajność systemu. Przykład fragmentacji jest pokazany na rys.37_7. Przypuszczamy że relacja na tym rysunku zawiera dane pro obiekty nieruchomości państwa. Każdy fragment relacji może zawierać dane pro obiekty nieruchomości oddzielnego regionu. Fragmenty są przechowane na serwerach, które są lokalizowane bezpośrednio w regionach. Każda aplikacja bazodanowa może mieć dostęp do danych nieruchomości własnego regionu oraz do danych innych regionów. Gdy jeden z fragmentów staje się niedostępny, np. na skutek awarii serwera regionu, użytkownicy mogą nadal swobodnie korzystać z danych zawartych w pozostałych, dostępnych fragmentach relacji. Poprzez fragmentację tabeli można wykonać jej kopię zapasową oraz odzyskiwać z niej dane w sposób równoległy, skracając w ten sposób czas realizacji operacji. Można wyróżnić fragmentację poziomą i pionową. Fragmentacja pozioma to podzbiór zbioru wierszy tabeli wyselekcjonowanych według określonych wartości klucza, odpowiadająca operacji selekcji(SELECT) algebry relacyjnej. Odtworzenie stanu pierwotnego, sprzed fragmentacji, wykonuje się korzystając z operacji UNION. Fragmentacja pionowa stanowi podzbiór zbioru kolumn tabeli, stanowiący określony zbiór cech opisywanego obiektu bazy. Powstaje dzięki operacji projekcji (PROJECT), a stan pierwotny uzyskuje się poprzez operację złączania JOIN kolumn w oparciu o wartości klucza głównego. 157 BAZY DANYCH Aplication Aplication ... Aplication Relation fragment a fragment b fragment c Server 1 Server 2 Server 3 Fig. 37_7 158 BAZY DANYCH Rozproszone bazy danych muszą mieć katalog systemowy zawierający informacje o rozmieszczeniu fragmentów bazy oraz o sposobie replikacji. Replikacja to jest przechowywanie kopii danych w miejscu odległym od miejsca przechowywania oryginału. Rozproszenie uzyskane przez replikację zmniejszają obciążenie sieci, zwiększają niezawodność systemu, pozwala zapewnić ciągłą pracę w przypadku wystąpienia awarii jednego z serwerów, poprawia dostępność systemu oraz bezpieczeństwo. W ogólnym ujęciu replikacja danych to proces reprezentowania obiektów bazy w więcej niż jednym miejscu. Może zatem służyć do tworzenia lokalnych kopii w celu zwiększenia bezpieczeństwa systemu lub opracowania raportów bez dostępu do wszystkich danych zawartych w bazie. Replikacji może zostać jedynie część bazy danych. Shemat systemu z replikacją danych pokazano na rys. 37_8. Client Client replication Main Server Mirror Server Client Client right of data updating right of data reading Fig. 37_8 159 BAZY DANYCH Mechanizm replikacji danych został zaimplementowany w serwerach baz danych różnych producentów, np. Informix (Informix Universal Server), Sybase (Sybase Replication Server). Wymaganiem jest tu zastosowanie serwera nadrzędnego(lub głównego) (Main Server, Primary Server) i poprzedniego(lub lustrzanego)(Mirror Server, Secondary Server). Wszystkie operacje wykonywane na danych zgromadzonych w serwerze nadrzędnym są replikowane i automatyczne odświeżane na serwerze podrzędnym. Replikacja odbywa się tylko w jednym kierunku – od serwera nadrzędnego do podrzędnego. Narzuca to pewien wymóg, że klienci korzystający z serwera podrzędnego mogą wykonywać operacje wyłącznie w trybie odczytu. W przypadku awarii serwera nadrzędnego następuje przełączenie klientów do serwera podrzędnego (rys. 37_9) w sposób automatyczny lub ręczny, zależnie od ustawienia pewnych parametrów w pliku konfiguracyjnym. Korzyścią wynikającą z zastosowania replikacji jest, obok zabezpieczenia przed utratą danych, odciążenia łączy i serwera nadrzędnego od obsługi klientów z prawem dostępu wyłączne do odczytu. Odciążenie łączy jest szczególnie widoczne wtedy, gdy grupa klientów łączy się do serwera z dużej odległości. Tego typu sytuacje spotyka się w Internecie. W celu uniknięcia częstych, odległych połączeń stosuje się repliki popularnych serwerów (tzw. Serwery lustrzane) zlokalizowane po stronie odległych klientów. Client Client Main Server Mirror Server Client Client right of data updating right of data reading Fig. 37_9 160 BAZY DANYCH Architektura Oracle Network Computing Architekture (NCA) Jako przykład narzędzia do realizacji rozproszonych systemów baz danych posłuży decyzję firmy ORACLE. Network Computing Architekture (NCA) jest przeznaczona dla tworzenia rozproszonych środowisk oraz realizuje trzywarstwowy model „Klient – Serwer” (rys.37_10). ORACLE NCA jest uzasadniona na następnych standardach: Technologii CORBA (Common Request Broker Architekture), która jest przeznaczona dla sterowania rozproszonymi obiektami Protokołu HTTP i języka HTML dla WEB środowiska Protokołu IIOP (Internet Inter–Object Protocol), który jest wykorzystywany przez technologię CORBA y dla współdziałania obiektów pomiędzy sobą. W środowisku Internet ten protokół jest transportowy, specyfikuje sposób wymiany komunikatów pomiędzy obiektami poprzez protokółu TCP/IP. Na odmianę od protokołu HTTP, IIOP może pamiętać dane pro wywołania obiektów oraz ich połączenia. Języka definicji interfejsu – IDL (Interface Definition Language), który jest opracowany przez OMG (Object Management Group) dla opisu interfejsów, które są niezależnymi od języka oprogramowania. Architektura NCA zawiera obiektowy mechanizm CORBA z takimi komponentami: Cartridges (nabój z ang.) - to jest biblioteka klas obiektów, która pozwoli projektantom dodawać nowe funkcji do aplikacji. To oprogramowanie może połączy się do jakikolwiek warstwy „Klient – Serwer”. Specyfikacji NCA pozwala tworzyć cartridges w dowolnym środowisku oprogramowania, np. Java, C++, itp. Wszystkie cartridges będzie pracować niezależne od systemu operacyjnego. Protokóły oraz standardowe interfejsy, które pozwalają współdziałać pomiędzy sobą przez szyna (lub magistral) programowy ICX (InterCartridge eXchange). Szyna (lub magistral) programowy to jest zbiór interfejsów oraz obiektów, które udostępniają przezroczyste różne cartridges jeden do drugiego. Każdy cartridge może odwołać do innego cartridge. Klienci, serwery aplikacji, serwery baz danych, które są bazowymi komponentami trzywarstwowej architektury CASE - środowisko dla opracowania oraz sterowania cartridges oraz aplikacjami. 161 BAZY DANYCH IIOP/HTTP CLIENT Universal Application Server ICX ICX Cartridge of Clients Cartridge of Application Universal Data Server ICX Cartridge of Data Fig.37_10 162 BAZY DANYCH Struktury plików wykorzystywane dla przechowania informacji w bazach danych Systemy zarządzania bazami danych (SZBD) są nadbudową nad plikami zawierającymi informacje o tablicach bazy, połączeniach tablic między sobą oraz niektóre inne. Jeśli pliki mają standardowy dla systemu operacyjnego format, to bezpośredni dostęp do danych SZBD realizuje na poziomie plikowych rozkazów systemy operacyjnego. Istniejące mechanizmy buforowania i sterowania plikami w systemach operacyjnych nie są dostosowane do efektywnego zarządzania bazami danych. Dlatego prawie wszystkie współczesne SSBD realizują bezpośrednie zarządzanie danymi na dyskach (twardych, optycznych, strimmerach itd. bez wykorzystania systemu plików komputera. Faktycznie wykorzystuje się własny system plików. W tym przypadku powstaje problem efektywnej organizacji i rozmieszczenia plików bazy danych. Wszystkie tablicy bazy danych powinny być umieszczone w plikach z organizacją stronicową. Stronica – to jest jednostka pamięci fizycznej (rekord fizyczny pliku), wielkość której krotna wielkości bloków systemu plików. Zadaniem SZBD jest szybkie określenie odpowiedniości pomiędzy rekordami logicznymi i ich miejscem na stronicach fizycznych w celu efektywnego poszukiwania i modyfikacji informacji w bazie danych. Na rys.42 pokazany jest przykład tablicy pewnej bazy danych oraz umowne rozmieszczenie logicznych rekordów tej tablicy w pamięci fizycznej. Tu pokazano również przykład odpowiedniości rekordów logicznych i stronic fizycznych pliku, kiedy stronica fizyczna pamięci może zawierać dwa rekordy z tablicy. Efektywność mechanizmów poszukiwania SZBD zależy od tego, jak szybko będzie odnaleziona niezbędna informacja na fizycznych stronicach, czyli od efektywności algorytmów określenia tej odpowiedniości. B zależności od organizacji fizycznej pliku (tzn. jego struktury) i od typu urządzenia, na którym on się znajduje korzystają z różnych metod zarządzania dostępem do plików. Zgodnie z metodami zarządzania dostępem wszystkie urządzenia pamięci zewnętrznej dzielą na pamięć z adresacją dowolną (dyski twarde i optyczne) oraz z adresacja sekwencyjną (strimmery, magnetofony). Rozpatrzymy różne struktury plików i metody dostępu do nich w celu oceniania możliwości ich wykorzystania. 163 BAZY DANYCH Najbardziej rozpowszechnionymi metodami dostępu są: Szeregowy (sekwencyjny) dostęp (adresacja sekwencyjna) Bezpośredni dostęp (adresacja dowolna) Indeksowe metody dostępu. Logic memory Physical memory Tabl Staff Sno LName Position ... SL21 White Manager ... SL37 Beech Snr Asst ... ... SL14 ... SL41 ... ... Ford Deputy ... ... Lee Assistant Page 1 Page 2 ... ... ... ... ... Page n Fig 38. Struktury plików dla metod szeregowego dostępu Te metody opracowane były głównie dla plików przechowywanych na urządzeniach pamięci z dostępem szeregowym (sekwencyjnym) – np. taśmach magnetycznych. W takich urządzeniach w celu otrzymania dostępu do fizycznego elementu rekordu trzeba „przewinąć” wszystkie umieszczone przed nim elementy. Na urządzeniach z bezpośrednim dostępem (z dowolnym typem adresacji) istnieje możliwość umieszczenia głowic odczytu-zapisu w dowolne miejsce prawie natychmiast. Jednak czas ustawienia głowicy nie jest równy zero, a jest, po prostu, bardzo mały w porównaniu do czasu odczytania-zapisu. 164 BAZY DANYCH W systemach plików z dostępem szeregowym (sekwencyjnym) cała pamięć fizyczna przedstawia się jako szereg elementów informacyjnych (stronic fizycznych lub rekordów plików). Pliki z szeregowym dostępem mają dwa typy rekordów: ze stałą długością i zmienną długością. Dla plików ze stałą długością rekordów adres umieszczenia rekordu z numerem K może być obliczony według wzoru: NK =BA + (K-1) * LZ +1, Gdzie NK – wyszukiwany adres umieszczenia rekordu z numerem K, BA - adres początku pliku, LZ – długość rekordu. W plikach ze zmienną długością rekordów każdy z nich może mieć dowolną długość z określonego przydziału. Żeby odnaleźć następny zapis w takich plikach korzystają z jednego ze sposobów: 1. Koniec każdego rekordu zaznaczany jest markerem – szeregiem specjalnych symboli, wykorzystywanych tylko dla tego celu. 2. Długość bieżącego rekordu jest znajduje się na początku każdego zapisu w określonym polu. Pliki z różnymi długościami rekordów zawsze są plikami tylko z dostępem szeregowym. Pliki ze stalą długością rekordów, umieszczone na urządzeniach pamięci bezpośredniego (dowolnego) dostępu, są plikami bezpośredniego dostępu. Pliki ze stałą długością rekordów mogą się znajdować na urządzeniach pamięci tak z dostępem bezpośrednim (dowolnym), jak i z dostępem szeregowym (sekwencyjnym). Pliki z różną długością rekordów zawsze są umieszczane na taśmach magnetycznych lub strimmerach. Niech jest zadany schemat relacji R (Sno, FName, Lname, Address, Tel_No, Position, Sex, DOB, Salary, Bno), przy czym każda strona fizyczna pliku (rys.34) może zawierać kilka rekordów tablicy bazy danych. Liczba tych rekordów nie jest stała. Rekordy są posortowane według atrybutu kluczowego Sno. Spróbujemy opracować następujące zapytanie SQL: SELECT * FROM STAFF WHERE Sno = ‘SG37’; W celu poszukiwania rekordu w plikach z dostępem szeregowym stosuje się dwa rodzaje przeszukiwania: liniowe i binarne. W przeszukiwaniu liniowym w celu odnalezienia niezbędnego rekordu trzeba wykonać sekwencyjne odczytanie kluczy kolejnych rekordów pliku, zaczynając od pierwszego, aż do odnalezienia rekordu z odpowiednim kluczem (‘SG37’ w naszym przypadku). 165 BAZY DANYCH Dlatego zazwyczaj stosuje się przeszukiwanie binarne pozwalające zmniejszyć ilość operacji sprawdzenia (porównania) kluczy w rekordach z N do log2N (w najgorszym przypadku), gdzie N – ilość rekordów w pliku. Algorytm przeszukiwania binarnego dla plików z dostępem szeregowym. Algorytm zawiera następne iteracyjne kroki. 1. Z początku włączamy do zbioru stron wszystkie strony fizyczne pliku, które zawierają rekordy logiczne i muszą być uporządkowane (posortowane) według wartości kluczy. 2. Określamy i odczytujemy środkową stronę fizyczną wśród istniejących w zbiorze stron. 3. Porównujemy klucz poszukiwanego rekordu logicznego ze wszystkimi kluczami rekordów logicznych znajdujących się na tej stronie. Jeśli rekord został odnaleziony - kończymy algorytm. Inaczej przechodzimy do p.4. 4. Jeśli wartość klucza pierwszego rekordu strony fizycznej jest większą od wartości klucza poszukiwanego, to znaczy, że ten rekord logiczny znajduje się na poprzednich stronach fizycznych zbioru. W tym przypadku do zbioru stron włączamy tylko poprzednie strony fizyczne. Jeśli wartość klucza ostatniego na stronie rekordu jest mniejsza od wartości klucza poszukiwanego, to oznacza, że ten rekord logiczny jest umieszczony na następnych stronach fizycznych zbioru. W tym przypadku do zbioru stron włączamy tylko następne strony fizyczne. Przejście do p.2. Przykład przeszukiwania binarnego w pliku z dostępem szeregowym i przedstawionym wcześniej zapytaniu SQL pokazany jest na rys.43. Tu umownie pokazano 6 stronic pamięci fizycznej, każda z których zawiera jeden rekord. Najpierw odczytana jest zawartość stronicy 3 (ona jest środkową). Wartość pola kluczowego rekordu znajdującego na tej stronicy jest mniejsza od wzorca ‘SG37’. Dlatego na następnej iteracji przeszukiwanie wzorca odbywa się tylko na stronicach 4,5 i 6. Następnie odczytywana jest zawartość stronicy 5 (ona jest środkową wśród pozostałych). Potrzebny rekord odnaleziony zostanie na iteracji trzeciej. 166 BAZY DANYCH Pages SELECT * FROM STAFF WHERE Sno = 'SG37'; SA9 1 SG5 2 SG14 3 (3) SG37 4 (2) SG21 5 SL41 6 (1) Fig 39 167 BAZY DANYCH Wady metod dostępu szeregowego: 1. Wstawienie nowych rekordów wymaga reorganizacji całego pliku - zapis starych rekordów na inne miejsca, a nawet na inne stronice, ponieważ na odpowiedniej stronicy może nie okazać się miejsca na nowy rekord. 2. Usunięcie rekordów powoduje powstanie „dziur”, co też wymaga reorganizacji całego pliku. W celu usunięcia pierwszej wady stosuje się tymczasowy nieposortowany plik przepełnienia (overlflow file) nazywany również plikiem tranzakcji (transaction file). W tym przypadku wszystkie operacje wstawienia nowych rekordów wykonują się w tym pliku, zawartość którego okresowo zostaje przekopiowana do pliku głównego. Wtedy operacje dodania nowych rekordów wykonuje się bardziej efektywnie, jednak więcej czasu potrzebuje operacja przeszukiwania. Jeśli rekord nie zostaje odnaleziony podczas przeszukiwania binarnego w posortowanym pliku, trzeba kontynuować przeszukiwanie (już tylko liniowe!) w pliku transakcji. Również po usunięciu rekordu trzeba reorganizować cały plik transakcji. Pliki z dostępem szeregowym rzadko stosują się dla przechowania tablic bazy danych, wyłączając pliki z indeksem pierwotnym ( o tym będzie powiedziano niżej). One mogą być wykorzystane dla tworzenia plików indeksowanych zawierających klucze pierwotne tablic. Pliki te przechowywane zazwyczaj są w buforach pamięci operacyjnej. Struktury plików dla metod dostępu bezpośredniego (dowolnego) Do tej grupy metod należą metody mieszające (hash’owania) i metody indeksowe. Metody mieszające W pliku hash’owanym rekordy nie muszą być zapisywane szeregowo. Zamiast tego dla obliczenia adresu strony (stronicy), na której znajduje się poszukiwany rekord, wykorzystują funkcja mieszająca (hash-function), argumentami której są wartości jednego lub kilku pól tego rekordu. Te pola mają nazwy klucza „hash” (hash key). Rekordy w pliku hash’owanym umieszczone w dowolnym porządku (rys.39-1). Dlatego pliki hash’owane nazywają również plikami ze dowolną strukturą (random files). Jasne, że one mogą się znajdować tylko na urządzeniach pamięci z dostępem bezpośrednim. Funkcja mieszająca “hash” wybiera się w taki sposób, żeby rekordy wewnątrz pliku były umieszczone równomiernie. Przypadkiem idealnym 168 BAZY DANYCH jest tu zależność liniowa między wartością klucza (hash key) K i adresem fizycznym strony, na której ten rekord się znajduje (rys.40). W tym przypadku gwarantuje się jednoznaczna zależność między fizycznymi i logicznymi rekordami. Jednak nie zawsze udaje się skonstruować taką zależność. Często się zdarza, że wartości kluczy znajdują się w różnych przedziałach (rys.40). W tym przypadku funkcja F(k) będzie miała zbiór zbędnych wartości odpowiadających nieistniejącym wartościom klucza. Wtedy stosują różne metody konstruowania funkcji mieszającej “hash”. Niżej będzie rozpatrzono kilka z nich. Logic memory HashFunction Tabl Staff Sno LName Position ... 3 SL21 White Manager ... SL37 Beech Snr Asst ... 5 0 ... SL14 ... SL41 ... ... Ford Deputy ... ... Lee Assistan t Physical memory Page 0 Page 1 Page 2 4 ... ... 3 Page 2 ... Page 4 ... 1 ... Page 5 Fig. 39_1 169 BAZY DANYCH N=F(K) K Not Allowable keys N K Allowable keys Fig. 40 170 BAZY DANYCH Metoda spłotu (folding). Bazuje się na wykonaniu operacji arytmetycznych na różnych częściach argumentów funkcji “hash”. W przypadku, kiedy argumenty mają typ symbolowy, one najpierw zostają przekształcone do typu liczbowego. Na przykład, jeśli identyfikator rekordu (klucz pierwotny) numeru pracownika przedstawia sobą dwie litery i dwie cyfry, to pierwsze dwa znaki przekształcane są do formatu liczbowego. Następnie otrzymany wynik dodaje się do pozostałej części klucza. Otrzymana w ten sposób suma wykorzystuje się jako adres fizyczny strony (stronicy), na której będzie zapisany odpowiedni rekord. Metoda reszty od dzielenia (division-remainder). Ta metoda korzysta z funkcji MOD, argumentem której jest pole klucza rekordu. Funkcja MOD dzieli to pole na pewną liczbę, a reszta od dzielenia jest adresem fizycznym strony, na której będzie się znajdował odpowiedni rekord. Przykład. Mamy 7 stron (stronic) fizycznych pamięci. Na jednej stronie można umieścić 3 rekordy z tablic bazy danych. Maksymalnie możliwa ilość rekordów w tablicy – 20. Numer strony fizycznej obliczamy jako MOD (identyfikator,7), tzn. jako reszta od dzielenia identyfikatora rekordu (klucza) przez liczbę 7. Rekord z kluczem 1 będzie umieszczony na stronie 1, rekord 7 na stronie 0, rekord 18 – na stronie 4, itd. Problem, powiązany z wykorzystaniem większości funkcji mieszających „hash” polega na tym, że one nie mogą gwarantować unikalności obliczonego adresu, ponieważ ilość możliwych wartości argumentów funkcji może być znacznie więcej od ilości dostępnych do zapisu adresów. Przypadek, kiedy ten sam adres zostaje obliczony dla dwóch i więcej różnych argumentów nazywa się kolizją (collision), natomiast podobne rekordy nazywają synonimami. W tym przypadku nowy rekord trzeba umieścić w inne miejsce (pod innym adresem), ponieważ jego miejsce już jest zajęte. Istnieją różne strategie rozwiązania kolizji (konfliktów). Jedną z nich jest rozwiązanie kolizji za pomocą obszaru przepełnienia pamięci. Zgodnie z tą strategią pamięć dzieli się na dwa obszary(rys.40_1): 1. Obszar główny. 2. Obszar przepełnienia. Dla każdego rekordu na stronie fizycznej pamięci dodaje się wskaźnik na rekord, który ma synonim w pamięci przepełnienia. W ten sposób wszystkie synonimy są połączone w jeden „łańcuch”. W ostatnim rekordzie łańcucha w polu wskaźnika znajduje się znak końca łańcucha. 171 BAZY DANYCH main area KEY Atributs The reference to the following record ... KEY Atributs The reference to the following record overflow area KEY Atributs The reference to the following record ... KEY Atributs The reference to the following record KEY Atributs The reference to the following record KEY Atributs The reference to the following record Fig.40_1 172 BAZY DANYCH Dla każdego nowego rekordu oblicza się wartość funkcji mieszającej „hash” – adres w obszarze głównym pamięci. Jeśli to miejsce już jest zajęte, rekord zostaje zapisany do obszaru przepełnienia na pierwsze wolne miejsce, a w rekordzie-synonimie znajdującym się w pamięci głównej w polu wskaźnika wpisuje się adres nowego rekordu w obszarze przepełnienia. Jeśli pole wskaźnika też już jest zajęte, łańcuch wskaźników modyfikuje się w taki sposób, żeby nowy rekord-synonim okazał się drugim w obszarze przepełnienia. W taki sposób czas umieszczenia dowolnego rekordu nie przekracza czasu wykonania dwóch operacji wymiany informacji z dyskiem. Przy wykonaniu operacji poszukiwania (odczytu) rekordu też najpierw obliczona zostaje wartość adresu rekordu umieszczonego w obszarze głównym pamięci – pierwszego rekordu w łańcuchu. Jeśli ten rekord nie jest poszukiwanym, dalej wykonuje się poszukiwanie rekordu w obszarze przepełnienia poruszając po łańcuchu rekordów-synonimów. Szybkość przeszukiwania zależy od długości łańcucha, dlatego jakość funkcji mieszającej „hash” określa się na podstawie maksymalnej długości łańcucha. Dobrym wynikiem na praktyce uważa się długość nie przekraczająca 10. W celu usunięcia dowolnego rekordu najpierw określa się jego miejsce. Jeśli usuwany jest pierwszy rekord w łańcuchu, to po usunięciu na jego miejsce zostaje zapisany drugi w łańcuchu rekord, przy czym wszystkie wskaźniki na synonimy pozostają bez zmian. Jeśli usuwany rekord znajduje się wewnątrz łańcucha rekordów-synonimów, to trzeba zmodyfikować wskaźniki: w pole wskaźnika rekordu znajdującego się przed usuwanym wpisuje się wskaźnik z rekordu usuwanego. Jeśli to jest ostatni rekord w łańcuchu, w pole wskaźnika wpisuje się znacznik końca łańcucha. Rozwiązanie kolizji komplikuje obsługę hash’owanych plików i zmniejsza wydajność pracy systemu. Wady metod mieszających: 1. Brak możliwości efektywnego przeszukiwania danych na podstawie zadanej maski lub zadanego przedziału wartości. Ten rodzaj przeszukiwania wymaga wstępnego posortowania wartości funkcji mieszającej F. Np., jeśli Rmin i Rmax określają graniczne wartości przedziału kluczy poszukiwanych rekordów, to musi być spełniony warunek F(Rmin) < F(Rmax). 2. Brak możliwości przeszukiwania na podstawie dowolnego innego pola (oprócz pola kluczy). Struktury plików dla metod indeksowanych 173 BAZY DANYCH Indeksowane metody organizacji plików oparte są o wykorzystanie indeksów dla poszukiwania rekordów. Zbiór indeksów może przedstawiać sobą osobny plik. Struktura każdego pliku indeksów związana jest z pewnym kluczem i zawiera rekordy z dwoma polami: polem klucza indeksu i pola adresu fizycznego strony, na której znajduje się rekord z kluczem równym wartości indeksu. Pojęcie pliku indeksów jest analogiczne indeksowi w książce: mając słowo kluczowe i indeks na końcu książki, można odnaleźć stronę książki, na której znajduje się wytłumaczenie tego słowa kluczowego. Plik zawierający rekordy ma nazwę pliku danych, natomiast plik zawierający rekordy indeksów – plikiem indeksów. Wartości pól kluczy w pliku indeksów są posortowane według pola indeksowania – zazwyczaj według jednego z atrybutów tablicy bazy danych. Jeśli ten atrybut jest kluczem pierwotnym pewnej tablicy, indeks ma nazwę pierwotnego (głównego). Jeśli jako indeks wykorzystany jest inny atrybut tablicy, indeks nazywa się wtórnym (drugorzędnym), a sam ten atrybut kluczem wtórnym. Pliki danych mogą nie być posortowane według indeksu wtórnego. Indeksy można realizować na różne sposoby. Jeśli indeks wskazuje bezpośrednio na stronę fizyczną pamięci, on ma nazwę jednopoziomowego indeksu. Pliki wykorzystujące taki indeks mają nazwę plików z indeksowoszeregową metodą dostępu (Indexed Sequential Access Method) (Metoda była opracowana przez firmę IBM). Jeśli indeks wskazuje na inny indeks, on ma nazwę wielopoziomowego. Indeks może być rozrzedzonym (rzadkim) (sparse) lub pełnym (gęstym) (dense). Rozrzedzony indeks zawiera rekordy indeksowe tylko dla niektórych kluczowych wartości poszukiwanych w danym pliku. Pełny indeks ma rekordy indeksowe dla wszystkich kluczowych wartości poszukiwanych w pliku. Przykłady realizacji pełnego i rzadkiego indeksów sporządzonych dla tablicy pracowników firmy pokazane są na rys.41. Jeśli rekordy w pliku są posortowane, nie ma potrzeby przechowywać pełny indeks – wystarczy trzymać tylko indeks ostatniego rekordu i wskaźnik na stronę (stronicę) fizyczną pamięci. Wtedy wszystkie rekordy z indeksami mniejszymi od danego oraz większymi od poprzedniego indeksu będą się znajdować na tej samej stronie pamięci. Powiązany z indeksem pierwotnym plik danych zawsze jest posortowany według kluczy tego indeksu. Każdy pierwotny klucz jest unikalnym, dlatego nie istnieje dwóch jednakowych indeksów pierwotnych. Tzn. mamy wzajemnie jednoznaczną zależność pomiędzy rekordami pierwotnego indeksu i stronami pliku danych. Dla poszukiwania rekordów na podstawie 174 BAZY DANYCH kluczy w indeksie pierwotnym zazwyczaj stosuje się metoda przeszukiwania binarnego. Wtórny indeks też jest posortowanym plikiem, analogicznie indeksowi pierwotnemu. Jednak plik danych nie musi być posortowany według wtórnego klucza. Klucz wtórnego indeksu może zawierać jednakowe wartości, co jest niedopuszczalne dla indeksu pierwotnego. Np. dla tablicy pracowników firmy można utworzyć wtórny indeks według pola numeru oddziału kampanii (Bno). Ponieważ wiele pracowników może pracować w jednym oddziale, ten indeks nie jest unikalnym. Dla pracy z takimi indeksami korzystają z pełnego wtórnego indeksu, w którym określono zależność dla każdego pola indeksu i odpowiedniej stronicy pliku danych. Zwiększenie rozmiaru pliku indeksów i jego poszerzenie na dużą ilość stronic pamięci powodują znaczny wzrost czasu odnalezienia poszukiwanego indeksu. Np. przy wykorzystaniu metody przeszukiwania binarnego trzeba wykonać log2 p operacji odczytu i porównania w indeksie zajmującym p stron w pamięci. Korzystając z wielopoziomowego indeksu można zmniejszyć przedział przeszukiwania. Idea dostępu do stron fizycznych pamięci bazuje się na rozdzieleniu indeksu na kilka podindeksów mniejszego rozmiaru i utworzeniu dla nich nowego indeksu. Rys. 38 ilustruje przykład dwupoziomowego indeksu dla tablicy pracowników. W naszym przykładzie na każdej stronie fizycznej pliku danych można umieścić dwa rekordy (dwa wiersze tablicy). 175 BAZY DANYCH Dense Indeks Indeks File Page SA9 1 SG5 1 The employee SA9 The employee SG5 1 SG14 2 SG37 2 The employee SG14 The employee SG37 2 SL21 3 SL41 3 The employee SL21 The employee SL41 3 Sparse Indeks Indeks File Page SG5 1 The employee SA9 The employee SG5 1 SG37 2 The employee SG14 The employee SG37 2 3 SL41 3 The employee SL21 The employee SL41 176 fig.41 BAZY DANYCH Indeks 2 level 1 level SG37 SG5 File Page The employee SA9 The employee SG5 1 The employee SG14 The employee SG37 2 The employee SL21 The employee SL41 3 SG37 SL41 SL41 fig.42 177 BAZY DANYCH Oprócz tego, na każdej stronicy indeksu pierwszego poziomu też znajdują się dwa rekordy (tylko w celu klarowności tłumaczenia). Każdy indeksowy rekord zawiera wartość klucza dostępu i adres strony pamięci. Przechowywana wartość klucza jest największą na adresowanej stronie. Podczas poszukiwania według wartości atrybutu identyfikatora pracownika (np. SL14) najpierw sprawdzony zostaje indeks drugiego poziomu, w którym odszukana zostaje strona z wartością ostatniego klucza większą lub równą SL14. W naszym przypadku wartość ostatniego klucza jest równa SG37. Odnaleziony rekord zawiera adres stronicy indeksu pierwszego poziomu, w którym trzeba kontynuować poszukiwanie. Powtarzając opisaną procedurę otrzymujemy adres strony 2, gdzie znajduje się poszukiwany rekord. Organizacja indeksów w postaci B-drzew (B-tree) Wielopoziomowe indeksy mogą być realizowane w postaci drzewa. Drzewo składa się z hierarchii węzłów (node), w której każdy węzeł oprócz korzenia (root) ma węzeł macierzysty oraz jeden lub kilka węzłów potomnych (child). Korzeń nie ma węzła macierzystego. Węzeł, który nie ma węzłów potomnych nazywa się listkiem lub lisciem (leaf). Głębokość drzewa – to jest maksymalna ilość poziomów od korzenia drzewa do liścia. Głębokość drzewa może być różna dla różnych ścieżek wiodących do liścia. Jeśli jednak ta głębokość jest wszędzie jednakowa, odpowiednie drzewo ma nazwę zbilansowanego lub B-drzewem (B-tree). Stopniem (degree) lub rzędem (order) drzewa nazywa się maksymalna liczba węzłów potomnych dla każdego węzła macierzystego. Drzewem binarnym (binary tree) nazywa się drzewo rzędu 2, tzn. każdy węzeł w którym ma nie więcej niż dwa węzły potomne. Drzewo binarne jest przypadkiem szczegółowym B-drzewa. Dla przechowywania indeksów stosuje się modyfikacja B-drzewa, która ma nazwę drzewa B(+). Takie drzewo określa się następującą. Jeśli korzeń drzewa nie jest liściem, on musi mieć co najmniej dwa węzła potomnych. W drzewie N-tego rzędu każdy węzeł (za wyłączeniem korzenia i liścia) powinien mieć od N/2 do N wskaźników i węzłów potomnych. Jeśli N/2 nie jest liczbą całkowitą, to ta liczba zaokrągla się do najbliższej większej liczby całkowitej. W drzewie N-tego rzędu B-drzewa ilość wartości kluczowych w liście powinna się znajdować w przedziale od (N-1)/2 do N/2. Jeśli liczba (N1)/2 nie jest całkowitą, ta liczba zaokrągla się do najbliższej liczby całkowitej. 178 BAZY DANYCH Ilość wartości kluczowych w węźle, który nie jest liściem jest o jeden mniejsza od ilości wskaźników. Drzewo zawsze powinno być zbilansowanym, czyli wszystkie ścieżki od korzenia do liścia muszą mieć jednakową głębokość. Liście drzewa są powiązane w kolejności zwiększenia wartości kluczowych. Na rys. 43 przedstawiono indeks w postaci drzewa B(+) rzędu trzeciego dla tablicy zawierającej dane pracowników firmy. Każdy węzeł w tym drzewie ma postać:: * Wartość kluczowa1 * Wartość kluczowa2 * Tu symbol (*) oznacza wskaźnik na inny rekord. Niektóre klucze oraz wskaźniki mogą być nieobecne w węźle. Algorytm poszukiwania w B-drzewie. Zaczynając od korzenia wykonujemy operacje porównania. Jeśli wartość poszukiwanego klucza jest mniejsza lub równa wartości klucza 1 lub klucza2 (w naszym przypadku), to dla przejścia do następnego węzła korzystamy z wskaźnika znajdującego się z lewa od pola tego klucza. W przypadku przeciwnym korzystamy z wskaźnika umieszczonego ostatnim w danym węźle. Na przykład, dla odnalezienia rekordu „SL21” zaczynamy przeszukiwanie od korzenia drzewa. Ponieważ wartość „SL21” jest większa od „SG14”, trzeba przejść zgodnie z wskaźnikiem umieszczonym z lewa od „SL21”, tzn. na liść z adresem rekordu „SL21”. Drzewo B(+) – jest najbardziej efektywna strukturą dla tworzenia indeksów. W praktyce każdy węzeł w drzewie jest realizowany na osobnej stronie fizycznej pamięci i zawiera więcej niż trzy wskaźniki i dwa kluczy. W drzewie B(+) dostęp do dowolnego rekordu wymaga jednakowego czasu, ponieważ podczas przeszukiwania sprawdza się jednakowa ilość węzłów. Poza tym ten indeks jest pełnym (gęstym), tzn. każdy rekord jest adresowany indeksem. Dlatego sortować rekordy w pliku danych nie ma potrzeby, tzn. plik danych może przedstawiać sobą nieuporządkowany plik z dostępem szeregowym. 179 BAZY DANYCH * SG14 * * * SG5 SA9 * SG37 * * * SG5 * SG14 SL21 * * * SG37 * * SL21 * * SL41 Fig.43 180 * BAZY DANYCH Zarządzanie transakcjami Celem systemu zarządzania transakcjami jest takie sterowanie operacjami w bazie danych, aby były one wykonane z możliwie wysokim współczynnikiem współbieżności i aby przeciwdziałać naruszeniu spójności bazy danych. Realizacja tego celu została osiągnięta za pomocą odpowiednich protokołów zarządzania transakcjami. Cechy transakcji Z punktu wzoru SZBD transakcja to jest ciąg operacji na bazie danych. Każda transakcja w momencie inicjowania otrzymuje jednoznaczny identyfikator. Identyfikator ten jest następne związany z każdą operacją składającą się na transakcję. Do operacji tych należą: ri [x] - czytanie danej x przez transakcję T , i w [x] - zapisanie danej x przez transakcję T , a - odrzucenie (wycofanie) transakcji T (operacja ABORT), c - zatwierdzenie transakcji T (operacja COMMIT). Mówiąc o danej x mamy na myśli jednostki danych na różnych poziomach i i i i i i granulacji – może to być dana elementarna, rekord, zbiór rekordów wyznaczonych przez warunek, tabela bazy danych itp. Przykład 1. Rozważmy system bankowy, w skład którego wchodzą: Baza danych zawierająca dane KONTO1 i KONTO2 wskazujące stan dwóch różnych kont w banku; Program zwracający stan podanego konta: Info(konto) { X:= read(konto); Return(x); } Program realizujący przekazanie podanej kwoty z jednego konta na drugie: Przelew(konto_z, konto_na, kwota) { X:= read(konto_z); X:= x-kwota; Write(konto_z,x); X:= read(konto_na); X:= x+kwota; 181 BAZY DANYCH Write(konto_na,x); } Każde wykonywanie dowolnego z tych programów powoduje utworzenie nowej transakcji. Jeśli w systemie istnieje wiele stanowisk komputerowych, z których programy te mogą być wywoływane, to wiele z tych transakcji będzie współbieżnych, co oznacza, że przed zakończeniem jednej transakcji rozpoczynana jest następna (inicjowana z innego stanowiska komputerowego). To oznaczy, że oddzielne operacji różnych transakcji mogą być przyplątane w różnych szeregach. Każda transakcja tworzona dla wywołania programu info(KONTO1) ma postać: T = (ri [KONTO1] , ci ), i=1,2,…, i jeśli czytanie zakończyło się pomyślnie lub T = (ri [KONTO1] , ai ), i=1,2,…, i jeśli czytanie się nie powiodło (na przykład podmiot wydający to polecenie nie miał wystarczających uprawnień). Podobnie, każde wywołanie programu przelew() z konkretnymi parametrami KONTO1 i KONTO2 powoduje utworzenie nowej transakcji T dla i=1,2,…, którą możemy zapisać jako ciąg i następujących operacji na bazie danych: T = (ri konto1, wi konto1, r konto2, w [konto2], c ) i i gdzie: operacja i i , r [KONTO1] - odczytuje stan konta KONTO1, i operacja wi [KONTO1] - zapisuje nowy stan konta KONTO1, operacja r [KONTO 2] - odczytuje stan konta KONTO2, i operacja wi [KONTO2] - zapisuje nowy stan konta KONTO2, oznacza pomyślne zakończenie transakcji(jej zatwierdzenie). Transakcja T może mieć również inną postać, jeśli po którejś operacji c i i system powoduje jej odrzucenia z powodu na przykład przerwania łączności z bazą danych, rozwiązywania problemu zakleszczenia, naruszenia warunku spójności (mówiącego na przykład, że stan konta nie może być niższy niż określona kwota), braku wystarczających uprawnień, itp. Wówczas transakcja może wyglądać następująco: 182 BAZY DANYCH T = (ri konto1, wi konto1, r konto2, w [konto2], a ) , i i i i T = (ri konto1, wi konto1, r konto2, a ) , i i i i T = (ri konto1, wi konto1, a ) , i i T = (ri konto1, a ) . i i W stosowanym zapisie transakcji abstrahujemy zarówno od konkretnych wartości, jak i od operacji wykonywanych poza bazą danych (operacji w pamięci operacyjnej, obszarze roboczym, interakcja z użytkownikiem lub z innymi systemami). Transakcje i protokoły zarządzania transakcjami muszą spełniać postulat ASOT (atomowość, spójność, odizolowanie, trwałość). Angielski termin ACID (atomocity, consistency, isolation, durability). Postulat ten rozumiany jest następująco: 1. Atomowość – każda transakcja stanowi pojedynczą i niepodzielną jednostkę przetwarzania (a także odtwarzania) – w transakcji nie ma więc podtransakcji. Każda transakcja jest bądź wykonana w całości, bądź też żaden jej efekt nie jest widoczny w bazie danych - „Wszystko lub niczego". 2. Spójność – transakcja rozpoczynając się w spójnym stanie bazy danych pozostawia bazę danych w stanie spójnym (tym samym lub innym). Jeśli transakcja narusza warunki spójności bazy danych, to SZBD powoduje jej odrzucenie. 3. Odizolowanie – zmiany wykonywane przez transakcję nie zatwierdzoną nie są widziane przez inne transakcje (chyba, że przyjęty poziom izolacji na to zezwala). 4. Trwałość – zmiany w bazie danych dokonane przez transakcję zatwierdzoną są trwałe w bazie danych, tzn. nawet w przypadku awarii systemu musi istnieć możliwość ich odtworzenia. Przykład 2. Rozważmy transakcje z przykładu 1. Atomowość oznacza, że transakcję T = (ri konto1, wi konto1, r konto2, w [konto2], c ) i i i i , musimy traktować jako niepodzielną całość. Nie można więc przyjąć, że na przykład system utrwala wykonanie w bazie danych dwóch pierwszych operacji zakładając, że po jakimś czasie zrealizuje dwie następne operacje. Bałaby to koncepcja wyróżniania podtransakcji, co w tradycyjnych systemach baz danych jest niedopuszczalne. Jeśli więc z jakiegoś powodu 183 BAZY DANYCH wykonanie transakcji ulegnie przerwaniu ( na przykład w wyniku awarii) po dwóch pierwszych operacjach, to system musi zapewnić wycofanie dokonanych zmian. Spójność oznacza, że system nie dopuści do zatwierdzenia transakcji, która naruszy jakikolwiek warunek spójności bazy danych. W rozważanym przypadku warunkiem spójności może być wymaganie, aby stan rachunku bankowego był zawsze większy od zera (statyczny warunek spójności) lub suma stanów kont po wykonaniu transakcji była taka sama jak przed jej wykonaniem (dynamiczny warunek spójności). Odizolowanie oznacza, że zmiany wykonane przez jedną transakcję nie są widoczne dla innych transakcji dopóty, dopóki transakcja ta nie zostanie zatwierdzona. Rozważmy jednak następujący ciąg operacji: r [konto1] , w [konto1] , r [konto2] , r [konto2], c , w [konto2], , c , gdzie T jest transakcja programu przelew(), a T transakcja programu info(). Transakcja T odczytuje stan konta KONTO2, zanim jeszcze transakcja T zmieniająca ten stan konta została zatwierdzona. Naruszony 1 1 1 1 2 2 1 1 2 2 1 jest więc rygorystyczny warunek odizolowania. Trwałość oznacza, że zmiany wprowadzone do bazy danych przez transakcję, która została zatwierdzona są w tej bazie danych trwałe, a więc również w przypadku różnorodnych awarii (z wyłączeniem fizycznego zniszczenia nośnika danych) musi istnieć mechanizm ich odzyskiwania. Z punktu widzenia stosowanych protokołów (algorytmów) zarządzania transakcjami istotne jest przyjęcie pojęcia konfliktowości operacji, tzn. przyjęcie, jakie operacje są konfliktowe, a jakie nie. Z góry można określić, jakie operacje nigdy nie będą konfliktowe, a mianowicie operacje oi [x] i p [ y ] nie są konfliktowe, jeśli: j a) i j , tj. Gdy pochodzą z tej samej transakcji, b) x y , tj. Gdy dotyczą różnych danych (lub rozłącznych zbiorów danych), c) gdy żadna z nich nie jest operacją zapisu, d) co najmniej jedna z nich pochodzi od transakcji, która w chwili wydania drugiej została już zakończona (zatwierdzona lub odrzucona). 184 BAZY DANYCH W pozostałych przypadkach możemy mieć do czynienia, ale nie musimy, z konfliktowością. Z warunkiem koniecznym, ale nie dostatecznym, operacji oi [x] i p j [ y ] są w konflikcie wtedy, gdy: a) i j – operacje pochodzą z dwóch różnych transakcji, b) co najmniej jedna z tych operacji jest operacją zapisu, c) x y – operacje dotyczą tej samej danej (przecinających się zbiorów danych), d) obydwie transakcje, z których pochodzą rozważane operacje są aktywne, e) druga z operacji ( p j [ y ] ) powoduje zmianę zbioru danych x (wyznaczonego przez pewną formułę operacja ( o [x] ). ) na których działa pierwsza i Definiowanie konfliktowości zależy ponadto od intencji użytkownika dotyczącej poziomu wzajemnego odizolowania transakcji od siebie. Użytkownik ma więc w istocie wpływ na interpretację cechy odizolowania. Standardem ISO wyróżniają się cztery poziomy izolacji, a tym samym cztery poziomy konfliktowości operacji: 0,1,2,3. Im wyższy poziom izolacji transakcji (konfliktowości) tym niższa współbieżność, a więc dłuższy czas wykonywania transakcji, ale jednocześnie większa niezawodność przetwarzania i jego bezpieczeństwo z punktu widzenia zachowania spójności bazy danych. Mówiąc o współbieżnym wykonywaniu operacji mamy na myśli wykonywanie operacji pochodzących z różnych transakcji i to w czasie, gdy obydwie te transakcje są aktywne. Transakcje, których operacje wykonywane są współbieżnie, nazywamy transakcjami współbieżnymi. Anomalne historii przetwarzania transakcji Z punktu widzenia analizy poprawności protokołów (algorytmów) zarządzania transakcjami istotnie jest analizowanie historii przetwarzania transakcji. Historia taka znana jest po wykonaniu wyznaczonego zbioru transakcji. Definicja 1. Niech T 1 , T 2 ,... T n będzie zbiorem transakcji. Ciąg H o , o ,... o 1 2 m 185 BAZY DANYCH operacji pochodzących z transakcji należących do zbioru historią przetwarzania transakcji za zbioru nazywamy . Jeśli operacja oo . Definicja 2. Mówimy, że transakcja T czyta z transakcji T daną x , jeśli T jest ostatnią transakcją aktywną, która zapisała x . Mówimy, że transakcja T zapisuje w transakcji T daną x , jeśli T odczytała x i pozostaje transakcją aktywną w momencie zapisu x przez T . o poprzedza operację o w historii H, to stosować będziemy zapis 1. Nieodtwarzalne historie przetwarzania. Przypuśćmy, że transakcja T 1 zmieniła wartość danej transakcja y danej T wczytała 2 xi x, a następnie na podstawie jej wartości zmieniła wartość w bazie danych. Przypuśćmy dalej, że transakcja T 2 została zatwierdzona , a po tym zdarzeniu powstała konieczność odrzucenia transakcji T 1 . Należałoby więc wycofać wszystkie zmiany, jakie wprowadziła w bazie danych transakcja T 2 , a także wszystkie konsekwencje tych zmian – w szczególności więc zmianę wartości danej y . Ta ostatnia operacja jest jednak niemożliwa, gdyż transakcja T 2 , która tę zmianę wykonała jest już zatwierdzona. Zaistniała więc sytuacja, w której baza danych jest nieodtwarzalna. Przykad 3. Rozważmy historię przetwarzania H : w [ x] r [ x] w [ y ] c w [ z ] a 1 2 1 2 2 1 1 . H 1 opisuje przetwarzanie nieodtwarzalne. Transakcja T 1 , w [ x] r [ x] , 2 1 i T w [ y] 2 c a . Operacja y wyznaczonej na podstawie 2 2 1 T 2 czyta z transakcji jest zatwierdzana przed odrzuceniem może oznaczać wartości danej x. zapis wartości T 2 1 , danej Zmiany tej jednak nie można wycofać podczas wycofywania konsekwencji transakcji transakcja T T 1 , gdyś została wcześniej zatwierdzona. 186 BAZY DANYCH Powodem opisanej anomalii jest to, że transakcja czytająca dane z innej transakcji została zatwierdzona w czasie aktywności transakcji, z której czytała. Aby sytuacji takiej uniknąć, należałoby czekać z zatwierdzeniem transakcji T 2 do czasu, aż zostanie zatwierdzona transakcja T 1 . Przyjmujemy więc, że historia H opisuje przetwarzanie odtwarzalne, jeśli każda transakcja jest zatwierdzana po zatwierdzeniu wszystkich transakcji, z których czyta. To znaczy, że c musi być później a (lub c ). 2 1 1 2. Historie przetwarzania z kaskadą odrzuceń. Przestrzeganie zasady odtwarzalności nie jest wystarczające. Mimo jej przestrzegania może dojść do sytuacji, gdy odrzucenie jednej transakcji pociągnie za sobą konieczność odrzucenia zależnej od niej (w jakimś sensie) innej transakcji, odrzucenie tej drugiej może spowodować konieczność odrzucenia trzeciej itd., co może prowadzić do kaskady odrzuceń. Niech na przykład transakcja T 2 wczyta dane zmienione przez nie zatwierdzoną jeszcze transakcję T 1 . Przypuśćmy, że transakcja T 1 zostaje po tym zdarzeniu odrzucona. Konsekwencją tego jest także konieczność odrzucenia transakcji T 2 . Ale T 2 już wpisała dani do innych pół tabel bazy danych ( w2 [u ] ). Może to spowodować konieczność kaskadowego odrzucania wielu transakcji. Przykład 4. Rozważmy następującą historie H 2 powstałą z historii H 1 : H : w [ x] r [ x] w [u] w [ z] a 2 1 2 2 1 1 . opisuje przetwarzanie odtwarzalne. Jednak wykonanie operacji a1 powoduje odrzucenie (wycofanie) transakcji i w konsekwencji kaskadowe H 2 odrzucenie transakcji T 2 . Sytuacji tej można uniknąć, jeśli czytanie danych zmienionych przez transakcje jest dopuszczalne dopiero wtedy, gdy transakcje te zostały już zatwierdzone. Historia H opisuje przetwarzanie bez kaskady odrzuceń, jeśli transakcji czyta dane zapisane przez transakcje już zatwierdzone. To znaczy, że r [ x ] musi być później a (lub c ). 2 1 1 187 BAZY DANYCH 3. Historie przetwarzania z anomalią powtórnego czytania. Przypuśćmy, że transakcja T zapisuje nową wartość danej y w transakcji T 2 czyta daną 2 , a następnie transakcja y i jest zatwierdzana ( transakcja ). Jeśli teraz transakcja T 2 T 1 T 1 zapisuje ponownie przeczyta daną y , to może się okazać, że dana ta ma inną wartość. Transakcja T 2 dysponuje więc dwiema różnymi wartościami tej samej danej. Może zdarzyć się też sytuacja, że transakcja T 1 usunie daną y . Wówczas przy próbie ponownego czytania, transakcja T 1 ma informację, że danej y nie ma w bazie danych. Opisana anomalię nazywa się anomalią powtórnego czytania. Przykład 5. Rozważmy historię przetwarzania transakcji: H : w [ x] r [ y ] w [ y ] w [ z ] c r [ y ] c 3 W 2 1 H 3 1 1 1 2 2 występuje anomalia powtórnego czytania, gdyś między dwoma wystąpieniami operacji czytania, r [ y] , wystąpiła operacja zapisu w [ y ] , 2 1 czyli r [ y] w [ y] r [ y] . 2 2 1 Historie nazywa się historią bez anomalii powtórnego czytania, jeśli transakcja nie może zapisywać danych czytanych przez transakcje jeszcze nie zatwierdzone. 4. Historie przetwarzania z fantomami. Przypuśćmy, że transakcja T 2 wczytała z tabeli spełniających warunek nowy rekord T 2 r . Następne inna transakcja, spełniający warunek R T 1 zbiór rekordów , dołączyła do R i została zatwierdzona. Jeśli ponownie odwoła się do rekordów tabeli R spełniających warunek , to okaże się, że tym razem zbiór ten jest inny. Podobna sytuacja wystąpi, jeśli transakcja T 1 dokona takiej modyfikacji rekordu r nie spełniającego warunku , że po jej wykonaniu rekord z warunek ten będzie spełniał. 188 BAZY DANYCH Ten nowy rekord pojawiający się w obszarze zainteresowań transakcji T nazywany jest fantomem lub zjawą. Przykład 6. Rozważmy historię przetwarzania H : r [u] w [ z] c r [u] c 4 2 1 W historii H 4 1 2 2 . może wystąpić zjawisko fantomów. Jeśli bowiem operacja r [u] wczytuje zbiór rekordów spełniających warunek 2 , operacja w [ z] 1 spowoduje, że zbiór takich rekordów ulegnie zmianie (na przykład tak zostaną zmienione pola rekordu z , że po zmianie rekord z będzie spełniał warunek ), to powtórne wykonywanie operacji r [u] zwróci inny zbiór 2 rekordów. Problem fantomów jest nieco podobny do anomalii powtórnego czytania. Jednak tym razem brak jest bezpośredniego konfliktu między wykonywanymi operacjami. Konflikt ten zauważalny jest dopiero wtedy, gdy uwzględnione są warunki, jakie spełniają zbiory danych, na których wykonywane są operacje. Przetwarzanie transakcji na różnych poziomach izolacji Przyjęcie konkretnego poziomu izolacji wiąże się z określonymi problemami – zbyt niski poziom zapewni zwiększenie współczynnika współbieżności, ale może doprowadzić do niekorzystnych cech związanych z zachowaniem spójności bazy danych. Poziom zbyt wysoki może powodować nieuzasadnione opóźnianie transakcji. Czytanie danych z transakcji nie zatwierdzonych (poziom izolacji 0) Czytanie danych z transakcji nie zatwierdzonych możliwe jest przy przyjęciu poziomu izolacji 0, tzn., gdy za konfliktowe uważa się tylko parę operacji zapisu, a dwie operacji, z których jedna jest operacja odczytu, nie są operacjami konfliktowymi. W standardzie SQL ten poziom izolacji nazywany jest także READ UNCOMMITED (popularne określany jako „brudne czytanie”). Można, więc czytać dane zmieniane przez transakcję, która nie została zatwierdzona. Reguły współbieżności dla tego poziomu izolacji przedstawiono w tablice 1, gdzie operacje w lewej kolumnie traktowane są jako wcześniejsze od operacji w górnym wierszu, T oznacza, 189 BAZY DANYCH że operacje mogą być wykonywane współbieżnie, czyli nie są konfliktowe, N oznacza brak współbieżności, a więc konfliktowość. Tablica 1. Reguły współbieżności dla poziomu izolacji 0 – READ UNCOMMITED Read Write Read T T Write T N Przyjęcie tego rodzaju współbieżności operacji może doprowadzić do braku odtwarzalności, kaskady odrzuceń, anomalii powtórnego czytania oraz do pojawiania fantomów. Zaletą jest jednak to, że uzyskujemy wysoki współczynnik współbieżności transakcji. Zakaz czytania danych z transakcji nie zatwierdzonych (poziom izolacji 1). Zakaz czytania danych z transakcji nie zatwierdzonych wprowadza poziom izolacji 1. Poziom ten w standardzie SQL określany jest także jako READ COMMITTED. Przy tym poziomie izolacji dopuszczalne jest jednak zapisywanie danych w transakcjach nie zatwierdzonych. Za konfliktowe uważa się wówczas takie pary operacji, gdzie pierwsza jest operacją zapisu, a druga czytania lub obydwie są operacjami zapisu. Dwie operacje, z których pierwsza jest operacją czytania, a druga operacją zapisu nie są, więc konfliktowe. Można, zatem zapisywać dane, które zostały przeczytane przez transakcję jeszcze nie zatwierdzoną. Tablica 2. Reguły współbieżności dla poziomu izolacji 1 – READ COMMITED Read Write Read T N Write T N Przyjęcie tego rodzaju współbieżności eliminuje anomalie związane z brakiem odtwarzalności i z kaskadą odrzuceń. Nie chroni jednak przed anomalią związaną z powtórnym czytaniem ani przed pojawianiem się fantomów. 190 BAZY DANYCH Zakaz czytania i zapisywania danych w transakcjach nie zatwierdzonych (poziom izolacji 2). Zakaz czytania w transakcjach nie zatwierdzonych i zakaz zapisywania w nich związany jest z przyjęciem konfliktowości na poziomie 2, gdy za konfliktowe uważa się takie pary operacji, gdzie, co najmniej jedna jest operacją zapisu. W standardzie SQL określa się go także jako REPEATABLE READ. Za niekonfliktowe uważa się tylko operacje czytania. Jeśli więc transakcja nie zatwierdzona przeczytała jakąś daną, to dana ta może być tylko czytana przez inną transakcję. Jeśli natomiast transakcja nie zatwierdzona zapisała jakąś daną, to nie można jej ani odczytać, ani tym bardziej zapisać dopóty, dopóki transakcja ta nie zostanie zatwierdzona. Reguły współbieżności operacji mają wówczas postać przedstawioną w tablicy 3. Tablica 3. Reguły współbieżności dla poziomu izolacji 2 – REPEATABLE READ Read Write Read T N Write N N Przyjęcie tego rodzaju współbieżności eliminuje anomalie powtórnego czytania. Nie eliminuje natomiast problemu fantomów. Historie szeregowalne (poziom izolacji 3) Rozwiązanie problemu fantomów wymaga poszerzenia rozważanych dotychczas pojęć współbieżności i konfliktowości w kierunku uwzględnienia formuł (predykatów) definiujących zbiory danych, na których działają rozważane transakcje. Niech dane będą operacje o [ ] i p [ ] pochodzące z dwóch różnych i aktywnych transakcji ( i są formułami określającymi zbiory danych, na których działają operacje) oraz niech o [ ] p [ ] . Przyjmijmy oznaczenia: 191 BAZY DANYCH a) X { x | ( x) } bezpośrednio przed wykonaniem operacji b) Y { y | ( y) } o [ ] , - zbiór danych spełniających warunek bezpośrednio przed wykonaniem operacji X { x | ( x) } c) - zbiór danych spełniających warunek p [ ] , - zbiór danych spełniających warunek bezpośrednio po wykonaniu operacji p [ ] . Pojęcie współbieżności operacji rozszerzamy obecnie następująco: 1. Dwie operacji READ [ ] i READ [ ] są zawsze współbieżne. [ ] [ ] 2. Dwie operacje o i WRITE są współbieżne, jeśli zbiór, na którym działa druga z tych operacji, jest rozłączny ze zbiorem związanym z wykonaniem pierwszej z nich oraz wykonanie drugiej operacji nie zmieni zbioru związanego z wykonaniem pierwszej. Formalnie : X Y 0 oraz X X . [ ] [ ] 3. Operacje WRITE oraz READ są współbieżne, jeśli zbiór, na którym działa druga z tych operacji, jest rozłączony ze zbiorem związanym z wykonaniem pierwszej z nich. Formalnie: X Y 0 . Reguły współbieżności przedstawiono w tablicy 4. Tablica 4. Reguły współbieżności dla poziomu izolacji 3 - SERIALIZABLE Write [ ] Read[ ] X Y 0 X Y 0 ( X Y 0) ( X Read[ ] T Write [ ] T T N T T X ) ( X Y 0) ( X X ) N N Przyjęcie tego rodzaju współbieżności eliminuje wszystkie problemy w tym również problem fantomów. Ten poziom izolacji określa się w standardzie 192 BAZY DANYCH SQL jako SERIALIZABLE. Według standardu jest to domyślny poziom izolacji. Szeregowalność transakcji Celem zarządzania transakcjami jest uzyskanie poprawnych historii przetwarzania. Pojęcie poprawności rozpatrywane jest na przyjętym poziomie izolacji. Definicja 3. Niech {T 1 , T 2 ,... T 3} będzie zbiorem transakcji, a H (o1 , o2 ,... o3) niech będzie historią przetwarzania transakcji ze zbioru . Historię H nazywamy sekwencyjnej, jeżeli dla każdych dwóch transakcji, wszystkie operacje jednej z nich poprzedzają wszystkie operacje drugiej. W przeciwnym wypadku historia jest współbieżna. Definicja 4. Niech {T 1 , T 2 ,... T 3} będzie zbiorem transakcji, a H (o1 , o2 ,... o3) niech będzie historią przetwarzania transakcji ze zbioru .Grafem szeregowalności historii H nazywamy graf G(H)= (V,E), gdzie: V – zbiór wierzchołków równy zbiorowi , E V V - zbiór krawędzi, przy czym krawędź T i T j E wtedy i tylko wtedy, gdy istnieją konfliktowe operacje o i i o j pochodzące z transakcji odpowiednio T i i T j takie, że o j o j . Wierzchołkami w grafie szeregowalności są więc transakcje ze zbioru , a krawędź T i T j oznacza, że istnieją konfliktowe operacje oi i o j pochodzące z transakcji odpowiednio T i i T j , gdzie oi poprzedza o j . Jeśli kolejność operacji konfliktowych w H jest taka, że określana przez nią relacja nie jest relacją częściowego porządku , to taka historia nie jest poprawna oraz graf szeregowalności jest acyklicznym (niepoprawnym). Szeregowalność jest poprawna, kiedy rezultat operacji je historii jest taki samy jako rezultat operacji historii sekwencyjną, a graf szeregowalności jest grafem acyklicznym. Zgodnie z powyższą definicją, sekwencję operacji jest wyznaczona na podstawie kolejności konfliktowych operacji występujących w historii przetwarzania H. Do badania poprawności historii przetwarzania wykorzystuje się analizę grafów szeregowalności. 193 BAZY DANYCH Tablica 5. Przykład grafu, który nie jest Szeregowanym Transakcja T 1 realizuje operacje przelewu kont. Transakcja operacje kapitalizacji kont. Dla początkowego stanu kont =400 przy poprawnej szeregowalności : a) X k =220; T X 2 realizuje =100, Y Y =330, jeżeli ( T 0 0 1 k > T 2 ) lub b) X k =210; Y k = 340, jeżeli ( T 2 -> T 1 ). Transakcja T 1 begin transaction Read (x) x := x+100 Write (x) X=200 Transakcja T 2 begin transaction Read (x) x := x * 1.1 Write (x) X=220(!) Read (y) y := y * 1.1 Write (y) Y=440 commit Read (y) y := y - 100 Write (y) Y=340(!) commit Graf szeregowalności transakcji tabl.5. x T1 T2 y Rys. 1. 194 BAZY DANYCH Tablica 6. Przykład grafu, który jest Szeregowanym Transakcja T 1 realizuje operacje przelewu kont. Transakcja operacje kapitalizacji kont. Dla początkowego stanu kont =400 przy poprawnej szeregowalności : a) X k =220; T X 2 realizuje =100, Y Y =330, jeżeli ( T 0 0 1 k > T 2 ) lub b) X k =210; Y k = 340, jeżeli ( T 2 -> T 1 ). Transakcja T 1 begin transaction Read (x) x := x+100 Write (x) Read (y) y := y - 100 Write (y) commit Transakcja X=200 T 2 begin transaction Read (x) x := x * 1.1 Write (x) X=220 Y=300 Read (y) y := y * 1.1 Write (y) commit Y=330 Graf szeregowalności transakcji tabl.6. x T T2 1 y 195 Rys. 2. BAZY DANYCH Łatwo wykazać (Bernstein, 1987), że jeśli graf szeregowalności jest acykliczny, to odpowiadająca mu historia przetwarzania jest poprawna – zorientowany graf acykliczny jest bowiem graficzną formą reprezentacji zbioru częściowo uporządkowanego. Jeśli natomiast w grafie szeregowalności istnieje jakikolwiek cykl, to odpowiadająca mu historia przetwarzania jest na pewno niepoprawna. Szeregowalność oznacza, że zbiór operacji występujących w historii H możemy ułożyć w ciąg, w którym operacje poszczególnych transakcji nie przeplatają się, ale jednocześnie zachowana jest kolejność wszystkich operacji konfliktowych. Taka historia przetwarzania odpowiada szeregowemu wykonywaniu transakcji, stąd historie generujące częściowy porządek w zbiorze transakcji nazywamy historiami szeregowalnymi. Zauważmy, że w przypadku wystąpienia pętli lub cyklu w grafie szeregowalności odpowiadającym historii H nie dałoby się przekształcić H w historie przetwarzania szeregowego. Zarządzanie transakcjami w języku SQL Transakcji mają właściwość ASOT. Transakcja rozpoczyna się w chwili wydania polecenia inicjującego transakcję (begin transaction...). Charakterystyki transakcji określa się za pomocą komend SET TRANSACTION i SET CONSTRAINTS o składni: SET TRANSACTION lista-opcji opcje: tryb dostępu: READ ONLY, READ WRITE rozmiar obszaru diagnostyk: DIAGNOSTICS SIZE n Poziom izolacji: ISOLATION LEVEL izolacja izolacja: SERIALIZABLE (domyślna) REPEATABLE READ, READ COMMITED, READ UNCOMMITED. SET CONSTRAINTS { lista-warunków/ ALL} { DEFERRED / IMMEDIATE } SET CONSTRAINTS ustała tryb sprawdzania warunków spójności na natychmiastowy (IMMEDIATE) lub opóźniony (DEFERRED). Przyjęcie określonego poziomu izolacji może być źródłem problemów omówionych wcześniej. W tablice 7 jest pokazany związek poziomów izolacji z problemami przetwarzania transakcji. Tablica 7. Poziom izolacji Brak Anomalia Fantomy 196 BAZY DANYCH 0: READ UNCOMMITED 1: READ COMMITED 2: REPEATABLE READ 3: SERIALIZABLE odtwarzalności powtórnego czytania T T N T N N N N T T T N Przykłady przetwarzania bazy danych na różnych poziomach izolacji. Przypuśćmy, że w bazie danych istnieje tabela Towar o postaci przedstawionej w tablicy 8. Tablica 8. Przykładowa tabela bazy danych „Towar”. Nazwa Cena Stan 200MMX 320 20 233MMX 370 50 Poziom izolacji 0. Przy poziomie izolacji 0 możliwe jest czytanie danych zmienionych przez transakcje jeszcze nie zatwierdzone. Mówi się wówczas o „brudnym czytaniu”. Dopuszczenie takiego czytania bardzo zwiększa współbieżność przetwarzania, ale jednocześnie może doprowadzić do udostępniania nieprawdziwych danych z bazy danych, co ilustruje przykład w tablicy 9. Tablica 9. Historia przetwarzania transakcji na poziomie izolacji 0 zapisodczyt Transakcja T1 set transaction isolation level 0 begin transaction update Towar set Cena = 300 Where Nazwa = ‘200MMX’ T1 zmienia cenę Transakcja T2 set transaction isolation level 0 begin transaction select Cena from Towar where nazwa = ‘200MMX’ T2 czyta zmienioną cenę Rollback T1 wycofuje zmianę T2 posiada niepoprawną informację o cenie 197 BAZY DANYCH Zerowy poziom izolacji może być stosowany tylko w takich transakcjach, o których wiemy, że nawet w przypadku błędnych danych nie spowodują poważnych negatywnych konsekwencji. Można go stosować na przykład dla transakcji, których zadaniem jest tylko udzielanie informacji z bazy danych. Poziom izolacji 1. Cechą charakterystyczną tego poziomu izolacji jest to, że możliwe jest aktualizowanie przez transakcję T2 danych wczytanych przez nie zakończoną jeszcze transakcję T1. Po powtórnym odwołaniu się do tych samych danych transakcji T1 można uzyskać sprzeczne informacje. Tablica 10. Historia przetwarzania transakcji na poziomie izolacji 1: odczytzapis Transakcja T1 set transaction isolation level 1 begin transaction select Cena, Stan from Towar where Nazwa = ‘200MMX’ T1 czyta cenę i stan towaru Transakcja T2 set transaction isolation level 1 begin transaction update Towar set Cena = 310 where Nazwa = ‘200MMX’ T2 zmienia cenę wczytaną przez T1 select sum(Cena*Stan) from Towar where Nazwa = ‘200MMX’ T1 czeka na zakończenie T2 Commit Wykonanie oczekującej operacji ‘select’ dla T1. Wynik jest sprzeczny z poprzednią operacją ‘select’ Poziom izolacji 2. W poziomie izolacji 2 mamy zagwarantowanie, że przy ponownym odwołaniu się do tych samych danych dostajemy identyczne informacje. Tablica 11. Historia przetwarzania transakcji na poziomie izolacji 2: odczytzapis-odczyt Transakcja T1 set transaction isolation level 2 Transakcja T2 set transaction isolation level 2 198 BAZY DANYCH begin transaction select Cena, Stan from Towar where Nazwa = ‘200MMX’ T1 czyta cenę i stan towaru begin transaction update Towar set Cena = 310 where Nazwa = ‘200MMX’ T2 czeka na zakończenie T1 select sum (Cena*Stan) from Towar where Nazwa = ‘200MMX’ T1 oblicza wartość towaru Commit Wykonanie oczekującej ‘update’ dla T2. operacji Poziom izolacji 2 zabezpiecza przed modyfikacją wczytanych danych, ale nie przed dołączeniem nowych wierszy. Sytuację te ilustruje historia przetwarzania podana w tablicy 12. Tablica 12. Historia przetwarzania na poziomie izolacji 2: odczytdołączenie-odczyt Transakcja T1 Transakcja T2 set transaction isolation level 2 set transaction isolation level 2 begin transaction select Cena, Stan from Towar where Nazwa = ‘200MMX’ T1 czyta cenę i stan towaru begin transaction insert into Towar values (‘200MMX’, 250,10) T2 dołącza nowy wiersz „fantom” Commit Select sum (Cena*Stan) from Towar where Nazwa =’200MMX’ T1 oblicza wartość towaru. Wynik jest sprzeczny z poprzednią operacją select Poziom izolacji 3. 199 BAZY DANYCH Przed pojawieniem się fantomów chroni poziom izolacji 3. Przy tym poziomie izolacji przetwarzanie z tablicy 12 miałoby historię podaną w tablicy 13. Tablica 13. Historia przetwarzania transakcji na poziomie izolacji 3: odczytdołączenie-odczyt Transakcja T1 Transakcja T2 set transaction isolation level 3 set transaction isolation level 3 begin transaction select Cena, Stan from Towar where Nazwa = ‘200MMX’ T1 czyta cenę i stan towaru begin transaction insert into Towar values (‘200MMX’, 250, 10) T2 czeka na zakończenie T1 Select sum (Cena*Stan) from Towar where Nazwa =’200MMX’ T1 oblicza wartość towaru. Commit Wykonanie „insert” przez T2 Metody sterowania współbieżnością transakcji na różnych poziomach izolacji. Sterowanie współbieżnością transakcji realizuje się przez przetwarzanie historii niepoprawnych do historii szeregowalnych. Szeregowalność może być realizowana za dopomogą blokowania danych oraz metody znaczników czasowych. Metody blokowania danych. Blokowanie to jest protokół, który jest wykorzystywany dla równoległego dostępu do danych przez różnych transakcji. Z każdą daną X jest związana blokada (lock). Kiedy niektóra transakcja otrzyma dostęp do danych, mechanizm blokowania nie dopuści się dostęp do tych samych danych od innych transakcji. Wyróżniają się dwa podstawowe typy blokad: blokadę współdzieloną (shared lock), blokadę wyłączną ( exclusive lock). Operacje na danej nie powodujące jej uaktualnienia powinny być poprzedzone założeniem blokady współdzielonej. Operacje uaktua¼niające daną po¼inny być poprzedzonej założeniem na niej blokady wyłącznej. 200 BAZY DANYCH Ze względu na proces blokowania, dane w bazie danych mogą występować w jednym z trzech stanów: dana nie zablokowana 0 dana zablokowana dla odczytu Read (współdzieloną - shared lock) dana zablokowana dla zapisu Write (wyłączną - exclusive lock). Blokada może być ustalona dla różnych poziomów detalizacji danych: wartość kolumny tabeli wiersz tabeli tabela, widok baza danych. Realne blokada realizuje się za dopomogą oddzielnych bitów w polu danych. Wartość tych bitów odpowiada typu blokady. Mechanizm blokowania zawiera zasoby sterowania kolejkami dla blokowania danych. Główne reguły protokołu blokowania danych: Transakcja która ustaliła się blokadę danej „dla odczytu” (Read) może tylko czytać oraz nie może tę daną uaktualnić. Transakcja która ustaliła się blokadę danej „dla zapisu” (Write) może czytać oraz uaktualnić tę daną. Transakcja realizuje się zgodnie z protokółem blokowania dwóch fazowego(two-phase locking): wszystkie operacje blokowania poprzedzają pierwszą operację odblokowania. Operacja czytania ri [x] transakcji i nie jest operacją konfliktową, dlatego blokada „dla odczytu” (Read) jednej danej x może być ustalona jednoczesne przez wielu transakcji. Natomiast blokada „dla zapisu” (Write) operacji wi [x] transakcji i blokuje dostęp do danej x przez inne transakcji. Protokół blokowania danych przez transakcji zawiera następne czynności: Jakakolwiek transakcja i , która potrzebuje dostęp do obiektu x , musi z początku ustalić blokadę tego obiektu . Blokada może bycz ustalona „dla odczytu” (Read) lub „dla zapisu” (Write). W ostatnim przypadku dostęp do czytania oraz do zapisu obiektu x będzie miała tylko transakcja, która ustaliła blokadę Write. Blokada będzie ustalona skuteczne, kiedy obiekt x nie ma żądnej blokady. 201 BAZY DANYCH W tych przypadkach, kiedy obiekt x jest już zablokowany przez inne transakcję, menedżer SŻBD musi analizować czy jest typ blokady nowej kompatybilnym z typem blokady ustalonej wcześniej. Kiedy transakcja T j potrzebuje dla obiektu x typ blokady Read oraz ten obiekt jest już wcześniej zablokowany blokadą Read przez inną transakcją transakcja transakcją T T będzie miała dostęp dla odczytu obiektu j . W innych przypadkach transakcja i T j T i x równolegle z będzie w stanu oczekiwania (Wait) dopóki, dopóty jest aktualna blokada obiektu przez transakcją Transakcja T T i x . utrzyma blokadę obiektu i , to x dopóki, dopóty przez sposób jawny nie odblokuje go. Odblokowanie może być spowodowane w razie skutecznego zatwierdzenia transakcji (Commit) lub w razie je wycofania (Rollback). Po odblokowaniu obiektu x od transakcji T i inne transakcji mogą „widzieć” obiekt Transakcja obiektu T x do i x. może rozszerzyć swoje blokadę „dla odczytu” (Read) poziomu blokady „dla zapisy” (Write), kiedy inne transakcje nie mają blokad tego obiektu. Algorytm blokowania dwufazowego Najszerzej stosowanym w praktyce jest algorytm blokowania dwufazowego (two-phase locking) oznaczony przez 2PL. Istotą tego algorytmu są następne założenia: Każda transakcja zawiera dwie fazy: fazę blokowania (ekspansji) oraz fazę odblokowania (zwijania). W fasie blokowania transakcja musi uzyskać blokady wszystkich danych, do których będzie dokonywać dostępu. Moment założenia wszystkich żądanych blokad, równoznacznych z zakończeniem fazy blokowania, jest nazywany punktem akceptacji (commit point). W fazie odblokowania (po operacji commit lub rollback), następuje zdejmowanie wszystkich nałożonych blokad. Ponadto w fazie tej nie można zakładać nowych blokad. Diagram czasowy fazę blokowania (ekspansji) oraz fazę odblokowania (zwijania) jest pokazany na rys. 44. 202 BAZY DANYCH W algorytmie 2PL odczyt danej możliwy natychmiast po nałożeniu blokady tej danej, a więc w fazie blokowania , natomiast zapis jest możliwy dopiero w po osiągnięciu przez transakcję punktu akceptacji, a więc w fazie odblokowania. Operacja zapisu jest wykonywana następująco. Założenie blokady wyłącznej („dla zapisu” (Write) ) jest równoznaczne z wykonaniem zapisu wstępnego w obszarze roboczym związanym z zapisywaną daną. Zapis właściwy jest realizowany dopiero w fazie odblokowania, w momencie zdejmowania blokady tej danej na podstawie zawartości obszaru roboczego. 203 BAZY DANYCH Blokady I faza ekspansji II faza zwijania Czas fig. 44 Tablica 14 . Przykład protokołu dwufazowego . Transakcja T 1 realizuje operacje przelewu kont. Transakcja operacje kapitalizacji kont. Dla początkowego stanu kont =400 przy poprawnej szeregowalności : a) X k =220; T X 2 realizuje =100, Y Y =330, jeżeli ( T k 0 0 1 > T 2 ) lub b) X k =210; Y k = 340, jeżeli ( T 2 -> T 1 ). 204 BAZY DANYCH Transakcja T 1 begin transaction Write_Lock (x) Wait Wait Wait Wait Wait Wait Wait Wait Read (x) x := x+100 Write (x) X=210 (+) Write_Lock (y) Read (y) y := y - 100 Write (y) Y=340 (+) commit/ Unlock(x),Unlock(y) Transakcja T 2 begin transaction Write_Lock (x) Read (x) x := x * 1.1 Write (x) X=110 Write_Lock (y) Read (y) y := y * 1.1 Write (y) Y=440 commit / Unlock(x),Unlock(y) Tablica 15. Przykład niepoprawnego grafu szeregowalności , realizowanego przez protokół, który nie jest dwufazowym. Transakcja T 1 realizuje operacje przelewu kont. Transakcja T 2 realizuje operacje kapitalizacji kont. Dla początkowego stanu kont =400 przy poprawnej szeregowalności : a) X k =220; X =100, Y Y =330, jeżeli ( T k 0 0 1 > T 2 ) lub b) X k =210; Y k = 340, jeżeli ( T 2 -> T 1 ). Transakcja T 1 begin transaction Write_Lock (x) Read (x) x := x+100 Write (x) X=200 Transakcja T 2 begin transaction Write_Lock (x) Wait /Unlock(x) Wait Read (x) x := x * 1.1 205 BAZY DANYCH Write_Lock (y) Wait Wait Wait Wait Write (x), X=220(!) Write_Lock (y) Read (y) y := y * 1.1 Write (y) commit / Unlock(y) Unlock(x) Y=440 Read (y) y := y - 100 Write (y) Y=340(!) commit/ Unlock(y) Zakleszczenia transakcji. Zakleszczenie (deadlock) to jest sytuacja przy dwóch fazowym blokowaniu transakcji, powstająca wtedy, gdy transakcja T 1 blokuje daną X i żąda dostępu do danej dostępu do Y , podczas gdy transakcja T danej X ; żadna z tych transakcji 2 blokuje daną Y i żąda nie może kontynuować swojego przebiegu. Możliwe są zakleszczenia, w których uczestniczy wiele transakcji. Tablica 16. Przykład zakleszczenia transakcji Transakcja T 1 Transakcja T 2 begin transaction begin transaction Write_Lock (y) Write_Lock (x) Read (y) Read (x) y := y - 100 x := x * 1.1 Write (y) Write (x) Write_Lock (x) Write_Lock (y) Wait... Wait... Jedynym sposobem walki z zakleszczeniem transakcji jest wycofanie jednej z zakleszczonych transakcji. Główne strategii walki z zakleszczeniem transakcji: 206 BAZY DANYCH Wykrywanie zakleszczeń Zapobieganie zakleszczeń. Wykrywanie zakleszczeń. Wykrywanie zakleszczeń może być realizowane przez graf oczekiwania transakcji (wait-for-graf). Ten graf odwzorowuje zależność jednej transakcji od drugiej. Przykład grafu jest pokazany na fig 45. Każdy wierzchołek odpowiada transakcji. Krawędź T 1 -> T 2 oznacza, że transakcja T 1 czeka na Z T1 X Tn T2 Y ... Fig.45 odblokowanie danej X przez transakcje T 2 . Pętla w grafu oczekiwań jest warunkiem koniecznym oraz dostatecznym istnienia zakleszczeń transakcji. Algorytm wykrywania zakleszczeń zawiera następnie kroki: 1. Wyznaczenia początkowej wartości interwału T pomiędzy dwoma kolejnymi generacjami grafu oczekiwań transakcji. Przy małym T, częste wykrywanie zakleszczeń powoduje obciążenie procesora oraz małą wydajność SZBD. Przy dużym T transakcje, które są zakleszczone, mogą być nie wyznaczone w ciągu interwału T . 2. Generacja grafu zakleszczeń po zakończeniu interwału T . 207 BAZY DANYCH 3. Analiza grafu zakleszczeń: If zakleszczenia istnieją Then wycofanie transakcji, która jest w pętle grafu oczekiwań; T:=T/2; GOTO 2; Else T:=2T; GOTO 2; EndIf Metody znaczników czasowych. Metody znaczników czasowych(Timestamp ordering) są alternatywą do metod szeregowałności historii przetwarzania transakcji przez blokowania danych. Te metody są wykorzystywane w przypadkach, kiedy konflikty pomiędzy transakcjami są rzadkie. Dla usunięcia konfliktów nie jest potrzebny graf oczekiwania transakcji. Definicja. Znacznik czasowy (Timestamp) transakcji T, czyli TS(T), jest jej unikalnym identyfikatorem, który wyznaczy się czas zjawy transakcji T w SZBD. Znaczniki są przydzielone transakcjom w kolejności, w której transakcje pojawiają się w SZBD. Również z transakcjami, w bazie danych z każdą daną (X) są związane następne dwie wartości znaczników czasowych: Read_TS(X) –największy (najstarszy) znacznik czasowy spośród wszystkich transakcji, które pomyślnie odczytały daną X. Wtrite_TS(X) - największy (najstarszy) znacznik czasowy spośród wszystkich transakcji, które pomyślnie zapisały daną X. Implementacja algorytmu znaczników czasowych dla operacji odczytywania danych: Read ( T j ,X) begin If (Write_TS (X)= =TRUE) Then < abort T j and restart it with a new Timestamp>; Else begin < Read X>; Read_TS (X) := max (Read_TS(X), TS( T j )); End; End Read; 208 BAZY DANYCH Dla realizacji operacji odczytywania daną X transakcja T j czyta typ znacznika czasowego daną X. Kiedy ten typ ma wartość Write_TS(X) ustaloną przez inną transakcję T i , transakcja T j będzie wycofana oraz startowana z nowym znacznikiem czasowym. Kiedy typ znacznika czasowego daną X jest Read_TS (X) ustalony przez inną transakcję T i , ten typ zmieni się na największy znacznik (najstarszy) spośród transakcji oraz T j T i . Implementacja algorytmu zapisywania danych: Write( T j ,X) begin znaczników czasowych dla operacji If (TS ( T j ) <Read_TS(X) or TS( T j )<Write_TS(X)) Then < abort T j and restart it with a new Timestamp>; Else begin <Write X> Write_TS(X) := TS( T j ); End; End Write; Dla realizacji operacji zapisywania daną X transakcja czyta z początku typ znacznika czasowego daną X ustalonego wcześniej przed inną transakcją. Kiedy ten znacznik jest starszy czym znacznik T j , transakcja T j będzie wycofana już z nowym znacznikiem czasowym. Kiedy transakcja T j jest starsza od etykiety znacznika czasowego daną (X ), dana (X ) będzie miała nową wartość: Write_TS(X) := TS( T j ). Zaleta metody znaczników czasowych: Wykorzystanie metody nie powoduje zakleszczeń transakcji. Wada metody znaczników czasowych: Dużo często jest wykorzystywane wycofanie transakcji. Odtwarzanie bazy danych Odtwarzanie bazy danych (Recovery Data Base) to jest proces przywrócenia je do poprawnego stanu zgodnie z postulatem ASOT. Baza danych wykorzystuje się dwa typy pamięci: ulotną trwałą. 209 BAZY DANYCH Wyróżniają się następny typy awarii, które powodują konieczność odtwarzania danych: uszkodzenia pamięci ulotnej; uszkodzenia pamięci trwałej. Odtwarzanie bazy danych przy uszkodzeniach pamięci ulotnej Pamięć ulotna jest pamięć operacyjna, a pamięć trwała jest pamięć dyskowa. Pomiędzy tymi dwoma typami pamięci musi być gwarantowane odwzorowanie. Pamięć ulotna zawiera specjalne bufory I/O mające na celu zmniejszenie liczby kosztownych operacji dostępu do wolnej pamięci dyskowej. Bloki dyskowe najczęściej są sprowadzone do bufora i pamiętane tam jako strony w buforze. Informacje o tym, jakie bloki dyskowe znajdują się w buforze , są przechowywane w tablicy bufora (lookaside table). Te bloki mogą zawierać informacje o danych BD. Kiedy w buforze zabraknie miejsca jakaś strona będzie zrzucona na dysk zgodnie ze strategią LRU, według której na dysk zostaje strona najmniej używana. Wszystkie strony w buforze zawierają rezultaty aktualizacji transakcji współbieżnych w bazie danych oraz zostają w buforze aż: zostaną usunięte w wyniku zastosowania strategii LRU, zostaną zapisane na dysku po zadanym czasie. Mówią, że strona w buforze jest „brudna”, jeżeli zastała uaktualniona przez transakcję od czasu ostatniego zapisu na dysk. Brudne strony mogą pozostawać w buforze jeszcze długo po tym, jak uaktualniające je transakcje zostały zaakceptowane. Przypuścimy, że wystąpił zanik napięcia. Jeżeli aktualizowane strony nie były zapisywane na dysk, to będzie stracona informacja o aktualizacjach. Z kolei zapisywanie strony na dysk zaraz po jej aktualizacji powoduje małą wydajność SZBD. Wydajność SZBD w tym przypadku byłaby wyznaczona wydajnością dysku magnetycznego. Oprócz tego, natychmiastowe zapisywanie danych może doprowadzić do niespójności, jeśli okazałoby się później, że transakcja, która dokonała modyfikacji, nie została zaakceptowana. Transakcja zostanie więc odrzucona, ale zmiany przez nią wprowadzone pozostaną. SZBD musi zapewnić atomowość i trwałość transakcji oraz dostarczyć mechanizm wycofania transakcji (wycofania zmian przez nie zaakceptowaną transakcję). Zasadą odtwarzania bazy danych jest przechowywanie zbytecznych danych, które odwzorowują konsekwentność operacji aktualizacji transakcji. Te dani są w dzienniku transakcji (pliku logu), który zawiera historię przetwarzania wszystkich transakcji od momentu ostatniego zapisywania dziennika na dysk. 210 BAZY DANYCH Istnieją dwa warianty realizacji dziennika transakcji: 1. Realizacja oddzielnego logu dla każdej transakcji 2. Realizacja ogólnego logu dla wszystkich transakcji. W pierwszym wariancie każda transakcja chroni historię zmian bazy danych przez operacji tej samej transakcji. Lokalne logi mogą być wykorzystywane dla indywidualnych wycofań oddzielnych transakcji. Oprócz logów lokalnych w tym wariancie jest potrzebny log ogólny dla wyznaczenia kolejności oraz parametrów czasowych wszystkich transakcji. Ten wariant pozwoli realizować szybkie wycofanie oddzielnych transakcji, ale potrzebuje jednoczesnego podtrzymywania wielu logów. Wariant drugi realizuje wykorzystywanie tylko jednego logu. Ten dziennik zawiera informacje pro wszystkie transakcje. Przykład fragmentu dziennika jest pokazany w tabl.14. Tabl.14. Num _Rec 1 2 Id_t r T1 T1 Time Operacja 10:12 10:13 Start Update 3 4 T2 T2 10:14 10:16 Start Insert 5 T2 10:17 Delete 6 T2 10:17 Update 7 8 9 10 T3 T1 T2 T3 10:18 10:18 10:19 10:20 Start Commit Commit Insert 11 T3 10:21 Commit Object Old_ m New_ m PPtr NPtr Staff SL21 20 30 0 1 2 8 12 0 3 4 5 4 6 5 9 0 2 11 0 7 11 10 0 Staff SG37 Staff SA9 Dzial Dz16 Dzial Dz19 90 12 13 40 Przeznaczenie atrybutów kolumn tabl. 14 jest następujące: „Num_Rec” - identyfikator rekordu logu; „Id_tr” – identyfikator transakcji; „Time” – znacznik czasowy operacji transakcji; „Operacja” – typ operacji transakcji; „ Object” – identyfikator obiektu danych, który był wykorzystywany przez operację transakcji; „ Old_ m” – kopia obiektu danych do realizacji operacji transakcji; 211 BAZY DANYCH „New_ m” - kopia obiektu danych po realizacji operacji transakcji; „PPtr” – wskaźnik na poprzedni rekord w logu, który zawiera operację tej samej transakcji; „NPtr” - wskaźnik na następny rekord w logu, który zawiera operację tej samej transakcji. Plik logu jest rozmieszczony w buforu pamięci ulotnej. Rekordy buforu logu mogą być wykorzystywane dla wycofania oddzielnych transakcji przez instrukcje ROLLBACK. Natomiast w przypadkach awarii pamięci ulotnej mogą być stracone wszystkie rekordy logu. W celu odtwarzania bazy danych w tych przypadkach, trzeba mieć kopię logu na dysku oraz ta kopia musi być uzgodniona ze stanem bazy danych. Istnieje protokół WAL(Write Ahead Log), który reglamentuje kolejność zapisywania bufora logu na dysk. W skróci go można określić stwierdzeniem: „zanim zapiszesz coś na dysk najpierw zapisz na dysk bufor logu”. Innymi słowy przed zapisywaniem obiektu bazy danych na dysk, najpierw trzeba zapisać log. Sama baza danych może nie zawierać wszystkich zmian, które odwzorowuje log, ale te zmiany można wprowadzić przez uruchomianie wyznaczonych transakcji w logu. Bufor logu jest zapisywany na dysk w dwóch przypadkach: przy akceptacji jakikolwiek transakcji przez operację COMMIT; przy zdarzeniu licznika czasu (timer). W przypadku awarii pamięci ulotnej menedżer odtwarzania bazy danych musi analizować stan transakcji w logu, która zapisywała rekordy do bazy w moment awarii. Jeżeli transakcja wykonała operację akceptacji (commit) , to menedżer odtwarzania bazy danych musi powtórzyć wszystkie je operacje z początku – wykonać operację REDO. REDO polega na wczytaniu do buforu strony z danymi bazy danych, potworzeniu jej aktualizacji i zapisywaniu tej strony na dysk. Nowa wartość zapisywanego rekordu do bazy jest pobierana z rekordu logu. Kiedy ta transakcja nie była zaakceptowana, to menedżer odtwarzania bazy danych musi wycofać wszystkie je rezultaty – od końca do początku – wykonać operację UNDO. UNDO polega na wczytaniu do buforu danej strony z danymi bazy danych, „odkręceniu” jej aktualizacji i zapisywaniu strony na dysk. Poprzednia wartość danych jest pobrana z rekordu logu. Na fig.46 jest pokazany przykład wykorzystywania logu dla odtwarzania bazy danych. Stan bazy danych moment tlpc (time of last physical consistency) jest zapisany na dysku. W moment tf (time failure) wystąpiła awaria. Dla odtwarzania bazy danych trzeba odczytać wszystkie strony pamięci trwałej, które odwzorowują stan bazy danych na moment tlpc, do bufora pamięci operacyjnej oraz odczytać plik logu. W logu są historie 212 BAZY DANYCH transakcji :T1 – T5. Dla odtwarzania bazy danych trzeba realizować następne czynności: Transakcja T1 była zatwierdzona do momentu tlpc, je rezultaty są w pamięci trwałej bazy danych, dlatego operacji odtwarzania dla tej transakcji nie są potrzebne. Część rezultatów transakcji T2 są w pamięci trwałej. Żeby dostarczać postulat atomowości (ASOT) trzeba powtórzyć wszystkie operacji T2 z początku (wykonać operację REDO). Część rezultatów transakcji T3 są w pamięci trwałej, ale ta transakcja nie została zatwierdzona. Dla transakcji T3 trzeba odkręcić je operacji od końca do samego początku (wykonać operację UNDO). Rezultaty transakcji T4 są nieobecne w pamięci trwałej. Dla transakcji T4 trzeba wykonać operację REDO, bo do momentu awarii została już zatwierdzona. Dla transakcji T5 nie trzeba żądnych czynności odtwarzania, bo rezultaty tej transakcji są nieobecne w pamięci trwałej. 213 tlpc BAZY DANYCH tf Czas T1 T2 T3 T4 T5 Fig 46 Odtwarzanie bazy danych przy uszkodzeniach pamięci trwałej Dla odtwarzania bazy danych przy uszkodzeniach dysków trzeba mieć zarchiwowane kopie bazy danych oraz dziennik transakcji od momentu ostatniej archiwacji. Odtwarzanie poczyna się z kopiowania danych z je kopii. Potem dla wszystkich transakcji, które są zaakceptowane realizuje się operacja REDO. 214 BAZY DANYCH Dla archiwacji bazy danych musi być wyznaczony termin przez administratora bazy danych. Ten termin może być wyznaczony automatyczne po przepełnieniu dziennika transakcji. 215 BAZY DANYCH Pytania kontrolne po kursu „Bazy danych” dla studentów studiów wieczorowych 1. Główne wady systemów plików. 2. Trzywarstwowa architektura ANSI. 3. Relacyjny model danych (Główne pojęcia i definicji). 4. Operacje nad relacjami (algebra relacji) 5. Instrukcja DQL SELECT 6. Włożone instrukcje SELECT 7. Instrukcje DML 8. Instrukcje DDL 9. Zapamiętane procedury i funkcje 10.Instrukcji sterowania dostępu do danych 11.Wykorzystywanie transakcji w SQL 12.Cykl życiowy bazy danych 13.Normalizacja relacji 14.Projektowanie modelu konceptualnego 15.Projektowanie modelu fizycznego 16.Utrzymanie integralności bazy danych 17. Standard ODBC 18.Dostęp w Jawie przez JDBC – sterownik 19.Modeli rozproszonych funkcji oraz modeli rozproszonych danych 20.Struktury plików oraz wady metod dostępu szeregowego 21.Struktury plików dla metod dostępu bezpośredniego 216 BAZY DANYCH Pytania kontrolne po kursu „Bazy danych” dla studentów studiów dziennych 1. Główne wady systemów plików. 2. Trzywarstwowa architektura ANSI. 3. Relacyjny model danych(Główne pojęcia i definicji). 4. Operacje nad relacjami (algebra relacji) 5. Instrukcja DQL SELECT 6. Włożone instrukcje SELECT 7. Instrukcje DML 8. Instrukcje DDL 9. Zapamiętane procedury i funkcje 10.Instrukcji sterowania dostępu do danych 11. Wykorzystywanie transakcji w SQL 12.Cykl życiowy bazy danych 13.Normalizacja relacji 14.Projektowanie modelu konceptualnego 15.Projektowanie modelu fizycznego 16.Utrzymanie integralności bazy danych 17. Standard ODBC 18.Dostęp w Jawie przez JDBC – sterownik 19.Modeli rozproszonych funkcji oraz modeli rozproszonych danych 20.Struktury plików oraz wady metod dostępu szeregowego 21.Struktury plików dla metod dostępu bezpośredniego 22.Zarządzanie transakcjami. Anomalne historii przetwarzania transakcji. Przetwarzanie transakcji na różnych poziomach izolacji. 23.Zarządzanie transakcjami. Szeregowalność transakcji. Kody SQL dla zarządzania transakcjami. Metody sterowania transakcjami na różnych poziomach izolacji. 24.Zarządzanie transakcjami. Odtwarzanie bazy danych. 217