www.eprace.edu.pl » obiektowe-bazy » Rozszerzenia obiektowe w relacyjnych bazach danych » Oracle

Oracle

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].

Kluczowe cechy obiektowe modelu relacyjno-obiektowego w Oracle

Dziedziczenie typów

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.

Modyfikacje typów

Przy użyciu polecenia ALTER TABLE można modyfikować (rozwijać) istniejące typy i czynić następujące zmiany:

Mechanizm obiektowej perspektywy

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.

Rozszerzenia obiektowe SQL’a

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.

Rozszerzenia obiektowe PL/SQL’a

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ść.

Java a obiektowość w bazie Oracle

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ą.

Zewnętrzne procedury

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

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.

Podręczny zbiór obiektów po stronie klienta

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

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.

Rozszerzenia obiektowe Pro*C/C++

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.

Rozszerzenia obiektowe OO4O

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.

Koncepcja obiektowości w bazie danych Oracle

Typy obiektowe

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:

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.

Dziedziczenie typów obiektowych

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ę.

Obiekty

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

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.

Tabele obiektowe

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:

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";

Przykład zapytania relacyjnego (dodawanie danych do tabeli):

INSERT INTO tabela_osoba VALUES (

"Jan Kowalski",

"0-12-123-4567" );

Typ bazodanowy REF

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.

Kolekcje

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.

Użycie rozszerzeń obiektowych w bazie danych Oracle9i

Definiowanie klas oraz typów kolekcji

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.

Metody

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;

Metody specjalne

Istnieje kilka charakterystycznych metod, do których można zaliczyć:

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 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 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.

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.

Dziedziczenie

Modyfikacje obiektów macierzystych

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:

Słowa kluczowe FINAL oraz NOT FINAL

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.

Tworzenie typów 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

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.

Dziedziczenie i przeciążanie metod

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:

Dodatkowe narzędzia ułatwiające obsługę rozszerzeń obiektowych

Business Components for Java (BC4J)

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:

JPublisher

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:

JPublisher pozwala na wiele możliwości konfiguracji, aby móc dostosować wynik mapowania bazy danych do potrzeb klienta.

JDeveloper

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.

Import/Eksport typów obiektowych

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.

SQL*Loader

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.



komentarze

Copyright © 2008-2010 EPrace oraz autorzy prac.