SQL - wyklady
Transkrypt
SQL - wyklady
BAZY DANYCH - WYKŁADY POJĘCIA PODSTAWOWE Dane: - to fakty - to reprezentacja o określonej treści i strukturze, nadająca się do przechowywania, przesyłania oraz wykonania działań logicznych i matematycznych - to typy proste (bazowe; liczby, teksty, daty) i złożone (masowe; kolekcje, relacje, wielozbiory) oraz abstrakcyjne typy danych Baza danych: - jest logicznie spójnym zestawem danych i metadanych zbudowanych w oparciu o pewien model danych, na których można wykonywać określone operacje (aspekt składniowy i operacyjny) - reprezentuje pewien fragment świata rzeczywistego (aspekt semantyczny) - jest projektowana, tworzona i utrzymywana z punktu widzenia przydatności dla określonych zastosowań (aspekt pragmatyczny) Model danych – pojęcie niezbyt jednoznaczne, którego znaczenie jest wypadkową takich cech: - metajęzyk (pojęcia, terminologia) do mówienia o danych, systemach baz danych i przetwarzaniu - sposób rozumienia organizacji danych - języki opisu i przetwarzania danych: diagramy struktur danych, języki zapytań - ogólne założenia dotyczące architektury systemu bazy danych - ograniczenia ideologiczne lub teorie matematyczne dotyczące struktur danych i dostępu do danych Model danych – jako architektura systemu baz danych obejmuje: - definicję danych - operowanie danymi - integralność danych - można wyróżnić trzy główne typy: o proste modele danych (system plików) o klasyczne (hierarchiczne, sieciowe, relacyjne) o semantyczne (częściowo obiektowe) Baza danych – w zależności od przyjętego punktu widzenia, może być traktowana co najmniej jako: - model świata rzeczywistego - zasób systemu informacyjnego - element składowy systemu - uniwersum interpretacji języka danych - zbiór struktur danych Własności baz danych: - abstrakcja danych - niezależność - integralność - współdzielenie - integracja - trwałość - bezpieczeństwo 1 System zarządzania bazą danych (database management system, DBMS) system oprogramowania zawierający w szczególności następujące mechanizmy: - środki do gromadzenia, utrzymywania i administrowania trwałymi i masowymi zasobami danych - środki zapewniające spójność i bezpieczeństwo danych - sprawny dostęp do danych (poprzez język zapytań) - środki programistyczne (API dla popularnych j. programowania) - jednoczesny dostęp do danych dla wielu użytkowników - środki pozwalające na odtwarzanie zawartości baz danych po awarii - środki optymalizujące pamięć i czas dostępu - współdziałanie w środowisku rozproszonych Zestaw narzędzi Interfejs Jądro systemu BAZA DANYCH Proces tworzenia bazy danych: - analiza wymagań dziedziny modelowej - modelowanie koncepcyjne - modelowanie logiczne - modelowanie fizyczne - implementacja modelu w ramach systemu baz danych Model encja—związek – zaliczany do modeli pojęciowych; język wizualnych diagramów - encja – grupa obiektów o podobnych własnościach, którą można i warto wyróżnić w modelowej rzeczywistości - związek – grupa powiązań między encjami - atrybut – cecha charakterystyczna encję lub związek - generalizacja/specjalizacja – zawieranie się grup obiektów - liczności – dla danej encji A, określenie minimalnej i maksymalnej liczby obiektów innej encji Rys. Przykładowy diagram encja—związek 2 JĘZYK ZAPYTAŃ - wysoki poziom konceptualizacji i abstrakcji deklaracyjny makroskopowy naturalny efektywny (optymalizowany) uniwersalny niezależny od dziedziny zastosowań pozwalający na pracę w trybie interakcyjnym Podstawowa składnia: SELECT [DISTINCT] przecinkowa lista wyrażeń FROM przecinkowa lista tabel [WHERE warunek logiczny] [GROUP BY kryterium grupowania[HAVING warunek logiczny]] [ORDER BY kryterium porządkowania]; Operatory: - porównań - =, >, <, <=, >=, <> != - logiczne – not, and, or - przynależności – [NOT] IN - zawierania – [NOT] BETWEEN - wzorca – [NOT] LIKE - testujący Null – IS [NOT] NULL Relacja – to specyficzny rodzaj tablicy, która - określa pojedynczą jednostkę (entity) świata rzeczywistego - nie zawiera zduplikowanych wierszy tzn. zawsze istnieje klucz główny - kolumny i wiersze są nieuporządkowane ZAPYTANIA Centralną instrukcją języka SQL jest instrukcja służąca do wydobywania informacji z bazy danych. Jest nią instrukcja SELECT, określająca, z jakich relacji (tabel) w bazie danych mają być sprawdzone dane, jakie warunki mają spełniać dane i w jakiej dokładnie postaci mają się pojawić przed użytkownikiem. Instrukcja SELECT składa się z kilku części nazywanych klauzulami (frazami). Ogólna postać: SELECT [DISTINCT] <nazwa atrybutu>./<wyrażenie> [[AS]<alias>],... FROM <nazwa relacji 1>, <nazwa relacji 2>,... [WHERE <nazwa warunku>] [GROUP BY <wyrażenie>/<nazwa atrybutu>,...[HAVING <warunek logiczny>]] [ORDER BY <wyrażenie>/<nazwa atrybutu> [ASC/DESC],...] UWAGA! Powtarzające się krotki (wiersze) relacji nie są automatycznie eliminowane z wyników zapytań. Słowo DISTINCT oznacza eliminację powtarzających się wierszy. W miejscu nazwy atrybutu możne wystąpić wyrażenie. Wyrażeniami na liście SELECT mogą zostać nadane nazwy zastępcze, czyli aliasy. Alias może mieć postać prostego identyfikatora, 3 czyli napisu złożonego z liter, cyfr i znaków podkreślenia albo ograniczonego identyfikatora, czyli dowolnego napisu ograniczonego podwójnym cudzysłowem np. „zarobki pracownika”. W szczególności w odpowiednikiem identyfikatora mogą występować spacje, które są niedozwolone w prostym identyfikatorze. Przykład: Uporządkować listę nazwisk pracowników wraz z identyfikatorami i okresem zatrudnienia w pełnych latach SELECT numer, nazwisko TRUNC (MONTHS_BETWEEN(SYSDATE, data_zatrudnienia)/12) AS zatrudnienie FROM pracownik ORDER BY zatrudnienie DESC; Przy wypisywaniu rezultatów (wyników), jako tytuł kolumny są używane aliasy. Mogą one występować w klauzuli ORDER BY jak w powyższym przykładzie gdzie porządkujemy dane o pracownikach wg stażu pracy. Onie klauzule SELECT i FROM są wymagane w każdym zapytaniu. Zasady wykonania prostego zapytania: 1. 2. 3. 4. 5. Weź relację podaną w klauzuli FROM Jeśli występuje klauzula WHERE, do każdej krotki danej relacji zastosuj warunek logiczny. Pozostaw krotki dające wartości TRUE (usuwając krotki False oraz Null) Do każdej pozostającej krotki oblicz wartości wyrażenia na liście SELECT Jeśli po słowie SELECT występuje DISTINCT usuń duplikaty wśród wynikowych krotek Jeśli występuje klauzula ORDER BY, wykonaj porządkowanie zgodnie ze specyfikacją UWAGA! Specjalna wartość Null – aby wskazać niepełne lub nieznane informację. Ta wartość różna od zera i spacji jest szczególnie użyteczna przy powiązaniu kluczy głównego i obcego. Pojęcie Null nie jest jednak do końca akceptowane. Codd utrzymuje, że wprowadzenie wartości Null do systemu relacyjnego zmienia konwencjonalną logikę dwuwartościową (True, False) na logikę trójwartościową (prawda, fałsz, nieznane). Oto tabelki definiujące operatory logiczne w sytuacji występowania trzech wartości logicznych. OR TRUE FALSE NULL TRUE TRUE TRUE TRUE FALSE TRUE FALSE NULL NULL TRUE NULL NULL AND TRUE FALSE NULL TRUE TRUE FALSE NULL FALSE FALSE FALSE FALSE NULL NULL FALSE NULL NOT TRUE FALSE FALSE TRUE NULL NULL Przy prezentacji danych użyteczną operacją jest reprezentowanie wartości Null jako konkretnej wartości. W ORACLE używamy specjalną funkcję NVL(v1, v2), której wartością jest v2, jeśli v1 jest Null, w przeciwnym razie v1. Np.: NVL (zarobki,0) NVL (stopień, ‘brak’) 4 Klauzula ORDER BY Klauzula ta może występować wyłącznie jako ostatnia klauzula polecenia SELECT. Domyślnie stosuje się narastający porządek sortowania, co w [przypadku liczb oznacza, że mniejsze poprzedzają większe, w przypadku dat, że wcześniejsze poprzedzają późniejsze, natomiast w przypadku łańcuchów znaków, że są one wyświetlane zgodnie z porządkiem alfabetycznym. Liczba atrybutów porządkowania jest jednak ograniczona liczbą atrybutów relacji. Atrybuty wymieniamy kolejno w klauzuli ORDER BY oddzielając je przecinkami. Ich kolejność jest istotna: porządkowanie odbywa się, bowiem najpierw według wartości pierwszego atrybutu, następnie, jeśli wartości te są równe dla dwóch lub więcej krotek, według drugiego atrybutu, itd. Ponadto po każdym z atrybutów porządkowania można użyć słowa kluczowego DESC, które powoduje odwrócenie domyślnego, narastającego porządku na malejący. Użycie atrybutu w klauzuli ORDER BY nie pociąga za sobą konieczności jego użycia w klauzuli SELECT. W klauzuli ORDER BY do wynikowych kolumn można odwołać się używając ich kolejnych numerów 1,2,... Funkcje statyczne (agregujące) związane z grupowaniem: - AVG ([distinct] wyr_licz) – średnia arytmetyczna (wartość Null nie jest brana pod uwagę) COUNT ([distinct] wyr|*) – zliczanie (ile jest wszystkich wierszy w tabeli) MAX ([distinct] wyr) – wartość maksymalna MIN ([distinct] wyr) – wartość minimalna SUM ([distinct] wyr_licz) – suma arytmetyczna Klauzula GROUP BY Umożliwia podział krotek relacji na grupy. Krotki tej samej grupy mają identyczną wartość atrybutu grupowania, który wskazano w klauzuli. Po podziale do każdej z grup można stosować funkcje agregujące. Klauzula GROUP BY może być stosowana rekurencyjnie, co oznacza, że można w niej wskazać wiele, atrybutów grupowania. W takim przypadku jest możliwe wydzielenie podgrupy w ramach wcześniejszej wydzielonej grupy. Kolejność dzielenia relacji na grupy i podgrupy odpowiada kolejności atrybutów grupowania. Przed grupowaniem krotek relacji jest możliwe wykonanie na niej projekcji lub selekcji. Projekcję realizujemy klasycznie – przez wskazanie atrybutów po słowie kluczowym SELECT. Podobnie jest z selekcją, którą realizujemy przez wskazanie warunku (warunków) w klauzuli WHERE. Stosowanie funkcji statycznych w klauzuli SELECT wyklucza możliwość wyprowadzenia wartości atrybutów pojedynczej krotki chyba, że nazwa atrybutu jest wymieniona w klauzuli GROUP BY. W konsekwencji każda nazwa atrybutu występująca na liście SELECT musi także pojawić się w klauzuli GROUP BY, jeśli nie argumentem funkcji statycznych. W szczególności cała relacja (tablica) jest grupą podstawową. Poprawne są zapytania postaci: SELECT COUNT(*) AS „Liczba pracowników” FROM pracownik; SELECT SUM(płaca) AS „Kwota ogółem” FROM pracownik; SELECT id_zesp, COUNT(*) FROM pracownik GROUP BY id_zesp; SELECT etat COUNT(*), AVG(płaca) FROM pracownik WHERE etat!=’DYREKTOR’ GROUP BY etat; 5 SELECT rok, max(data_urodzenia) FROM student GROUP BY rok; SELECT to_char(data_urodzenia,’DAY’), COUNT(*) FROM student GROUP BY to_char(data_urodzenia,’DAY’); SELECT imiona,COUNT(*) FROM student GROUP BY imiona ORDER BY 2; SELECT gr_dziekan,COUNT(*) FROM student WHERE rok=3 and kierunek=’INFORMATYKA’ GROUP BY gr_dziekan; Klauzula HAVING Podobnie jak WHERE umożliwia selekcję informacji. Służy do usuwania z wyniku zapytania nieistotnych grup i na zazwyczaj związek z zastosowaniem wartości funkcji statycznych. * SELECT id_zesp,COUNT(*) FROM pracownik GROUP BY id_zesp HAVING AVG(płaca)>1200; * SELECT p.id_zesp, nazwisko, nazwa FROM pracownik p, zespół z WHERE p.id_zesp=z.id_zesp OTHER BY nazwa, nazwisko; Można dokonać złączenia relacji z nią samą * SELECT p.nazwisko, p.data_zatrudnienia, k.nazwisko, k.data_zatrudnienia FROM pracownik k, pracownik p WHERE p.szef=k.numer and p.data_zatrudnienia<k.data_zatrudnienia; UWAGA! Pojedyncze polecenie SELECT może służyć do połączenia więcej niż dwóch relacji, które zgodnie z ogólnym formatem realizacji połączenia, wskazujemy w klauzuli FROM. Pamiętać należy, że w celu połączenia n relacji jest konieczne określenie, co najmniej n-1 warunków połączenia. Najbardziej naturalnym rodzajem złączenia jest związek klucz głównyklucz obcy. Jednak w ogólności warunek złączenia dwóch lub więcej relacji może być zupełnie dowolny. * SELECT nazwisko, adres, nazwa FROM pracownik p, zespół z WHERE p.id_zesp=z.od_zesp and płaca>1500; * SELECT nazwisko, adres FROM pracownik p, zespół z WHERE adres LIKE ‘Armii Krajowej%’ and p.id_zesp=z.od_zesp ORDER BY nazwisko; Składnia języka SQL ma odzwierciedlenie w algebrze relacyjnej Algebra relacyjna – jest zbiorem kilku operatorów. Każdy operator bierze jedną lub więcej relacji jako argument i produkuje jedną relację jako wynik. Trzema głównymi operatorami algebry relacji są selekcja (ograniczenia), rzut (projekcja), złączanie. Selekcja – jest operatorem, który bierze jedną relację jako swój argument i produkuje w wyniku jedną relację. Składnia operatora selekcji jest następująca: RESTRICT <nazwa relacji (tabeli)> [WHERE <warunek>] ==> <relacja wynikowa> 6 Rzut operatora rzutu bierze jedną relację jako swój argument i produkuje jedną relację wynikową. Rzut jest pionowym ograniczeniem. Składnia operatora jest następująca: PROJECT <nazwa relacji (tabeli)> [<lista kolumn>] ==> <relacja wynikowa> Złączenia (iloczyn kartezjański) są oparte na relacyjnym operatorze iloczynu kartezjańskiego, któremu bezpośrednio odpowiada właściwy operator teorii zbiorów. Brane są dwie relacje jako argumenty i produkowana jedna relacja wynikowa złożona ze wszystkich możliwych kombinacji wierszy (krotek) z wejściowych tabeli. Iloczyn kartezjański jest w praktyce rzadko używanym operatorem i w związku z jego możliwością generowania „eksplozji informacji”. Składnia operatora jest następująca: PRODUCT <relacja> WITH <relacja2> == <relacja wynikowa> Równozłączenie jest iloczynem kartezjańskim, po którym jest wykonana selekcja. Mówiąc dokładnie, łączymy dwie tabele, ale tylko dla wierszy, w których wartości w kolumnach złączenia są takie same. Zakładamy, że klucz główny jednej relacji i klucz obcy drugiej relacji tworzą domyślnie kolumny złączenia. Składnia jest następująca: EQUIJOIN <relacja1> WITH <relacja2> ==> <relacja wynikowa> Złączenie naturalne można zauważyć, że ono nie usuwa powtórzeń kolumny złączenia. Operator złączenia naturalnego jest iloczynem kartezjańskim, po którym następuje selekcja (jak w równozłączeniu) oraz rzut, w którym nie bierze się pod uwagę powtórzeń kolumn złączenia. Złączenie naturalne jest na pewno najpowszechniej używanym w praktyce typem złączenia. Składnia jest następująca. JOIN <relacja1> WITH <relacja2> ON <klucz> == <reacja wynikowa> Złączenia zewnętrzne stosujemy, gdy chcemy zachować w wyniku wszystkie wiersze z obydwu relacji bez względu na to, czy mają odpowiadające sobie wiersze w drugiej relacji, czy nie (wartość NULL). Istnieją trzy typy złączeń zewnętrznych: lewostronne, prawostronne, obustronne. Lewostronne złączenie zewnętrzne zachowuje nie pasujące wiersze w tabeli będącej pierwszym argumentem operatora złączenia. Suma jest operatorem, który bierze dwie zgodne relacje jako swoje argumenty i produkuje jedną relacje wynikową. Przez zgodne relacje rozumiemy, że tabele mają tą strukturę – te same kolumny określone na tych samych dziedzinach. <relacja1> UNION <relacja2> ==> <relacja wynikowa> Przecięcie ma działanie przeciwne do sumy. Suma uwzględnia wszystkie wiersze z obu zbiorów lub relacji przecięcie natomiast uwzględnia w relacji wynikowej tylko wiersze wspólne dla obu tabel. <relacja1> INTERSECTION <relacja2> ==> <relacja wynikowa> Różnica w większości argumentów algebry relacyjnej porządek określenia argumentów jest nieistotny <relacja1> DIFFERENCE <relacja2> ==> <relacja wynikowa> 7 ŁĄCZENIE RELACJI W przypadku, gdy relacja zapytania wymaga dostępu do więcej niż jednej relacji istnieje możliwość połączenia tych relacji z opcjonalnym wykonaniem na nich innych operacji algebry relacji (np. projekcji). Relacje mogą być łączone poziomo lub pionowo. Poziome łączenie relacji polega na utworzeniu relacji wynikowej, której krotki są wynikiem konkatenacji wybranych krotek relacji źródłowych. Najprostszym sposobem poziomego połączenia relacji jest zastosowanie operatora produktu kartezjańskiego. SELECT * FROM pracownik, zespół; W praktyce takie połączenie relacji jest wykonywane rzadko ze względu na duży rozmiar wynikowej tabeli (eksplozja informacji). Znacznie częściej jest stosowane tzw. złącze (ang. JOIN). W tym przypadku krotki jednej relacji są łączone z krotkami innej relacji tylko wtedy, gdy wartości korespondujących atrybutów tych krotek spełniają SELECT nazwisko adres FROM pracownik p, zespół z WHERE adres like ‘Armii Krajowej %’ AND p.id_zesp=z.id_zesp ORDER BY nazwisko; Złączenia zewnętrzne rozszerza rezultat prostego złączenia (nazwanego wewnętrznym) o te krotki a jednej relacji, dla których w trakcie złączenia nie znaleziono odpowiadającym im krotek w drugiej relacji. Warunek złączenia podaje się w postaci: atrybut1 = atrybut2 lub atrybut1 (+)= atrybut2 Przykłady: * Wypisz wszystkich pracowników podając dla każdego z nich nazwę zespołu, w którym pracuje: SELECT numer, nazwisko, nazwa FROM pracownik p, zespół z WHERE p.id_zesp=z.id_zesp (+); * Otrzymujemy informacje o pracownikach ich działach również, gdy pracownik nie ma przyporządkowanego zespołu podawana jest wartość NULL reprezentowana na wydruku przez pusty ciąg znaków. Wypisz nazwy zespołów, które nie zatrudniają pracowników: SELECT z.id_zesp, nazwa FROM pracownik p, zespół z WHERE p.id_zesp(+)=z.id_zesp AND p.numer IS NULL; * Wypisz wszystkie zespoły wraz z sumarycznym wynagrodzeniem(miesięcznie) SELECT z.id_zesp, nazwa,NUL(SUM(płaca_pod)) FROM pracownik p, zespół z WHERE p.id_zesp(+)=z.id_zesp GROUP BY z.id_zesp,nazwa; 8 * Wypisz pracowników i ich przełożonych (szefów) także tych, którzy nie mają przełożonych: SELECT p.numer, p.nazwisko, p.szef,k.nazwisko FROM pracownik p, pracownik k WHERE p.szef=k.szef(+) ORDER BY k.nazwisko; PIONOWE ŁĄCZENIE RELACJI W pionowym łączeniu relacji stosujemy jeden spośród operatorów zbiorowych: suma, przekrój, różnica. Operatory te działają na wynikach, co najmniej dwóch operacji selekcji a zatem zapytanie składa się z dwóch lub więcej poleceń SELECT. Składnia zapytania wykorzystującego operatory zbiorowe może być postaci: SELECT <lista atrybutów/wyrażeń> FROM <nazwa relacji1> [WHERE <warunek logiczny>] operator SELECT <lista atrybutów/wyrażeń> FROM <nazwa relacji1> [WHERE <warunek logiczny2>] [ORDER BY 1,...,n]; gdzie operator przyjmuje jedną z wartości UNION, UNION ALL, INTERSECT, MINUS UWAGI: * zastosowanie operatora UNION powoduje wyeliminowanie z wyniku zapytania krotek o takich samych wartościach atrybutów wyznaczonych przez połączenie tym operatorem zapytania * natomiast UNION ALL spowoduje, że w wyniku zapytania pojawią się wszystkie krotki * w łączonych operatorami zbiorowymi klauzulach SELECT musi występować ta sama liczba atrybutów oraz typy odpowiadających sobie atrybutów (tj. atrybutów SELECT różnych klauzul muszą być równe, zgodne) * w wyniku zapytania pojawiają się nazwy atrybutów wyłącznie z pierwszej klauzuli SELECT * połączone operatorami zbiorowymi polecenia SELECT są wykonywane w kolejności ich występowania (od góry do dołu) * jeżeli istnieje potrzeba użycia klauzuli ORDER BY bo musi ona występować jako ostatnia klauzula zapytania * w klauzuli ORDER BY nie stosujemy nazw atrybutów, lecz ich numery porządkowe Przykłady: SELECT nazwisko || ‘*’ FROM pracownik WHERE id_zesp=10 UNION SELECT nazwisko FROM pracownik WHERE id_zesp<>10 ORDER BY 1; 9 SELECT etat FROM pracownik WHERE id_zesp=30 UNION SELECT etat FROM pracownik WHERE id_zesp=10; SELECT nazwisko, płaca_pod, ‘Powyżej’ PŁACA FROM pracownik WHERE płaca_pod>1500 UNION SELECT nazwisko, płaca_pod, ‘1500’ PŁACA FROM pracownik WHERE płaca_pod=1500 UNION SELECT nazwisko, płaca_pod, ‘Poniżej’ PŁACA FROM pracownik płaca_pod<1500 ORDER BY 2; SELECT id_zesp FROM zespół MINUS SELECT id_zesp FROM pracownik; SELECT z.id_zesp, z.nazwa FROM zespół z, pracownik p WHERE p.id_zesp(+)=z.id_zesp MINUS SELECT z.id_zesp, z.nazwa FROM zespół z, pracownik p WHERE p.id_zesp=z.id_zesp; PODZAPYTANIA ZAGNIEŻDŻONE Wewnątrz klauzuli WHERE, HAVING a także FROM mogą występować podzapytania, mające taką samą postać jak zapytania, ale ujęte w nawiasy Ogólna postać zagnieżdżenia zapytań w klauzuli WHERE: SELECT <lista atrybutów/wyrażeń> FROM <nazwa relacji1> WHERE <nazwa atrybutu/lista atrybutów> <OPERATOR> (SELECT <lista atrybutów/wyrażeń> FROM <nazwa relacji2> WHERE <nazwa atrybutu/lista atrybutów> <OPERATOR> (SELECT <lista atrybutów/wyrażeń> FROM <nazwa relacji3> [...])) Mamy doczynienia z zapytaniem zewnętrznym i podzapytaniem - zapytaniem wewnętrznym. W podstawowym trybie zagnieżdżenia (niekorelowanym) podpytanie jest wykonywane jako pierwsze jednokrotnie a jego wyniki są przekazywane do zapytania zewnętrznego. Przykłady: SELECT * FROM pracownik WHERE płaca_pod (SELECT MIN(płaca_pod) FROM pracownik); 10 SELECT nazwisko etat FROM pracownik WHERE etat=(SELECT etat FROM pracownik WHERE nazwisko=’KOLSKI’); Wyszukuje pracowników zatrudnioych na tym etacie co KOLSKI W przypadku gdy podzapytanie wyznacza dokładnie jedną krotkę stosujemy tradycyjne operatory =,<,>,... gdy podzapytanie wyznacza więcej niż jedną krotkę stosujemy operator IN znany wcześniej a także nowe operatory ANY, ALL wraz z operatorami porównania. Operator ANY powoduje porównanie pojedynczej wartości (umieszczonej po jego lewej stronie) z każdą wartością wyznaczaną przez podzapytanie. Warunek selekcji zapytania zewnętrznego jest spełniony, jeżeli lista wartości wyznaczonych przez podzapytanie zawiera, choć jeden element spełniający ten warunek. Operator ALL powoduje porównanie pojedynczej wartości z każdą wartością wyznaczoną przez podzapytanie. Warunek selekcji zapytania zewnętrznego jest spełniony, jeżeli wszystkie wartości listy spełniają ten warunek. Przykłady: Podzapytania zwracające wiele krotek. Odnalezienie kolegów z danej grupy: SELECT nazwisko, rok, gr_dziekan FROM student WHERE (rok,gr_dziekan) IN (SELECT rok, gr_dziekan FROM student WHERE nazwisko LIKE upper(‘&wzorzec.nazw’) AND imiona LIKE upper(‘&wzorzec_im’)); Wyliczamy min płace podstawowe w ramach grup (zespołów) SELECT * FROM pracownik WHERE (płaca_pod, id_zesp) IN (SELECT MIN(płaca_pod), id_zesp FROM pracownik GROUP BY id_zesp); Wybieramy płace_pod bez powtórzeń i porównane – dowiadujemy się nazw. Pracownika który ma płace w zespole 10 SELECT nazwisko, płaca_pod, id_zesp FROM pracownik WHERE płaca_pod>ANY (SELECT DISTINCT płaca_pod FROM pracownik WHERE id_zesp=10); SELECT nazwisko, płaca_pod, id_zesp FROM pracownik WHERE płaca_pod>ALL (SELECT DISTINCT płaca_pod FROM pracownik WHERE id_zesp=30); SELECT nazwisko, płaca_pod FROM pracownik WHERE płaca_pod>ALL (SELECT płaca_pod FROM pracownik p, zespół z WHERE nazwa=’ADMINISTRACJA’ AND p.id_zesp=z.id_zesp) ORDER BY nazwisko; 11 Klauzula HAVING z zagnieżdżonymi zapytaniami SELECT etat, AVG (płaca_pod) FROM pracownik HAVING AVG (płaca_pod)> (SELECT AVG(płaca_pod) FROM pracownik WHERE etat=’DYREKTOR’ GROUP BY etat); SELECT etat, AVG (płaca_pod) FROM pracownik HAVING AVG (płaca_pod) (SELECT MIN(AVG(płaca_pod)) FROM pracownik GROUP BY etat) GROUP BY etat; SELECT id_zesp, nazwa FROM zespół WHERE id_zesp= (SELECT id_zesp FROM pracownik GROUP BY id_zesp HAVING SUM(płaca_pod)= (SELECT MAX(SUM(płaca_pod)) FROM pracownik GROUP BY id_zesp)); SELECT mimiona, rok, count(*) FROM student WHERE rok=&&liczba GROUP BY imiona,rok HAVING count(*)= (SELECT max(count(*)) FROM student WHERE rok=&&liczba GROUP BY imiona,rok); && - zmienna globalna SELECT a.id_zesp „Zespół”, TRUNC (100*a.liczba_płac/b.liczba_płac,1) AS „% Pracowników”, TRUNC (100*a.suma_wyn/b.liczba_wyn,1) AS „% Wynagrodzenia” FROM (SELECT id_zesp, count(*) AS Licdzba_prac, SUM(płaca_pod) AS suma_wyn FROM pracownik GROUP BY id_zesp) a, (SELECT count(*) AS liczba_płac, SUM(płaca_pod) AS suma_wyn FROM pracownik) b; ZAPYTANIA SKORELOWANE Zwykłe zapytanie jest wykonywane raz, na samym początku, a do jego wyników odwołuje się zapytanie zewnętrzne. W przypadku zapytania skorelowanego podzapytanie jest wykonywane dla każdego wiersza z zapytania zewnętrznego. Jedynym elementem składowym różniącym zapytane skorelowane od nieskorelowanych jest konieczność zastosowania aliasów relacji, na których operuje zapytanie zewnętrzne i odwołania się do nich w podzapytaniu. 12 Przykłady: Otrzymamy nazwisko, płace podstawową, etat gdzie płaca_pod jest większa od średniej arytmetycznej w ramach tego samego etatu SELECT nazwisko, płaca_pod, etat FROM pracownik p WHERE praca_pod > (SELECT AVG (płaca_pod) FROM pracownik WHERE etat=p.etet); Nazwiska, które się powtarzają SELECT nazwisko FROM pracownik p WHERE 1<(SELECT COUNT (*) FROM pracownik WHERE nazwisko=p.nazwisko); Otrzymamy nazwiska i płace, którego płaca jest największa i druga w kolejności SELECT nazwisko, płaca_pod FROM pracownik p WHERE 1<(SELECT COUNT (DISTINCT płaca_pod) FROM pracownik WHERE płaca_pod>p.płaca_pod); SELECT nazwisko, id_zesp FROM pracownik p WHERE EXISTS (SELECT mumer FROM pracownik WHERE pracownik.szef=p.numer); SELECT numer, nazwisko, etat FROM pracownik p WHERE NOT EXISTS (SELECT numer FROM pracownik WHERE etat=p.etat AND numer!=p.numer); SELECT nazwisko, id_zesp FROM zespół z WHERE NOT EXISTS (SELECT 1 FROM pracownik p WHERE p.id_zesp=z.id_zesp); NIEKTÓRE SPOTYKANE TYPY DANYCH znakowe typy danych – character lub char (typ o stałej długości); variable character lub varchar (typ o zmiennej długości) całkowitoliczbowe typy danych – numer, integer, int, smallint, tinyint dziesiętne typy danych – decimal, numeric, real, double, double precision, float, smallfloat datowy I czasowy typ danych – służą do przechowywania daty, czasu oraz kombinacji daty i czasu; (niekiedy jest dostępny typ przedział czasu); date, time, datetime, interval binarne typy danych – służą do przechowywania kodu, obrazów: text, blob, longblob pseudoatrybuty – rowid (fizyczny adres wiersza w tabeli), rownum (ilość zwracanych wierszy z zapytania) JĘZYK DEFINIOWANIA DANYCH TWORZENIE RELACJI Polecenie CREATE TABLE o następującym formacie ogólnym: CREATE TABLE <nazwa relacji> (<nazwa atrybutu 1><typ atrybutu 1>(<rozmiar>) [DEFAULT <wartość domyśłna>] 13 [[CONSTRAINT <nazwa ograniczenia 1>] <ograniczenie atrybutu 1>], ..., <nazwa atrybutu k><typ atrybutu k>(<rozmiar>) [DEFAULT <wartość domyśłna>] [[CONSTRAINT <nazwa ograniczenia k>] <ograniczenie atrybutu k>], ... [[CONSTRAINT <nazwa ograniczenia>] <ograniczenie relacji>]); W języku SQL wyróżniamy następujące typy atrybutów: NUMBER – liczby zapisane za pomocą cyfr (0-9), opcjonalnego znaku (+,-) oraz opcjonalnej kropki dziesiętnej. Rozmiar liczby nie może być większy od 38 cyfr. NUMBER (r) – j.w., z zastrzeżeniem, że rozmiar liczby nie może być większy od r znaków NUMBER (r,n) – j.w., dodatkowo n określa liczbę cyfr po przecinku. Jeśli n jest liczbą ujemną, wówczas wartość atrybutu jest zaokrąglona do n miejsc po przecinku CHAR (r) – łańcuchy znakowe, składające się z dużych i małych liter, cyfr, znaków specjalnych (+,-,%,$,&, etc.) r może przyjmować wartości całkowite od 1 do 255 VARCHAR2 (r) – łańcuchy znakowe, składające się z dużych i małych liter, cyfr, znaków specjalnych, r oznacza maksymalną długość łańcucha i może przyjmować wartości całkowite od 1 do 2000. Ten typ danych umożliwia przechowywanie łańcuchów znakowych z zmiennej długości. Oznacza to, że wartości tego atrybutu zajmują w bazie danych tyle miejsca, ile faktycznie wynosi ich długość. VARCHAR (r) – podobnie jak VARCHAR2. Zaleca się stosowanie VARCHAR2 dla atrybutów o zmiennej długości, ponieważ w kolejnych wersjach ORACLE semantyka tego typu może się zmienić. DATE – data z przedziału od 1 stycznia 4712 p.n.e. do 31 grudnia 4712 n.e. LONG – tak jak char, przy czym maksymalna długość łańcucha wynosi 2 GB. Wykorzystanie atrybutów tego typu w poleceniach SQL podlega pewnym ograniczeniom LONG RAW – tak jak LONG, ale wykonywany do przechowywania danych dowolnego typu (tj. nie tylko znaków) np. dźwięków, obrazów. Opcjonalnie po typie atrybutu podajemy ograniczenie integralnościowe atrybutu: NULL – umożliwia nadawanie atrybutowi wartości pustych NOT NULL –uniemożliwia nadawanie atrybutowi wartości pustych UNQUE – definiuje atrybut, który pełni rolę klucza unikalnego relacji. Wartość tak zdefiniowanego atrybutu jest unikalna dla wszystkich krotek relacji PRIMARY KEY – definiuje atrybut, który pełni rolę klucza podstawowego relacji Jeżeli dla atrybutu zdefiniować UNIQUE, to nie można dla tego atrybutu zdefiniować równocześnie ograniczenia PRIMARY KEY i odwrotnie. Zdefiniowanie ograniczenia UNIQUE lub PRIMARY KEY uniemożliwia nadanie atrybutowi wartości pustych REFERENCES – określa tzw. ograniczenie referencyjne tj. referencję do klucza podstawowego lub unikalnego innej relacji. Ograniczenie to jest wykorzystywane do definiowania tzw. klucza obcego relacji. Atrybut będący kluczem obcym nie może przyjmować wartości, których nie przyjmuje odpowiedni mu klucz. 14 ON DELETE CASCADE – ograniczenie to definiuje się dla klucza obcego. Działanie tego ograniczenia jest następujące: jeśli zostanie usunięta krotka z relacji z kluczem podstawowym, to automatycznie są usuwane te krotki z relacji z kluczem obcym, dla których wartości klucza obcego jest równa wartości klucza podstawowego usuwanej krotki. CHECK – określa warunek, który musi być spełniony przez wszystkie wartości atrybutu. W definicji tego ograniczenia można wykorzystać operatory =,>,<,!=, IS NOT NULL, LIKE BETWEEN, ..AND..IN oraz operatory logiczne AND, OR, NOT Opcjonalnie jako ostatni element definicji relacji określa się ograniczenia integralnościowe relacji. Różnią się one od ograniczeń atrybutów tym, że mogą odwoływać się do więcej niż jednego atrybutu relacji. Można zdefiniować następujące ograniczenia tego typu: UNIQUE, PRIMARY KEY, REFERENCE, ON DELETE CASCADE, CHECK ich znaczenie jest takie samo jak znaczenie odpowiadających im ograniczeń integralonościowych atrybutu. Dodatkowo dla relacji istnieje ograniczenie FOREIGN KEY, umożliwiające zdefiniowanie klucza obcego relacji złożonego z wielu sygn? Każdemu z ograniczeń można opcjonalnie przypisać nazwę poprzedzając ją słowem kluczowym CONSTRAINT. Jeśli nazwa nie zostanie jawnie nadana ograniczeniu, to SLBD określi ją dla niego domyślnie nazwę SYS_cn gdzie n oznacza numer ograniczenia. Przykłady: CREATE TABLE dydaktycy (id_dydakt NUMBER(2) CONSTRAINT id_dydakt_pk PRIMARY KEY, nazwisko VARCHAR (15) NOT NULL, tytuł VARCHAR2 (10) NOT NULL); Tabela składająca się z 3 kolumn, pierwsza kolumna typu liczb, druga i trzecia typu tekst. Pierwszy atrybut to klucz główny (wartości nie mogą być puste), nazwisko i tytuł nie mogą być puste. CREATE TABLE przedmioty ( id_przedm NUMBER(2) CONSTRAINT id_przedm_pk PRIMARY KEY, nazwa VARCHAR2 (15) NOT NULL); CREATE TABLE zajęcia ( id_zajęć NUMBER (2) CONSTRAINT id_zajęc_pk PRIMARY KEY, Rodzaj_zaj VARCHAR2 (15) CONSTRAINT rodzaj_zaj_chk CHECK (rodzaj_zaj [‘WYKŁAD’, ’LABORATORIUM’, ’PROJEKT’]), id_dydakt NUMBER (2) NOT NULL id_przedm NUMBER (2) NOT NULL, FOREIGN KEY (id_dydakt +) REFERENCES dydaktycy (id_dydakt) ON DELETE CASCADE, FOREIGN KEY (id_przedm) REFERENCES przedmiot (id_przedm)); 4 kolumny: 1 – identyfikator zajęć (klucz główny), 2 – rodzaj zajęć typu tekst 15 znaków jeszcze określony CONSTRAINT i warunek CHECK dotyczy rodzaju zajęć IN (przynależy) do zbioru wartości (wykład, lab, projekt) wpisując nie przyjmie innego tekstu, 3 – klucz obcy z tabeli dydaktycy, 4 – klucz obcy z tabeli przedmiot (identyfikator 15 przedmiotu) Na końcu określamy, że są to klucze obce i warunek, że jeśli usuwamy z pierwszej tabeli automatycznie usuwane są odnośniki z drugiej tabeli. Przy tworzeniu najpierw musi zaistnieć tabela, do której będą odniesienia. CREATE TABLE działy ( id_działu NUMBER (3) PRIMARY KEY, nazwa_działu VARCHAR2 (20) NOT NULL UNIQUE Miejsce VARCHAR2 (50)); Jawnie nie ma żadnych kontrastów, są ograniczenia. Nazwa działy nie może być pusta i nie może się powtarzać. CREATE TABLE pracownicy ( Id_pracownika NUMBER (10) PRIMARY KEY, Nazwisko VARCHAR2 (20) NOT NULL, Stanowisko VARCHAR2 (9), Kierownik NUMBER (6) REFERENCES pracownicy, Data_zatrudnienia DATE, Zarobki NUMBER (8,2), Premia NUMBER (8,2), Id_działu NUMBER (3) PEFERENCES działy, CHECK (premia<zarobki)); Jeśli wartość zależy od dwóch pół to musi być umieszczona po zdefiniowaniu obu tabel. Tabela ta połączona jest sama ze sobą CREATE TABLE zaszeregowanie ( Grupa NUMBER (2) PRIMARY KEY, Dolne NUMBER (8,2) NOT NULL, Górne NUMBER (8,2) NOT NULL, CHECK (dolne<górne)); WYPEŁNIENIE TABEL W celu utworzenia relacji i jednoczesnego wypełnienia jej danymi zawartymi w innych już istniejących relacjach, udostępniono alternatywny format polecenia CREATE TABLE. CREATE TABLE <nazwa relacji> [(<nazwa atrybutu 1>[DEFAULT <wartość domyślna>] [NULL/NOT NULL]...)] AS SELECT <klauzula select> Opcjonalny fragment polecenia umożliwia nadanie nazw atrybutom nowej relacji. W przypadku jego pominięcia przyjmowane są nazwy zgodne z nazwami zawartymi w klauzuli SELECT. CREATE TABLE lista_płac ( Id_pracownika NOT NULL nazwisko NOT NULL, Pensje DEFAULT 750 NOT NULL) AS SELECT id_pracownika, nazwisko, zarobki+pensja FROM pracownik; 16 Automatycznie zostanie utworzona tabela o 3 atryn. o danych nazwach i wypełniona danymi. PRZYKŁADY POZWALAJĄCE ZMIENIĆ SCHEMAT TABELI AKTUALIZACJA SCHEMATU RELACJI 1. Dodanie nowego atrybutu: ALTER TABLE <nazwa relacji> ADD (<nazwa atrybutu> <typ atrybutu> (<rozmiar>) [DEFAULT <wartość domyślna>] [[CONSTRAINT <nazwa ograniczenia>] <ograniczenie atrybutu>]); 2. Zmodyfikowanie istniejącego atrybutu: ALTER TABLE <nazwa relacji> MODIFY (<nazwa atrybutu> <typ atrybutu> (<rozmiar>) [DEFAULT <wartość domyślna>] [NULL / NOT NULL]); 3. Dodanie ograniczenia integralnego: ALTER TABLE <nazwa relacji> ADD [CONSTRAINT <nazwa ograniczenia>] <ograniczenie relacji>; 4. Kasowanie kolumn: ALERT TABLE <nazwa relacji> DROP <nazwa kolumny> Przykłady ALERT TABLE moja DROP (k1); ALERT TABLE moja DROP COLUMN k1; ALERT TABLE pracownik ADD (tytuł_naukowy VARCHAR2(10)); ALERT TABLE pracownik MODIFY (tytuł_naukowy VARCHAR2 (15) DEFAULT ‘mgr inż.’ NOT NULL); ALERT TABLE pracownik ADD (CONSTRAINT etat_chk CHECK (etat IN (‘DYREKTOR’, ’PROFESOR’, ’ADIUNKT’, ’STAŻYSTA’, ’SEKRETARKA’))); ALERT TABLE pracownik ADD (CONSTRAINT prac_fk FOREIGN KEY (Id_działu) REFERENCES dział (id_działu)); 17 Możliwe jest czasowe wyłączenie lub uaktywnianie ograniczenia integralnościowego stosując klauzulę DISABLE lub ENABLE ALERT TABLE <nazwa relacji> DISABLE/ ENABLE <rodzaj ograniczenia> /CONSTRAINT <nazwa ograniczenia> [CASCADE]; - gdzie rodzaj ograniczenia przyjmuje jedną z trzech wartości: INIQUE, PRIMARY KEY, ALL TIGGERS - opcjonalne słowo CASCADE powoduje odpowiednio wyłączenie lub uaktualnienie wszystkich pozostałych ograniczeń, których działanie zależy od wyłączonego lub uaktywnionego ograniczenia - ALL TIGGERS powoduje czasowe wyłączenie lub uaktywnienie wszystkich wyzwalaczy zdefiniowanych dla relacji Ograniczenie integralnościowe może również zostać usunięte z bazy danych ALERT TABLE <nazwa relacji> DROP <rodzaj ograniczenia>/ CONSTRAINT <nazwa ograniczenia> [CASCADE]; - gdzie rodzaj ograniczenia przyjmuje jedną z dwóch wartości PRIMARY KEY, UNIQUE opcjonalne słowo CASCADE umożliwia usunięcie wszystkich pozostałych ograniczeń, których działanie zależy od usuwanego ograniczenia Przykłądy ALERT TABLE zajęcia DISABLE CONSTRAINT rodzaj_zaj_chk; ALERT TABLE zajęcia DISABLE PRIMARY KEY; ALERT TABLE pracownik DROP CONSTRAINT etst_chk; ALERT TABLE zajęcia DROP PRIMARY KEY; Uwagi! Modyfikacja schematu relacji jest jednak bardzo ograniczona. Nie dopuszcza się zmiany atrybutu, który wcześniej został zadeklarowany jako atrybut mogący przyjmować wartości puste tj. atrybut z ograniczeniem (NULL), na atrybut nie pusty (NOT NULL), jeśli w relacji istnieje, co najmniej jedna krotka o pustej wartości tego atrybutu. Ponadto, bardzo ograniczone jest zmniejszenie rozmiaru atrybutu (a dokładniej rozmiaru jego typu), które jest dopuszczalne jedynie w przypadku, gdy wszystkie krotki zawarte w relacji o modyfikowanym schemacie przyjmują wartości tego atrybutu. Polecenie DESCRIBE <nazwa relacji>; Zmiana nazwy relacji: RENAME <strata nazwa relacji> TO <nowa nazwa relacji> Usuwanie relacji: DROP TABLE <nazwa relacji> [CASCADE CONTRAINT]; 18 - gdzie CASCADE CONSTRAINT jest opcjonalną klauzulą umożliwiającą usunięcie ograniczeń integralnościowych w innych relacjach, które w swojej definicji wykorzystują atrybuty kluczowe i unikalne usuwanej relacji usunąć relację może wyłącznie jej właściciel, tzn. użytkownik który ją utworzył operacje usuwania relacji w ogólności może doprowadzić do błędów w sesjach użytkowników odwołujących się do niej w późniejszym czasie, w sposób bezpośredni lub przez bazujące na niej perspektywy - AKTUALIZACJA ZAWARTOŚCI RELACJI TABELI DML – język poleceń manipulowania danymi Dopisywanie nowych krotek Wstawiane krotki mogą być wynikiem zapytania SELECT, a więc w ogólności mogą pochodzić z innych relacji. Postać polecenia będzie miała postać: INSERT INTO <nazwa relacji> [(lista atrybutów)] SELECT <lista atrybutów> FROM ...; Dopisanie jednej krotki to postać: INSERT INTO <nazwa relacji> [(lista atrybutów)] VALUES (wartość 1, wartość 2...); Opcjonalna lista atrybutów jest zbędna w przypadku wprowadzenia wszystkich atrybutów danej relacji. Modyfikowanie istniejących krotek: UPDATE <nazwa relacji> [alias] SET <nazwa atrybutu 1> [, nazwa atrybutu 2] = {wyrażenie podzapytanie} [WHERE <warunek logiczny>]; Usuwanie krotek z relacji: DELETE FROM <nazwa relacji> [WHERE <warunek ligiczny>]; Przykłady: INSERT INTO zajęcia VALUES (5,’LABORATORIUM’,10,12); INSERT INTO pracownik SELECT * FROM pracownik@ baza.zgoda.bytom.pl; UPDATE pracownik SET płaca_pod = (SELECT płaca_pod FROM dodatki d WHERE d.numer=pracownik.numer) WHERE numer IN (SELECT numer FROM dodatki); UPDATE pracownik SET 19 płaca_pod = (SELECT avg(płaca_pod) FROM pracownik WHERE numer IN (SELECT numer FROM pracownik WHERE płaca_pod= (SELECT min(płaca_pod) FROM pracownik))); UPDATE pracownik a SET (a.płaca_pod, a.płaca_dod)= (SELECT avg(płaca_pod)*1.2 max(nvl(płaca_dod,0)) FROM pracownik WHERE id_zesp=a.id.zesp) WHERE a.pracuje_od>’89/12/31’; DELETE FROM pracownik WHERE stanowisko IS NULL; Dostęp do perspektywy odbywa się zgodnie z ogólnymi zasadami dostępu do relacji wa więc: - za pomocą polecenia SELECT, w którego klauzuli FROM użyto nazwę perspektywy - poleceń INSERT UPDATE DELETE jeżeli perspektywa umożliwia modyfikowanie zawartości relacji na których bazuje W zależności od sposobu zdefiniowania perspektywy zwykle wyróżnia się perspektywy proste i złożone. Perspektywa prosta charakteryzuje się tym, że udostępnia dane z pojedynczej relacji, a w jej definicji nie stosuje się operacji na zbiorach funkcji ani też grupowania krotek. Ogólny format jest postaci: CREATE [OR REPLACE] VIEW <nazwa perspektywy> [(lista atrybutów)] AS SELECT … [WITH CHECK OPTION]; - opcjolnalna klauzula OR REPLACE zastępuje istniejącą perspektywę nową definicją dla wyrażeń wykorzystanych w poleceniu SELECT (np. sum(płaca_pod), nvl (płaca_dod,0)) należy określić aliasy lub nazwy odpowiadających im atrybutów perspektywy. Usunięcie perspektywy DROP VIEW <nazwa perspektywy> Przykłady: CREATE VIEW asystenci AS SELECT numer, nazwisko FROM pracownik WHERE etat=’ASYSTENT’; CREATE VIEW klientki AS SELECT * FROM klient WHERE płeć=’kobieta’; CREAT VIEW stat_zespół (nazwa, płaca_min, płaca_max, płaca_przec) AS SELECT nazwa MIN(płaca_pod), MAX(płaca_pod), AVG(płaca_pod) FROM pracownik, zespół WHERE pracownik.id_zesp=zsespół.id_zesp GROUP BY nazwa; CREAT VIEW ed 20 AS SELECT numer, nazwisko, p.id_zesp, adres FROM pracownik p, zespół z WHERE p.id_zesp=z.id_zesp; Możliwe są zmiany (INSERT, DELETE, UPDATE) w odniesieniu do tabeli pracownik, ale nie w odniesieniu do tabeli zespół CREATE OR REPLACE VIEW adiunkci AS SELECT numer, nazwisko, etat FROM pracownik WHERE etat=’ADIUNKT’ WITH CHECK OPTION; CREATE VIEW szefowie AS SELECT nazwisko, nazwa FROM pracownik p, zespół z WHERE numer IN (SELECT DISTINCT szef FROM pracownik ) AND p.id_zesp=z.id_zesp; CREATE VIEW pr_urlop_bezp AS SELECT * FROM pracownik WHERE płaca_pod=0 OR płaca_pod IS NULL WITH CHECK OPTION: LICZNIKI SEKWENCJE W systemie Oracle jest specjalna sekwencja – sekwencja (przechowywana jako obiekt w bazie danych), która służy do generowania jednoznacznych wartości dla kluczy głównych i unikalnych. Składnia jest postaci: CREATE SEQUENCE [nazwa użytkownika] <nazwa licznika> [INCREMENT BY <liczba>] [START WITH <wartość początkowa>] [CYCLE/NO CYCLE]; - nazwa użytkownika jest opcjonalnym parametrem określającym użytkownika który utworzył licznik INCREMENT BY jest opcjonalnym parametrem określającym wartość, o jaką będzie zwiększany licznik po każdym odczycie. Liczba może być ujemna START WITH jest opcjonalnym parametrem określającym początkową wartość licznika CYCLE/NO CYCLE jest opcjonalnym parametrem określającym czy po osiągnięciu wartości maksymalnej licznik rozpocznie zliczanie od wartości początkowej (cycle) czy też nie; domyślnie jest przyjmowana opcja no cycle. Sekwencji używa się ze składnią: <nazwa sekwencji>.NEXTVAL – generowanie kolejnej wartości <nazwa sekwencji>.CURRVAL – ostatnio wygenerowana wartość Przykłady: 21 CREATE SEQUENCE prac_seq INCREMENT BY 10 START WITH 1000; INSERT INTO pracownik VALVES (prac_seq.NEXTVAL,’stec’, ’RADCA PRAWNY’,NULL, ‘90/01/20’, 1200, 0, 10); Instrukcja: DROP SEQUENCE <nazwa sekwencji>; usuwa sekwencje. INDEKSY Tworzenie indeksów: CREATE [UNIQUE] INDEX <nazwa indeksu> ON <nazwa relacji> (nazwa atrybutu 1 [nazwa atrybutu 2]...); Po utworzeniu indeksu jest on stosowany w sposób automatyczny przez SZBD, każdorazowo wtedy, gdy wymaga tego strategia optymalizacji realizacji zapytań. Oznacza to, że użytkownik nie musi być świadomy istnienia indeksu, jak również wykorzystania indeksu przy realizacji jego określonych poleceń. Uwaga! - indeksy zajmują miejsce w bazie danych - kiedy wprowadzamy, modyfikujemy lub usuwamy dane z indeksowanej SZBD musi aktualizować indeksy może to spowalniać przeprowadzaną operację - w praktyce nie ma sensu zakładania indeksów na małych relacjach gdyż nie powoduje to odczuwalnej poprawy efektywności - dobrą zasadą jest tworzenie indeksów dla kluczy obcych oraz na atrybutach często stosowanych w klauzulach WHERE zapytań i na atrybutach połączeniowych relacji - indeksy zdecydowanie przyspieszają dostęp do danych Przykłady: CREATE UNIQUE INDEX idn_zespół ON pracownik (id_zesp); CREATE UNIQUE INDEX idn_nazwisko ON pracownik (nazwisko); Indeks można usunąć: DROP INDEX <nazwa indeksu>; SŁOWNIK DANYCH Słownik danych jest zbiorem informacji o obiektach bazy danych. Jest używany zarówno przez system zarządzania baz danych jak i przez użytkowników. Użytkownik ma uprawnienie tylko do odczytu informacji ze słownika danych. Słownik danych ma postać zbioru tabel i perspektyw. Oto przykładowe perspektywy słownika danych Oracle: 1. z przedrostkiem User – informacja o wszystkich obiektach, których dany użytkownik jest właścicielem: User_Tables, User_Constraint, User_Sequences, User_Views, User_Indexes, User_Triggers, User_Sources, User_Objects 2. z przedrostkiem All – dotyczy wszystkich obiektów do których użytkownik ma uprawnienia 22 3. z przedrostkiem Dba – informacja o obiektach dostępnych dla administratorów systemu UŻYTKOWNICY I UPRAWNIENIA Każdy, kto rozpoczyna pracę z bazą danych, Oracle musi być zdefiniowany poprzez podanie identyfikatora i hasło, aby móc wykonywać określone czynności (operacje). Za zarządzanie użytkownikami ich uprawnieniami i zasobami odpowiedzialny jest administrator. Może on: - tworzyć i usuwać użytkownika - definiować uprawnienia - ograniczać ilościowe zasoby użytkownika Tworzenie użytkownika: CREATE USER <nazwa użytkownika> IDENTIFIED BY <hasło użytkownika>; Usuwanie użytkownika: DROP USER <nazwa użytkownika>; Uprawnienia w bazie danych W bazie danych Oracle istnieją dwa typy uprawnień: 1. uprawnienia systemowe – prawo do wykonania określonej czynności lub wykonanie pewnych czynności na określonym typie obiektów 2. uprawniania obiektowe – prawo do wykonywania określonej czynności na konkretnym obiekcie Predefiniowane role to: CONNECT – możność połączenia do systemu Oracle RESOURCE – możność tworzenia tabel, sekwencji, indeksów i innych obiektów DBA – możność powołania innych użytkowników, niepełna możność administrowania cudzymi obiektami Transakcje – zdarzenia które powodują zmianę stanu są w terminologii baz danych nazywane transakcjami. Użytkownik realizuje swoje transakcje albo poprzez polecenia języka SQL. Kierowanie bezpośrednio albo pośrednio przy użyciu wcześniej przygotowanych aplikacji bazodaniowych. Przykłady: - przelew kwoty z konta na konto - system rezerwacji biletów lotniczych (połączenia) - wysyłkowa sprzedaż Każda transakcja powinna mieć właściwości ACID = atonowość, spójność, izolacyjność i trwałość. INTEGRALNOŚĆ 23 Ogólnym celem integralności jest zapewnienie, aby baza danych była dokładnym odzwierciedleniem świata rzeczywistego, który reprezentuje. W środowiskach z wieloma użytkownikami zapewnienie integralności jest również sprawą fizycznego wymiaru systemu baz danych. Jądro systemu SZBD zajmuje się problemami sprzętu i oprogramowania a także rozdziałem zasobów między wielu użytkowników. Zarządzanie transakcjami dotyczy współbieżności dostępu do bazy danych i zapewnienie spójności bazy danych. WSPÓŁBIEŻNOŚĆ Jeśli do bazy danych ma jednocześnie dostęp wielu użytkowników lub aplikacji mówi się, iż ich transakcje są wykonywane współbieżnie. Transakcje współbieżne mogą być przeprowadzane na jeden z dwóch sposobów: szeregowo lub równolegle. Serializowane transakcje BLOKADY Blokady (zamki): - do odczytu - do zapisu - wspólne Blokady mogą być stosowane w różnym stopniu szczegółowości: - na poziomie tabeli - stron - rekordów - pól w rekordach ZAKLESZCZANIE Jest stanem w którym dwie lub więcej transakcji blokuje sobie wzajemnie zasoby. Oznacza to że żadna z transakcji nie może kontynuować pracy. POZIOMY IZOLACJI Efekty: - fantom - niepowtarzalny odczyt - brudny odczyt TRANSAKCJE W ORACLE W Oracle 8 transakcja jest logiczną jednostką działania składająca się z jednej lub wielu poleceń SQL. Każda transakcja rozpoczyna się w momencie wprowadzania pierwszej poprawki instrukcji SQL: Kiesy transakcja rozpoczyna się system przypisuje jej segment wycofania. W segmencie tym zapisane są dane pochodzące z momentu poprzedzającego ich zmianę przez transakcje. Dzięki tym informacjom transakcje może zostać wycofana a dane znajdujące się w bazie danych przed rozpoczęciem transakcji odtworzone. Zakończenie transakcji następuje w wyniku: - wydania polecenia COMMIT lub ROLLBACK - wykonania jednej z instrukcji CREATE, DROP, ALERT - zakończenia sesji użytkownika z serwerem - anormalnego zerwania sesji użytkownika 24 Możliwe jest również dzielenie dłuższych transakcji na mniejsze poprzez deklarowanie znaczników pośrednich SAVEPOINT znacznik; Umożliwia to wycofanie w razie błędów jedynie fragmentu transakcji i ponownie próby jego wykonania bez powtórzenia całej transakcji od początku. Częściowe cofnięcie transakcji do znacznika nie zamyka transakcji. ROLLBACK TO SAVEPOINT znacznik; Użytkownik może ustalić zmienne środowiskowe AUTOCOMIS. Oracle automatycznie włącza i wyłącza różne typy blokad zależnie od sytuacji i nie wymaga przy tym żadnych akcji ze stron użytkownika. Jawne usuwanie blokady przez użytkownika jest możliwe za pomocą połączeń: - LOCK TABLE - SELECT ... FOR UPDATE INSTRUKCJE STERUJĄCE W PL/SQL Język PL/SQL posiada większość typowych instrukcji sterujących. IF <warunek logiczny> THEN <blok instrukcji> END IF; IF <warunek logiczny> THEN <blok instrukcji> ELSE <blok instrukcji> END IF; IF <warunek logiczny> THEN <blok instrukcji> ELSE IF <warunek logiczny> THEN <blok instrukcji> END IF; LOOP <blok instrukcji (w tym EXIT lub EXIT WHEN <warunek logiczny>)> END LOOP; FOR <zmienna> IN <wartość 1> ... <wartość 2> LOOP <blok instrukcji> END LOOP; WHILE <warunek logiczny> LOOP <blok instrukcji> END LOOP; [DECLARE <deklaracje obiektów PL/SQL, zmienne, stałe, wyjątki procedury funkcje>] BEGIN 25 <ciąg instrukcji do wykonania> [EXCEPTION <obsługa wyjątków>] END; - deklaracje i obsługa wyjątków są opcjonalne bloki mogą być zagnieżdżone jedynymi instrukcjami języka SQL jakie mogą pojawić się w loku PL/SQL są instrukcje SELECT, INSERT, UPDATE, DELETE, COMMIT i ROLLBACK. DEKLARACJE ZMIENNYCH I STAŁYCH Deklaracje zmiennych i stałych mają następującą postać: identyfikator typ_danych [NOT NULL] [:=wyrażenie]; identyfikator CONSTANT typ_danych [NOT NULL] [:=wyrażenie]; - opcjonalna część [:=wyrażenie] umożliwia inicjalizuje wartość zmiennej Przykłady znak CHAR(1); wynagrodzenie NUMBER(7,2); pi CONSTANT NUMBER(1,5):=3,14159; nazwa VARCHAR2(10):=’Drukarka’; termin DATE:=Sysdate; stan_cywilny BOOLEAN:=False; liczba_dzieci BINARY_INTEGER:=0; brak_danych EXCEPTION; psoba pracownik.nazwisko% TYPE; pracownik_rekord pracownik% ROWTYPE; Uwagi: - w PL/SQL są dostępne typy danych z języka SQL a ponadto typ BOOLEAN(logiczny) i BINARY_INTEGER liczb całkowitych – należy od podtypów NUMBER i przez to wymagający przy zapisie mniej pamięci - nie należy nadawać tej samej nazwy w atrybutu w tabeli - oprócz zmiennych deklarowanych w bloku PL/SQL mogą występować jeszcze zmienne z aplikacji korzystającej z bloku PL/SQL – poprzedza się je dwukropkiem (:zmienna) - mogą także występować zmienne podstawienia SQL*Plus (&zmienna) - typ zmiennej można zadeklarować używając pseudoatrybutu %TYPE określającego typ podanego przed nim atrybutu relacji - zmienną typu rekordowego deklarujemy z użyciem pesudoatrybutu %ROWTYPE lub przy użyciu złożonego typu danych RECORD ZMIENNE SYSTEMOWE Jest pewna liczba zmiennych zadeklarowanych przez system, z których można korzystać w kodzie PL/SQL (ale nie w SQL) ich wartości dotyczą ostatnio wykonanej instrukcji SQL: - SQL% ROWCOUNT – liczba wierszy przetworzonych przez ostatnią instrukcję SQL - SQL% FOUND=TRUE – jeśli zastał znaleziony (przetworzony) przynajmniej jeden wiersz - SQL% NOTFOUND=TRUE – jeśli żaden wiersz nie został przetworzony 26 - SQLERRM – tekstowa informacja o błędzie - SQLCODE – kod błędu Ostatnie dwie wymienione może uzyskać tylko w sekcji EXCEPTION. PROCEDURY FUNKCJE I PAKIETY są to obiekty zapisywane w bazie danych tak jak inne obiekty. Szczególnym rodzajem procedury są wyzwalacze baz danych. WYZWALACZE BAZ DANYCH Wyzwalacze baz danych (database tiggers) są procedurami składowymi w bazach danych w powiązaniu z jej konkretną relacją. Są one uruchamiane automatycznie w momencie wykonania polecenia SQL: INSERT, UPDATE, DELETE. Wyzwalacze baz danych służą głównie do oprogramowania więzów spójności i do oprogramowania stałych czynności, które powinny być wykonywane w każdej aplikacji korzystającej z baz danych. Oto składnia wyzwalacza baz danych: CREATE[OR REPLACE] TRIGGER <nazwa wyzwalacza> BEFORE/AFTER <specyfikacja instrukcji> ON <nazwa relacji> [FOR EACH ROW] <blok instrukcji PL/SQL> - specyfikacja instrukcji przyjmuje jedną z operacji INSERT, UPDATE, DELETE lub kilka z nich połączonych operatorem OR w przypadku UPDATE podaje się dodatkowo nazwę aktualizowanego atrybutu używając składni UPDATE OF <nazwa atrybutu> opcjonalna klauzula FOR EACH ROW spowoduje uruchomienie wyzwalacza dla każdej krotki spełniającej warunek polecenia, brak tej klauzuli to wyzwalacz zostanie uruchomiony tylko raz aby odróżnić w wyzwalaczu wierszowych stare i nowe wartości w wierszu używa się specjalnych ograniczeń na wiersz przed zmianą i po zmianie; :OLD.<nazwa atrybut> lub :NEW.<nazwa atrybutu> Przykłady: CREATE OR REPLACE TRIGGER sprawdź_płace BEFORE INSERT ON pracownik FOR EACH ROW BEGIN IF :NEW.płaca_pod<500 THEN RAISE_APPLICATION_ERROR (-20020,’Płaca podstawowa jest zbyt niska’); ENDIF; END; CREATE TRIGGER sprawdzanie_wynagrodzenia BEFORE INSERT OR UPDATE OF płaca_pod, etat ON pracownik FOR EACH ROW DECLARE Min NUMBER Max NUMBER; BEGIN SELECT górne, dolne INTO Min, Max FROM etaty WHERE etat:=NEW.etat; IF :NEW.płaca_pod<Min OR :NEW.płaca_pod<Max THEN 27 RAISE_APPLICATION_ERROR (-20500,’Wynagrodzenie’||:NEW.płaca_pod||’spoza zakresu’); ENDIF; END; Ciało wyzwalacza, który może być uruchomiony przez więcej niż jedno polecenie DML, może zawierać systemowe zmienne logiczne: inserting, deleting, updating świadczące o rodzaju instrukcji, które uruchomiła dany wyzwalacz. CREATE TRIGGER budżet_zespołu AFTER DELETE OR INSERT OR UPDATE OF Wynagrodzenie, id_zesp ON pracownik FOR EACH ROW BEGIN IF deleting OR (updating AND :OLD.id_zesp<>:NEW.id_zesp) THEN UPDATE budżet SET fundusz_płac=fundusz_płac-:OLD.wynagrodzenie WHERE nr.zesp=:OLD.id_zesp; ENDIF; IF inserting OR (updating AND :OLD.id_zesp<>:NEW.id_zesp) THEN UPDATE budżet SET fundusz_płac=fundusz_płac+:NEW.wynagrodzenie WHERE nr.zesp=:NEW.id_zesp; ENDIF; IF updating AND (:OLD.id_zesp=:NEW.id_zesp) AND (:OLD.wynagrodzenie<>:NEW.wynagrodzenie) THEN UPDATE budżet SET fundusz_płac=fundusz_płac-:OLD.wynagrodzenie +:NEW.wynagrodzenie WHERE nr.zesp=:OLD.id_zesp; ENDIF; END; CREATE OR REPLACE TRIGGER rejestr AFTER UPDATE OF etat, szef, płaca_pod, płaca_dod, id_zesp OR DELETE ON pracownik FOR EACH ROW BEGIN IF updating THEN INSERT INTO rejestr_prac values (:OLD.numer, :OLD.nazwisko, :OLD.etat, :OLD.szef, :OLD.pracuje_od, :OLD.płaca_pod, :OLD.płaca_dod, :OLD.id_zesp,user, sysdate, ‘UPDATE’); ELSIF deleting INSERT INTO rejestr_prac values (:OLD.numer, :OLD.nazwisko, :OLD.etat, :OLD.szef, :OLD.pracuje_od, :OLD.płaca_pod, :OLD.płaca_dod, :OLD.id_zesp,user, sysdate, ‘DELETE’); END IF; END; Wyzwalacz może być włączony i wyłączony za pomocą instrukcji: ALERT TRIGGER <nazwa wyzwalacza> ENABLE/DISABLE; Wyzwalacz można usunąć 28 DROP TRIGGER <nazwa wyzwalacz>; Używając dotychczas wprowadzonych konstrukcji języka PL/SQL nie było możliwe przeglądanie kolejno wszystkich wierszy będących wynikiem zapytania. Do tego celu został powołany obiekt o nazwie kursor, który stanowi bufor (obszar roboczy). Przed użyciem kursora należy go zadeklarować poleceniem postaci: DECLARE CURSOR <nazwa kursora> IS SELECT… FROM… WHERE…; Na zadeklarowanym kursorze można wykonywać operacje jego otwarcia, pobierania wartości oraz zamknięcia. Kursor otwieramy poleceniem OPEN, które powoduje przydzielenie niezbędnego obszaru pamięci. Do pobierania krotki wskazywanej przez kursor stosuje się polecenie FETCH. Kursor, który nie będzie więcej wykorzystywany w programie, powinien zostać zamknięty poleceniem CLOSE. Z każdym kursorem są związane 4 atrybuty, w których jest przechowywana informacja o przebiegu operacji wykonywanych przez kursor. kursor%found kursor%rowcount kursor%notfound kursor%isopen Przykłady: BEGIN DECLARE CURSOR pracownik_kursor IS SELECT numer, płaca_pod, pracuje_od, pracownkik.id_zesp FROM pracownik, zespół WHERE pracownik.id_zesp=zespół.id_zesp AND nazwa=’BAZA DANYCH’; pracownik_dane pracownik_kursor%ROWTYPE; BEGIN OPEN pracownik_kursor; LOOP FETCH pracownik_kursor INTO pracownik_dane; EXIT WHEN pracownik_kursor%NOTFOUND; IF pracownik_dane.pracuje_od<’80/01/01’ THEN UPDATE pracownik SET płaca_pod=płaca_pod*1.3 WHERE numer= pracownik_dane.numer; ELSIF pracownik_dane.pracuje_od>’80/12/31’ AND pracownik_dane.pracuje_od<’86/01/01’ THEN UPDATE pracownik SET płaca_pod=płaca_pod*1.2 WHERE numer= pracownik_dane.numer; ELSE UPDATE pracownik SET płaca_pod=płaca_pod*1.05 WHERE numer= pracownik_dane.numer; END IF: END LOOP; COMMIT; CLOSE pracownik_kursor; END; END; 29 BEGIN DECLARE CURSOR pracownik_kursor (id-zespołu NUMBER) IS SELECT numer, nazwisko, płaca_pod FROM pracownik p WHERE p.id_zesp=id_zespołu AND 3> (SELECT COUNT(DISTINCT płaca-pod) FROM pracownik WHERE id_zesp=p.id_zesp AND płaca_pod<=p.płaca_pod; Pracownik_rekor pracownik_kursor %ROWTYPE; BEGIN FOR pracownik_rekord IN pracownik_kursor (20) LOOP UPDATE pracownik SET płaca_pod=płaca_pod*1.05 WHERE numer=pracownik-rekord.numer; END LOOP; COMMIT; END; END; CREATE OR REPLACE FUNCTION podaj_stan_zespołu (liczba IN NUMBER) RETURN NUMBER IS wartość NUMBER; BEGIN SELECT COUNT(*) INTO wartość FROM pracownik WHERE id_zesp=liczba; RETURN wartość; END; CREATE OR REPLACE PROCEDURE nowy_pracownik (nazwisko_pracownik IN CHAR, nazwisko_szefa IN CHAR, nazwa_zespołu IN CHAR, etat IN CHAR DEFAULT ‘STAŻYSTA’ pensja IN NUMBER DEFAULT 900) IS nr_szefa NUMBER(6); nr_ZESPOŁU NUMBER(6); BEGIN SELECT id_zesp INTO nr_zespołu FROM zespół WHERE nazwa=nazwa_zespołu; SELECT numer INTO nr_szefa FROM pracownik WHERE nazwisko=nazwisko_szefa AND id_zesp=nr_zespołu; INSERT INTO pracownik VALUES (seq_pracownik.NEXTVAL, nazwisko_pracownika, etat, nr_szefa, SYSDATE, pensja, NULL, nr_zespołu); EXCEPTION WHEN NO_DATA_FOUND THEN 30 RAISE_APPLICATION_ERROR(-20000,’Nie znaleziono takiego szefa lub zespołu’); END; CREATE OR REPLACE PROCEDURE podwyżka(nazw IN CHAR, podwyżka IN NUMBER) IS pensja_min NUMBER(8); pensja_max NUMBER(8); pensja NUMBER(8); zbyt_wysoka_pensja EXCEPTION; BEGIN SELECT płaca_min, płaca_max INTO pensja_min, pensja_max FROM pracownik WHERE nazwisko=nazw); IF ((pensja+podwyżka)BETWEEN pensja_min AND pensja_max) THEN UPDATE pracownik SET płaca_pod=płaca_pod+podwyżka WHERE nazwisko=nazw; ELSE RAISE zbyt_wyskoka_pensja; END IF; EXCEPTION WHEN zbyt_wyskoka_pensja THEN DBMS_OUTPUT.PUT_LINE (‘Pensja jest większa niż pensja dozwolona’); NULL; END; Obiektowe bazy danych Co to jest obiektowa baza danych? - zbiór obiektów, ich stan, zachowanie się i związki występujące między nimi określone zgodnie z obiektowym modelem danych. - Składy trwałych obiektów - Jest to system, który umożliwia zarządzanie bazą danych, zorientowany obiektowo - Jest to system, który dziedziczy wszystkie zasadnicze cechy technologii obiektowej i baz danych. Obiektowy model danych Model danych, w którym wykorzystano cechy obiektowości: pojęcia klas i obiektów klasy, enkapsulacja, mechanizm identyfikacji obiektów, dziedziczenie, przeciążenie funkcji. UML (Unified Modeling Language) Zunifikowany język do modelowania, zawierający pojęcia i notacje służące do obiektowej analizy, modelowania i projektowania. UML został opracowany przez człowych metodologów G. Boocha, I. Jackobsona, J. Rumbaugha. UML jest lansowany jako standard notacyjny również jako fragment standardu OMO. W notacji UML definiowane są następujące diagramy: - diagramy przypadków użycia (use case) - diagramy klas (class diagrams). Są one odmianą dość klasycznych diagramów - diagramy odwzorowujące dynamiczne własności systemy (behavior) - diagramy stanów - diagramy aktywności - diagramy implementacyjne OBMG (Object Database Management Group) jest organizacją skupiającą firmy obiektowe bazy danych. ODMG tworzy standardy takich baz. Elementami tego standardu są ODL (Object Definition Language) OQL (Object Query Language) oraz tzw. wiązania do 3 języków programowania C++, smalltalk, Java. Zadaniem wiązań jest udostępnienie bazy danych z 31 poziomu danego języka programowania. To właśnie wiązania definiują DML (język manipulowania danymi). Hurtownie danych: (magazyn danych, data warhouse) - jest scentralizowana bazą danych - jest oddzielona od baz operacyjnych - scala informację z wielu źródeł - jest zorientowana tematycznie - przechowuje dane historyczne - utrzymuje wielką ilość informacji - agreguje informację W hurtowniach danych przechowuje się dane różnych rodzajów: - elementarne (kopie aktualnych danych źródłowych pozyskany z baz operacyjnych) - zmaterializowane agregaty(wyliczone wartości sum, średnich w różnych przekrojach) - metadane. Cykl życia danych w hurtowniach to: - ładowanie i scalanie - agregacja - przesunięcie do danych historycznych - usuwanie(rzadko albo nigdy) Wykorzystywanie hurtowni danych Dane zgromadzone w hurtowniach i składnicach danych są zwykle wykorzystywane przez menadżerów – użytkowników systemów wspomagania decyzji. Systemy takie wykonują różnego rodzaju analizy: - przetwarzanie analityczne OLAP (On-line Analytical Processing) - eksploracja danych (datamining) czyli automatyczne pozyskiwanie wiedzy z baz danych. Analiza wielowymiarowa i dane wielowymiarowe. Struktura wielowymiarowa przedstawia elementarne komórki danych, tzn. w funkcji wielu niezależnych czynników zwanych wymiarami. Typowe wymiary to: - czas (np. w dniach, miesiącach, latach) - produkt (np. typ i rodzaj) - jednostka organizacyjna (np. wydział, filia) lub terytorium (gmina, miasto) Fakty są opisane atrybutami liczbowymi tzw. miarami. Najbardziej typowym faktem jest wielkość sprzedaży, której miarami są np. ilośc sprzedanego towaru i jego wartość. 32