1.Podstawy Szczegółowa analiza zagadnienia normalizacji to temat na co najmniej kilka artykułów. Zainteresowanym, a jeszcze niewtajemniczonym mogę polecić kilka publikacji, które przybliżą szerzej ten problem. Osobom chcącym poznać zagadnienie dogłębnie, z uwzględnieniem teorii matematycznej, polecam przede wszystkim książki J.D. Ulmana i C. Delobela, M. Adiby . Tym zaś, którzy nie mają cierpliwości do matematycznych wywodów i wolą poznać zagadnienie metodą biblijną, czyli na przykładach, polecam książkę W. Cellarego i Z. Królikowskiego . Tym, którzy nie mają ochoty na szperanie w bibliotekach, postaram się w skrócie wyjaśnić, o co chodzi w procesie normalizacji. Najogólniej rzecz biorąc: normalizując bazę danych usuwamy z niej nadmiarowość (zwaną też często redundancją). Nadmiarowość w bazie danych jest bardzo szkodliwa. Jej istnienie powoduje niepotrzebny wzrost objętości danych; jest też przyczyną kłopotów z utrzymaniem spójności bazy danych, prowadząc do tzw. anomalii. Weźmy pierwszy prosty przykład. Tabela "Zakupy" ma przedstawiać informacje o nazwie i kodzie klienta dokonującego zakupu, o nazwie i kodzie oraz o ilości kupowanego towaru. Z góry zastrzegam, że tabela ta ma charakter jedynie przykładowy i brakuje w niej wielu istotnych pól, które znalazłyby się w praktycznym rozwiązaniu tego zagadnienia. Tabela "Zakupy" przed normalizacją (w 1NF) Nadmiarowość w tym przykładzie jest oczywista. Niepotrzebnie występują pary powtórzeń: kod towaru - nazwa towaru oraz kod klienta - nazwa klienta. Dodatkowe trudności wystąpią podczas prób aktualizacji - jeżeli Nowak zmieni nazwę na Nowak S.A., trzeba będzie skorygować wszystkie rekordy, w których wystąpiła nazwa firmy. Nie wspominając już o tzw. anomaliach brzegowych: co np. z polami "kod klienta" i "nazwa klienta", jeżeli danego towaru nikt jeszcze nie zamówił? Jeżeli jednak założymy, że kodowi towaru lub klienta przypisana jest tylko jedna nazwa, wówczas wystarczy pamiętać w tej tabeli jedynie kod towaru i kod klienta, natomiast pełną nazwę klienta (i odpowiednio - towaru) należy przechowywać w osobnych plikach (tabelach). Dodatkową korzyść ze znormalizowania tej tabeli odczujemy, gdy przyjdzie nam np. zmienić nazwę klienta z Nowak na Nowak S.A. - po znormalizowaniu zrobimy to tylko w 1 miejscu, przed - trzeba by poprawiać każde wystąpienie klienta Nowak w tabeli zamówień. Tabele "Klienci" oraz "Towary" powstałe po normalizacji Tabela "Zakupy" po normalizacji została "odchudzona" o nadmiarowe nazwy towarów oraz klientów Pomiędzy tak powstałymi plikami danych obowiązują teraz relacje, które przedstawia poniższy schemat: Relacje pomiędzy tabelami bazy Po wprowadzeniu tych modyfikacji znikają wszystkie problemy, o których wspomiałem przedstawiając tabelę nieznormalizowaną. Wróćmy na chwilę do teorii. Zdefiniowanych zostało 5 postaci normalnych (ang. Normal Form, w skrócie NF); każda kolejna postać oznacza mniejszą nadmiarowość, jest więc można powiedzieć - doskonalsza. Warto zaznaczyć, że o ile 1NF jest wręcz naturalna w relacyjnych bazach danych i uzyskiwana jest na mocy definicji relacyjnej bazy danych, 2NF i 3NF również nie przysparzają kłopotów w realizacji, o tyle normalizacja do 4NF i 5NF wymaga pewnego wysiłku umysłowego. Wygodnie jest nawet posłużyć się pewnymi metodami algorytmicznymi wykrywającymi i usuwającymi nadmiarowość na tym poziomie. Projektanci baz danych najczęściej kończą proces normalizacji na 3NF, ufając swemu intuicyjnemu przeświadczeniu, że wszystko jest już "w porządku". W niektórych przypadkach stosowanie normalizacji traci sens. Wada pierwsza - czas Podstawową wadą normalizacji jest wydłużenie czasu wyszukiwania. By to unaocznić, wróćmy do poprzedniego przykładu: załóżmy, że baza jest już znormalizowana i chcemy sporządzić raport zawierający informacje o numerze i nazwie towaru oraz kodzie i nazwie kontrahenta. Gdyby baza miała postać sprzed normalizacji, zagadnienie sprowadziłoby się tylko do wydrukowania pól tej tabeli; po normalizacji musimy przeszukać dwie dodatkowe bazy danych w celu odszukania nazwy towaru i nazwy kontrahenta. Problem ten jest błahy w przypadku małych baz danych, przy dużych bazach o wysokim stopniu normalizacji staje się prawdziwą zmorą. Weźmy przykład z dziedziny księgowości: w programach typu księga handlowa tworzony jest tzw. plan kont. Pełna księgowość charakteryzuje się tym, że istnieją tzw. konta syntetyczne. Konto syntetyczne może mieć wiele kont analitycznych, ale konto analityczne może mieć tylko jedno konto syntetyczne. Jest to więc typowa relacja typu "jeden do wielu". Mówiąc inaczej możemy stwierdzić, że atrybut "konto syntetyczne" jest zależny funkcjonalnie od atrybutu "konto analityczne". Stąd już tylko krok do uzyskania drugiej postaci normalnej. Kierując się zasadami normalizacji powinniśmy w pojedynczych zapisach księgowych dotyczących danego konta analitycznego wyeliminować atrybut opisujący konto syntetyczne. Cóż jednak dalej? Często trzeba przecież sporządzać wydruk księgowań w porządku chronologicznym, gdzie każda linia tego wydruku powinna zawierać informacje o koncie syntetycznym i analitycznym. Jeżeli dokonaliśmy normalizacji opisanej powyżej, przed wydrukiem każdego rekordu trzeba będzie przeszukiwać plik zawierający plan kont, by odnaleźć numer konta syntetycznego. Jeżeli wydruk będzie się składał np. z 10000 zapisów, zaś plan kont będzie zawierał 500 pozycji, może to znacznie zwolnić działanie programu. Po przeanalizowaniu tych uwarunkowań wielu programistów zrezygnuje z normalizacji takiej relacji - umieszczając w pojedynczym zapisie księgowy numery obydwu kont. Podobny problem występuje w przypadku programów magazynowych - ilość danego towaru w magazynie można wyliczyć, sumując jego stan początkowy oraz transakcje zakupu, a następnie odejmując wszystkie transakcje sprzedaży. Zgodnie z zasadami normalizacji oznaczałoby to, że nie trzeba pamiętać aktualnej ilości towaru na magazynie. W praktyce zaś tego typu uproszczenie powodowałoby konieczność każdorazowego przeglądania wszystkich dokumentów magazynowych, by obliczyć stan danego towaru. Do podobnych wniosków dochodzili wszyscy twórcy znanych mi programów magazynowych, wprowadzając dodatkowe pole (np. "stan aktualny") w rekordzie opisującym dany towar. Wada druga - matematyka a rzeczywistość We wszystkich publikacjach opisujących proces normalizacji, jedna z podstawowych uwag mówi, że nie należy przechowywać w bazie danych wartości, które można wyliczyć. Jeżeli zatem w bazie danych mamy informacje, że Jan Kowalski zarobił 200 zł i z tej kwoty zapłacił 20 proc. podatku, to zwykle nie zapamiętujemy, ile dostał do ręki, bo to przecież kwota brutto odjąć 20 proc. z tej kwoty. Każdy, kto pisał program związany w jakiś sposób z podatkiem VAT (magazynówka, księgowość itp.), mając na uwadze powyższe zalecenie stwierdzał, że wystarczy pamiętać jedynie kwotę netto i stawkę podatku (0,7 lub 22 procent), zaś brutto i kwotę VAT można będzie w dowolnym momencie wyliczyć. Jakież było jego zdziwienie, gdy po zaksięgowaniu maksimum 10 pierwszych faktur, okazywało się, że nie zawsze 2 + 2 równa się 4: w matematyce co prawda przyjęto zaokrąglenie "od pięciu w górę", jednak pan na stacji benzynowej (bez wspomagania komputerowego w dodatku) wypisujący rachunek za paliwo może o tym wiedzieć. Trzeba więc księgować faktyczną kwotę z rachunku lub faktury, co sprowadza się do konieczności dodania tych dwóch pól, które z taką satysfakcją zaoszczędziliśmy. O tym, że przedstawiony sposób rozumowania programisty jest typowy można się przekonać analizując strukturę plików bazy danych różnych programów finansowych - pola opisujące kwotę VAT i brutto (lub netto, jeżeli liczy się "od brutta") znajdują się z reguły pod koniec rekordu, co świadczy o ich późniejszym "dopisaniu". Wada trzecia - nadmiarowość na osi czasu Nadmiarowość występuje np. w sytuacji opisanej dalej. W pewnym zakładzie każdy z pracowników otrzymywał tzw. dodatek stażowy obliczany wg schematu: stawka zasadnicza * liczba przepracowanych lat / 100 Wyrażenie było nieskomplikowane, programista zdecydował się więc skorzystać z zależności funkcyjnych i nie zapamiętywać w bazie danych kwoty dodatku stażowego. Po roku jednak zmienił się algorytm obliczania tego dodatku: (stawka zasadnicza + dodatek za szkodliwość) * * liczba przepracowanych lat / 100 Jak można się domyślać, gdyby po zmianie algorytmu ktoś próbował wydrukować płace za poprzedni rok, pojawiłyby się niezgodności. Programista miał do wyboru: skomplikować algorytm obliczania płac, umieszczając w nim uwarunkowanie od daty i ryzykując, że za rok będzie musiał dokonać kolejnej modyfikacji, albo dodać w bazie nowe pole, zawierające kwotę dodatku stażowego. 2.Opis normalizacji Normalizacja to proces organizacji danych w bazie danych. Polega on na tworzeniu tabel i ustanawianiu pomiędzy nimi powiązań według reguł obowiązujących zarówno przy ochronie danych, jak i uelastycznianiu bazy danych przez eliminowanie powtarzających się i niespójnych zależności. Powtarzające się dane niepotrzebnie zajmują miejsce na dysku i są przyczyną powstawania problemów z obsługą. Jeśli konieczna jest zmiana danych istniejących w więcej niż jednej lokalizacji, musi być ona przeprowadzona we wszystkich lokalizacjach w ten sam sposób. Implementacja zmiany adresu klienta jest o wiele łatwiejsza, jeśli dane są przechowywane tylko w tabeli Klienci i w żadnym innym miejscu bazy danych. Co to jest „niespójna zależność” ? O ile przeglądanie tabeli Klienci w poszukiwaniu adresu konkretnego klienta można nazwać zachowaniem intuicyjnym, to poszukiwanie w tej tabeli pensji, której wypłaty wymaga pracownik od klienta, nie ma żadnego sensu. Pensja pracownika jest związana z pracownikiem lub zależy od pracownika i dlatego powinna być przeniesiona do tabeli Pracownicy. Niespójne zależności mogą utrudniać dostęp do danych, ponieważ ścieżka ich odnajdywania może zostać utracona lub uszkodzona. Istnieje kilka reguł normalizacji baz danych. Każda reguła nosi nazwę „postać normalna”. Jeśli przestrzegana jest pierwsza reguła, o postaci bazy danych mówi się, że jest „pierwszą postacią normalną”. Jeśli przestrzegane są pierwsze trzy reguły, postać bazy danych przyjmuje się za „trzecią postać normalną”. Chociaż możliwe są inne poziomy normalizacji, trzecia postać normalna uważana jest za najwyższy poziom wymagany przez większość aplikacji. Jak to bywa z wieloma formalnymi regułami i specyfikacjami, rzeczywistość nie zawsze pozwala na ich dokładne odwzorowanie. Ogólnie, do odnalezienia niedogodności normalizacja wymaga dodatkowych tabel i dla niektórych osób jest to uciążliwe. Przed podjęciem decyzji o złamaniu jednej z pierwszych trzech reguł normalizacji należy upewnić się, że projekt aplikacji przewiduje występowanie problemów, takich jak powtarzające się dane lub niespójne zależności. Do poniższych opisów dodane zostały przykłady. Pierwsza postać normalna W poszczególnych tabelach wyeliminuj powtarzające się grupy. Dla każdego zestawu danych pokrewnych utwórz oddzielną tabelę. Dla każdego zestawu danych pokrewnych określ klucz podstawowy. Do przechowywania podobnych danych w jednej tabeli nie należy używać wielu pól. Na przykład rekord służący do śledzenia pozycji inwentarzowej, która może pochodzić z dwóch różnych źródeł, może zawierać pola Kod sprzedawcy 1 oraz Kod sprzedawcy 2. Co się zdarzy po dodaniu trzeciego sprzedawcy? Dodawanie pola nie dostarcza odpowiedzi. Wymaga to modyfikacji programu i tabel oraz nie umożliwia obsługi zmieniającej się dynamicznie liczby sprzedawców. Zamiast tego należy umieścić wszystkie informacje o sprzedawcach w oddzielnej tabeli o nazwie Sprzedawcy, a następnie połączyć magazyn ze sprzedawcami za pomocą klucza z numerem pozycji, albo sprzedawców z magazynem za pomocą klucza z kodem sprzedawcy. Druga postać normalna Utwórz oddzielne tabele dla zestawów wartości, odnoszących się do wielu rekordów. Ustal powiązania tabel za pomocą klucza obcego. Rekordy nie powinny zależeć od niczego innego niż klucz podstawowy tabeli (w razie potrzeby może to być klucz złożony). Rozważmy, na przykład, adres klienta w systemie księgowym. Obecność adresu konieczna jest w tabeli Klienci, ale również w tabelach Zamówienia, Wysyłka, Faktury, Należności i Inkaso. Zamiast przechowywać adres w postaci wpisu w każdej tabeli, przechowuje się go w jednym miejscu: albo w tabeli Klienci, albo w oddzielnej tabeli Adresy. Trzecia postać normalna Wyeliminuj pola, które nie zależą od klucza. Wartości rekordu, które nie są częścią jego klucza, nie należą do tabeli. Zazwyczaj, jeśli zawartość grupy pól odnosi się do więcej niż jednego rekordu tabeli, należy rozważyć umieszczenie tych pól w oddzielnej tabeli. Na przykład w tabeli Rekrutacja pracowników może znajdować się nazwa i adres uczelni, którą ukończył kandydat. Do korespondencji seryjnej potrzebna jest jednak kompletna lista uczelni. Jeśli informacje o uczelniach przechowywane są w tabeli Kandydaci, nie ma możliwości wyświetlenia listy uczelni bez aktualnych kandydatów. Utwórz oddzielną tabelę Uczelnie i połącz ją z tabelą Kandydaci za pomocą klucza z kodem uczelni. WYJĄTEK: Stosowanie reguł trzeciej postaci normalnej, chociaż teoretycznie wskazane, nie zawsze jest praktyczne. Chcąc wyeliminować wszystkie możliwe wewnętrzne zależności pomiędzy polami tabeli Klienci, należy utworzyć oddzielne tabele dla miast, kodów pocztowych, przedstawicieli handlowych, klas klienta i innych czynników, które mogą być zduplikowane w wielu rekordach. Normalizacja oznacza teoretycznie poprawę wydajności. Jednak wiele mniejszych tabel może spowodować spadek wydajności lub brak możliwości otwarcia pliku i przekroczenie pojemności pamięci. Bardziej realne może okazać się zastosowanie trzeciej postaci normalnej tylko do często zmienianych danych. Pozostawiając niektóre pola zależne, zmień projekt aplikacji tak, aby po zmianie dowolnego pola wymagała od użytkownika sprawdzenia wszystkich pól pokrewnych. Inne postacie normalizacji Istnieje czwarta postać normalna, zwana również postacią normalną Boyce'a-Codda (BCNF) oraz piąta postać normalna, ale są one rzadko wykorzystywane w praktyce. Zlekceważenie tych reguł może skutkować mniej doskonałym projektem bazy danych, ale nie powinno ono wpływać na funkcjonalność. Normalizowanie przykładowej tabeli W poniższych krokach przedstawiono proces normalizacji fikcyjnej tabeli studentów. 1. Tabela nieznormalizowana: NrStudenta Doradca Pok-Dor Klasa1 Klasa2 Klasa3 2. 1022 Nowak 412 101-07 143-01 159-02 4123 Kowalski 216 201-01 211-02 214-01 Pierwsza postać normalna: brak powtarzających się grup Tabele powinny mieć tylko dwa wymiary. Ponieważ jeden student ma kilka klas, klasy powinny znajdować się w oddzielnej tabeli. Występowanie pól Klasa1, Klasa2 i Klasa3 w powyższych rekordach jest oznaką problemów podczas projektowania. Arkusze kalkulacyjne często wykorzystują trzeci wymiar, ale tabele nie powinny. Innym podejściem do problemu jest relacja jeden-do-wielu, w której nie należy strony jeden i strony wielu umieszczać w tej samej tabeli. Zamiast tego, należy utworzyć inną tabelę w pierwszej postaci normalnej, eliminując powtarzające się grupy (NrKlasy), tak jak to przedstawiono poniżej: 3. NrStudenta Doradca PokNrKlasy Dor 1022 Nowak 412 101-07 1022 Nowak 412 143-01 1022 Nowak 412 159-02 4123 Kowalski 216 201-01 4123 Kowalski 216 211-02 4123 Kowalski 216 214-01 Druga postać normalna: eliminowanie powtarzających się danych W powyższej tabeli dla każdego pola NrStudenta istnieje wiele wartości w polach NrKlasy. Pole NrKlasy nie jest czynnościowo zależne od pola NrStudenta (klucz podstawowy), dlatego ta relacja nie znajduje się w drugiej postaci normalnej. Drugą postać normalną przedstawiono na następujących dwóch tabelach: Studenci: NrStudenta Doradca Pok-Dor 1022 Nowak 4123 Kowalski 216 Rejestracja: NrStudenta NrKlasy 1022 101-07 1022 143-01 1022 159-02 4123 201-01 412 4. 4123 211-02 4123 214-01 Trzecia postać normalna: eliminowanie danych, które nie zależą od klucza W ostatnim przykładzie pole Pok-Dor (numer pokoju doradcy) jest czynnościowo zależne od atrybutu Doradca. Rozwiązaniem jest przeniesienie tego atrybutu z tabeli Studenci do tabeli Wydział, tak jak to przedstawiono poniżej: Studenci: NrStudenta Doradca 1022 Nowak 4123 Kowalski Wydział: Nazwa Pokój Wydział Nowak 412 42 Kowalski 216 42 3."Model relacyjny" oraz "postacie normalne modelu relacyjnego" "Model relacyjny" oraz "postacie normalne modelu relacyjnego" zostały po raz pierwszy zdefiniowane przez dr. E. F. Codda (Codd 1970), a następnie rozwinięte później przez innych autorów. Wymyślił on termin "relacje znormalizowane", zapożyczając go z aktualnego żargonu politycznego. Dziedzina matematyki, zwana algebrą relacyjną, zajmuje się odwzorowaniami zbiorów, określanymi rachunkiem predykatów z dziedziny logiki matematycznej. Tak samo jak w przypadku równania algebraicznego, występuje tu wiele postaci tej samej instrukcji relacyjnej, ale "postaciami normalnymi" relacji są pewne konstrukcje o wymaganej, sformalizowanej definicji. Celem postaci normalnych jest unikanie pewnych anomalii danych, jakie. mogą występować w tabelach nieznormalIzowanych. Anomalie danych łatwiej będzie wyjaśnić posługując się przykładem, ale wykażmy się cierpliwością aż do czasu zdefiniowania kilku terminów. I Predykat jest to instrukcja postai A(X) oznaczająca, że X posiada właściwość A. I Na przykład, "John pochodzi ze stanu Indiana jest predykatem; w tym przypadku "John" jęst predykatem. Relacja to predykat o dwóch podmiotach. Powszechnie stosowanym sposobem przedstawiania zbioru instrukcji relacyjnych jest tabela, w której kolumny są atrybutami relacji, a każdy wiersz stanowi określoną instrukcję relacyjną. Dr Codd definiując model relacyjny podał 12 reguł dotyczących przedstawiania relacji jako tabeli: 0. (Tak, to jest reguła zerowa). Aby można było uznać dany system za system zarządzania relacyjnych baz danych, musi on wykorzystywać (wyłącznie) relacyjne mechanizmy do zarządzania bazą danych. 1. Reguła informacyjna: jest to po prostu wymaganie, aby wszystkie informacje zawarte w bazie danych były przedstawiane w jeden i tylko jeden sposób, mianowicie za pomocą wartości umieszczanych w kolumnach w obrębie wierszy tabel. SQL stosuje tę regułę. 2. Reguła gwarantowanego dostępu: te reguła jest zasadniczo powtórną instrukcją zasadniczego wymagania dotyczącego kluczy podstawowych. Stanowi ona, że każda poszczególna wartość skalrna w bazie danych musi mieć zapewnioną możliwość logicznego adresowania, wykorzystując nazwę zawierającej ją tabeli, nazwę zawierającej ją kolumny oraz wartość klucza podstawowego zawierającego ją wiersza. SQL spełnia tę regułę w przypadku tabel posiadających klucz podstawowy, ale w ogóle nie wymaga, aby tabele posiadały ten klucz. 3. Uporządkowana obsługa wartości NULL: wymaga się, aby SZBD (System zarządzania bazami danych) obsługiwał reprezentację brakujących informacji oraz informacji nieadekwatnych, to znaczy uporządkowanych, odmiennych od wszystkich wartości prawidłowych oraz niezależnych od typu danych. Przyjmuje się również, że SZBD musi obsługiwać taką reprezentację w uporządkowany sposób. W SQL-u występuje wartość NULL, która jest wykorzystywana zarówno dla wartości brakujących, jak i dla wartości nieadekwatnych zamiast dwóch oddzielnych symboli, czego chciał dr Codd. 4. Aktywny katalog dostępny na bieżąco, oparty na modelu relacyjnym: wymaga się, aby system obsługiwał wbudowany katalog relacyjny z bieżącym dostępem dla uprawnionych użytkowników używających ich zwykłego języka zapytań. SQL spełnia ten wymóg. 5. Reguła dotycząca podjęzyka obsługi danych o pełnych możliwościach: System musi obsługiwać przynajmniej jeden język relacyjny, który o charakteryzuje się liniową składnią, o może być używany zarówno w trybie interaktywnym, jak iw obrębie programów aplikacyjnych oraz o obsługuje operacje definiowania danych (łącznie z definiowaniem perspektyw), operacje manipulowania danymi (aktualizację, także wyszukiwanie), ograniczenia związane z bezpieczeństwem i integralnością oraz operacje zarządzania transakcjami (rozpoczynanie, zapis zmian i ponowny przebieg). SQL jest całkiem niezły pod tym względem, ponieważ wszystkie zdefiniowane przez Codda operacje można napisać w DML (ang. Data Manipulation Language, Język manipulowania danymi). 6. Reguła aktualizacji perspektyw: wszystkie perspektywy, które teoretycznie dają się aktualizować, muszą być aktualizowane przez system. Pod tym względem SQL jest słabo wyposażony; postanowiono o standaryzacji najbezpieczniejszego przypadku. Aktualizowanie perspektyw jest bardzo złożonym zagadnieniem. 7. Polecenia wstawiania, aktualizacji oraz usuwania w języku wysokiego poziomu: wymaga się, aby system obsługiwał operatory INSERT, UPDATE oraz DELETE dotyczące całych zbiorów. SQL spełnia ten wymóg. 8. Fizyczna niezależność danych: to oczywiste. Każdy istniejący produkt wykazuje pewną fizyczną zależność, ale SQL jest pod tym względem lepszy od większości innych języków programowania. 9. Logiczna niezależność danych: to także jest oczywiste. Ten aspekt jest całkiem dobrze realizowany w SQL-u. 10. Niezależność integralnościowa: ograniczenia integralnościowe muszą być specyfikowane pojedynczo z programu aplikacyjnego i przechowywane w katalogu. Musi istnieć możliwość dokonywania stosownej zmiany takiego ograniczenia bez zbędnego oddziaływania na istniejące aplikacje. SQL-92 spełnia ten wymóg. 11. Niezaeżność dystrybucyjna: istąiejące aplikacje powinny działać bez zakłóceń, : (a) kiedy następuje wprowadzenIe rozproszonej Wersji SZBD oraz (b) kiedy istniejące dane rozproszone są ponownie dystrybuowane w obrębie systemu. Obecny etap to dopiero początek pracy z rozproszonymi wersjami SQL-a, jest zatem nieco zbyt wcześnie, aby można było ocenić, czy SQL spełnia to kryterium. 12. Reguła nieprowadzenia "działalności wywrotowej": jeśli system jest wyposażony w interfejs niskiego poziomu (operacje na pojedynczych rekordach), nie może być użyty do prowadzenia działalności wywrotowej (np. omijania zabezpieczeń relacyjnych lub ograniczeń integralnościowych). W tym przypadku SQL-92 jest dobry . Codd określił również 9 cech strukturalnych, 3 cechy integralnościowe oraz 18 cech manipulacyjnych, które także są wymagane. Codd swą listę 12 reguł rozszerzył do 333 w drugiej wersji modelu relacyjnego. Postacie normalne stanowią próbę zapewnienia, aby użytkownicy nie zniszczyli wartościowych danych, ani nie wprowadzili nieprawidłowych danych do bazy. Jednym ze sposobów uniknięcia błędów jest tylko jednokrotne występowanie informacji w bazie danych, ponieważ w przypadku występowania informacji więcej niż raz, jedna z tych instancji jest prawdopodobnie błędna człowiek z dwoma zegarkami nigdy nie jest pewien bieżącego czasu.Proces projektowania bazy danych jest zwany normalizacją. Nie jest on tajemniczy, ale może być złożony. Aby ułatwić sobie to zadanie, możemy zakupić programy narzędziowe kategorii CASE, ale najpierw powinniśmy poznać trochę teorii, zanim zaczniemy ich używać. http://db.tigra-system.pl/art.php?id=11