Baza danych Oracle powstała w roku 1977 w firmie Relational Software Incorporated. Pierwszym klientem był rząd Stanów Zjednoczonych. W roku 1979 firma zmieniła nazwę na Oracle, czyli na taką jak jej główny produkt. Baza zyskała szeroką popularność w swej szóstej wersji z roku 1989. Produkt ten posiadał już rozwinięte mechanizmy zwiększające efektywność i niezawodność systemu oraz potrafił wykorzystać potencjał systemów wieloprocesorowych. Kolejna wersja z 1993 roku oferowała wzbogacone możliwości deklaratywnego definiowania więzów integralności oraz ich weryfikacji w trakcie pracy oprogramowania aplikacyjnego. Dodatkowo, istniała możliwość definiowania funkcji użytkowych w języku PL/SQL, które są dołączane do bazy danych i wykorzystywane jak funkcje systemowe. Podwyższona została efektywność systemu przez równoległe operacje, takie jak: wykonywanie zapytań, tworzenie indeksów, ładowanie danych oraz przez replikowanie danych znacznie redukujące kodowanie przy tworzeniu rozproszonych aplikacji.
Obecnie serwer Oracle to bardzo zaawansowana i najbardziej ceniona baza danych na świecie. Posiada ona największy udział na rynku baz danych, szacowany przez firmę DataQuest na 41%.
W wersjach 8i oraz 9i nabyła wiele cech, które mogą zbliżać ją do obiektowych baz danych. Co prawda rdzeń stanowi nadal model relacyjny, jednakże rozszerzenia obiektowe tworzą z niej hybrydową bazę relacyjno-obiektową. Oznacza to, iż bazę tę można traktować jako bazę stricte relacyjną, zapominając o jej obiektowych rozszerzeniach, natomiast nie można jej uznać jako bazę czysto obiektową ze wszystkimi jej zaletami. Obiektowe modyfikacje bazy nie zaburzyły dotychczasowej relacyjnej funkcjonalności, takiej jak zapytania (SELECT FROM WHERE), szybkie potwierdzenia, partycjonowane tabel, równoległe zapytania, klastrowane składowanie danych, eksport/import, itp.
SQL oraz różnorodne programistyczne interfejsy do Oracle włączając w to PL/SQL, Java, Oracle Call Interface, Pro*C/C++, OO4O zostały wzbogacone o wsparcie nowych cech obiektowych. Przedstawione poniżej informacje pochodzą w większości z dostarczonego przez producenta opracowania „Oracle 9i Application Developers Guide - Object-Relational Features” [Gietz 2001].
Dziedziczenie typów zostało dodane, aby umożliwić tworzenie hierarchii typów, przez zdefiniowanie kolejnych poziomów coraz bardziej specjalizowanych podtypów, wywodzących się od ogólniejszych przodków. Zasada jest analogiczna jak w przypadku dziedziczenia obiektów w obiektowych językach programowania.
Przy użyciu polecenia ALTER TABLE można modyfikować (rozwijać) istniejące typy i czynić następujące zmiany:
dodawać i usuwać atrybuty,
dodawać i usuwać metody,
modyfikować atrybuty, aby osiągnąć żądany zakres, precyzję lub skalę,
zmieniać właściwości FINAL oraz INSTANTIABLE.
Oprócz przechowywania „prawdziwych” obiektów w bazie, Oracle pozwala na tworzenie obiektowych abstrakcji wykorzystując istniejące dane relacyjne. Poprzez mechanizm obiektowej perspektywy (ang. object view) istnieje dostęp do relacyjnych danych w taki sam sposób jakby to były obiekty. Wykorzystując tę cechę, można używać bazy w formie obiektowej bez konieczności modyfikowania jej schematu.
Obiektowa perspektywa pozwala także na wykorzystanie polimorfizmu, który jest możliwy w hierarchii typów.
Aby obsłużyć nowe, obiektowo zorientowane cechy bazy, rozszerzono nieco składnię języka SQL. Dodano nowy DDL12, DML13 oraz składnie zapytań, aby tworzyć, zmieniać oraz kasować typy obiektowe, referencje oraz kolekcje. Dodano także cechy, które pozwalają obiektowo operować na relacyjnych danych, poprzez mechanizm obiektowej perspektywy.
PL/SQL jest językiem programowania baz danych firmy Oracle. Język ten jest mocno zintegrowany z językiem SQL. Wraz z dodaniem typów definiowanych przez użytkownika, język ten został rozszerzony o operacje z tym związane. Obecnie programiści mogą używać języka PL/SQL, aby wykorzystać całą nową funkcjonalność.
Wersja wirtualnej maszyny Javy, stworzona przez Oracle, jest mocno zintegrowana z systemem bazy danych, aby zapewnić dostęp do rozszerzeń obiektowych, poprzez wzbogacenie JDBC. Korzystając z bazy w wersji 8i istnieje możliwość definiowania własnych typów obiektowych z poziomu Javy, natomiast wersja 9i pozwala także na tworzenie typów bazodanowych bezpośrednio z istniejących klas Javy. Dzięki temu, programiści Javy mogą traktować bazę danych Oracle jako obiektową.
Funkcje bazodanowe, procedury lub metody z typów obiektowych, mogą być implementowane w językach PL/SQL, Java lub C, jako zewnętrzne procedury. Procedury takie są bardzo pożądane do zadań, które mają być wykonane szybko w niskopoziomowym języku takim jak C, który jest bardzo efektywny. Zewnętrzne procedury są zawsze wykonywane w bezpiecznym trybie, poza przestrzenią adresową systemu bazodanowego.
Translator typów obiektowych (ang. Object Type Translator) umożliwia mapowanie obiektów do schematów obiektowych, które później są używane do generowania plików nagłówkowych zawierających klasy Javy lub struktury w C. Owe pliki nagłówkowe mogą zostać użyte przez programistów w swoich programach do zapewnienia przezroczystego dostępu do obiektów bazodanowych, bez konieczności jakiejkolwiek konwersji. Aby translator typów obiektowych mógł pracować, musi mieć dostęp do Oracle Data Dictionary, skąd pobiera niezbędne informacje.
W celu zwiększenia szybkości dostępu do obiektów znajdujących się w bazie danych, został stworzony podręczny skład obiektów (ang. object cache). Kopie obiektów mogą być przechowywane w podręcznym składzie od momentu gdy zostaną pierwszy raz ściągnięte przez użytkownika. Dzięki temu można osiągnąć duże przyspieszenie działania aplikacji. Wszystkie zmiany dokonane na obiektach w składzie mogą być zapisane w bazie poprzez Oracle Call Interface Object Extensions.
Oracle Call Interface Object Extensions to obiektowy interfejs między aplikacjami oraz narzędziami programistycznymi a bazą danych. Za jego pomocą można uzyskać dostęp do obiektów w bazie, możliwość modyfikowania obiektów oraz ich atrybutów. Technicznie rzecz biorąc OCIOE ściąga obiekty z bazy do podręcznego zbioru i tam dopiero istnieje możliwość modyfikacji.
OCIOE jest zorganizowany jako środowisko czasu wykonania, które posiada funkcje do połączeń z serwerem bazodanowym Oracle. Funkcje te umożliwiają także uzyskanie informacji na temat struktury bazy oraz poszczególnych obiektów.
Oracle Pro*C/C++ to prekompilator, który dostarcza osadzony interfejs programistyczny SQL wewnątrz języka C++ oraz zapewnia wyższy poziom abstrakcji, niż Oracle Call Interface Object Extensions. Podobnie jak OCIOE, prekompilator Pro*C/C++ umożliwia programistom użycie podręcznego zbioru obiektów po stronie klienta oraz translatora typów obiektowych. Pro*C/C++ umożliwia sprawdzanie zgodności typów programu z typami zdefiniowanymi w bazie danych.
OO4O (Oracle9i Objects For OLE) jest zestawem komponentów COM, których zadaniem jest komunikacja z serwerem Oracle9i, a także wykonywanie zapytań oraz zarządzanie zwróconymi wynikami. OO4O umożliwia łatwe i efektywne wykorzystanie cech serwera Oracle9i. Interfejs ten może być użyty w dowolnym języku programowania, obsługującym technologię COM firmy Microsoft. Obecnie jest to możliwe między innymi w rodzinie kompilatorów zawartych w MS Visual Studio, IIS Active Server Pages oraz kompilatorach firmy Borland.
Typ obiektowy nie jest szczególnym rodzajem typów w Oracle. Można używać ich w ten sam sposób, jak używa się typów dostępnych w czysto relacyjnych bazach. Przykładowo można wyspecyfikować daną klasę jako typ kolumny w relacyjnej tabeli i deklarować obiekty tej klasy. Typy obiektowe mają jednakże kilka istotnych różnic w porównaniu z tradycyjnymi typami bazodanowymi. Są to przede wszystkim:
Zestawy obiektów nie mogą być tworzone przez bazę danych.
Istnieje możliwość definiowania dowolnych typów obiektowych w zależności od potrzeb.
Obiekty nie są jednostkami atomowymi. Obiekty posiadają części: atrybuty oraz metody. Atrybuty przechowują dane zawarte w obiekcie. Atrybut posiada swój typ, który może być nawet typem obiektowym. Wszystkie atrybuty razem zawierają dane obiektu. Metody, czyli procedury lub funkcje, umożliwiają aplikacji wykonanie użytecznych operacji na atrybutach klasy. Metody to opcjonalny element klasy. Metody definiują zachowanie obiektu, czyli wszystko to, co obiekt potrafi zrobić.
Klasy są mniej ogólnymi typami niż wbudowane typy obiektowe. Zazwyczaj dobrze wiadomo, co może być przechowywane w obiektach danej klasy i do czego będą one używane. Jest to ich główna zaleta, gdyż mogą swoją strukturą odzwierciedlać rzeczywisty układ rzeczy, nad którą pracuje dany program. Obiekty umożliwiają prostsze i bardziej intuicyjne zarządzanie danymi, niż ma to miejsce w tradycyjnym modelu.
O typach obiektowych (klasach) można myśleć jako o wzorze, natomiast o obiekcie (instancji klasy) jako o czymś, co zostało zbudowane według tego wzoru.
Istnieje możliwość specjalizowania klasy poprzez tworzenie podtypów, które mają jakieś dodatki, inne cechy itp. w stosunku do typu będącego ich przodkiem. Podtypy oraz typy macierzyste są powiązane przez swoją hierarchię. Podtyp to specjalizowana wersja przodka. Typ potomny posiada wszystkie atrybuty i metody, które posiadał przodek oraz dodatkowe, dodane przez klasę potomną. Wszystkie typy macierzyste oraz typy potomne, razem tworzą swoistą hierarchię.
Podczas tworzenia zmiennej typu obiektowego, tworzy się instancję klasy, czyli obiekt. Ponieważ instancja klasy jest czymś konkretnym, można nadawać atrybutom specjalne wartości (jeśli metody na to pozwalają), odczytywać je oraz wywoływać metody klasy.
Metody to funkcje lub procedury, które zostały zadeklarowane w danej klasie. Metody określają zachowanie danej klasy. Jednym z głównych zadań metod jest zapewnienie dostępu do danych zawartych w obiekcie.
Tabela obiektowa jest specjalnym rodzajem tabeli, w której każdy wiersz reprezentuje jeden obiekt.
Dla przykładu poniższy kod tworzy klasę OSOBA:
CREATE TYPE osoba AS OBJECT (
imie VARCHAR2(30),
telefon VARCHAR2(20) );
Teraz, mając już definicję klasy OSOBA, można zdefiniować tabelę obiektową dla obiektów typu OSOBA:
CREATE TABLE tabela_osoba OF osoba;
Tabelę taką można traktować teraz na dwa różne sposoby:
Jako tabelę z jedną kolumną, w której każdy wiersz to obiekt typu OSOBA. Takie spojrzenie pozwoli pobierać całe obiekty i używać ich później do wykonywania operacji w językach zorientowanych obiektowo.
Przykład zapytania obiektowego, które zwróci wiersz jako instancję klasy (o ile taki istnieje w bazie):
SELECT VALUE(p) FROM tabela_osoba p
WHERE p.imie = "Jan Kowalski";
Jako wielokolumnową tabelę, gdzie każdy parametr klasy OSOBA reprezentuje jedną kolumnę. W przykładzie istnieją dwie kolumny nazwane imie oraz nazwisko. Spojrzenie takie, umożliwi wykonywanie relacyjnych operacji.
Przykład zapytania relacyjnego (dodawanie danych do tabeli):
INSERT INTO tabela_osoba VALUES (
"Jan Kowalski",
"0-12-123-4567" );
REF jest specjalnym pierwotnym typem bazodanowym bazy Oracle. Jest to logiczny wskaźnik do wiersza tabeli obiektowej. Typy REF mogą być używane do modelowania związków pomiędzy obiektami, szczególnie relacji wiele-do-jeden. Pozwala to zredukować potrzebę używania obcych kluczy w tabelach. Aby korzystać z typów REF używa się notacji kropkowej.
Typy REF mogą być używane do uzyskania dostępu do obiektów, na które wskazują. Za ich pomocą można dostać również kopię danego obiektu. Można zmieniać REF, aby wskazywał na inny obiekt niż obecny, jednakże musi to być obiekt takiego samego typu. Istnieje także możliwość przypisania do REF’a wartości NULL.
W celu utworzenia relacji jeden-do-wielu, Oracle udostępnia dwa typy kolekcji: VARRAY oraz tabele zagnieżdżone (ang. nested tables). Typy kolekcji mogą być użyte wszędzie tam, gdzie używane są inne typy danych.
Do tworzenia typów obiektowych oraz typów kolekcji używa się słowa kluczowego CREATE TYPE.
Przykłady tworzenia typów obiektowych:
CREATE TYPE osoba AS OBJECT (
imie VARCHAR2(30),
telefon VARCHAR2(20)
);
CREATE TYPE produkt AS OBJECT (
produkt VARCHAR2(30),
ilosc NUMBER,
cena NUMBER(12,2)
);
CREATE TYPE tabela_magazyn AS TABLE OF produkt;
CREATE TYPE zamowienie AS OBJECT (
id NUMBER,
kontakt osoba,
produkty tabela_magazyn,
MEMBER FUNCTION
get_value RETURN NUMBER
);
W powyższym kodzie zostały zdefiniowane typy obiektowe: osoba, produkt, tabela_magazyn oraz zamowienie.
Typ tabela_magazyn jest typem kolekcji. Klasa zamowienie posiada atrybut produkty właśnie typu tabela_magazyn. Każdym wierszem tej kolekcji jest obiekt typu produkt. Przykład powyższy jest uproszczony, gdyż nie pokazuje, w jaki sposób zdefiniować ciało metody get_value.
Głównym przeznaczeniem metod jest umożliwienie dostępu do danych przechowywanych w instancjach klas. Definiuje się oddzielnie metody dla każdej operacji, jaka jest wywołana do wykonywania przez obiekt.
Poniżej zaprezentowano przykład definiowania metody w języku PL/SQL:
CREATE TYPE Ulamek AS OBJECT (
licznik INTEGER,
mianownik INTEGER,
MEMBER PROCEDURE skroc
);
CREATE TYPE BODY Ulamek AS
MEMBER PROCEDURE skroc IS
g INTEGER;
BEGIN
g := nwd(licznik, mianownik);
licznik := licznik / g;
mianownik := mianownik / g;
END skroc;
END;
Istnieje kilka charakterystycznych metod, do których można zaliczyć:
Metody MAP
Metody tego typu umożliwiają porównywanie obiektów poprzez mapowanie ich do jednego z typów skalarnych takich jak: DATE, NUMBER, VARCHAR2, CHARACTER lub REAL. Tak zmapowane obiekty porównuje się później za pomocą standardowych operatorów porównania, przykładowo:
obj_1.map() > obj_2.map()
Metody ORDER
Metody typu ORDER umożliwiają porównywanie obiektu macierzystego z innym obiektem, który jest przekazywany jako parametr. Jeśli metoda taka uzna, że obiekt przekazany jako parametr jest „większy” od obiektu macierzystego powinna zwrócić liczbę ujemną, jeśli uzna że obiekty są sobie równe to zwraca zero, natomiast jeśli obiekt macierzysty jest „większy” to zwraca liczbę dodatnią.
Metody statyczne
Metody statyczne są wywoływane z klasy, a nie z jej instancji. Używa się ich dla operacji, które są globalne i nie potrzebują referencji do danej instancji obiektu.
Konstruktory
Każdy obiekt posiada zdefiniowany przez system konstruktor. Jest to metoda, która tworzy nowy obiekt i nadaje wartości jego atrybutom. Konstruktor jest funkcją, która przy wywołaniu zwraca obiekt. Nazwa konstruktora jest taka sama, jak nazwa klasy. Parametry konstruktora mają takie same nazwy jak atrybuty klasy. Wywołanie konstruktora jest równoznaczne z wykonaniem instrukcji INSERT języka SQL.
Jak już wspomniano wcześniej, baza danych Oracle9i umożliwia tworzenie typów obiektowych, które dziedziczą po już istniejącym typie obiektowym.
Klasa potomna może różnić się od klasy macierzystej w trzech podstawowych kwestiach:
może dodawać nowe atrybuty,
może dodawać nowe metody,
może tworzyć własne implementacje istniejących metod.
Programista tworząc nową klasę musi zdecydować, czy będzie ona mogła być później podstawą do tworzenia klasy potomnej. Aby to umożliwić, należy na końcu deklaracji klasy dodać słowo kluczowe NOT FINAL. Decyzję można potem zmienić poleceniem ALTER TYPE (zmieniając klasę na FINAL).
Bardzo podobnie sprawa wygląda w przypadku metod; można określić czy dana metoda będzie mogła być zmieniana w typach potomnych.
Aby stworzyć klasę potomną, używa się polecenia CREATE TYPE, w którym specyfikuje się klasę macierzystą:
CREATE TYPE Student UNDER Osoba (
rok_studiow NUMBER,
wydzial VARCHAR2(30)
) NOT FINAL;
Powyższy kod tworzy typ obiektowy Student, który jest podtypem klasy Osoba. Jako podtyp, klasa Student posiada wszystkie atrybuty i metody zadeklarowane w klasie Osoba oraz te, które klasa Osoba odziedziczyła ze swojego przodka, jeśli taki istniał. Dodatkowo klasa Student posiada dwa nowe atrybuty. Nowe atrybuty deklarowane w typach potomnych muszą mieć nazwy różne od tych, które zostały odziedziczone.
Typy wirtualne nie posiadają konstruktora, co uniemożliwia tworzenie ich instancji. Klasy takie mogą być jedynie typami macierzystymi. Aby zadeklarować klasę jako wirtualną, używa się słowa kluczowego NOT INSTANTIABLE.
Metody również mogą być zadeklarowane jako wirtualne. Pozwala to na deklarowanie metod, bez konieczności implementowania ich. Metody takie tworzymy, kiedy spodziewamy się, iż każda klasa dziedzicząca będzie przesłaniać swoją metodą działanie metody obecnej. Jeśli klasa potomna nie zawiera implementacji każdej z metod, którą odziedziczyła jako wirtualną, sama musi być wirtualna.
Klasa potomna automatycznie dziedziczy wszystkie metody przodka. Metody te można przedefiniować, można także dodać nowe metody. Można nawet dodać metodę, która posiada taką samą nazwę jak metoda którą się już odziedziczyło. Definiowanie wielu metod posiadających taką samą nazwę określane jest jako przeciążanie metod.
Kiedy klasa posiada wiele metod o takich samych nazwach, kompilator używa sygnatur metod, aby móc je rozróżniać. Sygnatura zawiera nazwę metody, jej numer, typ oraz listę jej parametrów.
Przesłanianie metod polega na przedefiniowaniu metody dziedziczonej. Jeśli klasa przesłania jakąś metodę, to nowa wersja będzie wykonywana zamiast starej. Metoda będzie przesłonięta, jeśli nowa wersja posiada dokładnie taką samą sygnaturę. Metody nie mogą być przesłanianie w następujących przypadkach:
metoda przodka jest zadeklarowana jako FINAL,
metoda przodka jest typu ORDER,
metoda potomka jest statyczna, a przodka nie,
metoda przodka jest statyczna,
metoda potomka ma inne wartości domyślne niż metoda przodka.
BC4J to zestaw komponentów w standardzie EJB oraz CORBA, które mają za zadanie uprościć tworzenie, rozpowszechnianie oraz dostosowywanie biznesowych aplikacji w języku Java. Zestaw ten jest pomyślany jako szkielet (ang. framework) dostarczający programistom komponentów mających za zadanie:
uprościć tworzenie oraz testowanie logiki biznesowej w komponentach integrujących aplikacje z bazami danych,
umożliwić wielokrotne używanie istniejących komponentów, poprzez różnorodne, oparte na SQL’u przeglądanie danych,
umożliwić dostęp do danych oraz ich modyfikację z serwletów, JSP (Java Server Pages) oraz klientów opartych na JavaSwing,
umożliwić dostosowywanie warstwy aplikacji odpowiedzialnej za kontakt z użytkownikiem, bez konieczności zmiany wnętrza.
JPublisher jest narzędziem, napisanym w całości w języku Java, które potrafi generować klasy Javy, reprezentujące następujące elementy bazodanowe:
typy obiektowe,
typy wskaźnikowe REF,
typy kolekcji,
pakiety PL/SQL.
JPublisher pozwala na wiele możliwości konfiguracji, aby móc dostosować wynik mapowania bazy danych do potrzeb klienta.
JDeveloper jest zintegrowanym narzędziem programistycznym do tworzenia wieloużytkownikowych aplikacji w języku Java. Środowisko to pozwala na programowanie, usuwanie błędów oraz testowanie aplikacji. Korzystając z tego narzędzia można tworzyć aplikacje klienckie, aplikacje przez WWW, aplikacje oraz komponenty serwerów aplikacji.
JDeveloper działa w środowisku Windows NT, jest dobrze zintegrowany z serwerem aplikacji Oracle oraz bazą danych Oracle.
Narzędzie pozwala na przemieszczanie danych z oraz do bazy danych Oracle. Umożliwia także na tworzenie kopii zapasowych, archiwizację danych oraz późniejsze ewentualne odtwarzanie z kopii.
Import/Eksport obsługuje typy obiektowe. Przy eksportowaniu zapisywane są definicje typów wszystkich danych. Przy imporcie możliwe jest tworzenie klas potomnych, zanim jeszcze definicja klasy macierzystej zostanie zaimportowana.
Możliwe jest przeglądanie hierarchii klas z plików utworzonych w czasie eksportu danych.
Narzędzie SQL*Loader pozwala na przenoszenie danych z zewnętrznych plików do tabel w bazie danych Oracle. Pliki mogą zawierać dane składające się z podstawowych typów bazodanowych, jak również dane w złożonych, zdefiniowanych przez użytkownika typach, takich jak obiekty, kolekcje oraz LOB’y.
SQL*Loader używa plików kontrolnych, które zawierają opisy danych w języku DDL.
Copyright © 2008-2010 EPrace oraz autorzy prac.