Plan wykładu Bazy danych Wykład 11: Indeksy. Język DDL i DML. Pojęcie indeksu - rodzaje indeksów Metody implementacji indeksów struktury statyczne struktury dynamiczne Małgorzata Krętowska Wydział Informatyki PB 2 Metody organizacji pliku rekordów przypomnienie wiadomości Plik nieuporządkowany Plik posortowany Plik haszowany Pojęcie indeksu Indeks to struktura danych na dysku umożliwiająca szybkie wyszukiwanie danych w bazie danych na podstawie wartości klucza wyszukiwania jak np. nazwisko osoby. Indeks = skorowidz w książce. W najprostszej postaci wyszukiwanie polega na tym, że mając wartość poszukujemy rekordów, w których ta wartość występuje w danym polu. 3 4
Klucz wyszukiwania Plik indeksowy Klucz wyszukiwania (wartość indeksowana) dla indeksu jest to wybrane pole lub pola rekordu, względem których ma odbywać się wyszukiwanie. Indeks jest to struktura danych składająca się z węzłów, w których są zapisywane rekordy indeksu w następującej postaci: pozycje danych k* określane względem wartości klucza wyszukiwania k tzn sam rekord o kluczu k para (k,w) gdzie k jest kluczem rekordu, a w jest wskaźnikiem do rekordu o tym kluczu para (k,w 1,.., w n ), gdzie k jest kluczem rekordu, a w 1,.., w n są wskaźnikami do rekordów o kluczu k (wymaga zmiennej liczby pól) pozycje indeksu kierujące wyznaczeniem właściwej pozycji danych k* w oparciu o wartość klucza wyszukiwania k (np. para (wartość klucza, wskaźnik do węzła w indeksie) 5 Zawartość indeksu jest przechowywana w pliku indeksowym W skład pliku indeksowego wchodzą rekordy indeksu będące pozycjami danych lub pozycjami indeksu. Węzeł odpowiada na ogół stronie dyskowej i zawiera albo pozycje danych albo pozycje indeksu. 6 Rodzaje indeksów Indeks główny (podstawowy) Indeks główny lub podstawowy (primary index) założony na atrybucie porządkującym unikalnym Indeks zgrupowany (clustering index) założony na atrybucie porządkującym nieunikalnym Indeks wtórny (secondary index) założony na atrybucie nieporządkującym Podział ze względu na liczbę wskazań do pliku danych: Indeks gęsty (dense) posiada rekord indeksu dla każdego rekordu indeksowanego pliku danych Indeks rzadki (sparse) posiada rekordy tylko dla wybranych rekordów indeksowanego pliku danych 7 8
Indeks zgrupowany Indeks zgrupowany z blokami nadmiarowymi 9 10 Indeks wtórny Złożone klucze wyszukiwania Pojedyncze klucze wyszukiwania - wyszukiwanie według pojedynczego pola Złożone klucze wyszukiwania - wyszukiwanie według kombinacji większej liczby pól 29,5000 34,1500 34,2000 43,3000 <wiek, zarobki> 1500,34 2000,34 3000,43 5000,29 <zarobki, wiek> Adamski 34 1500 Bakun 29 5000 Molski 34 2000 Wilczak 43 3000 Rekordy danych posortowane względem imienia 29 34 34 43 <wiek> 1500 2000 3000 5000 <zarobki> 11 12
Metody implementacji indeksów Indeksy statyczne Indeksy dynamiczne Statyczne drzewo ISAM (indexed sequential access method) Wyszukiwanie binarne - (pliki posortowane) porównujemy poszukiwany klucz z kluczem rekordu znajdującym się w środku ciągu i w zależności od wyniku porównania poszukujemy klucza albo w lewej części albo w prawej, stosując rekurencyjnie opisywaną metodę Poszukiwanie binarne łatwiej zastosować jest nie bezpośrednio do pliku rekordów, ale do pliku zawierającego same klucze rekordów k 1 <k 2 <...<k N, gdzie k i jest najmniejszym kluczem na stronie o numerze i. Plik z kluczami stanowi plik indeksowy Po wyznaczeniu najbliższego pasującego klucza wystarczy przejść do strony z rekordami, na której znajduje się rekord o danym kluczu. Jednopoziomowy plik indeksowy k1 k2 kn Plik indeksowy Strona 1 Strona 2 Strona 3 strona N Plik danych 13 14 Statyczne drzewo ISAM Strona indeksu jednopoziomowego (węzeł) składa się z pozycji indeksu <k i, P i >, gdzie k i jest kluczem, a P i jest wskaźnikiem na stronę zawierającą wartości klucza >= od klucza k i. Wskaźnik P 0 stanowi wskaźnik na stronę o wartościach klucza <k 1. Pozycja indeksu p 0 k 1 p 1 k 2 p 2... k m p m Strona indeksu k 1 <k 2 <...<k m Zasady poszukiwania danego klucza 21 34 56 Indeks wielopoziomowy (drzewo ISAM) Strona indeksu wielopoziomowego (węzeł) składa się z pozycji indeksu <k i, P i >, gdzie k i jest kluczem, a P i jest wskaźnikiem do węzła wyższego poziomu zawierającego wartości kluczy >= od klucza k i. Wskaźnik P 0 stanowi wskaźnik do węzła wyższego poziomu zawierającego wartości klucza <k 1. Pozycja indeksu p 0 k 1 p 1 k 2 p 2... k m p m Wskaźniki na węzły wyższego poziomu Strona indeksu k 1 <k 2 <...<k m Do strony z wartościami klucza <21 Do strony z 21<=k <34 Do strony z 34<=k <56 Do strony z k >=56 15 16
Struktura drzewa ISAM Problemy Węzły wewnętrzne Dodawanie i usuwanie rekordów w przypadku indeksu głównego jest to problem złożony, gdyż musimy wstawić rekord na odpowiedniej pozycji w pliku. Wiąże się to z przeniesieniem części rekordów w pliku, a co za tym idzie zmiany wpisu w indeksie, gdyż przesunięcie rekordów powoduje zmiany wartości kluczy w danym bloku. liście Strony nadmiarowe Strony główne Próby rozwiązania problemu: Wykorzystanie nieuporządkowanego pliku przepełnienia Użycie listy jednokierunkowej rekordów przepełnienia dla każdego bloku w pliku danych (przykład indeksu - kolejny slajd) 17 18 Podsumowanie drzew ISAM Dynamiczne indeksy wielopoziomowe Drzewa ISAM dobrze sprawdzają się do wyszukiwania rekordu na podstawie wartości jego klucza, a także rekordów z zakresu wartości klucza: A<=klucz<=B; A<=klucz, klucz<=b Gdy liczba rekordów w pliku jest mniej więcej stała struktura ISAM jest dobra B-drzewa B + - drzewa Niebezpieczeństwo grupowania się kluczy w ciągi na stronach nadmiarowych (rozwiązanie struktury dynamiczne) 19 20
B-drzewo B-drzewo B-drzewo rzędu p: każdy wierzchołek wewnętrzny na postać: <P 1, <K 1, Pr 1 >, P 2, <K 2, Pr 2 >,...,<K q-1, P q-1 >, P q > gdzie q<=p. Każde P i oznacza wskaźnik drzewa - wskaźnik na inny wierzchołek w B-drzewie. Każde Pr i oznacza wskaźnik danych - wskaźnik na rekord, którego wartość pola klucza wyszukiwania jest równa K i (lub blok w pliku zawierający ten rekord) w każdym wierzchołku K 1 <K 2 <...<K q-1 dla wszystkich wartości pola wyszukiwania X w poddrzewie, na które wskazuje wskaźnik P i mamy K i-1 <X<K i, dla 1<i<q oraz K i-1 <X dla i=q Każdy wierzchołek prócz korzeni i liści posiada co najmniej ceil(p/2) wskaźników drzewa Wszystkie liście znajdująsię na tym samym poziomie. Liście posiadają taką samą strukturę co wierzchołki wewnętrzne poza tym, że ich wskaźniki drzewa są zerowe P 1 K 1 Pr 1 P 2 K i-1 Pr i-1 P i K i Pr i K q-1 Pr q-1 P q Wskaźnik danych Wskaźnik Wskaźnik Wskaźnik danych danych danych X<K 1 Ki-1 <X<K i K q-1 <X Z powodu niejednolitosci węzłów dla B drzew operacje INSERT i DELETE są bardziej skomplikowane => B + - drzewa. 21 22 B + - drzewo Wykorzystywane przez większość implementacji dynamicznych indeksów Wyróżniamy wierzchołki wewnętrzne i liście (różne struktury danych) Wymagana zajętość strony indeksu wynosi minimum 50% ( z wyjątkiem korzenia) Zajętość każdej strony liścia wynosi minimum 50%. Wierzchołki liści są zwykle połączone razem, co zapewnia możliwość uzyskiwania uporządkowanego dostępu do rekordów względem pola wyszukiwania B + - drzewo jest wyważone tzn. każdy liść znajduje się na tej samej głębokości Wierzchołki wewnętrzne Struktura wierzchołków wewnętrznych B+ - drzewa rzędu p: Każdy wierzchołek wewnętrzny ma postać <P 1, K 1, P 2,K 2,..., P q-1, K q-1, P q > gdzie q<=p i każde p i jest wskaźnikiem drzewa W każdym wierzchołku wewnętrznym K 1 <K 2 <...<K q-1. Dla wszystkich wartości pola wyszukiwania X w podrzewie, na które wskazuje wskaźnik p i mamy: K i-1 <X<=K i, dla 1<i<q oraz K i-1 <X dla i=q Każdy wierzchołek wewnętrzny posiada najwyżej p wskaźników drzewa Każdy wierzchołek wewnętrzny oprócz korzenia i liści posiada co najmniej ceil(p/2) wskaźników drzewa. Korzeń posiada co najmniej 2 wskaźniki drzewa. Wierzchołek wewnętrzny o q wskaźnikach drzewa, gdzie q<=p posiada q-1 wartości pola wyszukiwania 23 24
Wierzchołki wewnętrzne P 1 K 1 P i-1 K i K q-1 P q Wskaźniki drzewa X<=K 1 Ki-1 <X<=K i K q-1 <X Wierzchołki liści Struktura wierzchołków liści B + - drzewa rzędu p: Każdy wierzchołek liścia ma postać: <<K 1, Pr 1>,<K 2,Pr 2 >,..., <K q-1, Pr q-1 >, P nast > gdzie q<=p i każde Pr i jest wskaźnikiem danych, zaś P nast wskazuje na następny wierzchołek liścia w B + -drzewie. W każdym wierzchołku liścia K 1 <K 2 <.., K q-1, dla q<=p Każde Pr i jest wskaźnikiem danych wskazujących na rekord, którego wartość pola wyszukiwania jest równa k i lub na blok pliku zawierający dany rekord (lub na blok rekordu wskaźników wskazujących na rekordy, których wartością pola wyszukiwania jest K i, jeżeli pole wyszukiwania nie jest kluczem) Każdy wierzchołek liścia posiada co najmniej ceil(p/2) wskaźników drzewa Wszystkie wierzchołki znajdują się na tym samym poziomie 25 26 Wierzchołki liści K 1 Pr 1 K 2 Pr 2 K i Pr i K q-1 Pr q-1 P nast Wskaźnik danych Wskaźnik danych Wskaźnik na następny wierzchołek liścia w drzewie Podsumowanie drzew Zastosowania indeksów o strukturze drzewiastej wyszukiwanie zakresowe wyszukiwanie równowartościowe sortowanie (order by) wyszukiwanie przy uzgadnianiu wierszy w trakcie złączania tabel Drzewo ISAM - struktura statyczna struktura prostsza niż B + -drzewa modyfikowane są tylko liście wymagane są strony nadmiarowe, mogące pogorszyc czas wykonywania wyszukiwania B + -drzewo - struktura dynamiczna w praktyce wysokość<=3 zakładając, że korzeń drzewa jest zawsze trzymany w buforze RAM, koszt wyszukania pozycji dancyh rekordu wynosi co najwyżej 3 operacje we/wy 27 28
Tworzenie tabel CREATE TABLE nazwa_tabeli (kolumna1 typ_danych(rozmiar) [DEFAULT wartość_domyślna] [NULL NOT NULL] [CONSTRAINT nazwa_ogr] ograniczenie_atr], kolumna2 typ_danych(rozmiar) [DEFAULT wartość_domyślna] [NULL NOT NULL] [CONSTRAINT nazwa_ogr] ograniczenie_atr...); Przykład: CREATE TABLE Departament (nr_departamentu number(2), nazwa varchar2(12), lokalizacja varchar(12)); CREATE TABLE Departament (nr_departamentu number(2) not null, nazwa varchar2(12), lokalizacja varchar(12)); Typy kolumn char(rozmiar) - ciąg znaków stałej długości. Rozmiar (liczba znaków) określany w nawiasach o długości nie większej niż 255 bajtów. varchar2(rozmiar) - ciąg znaków zmiennej długości. Rozmiar (liczba znaków, max 2000, domyślnie 1) określany jest w nawiasach. number(rozmiar) - typ numeryczny. Rozmiar określa liczbę cyfr w kolumnie. number(rozmiar,d) - typ numeryczny. Rozmiar określa liczbę znaków w kolumnie, "d" określa maksymalną liczbę cyfr na prawo od kropki dziesiętnej. Skala "d" nie może być większa od precyzji "rozmiar" date do reprezentacji dat i czasu long rozszerzenie typu varchar2, które pozwala przechowywać napisy do 2GB 29 30 Klauzula CONSTRAINT Służy do definiowania innych niż NOT NULL warunków integralności CREATE TABLE nazwa_tabeli (kolumna1 typ_danych(rozmiar) [DEFAULT wartość_domyślna] [NULL NOT NULL] [CONSTRAINT nazwa_ogr] ograniczenie_atr]...); CREATE TABLE nazwa_tabeli (kolumna1 typ_danych(rozmiar) [DEFAULT wartość_domyślna] [NULL NOT NULL]... CONSTRAINT nazwa_ogr typ_ograniczenia CONSTRAINT nazwa_ogr typ_ograniczenia...); Klauzula CONSTRAINT [CONSTRAINT nazwa_ogr] typ_ograniczenia Nazwa_ograniczenia - identyfikator warunku integralności, występujący np. w komunikatach o błędach spowodowanych przez niedozwoloną operację naruszającą to ograniczenia Typ_ograniczenia: CHECK, PRIMARY KEY, UNIQUE, FOREIGN KEY Ograniczenie - dodatkowe informacje, jego postać zależy od typu ograniczenia 31 32
Typy ograniczeń Ograniczenie CHECK - określa warunek, jaki musi spełniać wartość w kolumnie każdego wiersza tabeli. Jeśli więzy są definiowane po definicji wszystkich kolumn, warunek może dotyczyć kilku kolumn, jeśli na poziomie kolumny - tylko tej kolumny. CONSTARAINT CHECK (warunek logiczny) Warunek logiczny musi być prosty - niedopuszczalne są podzapytania, ani funkcje, których wartość zależy od okoliczności wywołania np. SYSDATE. Można używać OR i AND. Przykład W tabeli pracownik żądamy, aby nazwiska były wpisywane wielkimi literami CREATE TABLE pracownik (... nazwisko varchar2(10) CONSTRAINT wielkie_litery CHECK (nazwisko=upper(nazwisko))...); Prowizja osób innych niż sprzedawca musi być NULL. CREATE TABLE pracownik (... Definicje wszystkich kolumn, CONSTRAINT stanowisko_prowizja_spr (prowizja IS NULL OR stanowisko= SPRZEDAWCA ) ); 33 34 PRIMARY KEY Definiuje klucz główny tabeli (wymusza automatycznie warunek NOT NULL). Jeżeli klucz główny stanowi pojedyncza kolumna wygodnie jest zapisać ten warunek w składni przy kolumnie:... Kolumna typ CONSTRAINT nazwa_ogr PRIMARY KEY,... Jeżeli klucz składa się z dwóch lub więcej kolumn, wtedy należy określić go w składni po kolumnach:... CONSTARINT nazwa_ogr PRIMARY KEY (kol1,kol2,...)... Przykład W tabeli pracownik kluczem jest numer pracownika: id_pracownika CREATE TABLE pracownik (id_pracownika NUMBER(4) CONSTARINT pracownik_pk PRIMARY KEY,...); lub CREATE TABLE pracownik (id_pracownika NUMBER(4) PRIMARY KEY,...); Ustalić klucz w tabeli zlecenie. CREATE TABLE zlecenie (... definicje kolumn CONSTRAINT zlecenie_pk PRIMARY KEY(nr_projektu, id_pracownika)); 35 36
UNIQUE Definiuje klucz unikalny tabeli. Klucz unikalny pełni podobną rolę co klucz główny, z tym, że nie wymusza automatycznie warunku NOT NULL na należących do niego kolumnach Klucz unikalny składający się z jednej kolumny:... Kolumna typ CONSTRAINT nazwa_ogr UNIQUE,... Klucz dla dwóch lub większej liczby kolumn:... CONSTARINT nazwa_ogr UNIQUE (kol1,kol2,...)... Przykład W tabeli departament nazwy departamentów nie są kluczem głównym ale też nie powinny się powtarzać. CREATE TABLE departament (... nazwa NUMBER(4) NOT NULL CONSTRAINT d_nazwa_u UNIQUE,...); 37 38 FOREIGN KEY Definiuje klucz obcy, reprezentujący związek z inną tabelą. Powoduje, że wartości wskazanych kolumn mogą przyjmować jedynie wartości klucza głównego (lub unikalnego) pewnej (najczęściej innej) tabeli. Jeżeli klucz obcy stanowi jedna kolumna:... Kolumna typ CONSTRAINT nazwa_ogr REFERENCES nazwa tabeli (kolumna1),... Jeżeli klucz obcy zbudowany jest z większej liczby kolumn... CONSTARINT nazwa_ogr FOREIGN KEY (lista_kolumn1) REFERENCES nazwa_tabeli (lista_kolumn2)... FOREIGN KEY Aby możliwe było zdefiniowanie klucza obcego: tabela do której odnosi się klucz musi być utworzona na wskazanym zestawie kolumn musi być utworzony klucz główny lub klucz unikalny jeśli w tabeli obcej odwołujemy się do kolumn z klucza głównego, listę kolumn z tabeli obcej można pominąć Własności kluczy obcych w tabeli z kluczem obcym nie można wstawić wiersza, którego wartość w kolumnie z klucza obcego nie ma odpowiedników w tabeli obcej, w tabeli z kluczem obcym nie można zmodyfikować wiersza, tak aby jego wartość kolumnie z klucza obcego nie miała odpowiedników w tabeli obcej, z tabeli obcej nie można usunąć wiersza, do którego odnoszą się jakiekolwiek wiersze z tabeli z kluczem obcym - wstawienie dyrektywy ON DELETE CASCADE spowoduje, że przy usuwaniu wiersza z tabeli będą usuwane wszystkie odwołujące się do niego wiersze z tabel z kluczem obcym. 39 40
Przykład Utworzyć klucze obce w tabeli pracownik. Jakie to będą klucze? CREATE TABLE pracownik( nr_pracownika number (4) PRIMARY KEY, nazwisko varchar2(10), stanowisko varchar2(9), kierownik number(4) CONSTARAINT pracownik_fk_pr REFERENCES pracownik (nr_pracownika), data_zatrudnienia date, pensja number(7,2), prowizja number (7,2), nr_departamentu number(2) NOT NULL CONSTRAINT pracownik_fk REFERENCES departament ON DELETE CASCADE ); Klauzula DEFAULT Służy do wskazania jaka wartość ma być wstawiona w polu kolumny jeśli w poleceniu wstawiania nie określono wartości tej kolumny.... Kolumna typ DEFAULT wyrażenie,... Podane wyrażenie musi być zgodne z typem kolumny. Wyrażenie musi być proste, nie mogą występować podzapytania Dozwolone są funkcje typu SYSDATE. 41 42 Tworzenie tabeli przez zapytanie CREATE TABLE nazwa_tabeli [nazwa_kolumny [NULL/NOT_NULL],...] AS SELECT zapytanie nowa tabela składa się z kolumn oraz wierszy określonych poleceniem SELECT jeśli pozycje występujące na liście SELECT mają prawidłowe nazwy (nie są to wyrażenia) lub mają aliasy, lista nazw kolumn nowej tabeli może zostać pominięta jeśli podana jest lista nazw nowej tabeli, liczba pozycji musi się pokrywać z liczbą pozycji, występujących po poleceniu SELECT Przykład Utworzyć tabelę zawierającą nazwisko, pensję i grupę zaszeregowania każdego pracownika. CREATE TABLE pracownik_pensja (nazwisko, pensja, stopien) AS SELECT nazwisko, zarobki, nr_przedziału FROM pracownik, poziom_zarobkow WHERE pensja between dolna_granica and gorna_granica; 43 44
Zmiana definicji tabeli Dodawanie kolumn Zmiana definicji tabeli: ALTER TABLE Dodawanie kolumn: ALTER TABLE nazwa_tabeli ADD (kolumna typ [(rozmiar)], kolumna typ [(rozmiar)],...); Zmiana definicji tabeli Zarządzanie więzami integralności Dodawanie więzów integralności: ALTER TABLE nazwa_tabeli ADD (CONSTRAINT nazwa_ogr [warunek])...); Włączanie i wyłączanie sprawdzanie więzów integralności: ALTER TABLE nazwa_tabeli ENABLE CONSTRAINT nazwa_ogr; ALTER TABLE nazwa_tabeli DISABLE CONSTRAINT nazwa_ogr; Usuwanie warunku integralności: ALTER TABLE nazwa_tabeli DROP CONSTRAINT nazwa_ogr; 45 46 Modyfikacja definicji kolumny ALTER TABLE nazwa_tabeli MODIFY (kolumna typ [(rozmiar)] [NULL NOT NULL]); Nie można wykonać następujących modyfikacji: kolumny, w której występują wartości NULL nie można przedefiniować z NULL na NOT NULL nie można dodać nowej kolumny o własności NOT NULL (chyba, że tabela jest pusta). Dopiero po wpisaniu wartości kolumny można ją zmodyfikować. Nie jest możliwe zmniejszenie rozmiaru kolumny lub zmiany jej typu, chyba, że kolumna jest pusta nie jest możliwa zmiana typu kolumny Usuwanie tabel DROP TABLE nazwa_tabeli; usunięcie tabeli powoduje utratę wszystkich danych zawartych w tabeli oraz wszystkich indeksów tabela może zostać usunięta przez jej właściciela albo administratora bazy danych jeżeli istnieją tabele z kluczami obcymi odwołującymi się do usuwanej tabeli, usuwanie się nie powiedzie, chyba, że na końcu dodamy dyrektywę CASCADE CONSTRAINS. Wtedy zostaną usunięte odpowiednie definicje kluczy obcych w innych tabelach. 47 48
Zmiana nazwy tabeli RENAME stara_nazwa TO nowa_nazwa 49