Porównanie szybkości działania baz danych w I i III postaci normalnej.
Do przeprowadzenia badania zastosowano bazę danych MySQL
wykorzystującą silnik MyISAM.
Specyfikacja komputera, na którym przeprowadzono badania:
Procesor: AMD Sempron 2600+ ( 1,6@2,0 GHz)
Pamięć operacyjna: 1GB (400 MHz)
Dysk twardy: Seagate 500 GB Barracuda 7200RPM 16MB cache, SATA II, NCQ
System operacyjny: Windows XP Professional SP2
Na potrzeby badania została zaprojektowana baza danych zawierająca kody
pocztowe oraz informacje o mieście, powiecie oraz województwie dla danego kodu. Baza zawiera 43272 rekordów.
I postać normalna
Relacja jest w pierwszej postaci normalnej, jeśli wartości atrybutów są elementarne
(atomowe, niepodzielne): są to pojedyncze wartości określonego typu, a nie zbiory
wartości. Tabela reprezentująca tę relację nie zawiera powtarzających się grup
informacji. Każda kolumna jest wartością skalarną (atomową), a nie macierzą lub
listą czy też czymkolwiek, co posiada własną strukturę.
III postać normalna
Relacja jest w trzeciej postaci normalnej wtedy i tylko wtedy gdy jest w II postaci
normalnej i kolumny są w bezpośredniej zależności funkcyjnej jedynie od klucza
głównego. Nie ma takiej zależności między innymi kolumnami. Oznacza to, że nie
istnieją żadne zależności przechodnie (nietrywialne).
Porównanie czasu zapytania wyświetlającego wszystkie kody łącznie z miejscowościami oraz powiatami znajdującymi się w danym województwie.
Zapytanie dla 1NF
SELECT `kod` , `miejscowosc` , `wojewodztwo` , `powiat`
FROM `kody`
WHERE `wojewodztwo` = 'wielkopolskie'
Zapytanie dla 3NF
SELECT `kod` , `miejscowosc` , powiat, wojewodztwo
FROM kody
JOIN miejscowosci
ON kody.miejscowosci_idmiejscowosci = miejscowosci.idmiejscowosci
JOIN powiaty
ON miejscowosci.powiaty_idpowiaty = powiaty.idpowiaty
JOIN wojewodztwa
ON powiaty.wojewodztwa_idwojewodztwa = wojewodztwa.idwojewodztwa
WHERE `wojewodztwo` = 'wielkopolskie'
Próba: | 1NF (sek) | 3NF (sek) |
1 | 0,0216 | 0,0013 |
2 | 0,0204 | 0,0014 |
3 | 0,0213 | 0,0014 |
4 | 0,0211 | 0,0016 |
5 | 0,0210 | 0,0018 |
6 | 0,0213 | 0,0020 |
7 | 0,0215 | 0,0060 |
8 | 0,0214 | 0,0010 |
9 | 0,0205 | 0,0011 |
10 | 0,0461 | 0,0011 |
Średnia: | 0,0236 | 0,0019 |
Mediana: | 0,0213 | 0,0014 |
Odchylenie: | 0,0079 | 0,0015 |
Porównanie zapytania dodawania rekordu do bazy danych.
Zapytanie dla 1NF
INSERT INTO kody( `kod` , `miejscowosc` , `wojewodztwo` , `powiat` )
VALUES ('00-908', 'Warszawa', 'mazowieckie', 'm. Warszawa')
Zapytanie 3NF
Zestaw zapytań powodujący dodanie tego samego wpisu w 3NF.
INSERT INTO wojewodztwa (`województwo`) VALUES ('mazowieckie');
INSERT INTO powiaty (`powiat`, `wojewodztwa_idwojewodztwa`)
VALUES ('m. Warszawa',
(SELECT idwojewodztwa FROM wojewodztwa
WHERE wojewodztwo ='mazowieckie')
);
INSERT INTO miejscowosci (`miejscowosc,powiaty_idpowiaty`)
VALUES ('Warszawa',
(SELECT idpowiaty FROM powiaty
WHERE powiat ='m. Warszawa')
);
INSERT INTO kody( `kod` , `miejscowosci_idmiejscowosci`)
VALUES ('00-908',
(SELECT idmiejscowosci FROM miejscowosci
WHERE miejscowosc ='Warszawa')
);
Próba: | 1NF (sek) | 3NF (sek) |
1 | 0,0005 | 0,0910 |
2 | 0,0005 | 0,0832 |
3 | 0,0006 | 0,0916 |
4 | 0,0006 | 0,0833 |
5 | 0,0005 | 0,0832 |
6 | 0,0007 | 0,0749 |
7 | 0,0005 | 0,0832 |
8 | 0,0005 | 0,1654 |
9 | 0,0005 | 0,1343 |
10 | 0,0005 | 0,0832 |
Średnia: | 0,0005 | 0,0973 |
Mediana: | 0,0005 | 0,0833 |
Odchylenie: | 0,0001 | 0,0290 |
Czas na małe podsumowanie
Ponieważ w przypadku operacji dodawania rekordu w 3 postaci normalnej doszło do dość sporych odchyleń do oceny użyto mediany.
Podczas pobierania danych z bazy zdecydowanie szybsza jest 3NF (Ponad 12 razy). Dzieje się tak ponieważ podczas przeszukiwania rekordów nie ma nadmiarowych danych, które również trzeba sprawdzić. W naszym przypadku w trakcie badań gdy chcieliśmy uzyskać wyniki jedynie dla danego województwa musieliśmy w trzeciej postaci normalnej przeszukać jedynie 16 rekordów po czym wyświetlić wyniki z dopasowaniem kluczy. W 1NF silnik bazy danych musiał przeszukać 43272 rekordów i każdorazowo sprawdzać województwo.
W przypadku dodawania wpisu zdecydowanie szybsza jest 1NF (w teście około 166 razy szybsza) ponieważ jest to tylko jedno zapytanie zawierające wszystkie dane. W przypadku 3NF trzeba dokonać wpisów we wszystkich relacjach oraz odpytać bazę jakie wartości kluczy obcych należy nadać w relacji.
W świecie rzeczywistym zdecydowanie częściej dokonuje się operacji SELECT odczytującej dane z bazy danych dlatego uważam 3NF za postać bardziej wydajną, jednak istnieją modele danych, w których zastosowanie 1NF jest zdecydowanie bardziej opłacalne czasowo.