Rozdział 21
Integralność danych
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. Sytuację komplikuje fakt, że bazy danych w ogromnej większości są aplikacjami sieciowymi. Dostęp do danych oraz możliwość ich modyfikacji musi być zapewniony jednocześnie wielu użytkownikom.
Podstawowym sposobem zachowania integralności danych jest przetwarzanie ich w częściach noszących nazwę transakcji. Transakcja to seria zmian wprowadzonych do bazy danych i traktowanych przez SZBD jako pojedyncza zmiana. W Accessie transakcja powinna zostać rozpoczęta instrukcją BeginTrans. Wszystkie modyfikacje, wchodzące w skład transakcji mogą zostać zatwierdzone poleceniem CommitTrans lub wycofane poleceniem Rollback. Zatwierdzenie transakcji powoduje wprowadzenie na trwałe zmian do bazy danych, wycofanie niezatwierdzonej transakcji nie zmieni przechowywanych w bazie informacji.
W Accessie wywołanie polecenia języka SQL traktowane jest automatycznie jako zatwierdzenie niejawnie rozpoczętej transakcji.
Stosując transakcyjny model modyfikowania danych zapobiegamy utracie danych w przypadku nagłej awarii SZBD, powstałej w trakcie przetwarzania danych. Rozważmy ten problem na przykładzie: Modyfikujemy tabelę Uczeń dzieląc informacje zawarte w kolumnie Adres pomiędzy dwie kolumny: Miasto i Ulica. Przygotowaliśmy nową tabelę i uruchomiliśmy skrypt, który odczytuje dane o kolejnych uczniach ze starej tabeli, kasuje je, następnie wyszukuje w adresie nazwę miasta i komplet danych o uczniu zapisuje do nowej tabeli. Niestety, podczas działania skryptu serwer bazy został wyłączony. Gdyby SZBD skasował dane z pierwotnej tabeli zanim zakończyłby ich zapisywanie w nowej tabeli, dane o pewnych uczniach byłyby utracone. Inaczej, jeżeli wszystkie polecenia skryptu byłyby traktowane jako wchodzące w skład pojedynczej transakcji. W takim przypadku SZBD albo zatwierdziłby wszystkie, albo wycofałby wszystkie, z wchodzących w skład transakcji poleceń. Dzięki temu po ponownym włączeniu serwera w bazie nie brakowałoby żadnych danych o uczniach.
Kolejną zaletą metody transakcyjnej jest zachowanie spójności danych modyfikowanych jednocześnie przez kilku użytkowników. SZBD utrzymują spójność danych w takich wypadkach poprzez nakładanie blokad na modyfikowane przez użytkownika obiekty. Przypuśćmy, że uruchomiliśmy skrypt zmieniający (dodający jeden stopień uczniom z oceną dopuszczającą) ocenę semestralną z matematyki. Niestety, nasz kolega w klasie obok właśnie zmieniał ocenę Jasia. W rezultacie, ponieważ podczas sprawdzania ocen Jaś miał dwóję, nasz program "wpisze go" na listę uczniów którym należy podnieść ocenę o jeden. W tym momencie SZBD zapisze wystawioną przez kolegę ocenę do bazy, a na koniec, nasz skrypt doda do wystawionej właśnie Jasiowi oceny jeden stopień. W rezultacie ocena Jasia na koniec roku nie będzie tróją (jak chcieliśmy), ani czwórką (jak , z sobie tylko wiadomych powodów, chciał nasz kolega), ale piątką! Błędu tego uniknęlibyśmy zakładając blokadę na odczytywane przez nasz skrypt oceny i umożliwiając modyfikację tych wierszy innym użytkownikom dopiero po zatwierdzeniu wprowadzanych przez nas zmian.
Kolejną kwestią, związana z integralnością danych, są mechanizmy zapobiegające wprowadzaniu nieprawidłowych danych do bazy. Przypuśćmy, że przez przypadek wpisaliśmy 35, zamiast 3.5 jako ocenę z matematyki jednej z uczennic naszej klasy. Następnego dnia dyrektor sprawdził średnią ocen z poszczególnych przedmiotów i uzyskał wynik wyraźnie różny od poprawnego, przedstawionego na rys. 20.9.
Rys. 21.1 Średnia ocen obliczona na podstawie błędnych danych
Średnia |
Nazwa przedmiotu |
4 |
Elementy informatyki |
5 |
Fizyka |
3 |
Język angielski |
5,3125 |
Matematyka |
W większości przypadków wystarczającym zabezpieczeniem jest ograniczenie zakresu danych poprawnych dla poszczególnych kolumn tabeli.
Rys. 21.2 Ograniczenie zakresu ocen do skali 1-6
Dodatkowym mechanizmem, który wymusza pewną integralność danych wewnątrz bazy są zawężenia. Jeżeli do określonej kolumny tabeli dodamy zawężenie, to zawsze, kiedy dane w tej kolumnie będą modyfikowane lub będą dodawane do niej nowe dane, baza danych będzie sprawdzać, czy wprowadzane lub modyfikowane wartości są zgodne z zawężeniem nadanym tej kolumnie. W przypadku, gdy wprowadzane lub modyfikowane wartości nie będą zgodne z zadanym zawężeniem, baza danych zwróci komunikat o błędzie i zatrzyma wykonywanie takiego polecenia.
Poniżej omówimy pięć rodzajów zawężeń:
Zawężenie NOT NULL: Jeżeli dla jakiejś kolumny wprowadzimy zawężenia NOT NULL, oznaczać to będzie, że w tej kolumnie nie będą mogły znajdować się pola nie posiadające żadnej wartości (lub inaczej mówiąc nie wypełnione)
Zawężenie UNIQUE: Zawężenie UNIQUE powoduje, że dla kolumny (lub kilku kolumn), dla której zostało wprowadzone, nie może zostać wprowadzona wartość, która znajduje się już w innym polu tej kolumny.
Zawężenie PRIMARY KEY (klucz podstawowy): Klucz podstawowy wymusza automatycznie dla kolumn, na których jest oparty, zawężenie NOT NULL i UNIQUE.
Zawężenie FOREIGN KEY (klucz zewnętrzny): Klucze zewnętrzne mogą posiadać wartości NULL (nie wypełnione pola) — o ile oczywiście nie zabraniają tego inne nadane zawężenia.
Zawężenie CHECK: Zawężenie CHECK ma najbardziej ogólne zastosowanie ze wszystkich omówionych zawężeń. Jest ono wyrażeniem, które zwraca wartość true lub false (prawda lub fałsz). Jeżeli zawężenie CHECK zwróci wartość false, polecenie SQL-owe, które je spowodowało zostanie zatrzymane, a maszyna bazodanowa zwróci komunikat o błędzie.
W większych systemach bazodanowych, takich jak Oracle, SQL Server, czy Postgres mechanizmy utrzymywania spójności danych są bardzo rozbudowane. Jednym ze sposobów "wymuszania" poprawności danych jest wywoływanie, przed zatwierdzeniem transakcji modyfikującej dane, specjalnej procedury wyzwalanej, (ang. Trigger) sprawdzającej spełnianie przez zmodyfikowane dane nawet bardzo skomplikowanych reguł poprawności. Poprzez procedury wyzwalana można na przykład sprawdzić, czy zatwierdzenie zmiany w tabeli A nie spowoduje przekroczenie przez powiązane dane, warunki poprawności ustalonego dla tabeli B.
Mówiąc najprościej procedura wyzwalana jest pewnym zdefiniowanym postępowaniem przypisanym do odpowiedniego zdarzenia określonej tabeli. Ich zastosowanie jest bardzo zbliżone do tego, jakie mają zawężenia (ang. Constraints), jednakże możliwości procedur wyzwalanych są nieporównywalnie większe.
Trzy główne zdarzenia, które mogą spowodować wywołanie procedury wyzwalanej, to:
polecenie UPDATE
polecenie INSERT
polecenie DELETE
Można więc na przykład zdefiniować odpowiednią procedurę, która zostanie wyzwolona zawsze, kiedy użytkownik zmieni dane w rekordzie (lub rekordach) wybranej tabeli, co pozwoli na monitorowanie dostępu do jakichś istotnych danych.
Ponieważ procedury wyzwalane są definiowane na poziomie rekordów tabeli, dlatego też można wyspecyfikować czy dana procedura ma być wyzwalana dla każdego rekordu, czy też jedynie dla pojedynczego polecenia SQL-owego (niezależnie od tego, ile rekordów tabeli zostanie zmodyfikowanych, w wyniku działania tego polecenia).
Istnieją trzy sposoby, na które może zostać wywołana procedura wyzwalana (oczywiście zależy to od tego, jak owa procedura została zdefiniowana oraz od samej bazy danych).
Przed wykonaniem zdarzenia wyzwalającego procedurę
Po wykonaniu zdarzenia wyzwalającego procedurę
Zamiast wykonania zdarzenia wyzwalającego procedurę
Warto w tym momencie wspomnieć parę słów o trzecim sposobie wyzwalania procedur. Celem takiego właśnie sposobu wyzwalania omawianych procedur (wykonanie procedury wyzwalanej zamiast zdarzenia, które ją uruchomiło) było danie użytkownikom możliwości manipulacji danych, za pomocą procedur wyzwalanych, na widokach, które nie pozwalają na ich użycie (np. dla widoków, które odwołują się do danych z kilku różnych tabel).
W niektórych bardziej zaawansowanych bazach danych (np. Oracle, InterBase) wprowadzone zostały również możliwości definiowania procedur, wyzwalanych przez zdarzenia systemowe, takie jak np. start serwerów bazodanowych, ich wyłączenie, zalogowanie lub wylogowanie się przez użytkownika.
Plik zawierający listę wykonywanych w odpowiedniej kolejności poleceń języka SQL.
W Accessie blokada może zostać założona na wierszu, tabeli albo całym pliku z danymi.
Przykładowe zawężenie CHECK przedstawia rys. 21.2.
2 Część I ♦ Podstawy obsługi systemu WhizBang (Nagłówek strony)
2 C:\My Documents\MATURA\R-21.DOC