Bazy danych
Wstęp
edytujBazy danych to dziedzina informatyki, dynamicznie się rozwijająca i mająca szerokie zastosowanie w wielu miejscach wszędzie tam, gdzie niezbędne jest przetwarzanie jakichkolwiek danych. Rzadko spotykanym bowiem zjawiskiem jest aplikacja, która nie operuje na żadnych danych, a bazy niezwykle ułatwiają pracę z nimi. Zwykły użytkownik komputera, a nawet osoba, która z niego nie korzysta, spotyka się z bazami danych na każdym kroku. Czytelnik korzysta właśnie z serwisu, który nie istniałby bez bazy danych. Kupno biletu kolejowego, robienie zakupów czy nawet zwykłe wykonanie połączenia telefonicznego to czynności, które zazwyczaj nie kojarzą się z informatyką i z jej omawianym działem, a jednak korzystają z jego wytworów i mają z nim bardzo wiele wspólnego. Można zaryzykować stwierdzenie, że wiele innych dziedzin zarówno informatyki, jak i życia nie rozwijałoby się lub ich rozwój byłby ograniczony, gdyby nie istniały bazy danych. Problem przetwarzania informacji przez aplikacje istniał od początku istnienia programowania, a upływ czasu spowodował powstanie baz danych oraz systemów zarządzania bazami danych (silnikami baz danych). Jakiekolwiek operowanie na większych ilościach informacji implikuje bowiem rozwój tego działu informatyki.
Zwroty "operowanie na danych", "większe ilości informacji" jest oczywiście nieprecyzyjny, a np. "silnik bazy danych" może być kompletnie niezrozumiały. Warto byłoby z początku sprecyzować zatem, co one (oraz inne im podobne) oznaczają, a w późniejszym czasie sformalizować w pewien sposób obszar, w jakim się poruszamy.
Co to są bazy danych i systemy zarządzania bazą danych i dlaczego je stosować?
edytujNa początek warto zdefiniować samo pojęcie "baza danych". Termin ten zależnie od kontekstu znaczy bowiem coś innego. Często mówi się bowiem: „używam bazy danych”, „baza danych PostgreSQL pozwala na...”, „schemat bazy danych”, „nazwa bazy danych potrzebna do zalogowania”, „parametry połączenia z bazą” itp., a w każdym z wymienionych zwrotów mamy na myśli coś innego. Najogólniej rzecz biorąc, „baza danych” to zbiór informacji wraz z możliwością łatwego dostępu oraz ich zmiany (tj. modyfikacją, dodawaniem nowych i usuwaniem starych) z poziomu aplikacji z niej korzystającej. W taki właśnie sposób rozumiane jest to określenie w pierwszym z wymienionych zwrotów. „Używam bazy danych” oznacza „korzystam ze zbioru informacji, który łatwo odczytywać i zmieniać”.
Patrząc na temat pod tym kątem, można powiedzieć, że np. plik tekstowy można uznać za bazę danych jeśli odczytanie i modyfikację zapisanych w nim informacji w konkretnym zastosowaniu uznamy za łatwe (i symetrycznie – jeśli nie uznamy tego za łatwe nie można będzie pliku nazwać „bazą danych”). Przykładowo niech program wyświetla krótki komunikat, który powinien mieć możliwość dowolnej zmiany. Zastosowanie wtedy zwykłego pliku z tekstem jest jak najbardziej dobrym rozwiązaniem i można go nazwać „bazą danych”. Na rysunkach poniżej przedstawiono schematycznie sposoby, w jaki aplikacja może korzystać z danych. I tak rysunek 1 przedstawia najprostszą sytuację, kiedy dane, z jakich program korzysta, są wbudowane do niego na stałe.
Trudno w takim przypadku mówić o bazie danych, gdyż zazwyczaj nie istnieje możliwość zmiany zawartych w programie informacji, a już na pewno jest to utrudnione. Rysunek 2 przedstawia sytuację pasującą do przykładu z zewnętrznym plikiem tekstowym.
Zbiór na dysku zawiera potrzebne informacje i jest wydzielony od samej aplikacji. Pozwala to na łatwą ich modyfikację oraz odczyt. Jak widać, elipsa reprezentująca program i bazę danych nachodzą na siebie. Symbolizuje to fakt, iż program musi znać strukturę pliku podczas odczytu informacji z bazy oraz bezpośrednio w nią ingerować w trakcie ich modyfikacji. Struktura pliku jest tutaj rozumiana jako sposób przechowywania danych, która może być bardziej złożona niż ta wspomniana wyżej. Przykładowo jeśli aplikacja wyświetla kilka tekstów, niezbędnym staje się rozdzielenie ich jakoś w pliku, tak aby program był w stanie przeczytać bądź modyfikować konkretny z nich. Trzeba zatem wymyślić sposób, w jaki dane przechowywane są w bazie. Można by założyć zatem, iż jedna linijka w pliku tekstowym to jeden komunikat i skutecznie rozwiąże to przedstawiony problem. Spowoduje to jednak pojawienie się też trudności, jeśli okaże się, że wyświetlane komunikaty będą mogły zawierać znaki nowej linii. Program musi rozróżnić taki znak w środku tekstów od tego, który je rozdziela w samym pliku. Ponadto np. w nowszej wersji aplikacji może pojawić się potrzeba przechowywania poza samym tekstem komunikatu także innych informacji go dotyczących, np. jego rodzaj (informacja, ostrzeżenie, pytanie) oraz nazwę obrazka wyświetlanego obok. Spowoduje to konieczność zmiany struktury pliku i np. ustaleniu, iż każda linijka zawiera informacje o jednym komunikacie rozdzielone specjalnym znakiem przy czym znak enter oraz znak rozdzielający w samych danych nie mogą się pojawiać, aby nie spowodować problemów z ich interpretacją. W każdym razie wymusi to zmianę sposobu przechowywania danych, a to pociągnie za sobą konieczność zmiany już napisanego kodu korzystającego z niego. Skomplikujmy jeszcze nieco nasz przykład i załóżmy że, komunikatów jest bardzo dużo, a my chcemy wyświetlić wszystkie których rodzaj obrazka mówi, iż jest to ważny komunikat ostrzegawczy. Przeszukiwanie wtedy pliku i sprawdzanie każdej linijki może okazać się za wolne. Sprytny programista mógłby pogrupować wyświetlane teksty na podstawie rodzaju i utworzyć dla każdej grupy oddzielny plik w specjalnym katalogu, ale to z kolei pociągnie kolejne zmiany już napisanego kodu. Co będzie jednak, jeśli chcielibyśmy także przyspieszyć odczytywanie komunikatów wyświetlanych obok konkretnego obrazka znając jego nazwę? A jeśli aplikacja ma umożliwić wymianę bardziej złożonych informacji (np. finansowych) pomiędzy osobami znajdującymi się w różnych częściach świata? Sam plik na dysku twardym komputera wtedy nie wystarczy. W takim przypadku można by umieścić go na komputerze z dostępem do Internetu i korzystając z np. serwera FTP, czytać i zapisywać go (rysunek 3). Rozwiąże to drugi problem, jednak zwiększy pierwszy. Przeszukiwanie danych będzie wymagało każdorazowego przesłania zawartości pliku przez łącze sieciowe, co drastycznie zmniejszy wydajność.
Proszę zwrócić uwagę, że sam plik nie jest już nazywany „bazą danych”, gdyż umieszczony na serwerze sam nie pozwala na dostęp do zawartych w nich danych ani na ich modyfikację. Dopiero dane wraz z serwerem FTP tworzą twór zdefiniowany wcześniej jako baza danych. Przedstawione rozwiązanie jest zadowalające jedynie w marginalnej części przypadków, bo (pomijając mało wydajne przeszukiwanie), co się stanie, jeśli więcej niż jedna kopia programu jednocześnie będą chciały zapisać dane do tego pliku (rysunek 4)?
Czy „wejdą sobie w drogę”? Czy trzeba samodzielnie opracować jakiś mechanizm blokady? Program nie ma jednak łatwej możliwości sprawdzenia, czy dany plik z serwera FTP próbuje odczytać inna aplikacja próbująca korzystać z tych samych danych. „Wie” to serwer, ale nie udostępnia tej wiedzy. Problem komplikuje się jeszcze bardziej, jeśli dołożymy do programu możliwość zmiany nie tylko samych danych, ale także ich rodzaju i dodawanie nowych typów przechowywanych informacji. Oczywiście można dodać do aplikacji kod, który na podstawie np. innych plików opisujących dane będzie „rozpoznawać”, jakie informacje są zapisane, i na tej podstawie dopiero będzie je same odczytywał (informacje opisujące inne informacje nazywane są „metadanymi”). Staje się to jednak niezwykle skomplikowane. Jak widać zatem, im bardziej wymagający jest program, tym bardziej złożona staje się obsługa danych i więcej pracy wymaga jego stworzenie, zarówno jeśli chodzi o stopień skomplikowania sposobu, w jaki trzymane są dane, jak i mechanizmy blokujące część informacji na czas ich modyfikacji oraz pozwalające na jednoczesny dostęp do nich wielu użytkownikom. Pisanie za każdym razem tak dużej części kodu byłoby nieefektywne i bardzo wydłużałoby proces tworzenia oprogramowania. Właśnie to ostatnie jest jednym z głównych powodów, dla których pomiędzy bazą danych (rozumianą jako zbiór informacji z określonym sposobem jego przechowywania) a programem wprowadza się dodatkowe „coś”, co rozwiązuje przestawione problemy. Tym czymś jest system zarządzania bazą danych, w skrócie SZBD (rysunek 5)
Często dla uproszczenia także nazywany bazą danych, tak jak miało to miejsce w zwrocie „baza danych PostgreSQL pozwala na...”, gdzie mowa o konkretnym takim systemie. Równie często spotyka się określenie „silnik bazy danych”. System zarządzania bazą danych przejmuje na siebie wiele obowiązków związanych z „technicznymi” aspektami przechowywania danych między innymi to, w jaki sposób są one trzymane na dysku. Dzięki temu, iż większość obecnie stosowanych silników bazy danych może działać jako oprogramowanie serwera możliwym staje się udostępnienie bazy dla komputerów na całym świecie. SZBD przejmuje na siebie także odpowiedzialność za blokowanie informacji na czas ich modyfikacji, by uniknąć konfliktów oraz pozwala dokonać wyszukiwania danych po stronie serwera, przez co do aplikacji trafiają tylko odfiltrowane dane, które są dla niej istotne. Program chcąc odczytać bądź zmodyfikować dane, musi korzystać z pośrednictwa SZBD. Aby to jednak było możliwe, SZDB i aplikacja muszą móc się „porozumieć”, co symbolizowane jest na rysunku przez przecinające się elipsy, lecz – jak widać – do danych bezpośredni dostęp ma jedynie SZBD.
Różne sposoby patrzenia na dane – ogólnie o modelach danych
edytujGłównym zadaniem bazy jest przechowywanie pewnych danych. Czym jednak są te dane? Z punktu widzenia komputera to jedynie ciąg bitów zapisany w pamięci. Z punktu widzenia człowieka są zaś one pewnymi informacjami, które oznaczają konkretną rzecz istotną w aktualnie rozpatrywanej dziedzinie zagadnień. Jest to ważne, gdyż sama wartość pewnej danej nic nie znaczy. Przykładowo liczba "185" nie mówi nic, dopóki nie będziemy wiedzieli, jak ją zinterpretować. Podobnie jest z pewną grupą danych. Zbiór pewnych liczb także niewiele znaczy, dopóki nie będziemy wiedzieli, jak je zinterpretować. Interpretacja danych zależy jednak od konkretnego przypadku. Każda aplikacja będzie zapewne przechowywać przy użyciu bazy danych różnego rodzaju informacje mające diametralnie różny sens i znaczenie. Ponadto dane, które są zapamiętywane, często są ze sobą w pewien sposób powiązane. Przykładowo jeśli baza przechowuje informacje o klientach, to zapewne zapamięta ich dane osobowe, takie jak adres, nazwisko itp. Jeśli jej zadaniem jest przechowywanie także zamówień, to zapamięta też takie informacje jak data złożenia zamówienia, produkty, które zostały zamówione, kwota zamówienia itd., przy czym pewne zamówienia są powiązane z klientem. Istnieje zatem logiczny związek pomiędzy pewnymi grupami danych przechowywanymi w bazie danych bardzo ważny, jeśli chodzi o możliwość ich wzajemnego przetwarzania. Związek ten odrobinę inaczej wygląda jednak z punktu widzenia człowieka, który interpretuje dane, a inaczej z punktu widzenia SZBD, który je jedynie przechowuje. System zarządzania bazą danych musi być bowiem w stanie obsłużyć dane niezależnie od tego, jaką treść one za sobą niosą i jak są ze sobą nawzajem powiązane. Mając jednak informacje, jak są one ze sobą powiązane, może sprawdzać poprawność takich powiązań. Odwołując się do przykładu – każde zamówienie może złożyć jeden klient. Z logicznego punktu widzenia niemożliwym jest, by jedno zamówienie złożyło więcej niż jeden klient lub nie złożył go nikt. Baza zatem może sprawdzić i nie pozwolić na takie opisane wyżej sytuacje. Musi w tym celu jednak mieć informacje o tym, jak dane są powiązane. Właśnie o tym mówi logiczny model danych – jeden z modeli, przez pryzmat którego możemy patrzeć na dane. Utrzymanie danych w bazie, tak aby były logicznie poprawne (czyli zgodne z modelem logicznym, sensowne z punktu widzenia ich interpretacji), to utrzymanie spójności danych. Zacznijmy jednak od początku.
Baza danych powstaje w celu odwzorowania pewnego wycinka rzeczywistości w pamięci komputera. Jest tak zarówno w przypadku bazy przechowującej informacje o zamówieniach klientach w sklepie internetowym, na temat ludności, jak i bazie zbierającej statystyki połączeń telefonicznych firmy telekomunikacyjnej. Podstawą bazy danych jest wycinek rzeczywistości istotny z punktu widzenia tworzonej aplikacji. Opis tego fragmentu z perspektywy przyszłego użytkownika aplikacji jest zwany modelem zewnętrznym. Na tym etapie abstrakcji problemu nie ma jeszcze informacji szczegółowych dotyczących tego, jakie konkretnie informacje są przechowywane bądź szczegółowych powiązań między nimi, a jedynie ogólna wizja, jakie dane występują w systemie informatycznym z punktu widzenia jednego z użytkowników. W procesie analizy dziedziny problemu, którym zajmuje się aplikacja bazodanowa i zbierania informacji z kilku źródeł powstaje poszerzony obraz, jakie dane znajdą się w systemie zwany modelem pojęciowym. Model ten opisuje pojęcia właśnie – czyli to, co znajduje się w bazie danych z uwzględnieniem sposobu, w jaki system zarządzania bazą danych traktuje dane i jak udostępnia je użytkownikowi, czyli z uwzględnieniem modelu danych. Współczesne systemy baz danych opierają się najczęściej na modelu relacyjnym. Na razie możemy przyjąć, iż oznacza to, że dane przechowywane są w formie tabel, w których każda kolumna to opis konkretnej cechy, a wiersz to rekord, czyli całościowy opis konkretnego elementu. Każda tabela zbiera dane dotyczące takich samych elementów. W bazie może istnieć wiele tabel powiązanych ze sobą. Przykładowo w bazie może istnieć tabela klientów i tabela zamówień powiązane odpowiednio pomiędzy sobą. Dokładniejszy opis różnych modeli danych znajduje się w dalszej części ("Rozwój różnych modeli baz danych"), a model relacyjny jest ponadto bardziej szczegółowo opisany w części "Relacyjny model danych". W każdym razie model pojęciowy stworzony przez analityka (czasem tylko w głowie) zawiera informacje o tym, co w bazie danych się znajdzie i jak to się prawdopodobnie przełoży na tabele (w przypadku modelu relacyjnego danych). Proces analizy i projektowania aplikacji prowadzi w późniejszym czasie do zebrania informacji na temat powiązań pomiędzy danymi, ich struktury, zależności między nimi, czyli do powstania modelu logicznego. Jest to zapis informacji na temat tego, jakie dane przechowywane są w bazie danych w kontekście konkretnego modelu danych – czyli z uwzględnieniem sposobu, w jaki system zarządzania bazą danych udostępnia je dla użytkownika. Model logiczny służy głównie do lepszego zrozumienia przez programistę korzystającego z bazy sposobu, w jaki dane są ze sobą powiązane (często jest to osoba inna niż projektant bazy) oraz przekłada się na informacje skierowane do bazy na temat powiązań pomiędzy rekordami danych, informacji dotyczących charakteru tych powiązań – na przykład tego, czy powiązanie musi wystąpić, czy jest opcjonalne oraz jaką ma krotność, czyli jeśli występuje, to czy może tylko pomiędzy jednym rekordem, czy wieloma. System zarządzania bazą danych może przechowywać informacje o modelu logicznym danych i posługiwać się nim w celu uniemożliwienia naruszenia spójności danych.
Główne zadania systemu zarządzania bazą danych
edytuj[W tej części w zamierzeniu mają znaleźć się informacje na temat SZDB, ale bez rozpatrywania konkretnego typu bazy danych (tj. czy jest to baza relacyjna, czy nie).]
- Ta sekcja jest zalążkiem. Jeśli możesz, rozbuduj ją.
Rozwój różnych modeli baz danych
edytuj[Krótki opis modeli hierarchicznego, sieciowego i relacyjnego (ogólnie) z uwzględnieniem rysu historycznego.]
- Ta sekcja jest zalążkiem. Jeśli możesz, rozbuduj ją.
Relacyjny model danych
edytuj[Opis model relacyjny – szerszy opis z uwzględnieniem operacji łączenia relacji (tu uwagi o kluczach i kluczach obcych) + teoretyczne podstawy matematyczne (krótko!)]
- Ta sekcja jest zalążkiem. Jeśli możesz, rozbuduj ją.
Normalizacja danych w tabelach
edytuj[Opis poziomów normalizacji i uzasadnienie po co się jej dokonuje – pokazanie np. różnicy w sposobie przechowywania danych w arkuszu kalkulacyjnym a w BD.]
- Ta sekcja jest zalążkiem. Jeśli możesz, rozbuduj ją.
Język SQL
edytuj[Opis możliwości języka SQL (DDL i DML) – zwrócenie uwagi na standard oraz konkretne implementacje (najlepiej PostgreSQL, Oracle i MySQL).]
- Ta sekcja jest zalążkiem. Jeśli możesz, rozbuduj ją.
Porównanie popularnych silników baz danych
edytujparametr | CA Ingres R3 | Firebird 1.5.1 | MySQL 4.1.5g | PostgreSQL 8.0.2 |
---|---|---|---|---|
nazwa licencji | Computer Associates Trusted Open Source License (CATOSL) | InterBase Public License | GPL z wyłączeniem FOSS | BSD |
darmowa do zastosowań komercyjnych | TAK | TAK | NIE | TAK |
dokumentacja | * * | * | * * * | * * * * |
rozmiar plików ze źródłami | 74.6 MB | 4.3 MB | 18.5 MB | 10.2 MB |
języki proceduralne | TAK | TAK | NIE | TAK |
własne typy danych | TAK | TAK | NIE | TAK |
replikacja danych | * * * | * | * * | * |
max. liczba kolumn w tabeli | 1024 | w zależności od typu danych (16384 dla kolumn integer) | 3398 | w zależności od typu danych od 250 do 1600 |
max. rozmiar rekordu | 256 KB | 64 KB | 64 KB | 1.6 TB |
max. wielkość BLOB'a | 2 GB | 0.5 GB | 4 GB | 4 GB |