Entwurf und Realisierung einer relationalen Datenbank für die

Werbung
Entwurf und Realisierung einer
relationalen Datenbank für die
Darstellung kombinatorischer
Bibliotheken in der Biochemie
Mohammad Reza Jafari
Diplomarbeit am Institut für Informatik III
Rheinische Friedrich-Wilhelms-Universität Bonn
Gutachter:
Prof.Dr.Rainer Manthey
Inhaltsverzeichnis
1 Einleitung
1
2 Mathematisch-Chemische Grundlagen
2.1 Biochemischer Hintergrund . . . . . . . . . . . . . . . . . . .
2.2 Elementare Begriffe der Graphentheorie . . . . . . . . . . . .
2.2.1 Darstellungsformen für Graphen . . . . . . . . . . . .
2.2.2 Suchalgorithmen für Graphen . . . . . . . . . . . . . .
2.3 Darstellung Chemischer Strukturen als Graph . . . . . . . . .
2.3.1 Darstellung kombinatorischer Bibliotheken als Graph .
2.4 Subgraphisomorphismus . . . . . . . . . . . . . . . . . . . . .
2.5 Darstellung chemischer Strukturen als ASCII-Dateien . . . .
2.5.1 Das (C)SLN-Dateiformat . . . . . . . . . . . . . . . .
2.6 Kombinatorische Bibliotheken im Protein-Ligand-Docking . .
2.6.1 Das Docking-Programm FlexX . . . . . . . . . . . . .
2.6.2 Das FlexX-Modul FlexXC . . . . . . . . . . . . . . . .
3 Datenbank-Grundlagen
3.1 Datenbankmodellierung . . . . . . . . . . . . . . . .
3.1.1 Das Entity-Relationship-Modell . . . . . . . .
3.1.2 Das relationale Datenmodell . . . . . . . . .
3.1.3 Abbildung des Entity-Relationship-Modells in
3.2 Relationale Anfragesprachen . . . . . . . . . . . . . .
3.2.1 Relationenalgebra und Relationenkalkül . . .
3.2.2 SQL . . . . . . . . . . . . . . . . . . . . . . .
3.3 Das Oracle DBMS . . . . . . . . . . . . . . . . . . .
3.3.1 Objekt-Relationale Konzepte in Oracle . . . .
3.3.2 Oracle Data-Cartridges . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
4
4
6
7
7
8
9
10
11
11
13
13
14
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
das relationale Datenmodell
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
16
16
17
19
19
20
21
22
27
28
29
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4 Modellierung kombinatorischer Bibliotheken
4.1 Konzeptueller Entwurf . . . . . . . . . . . . . . . . . . . . . . . . .
4.1.1 Modellierung eines chemischen Moleküls . . . . . . . . . . .
4.1.2 Modellierung der kombinatorischen Natur der Bibliotheken
4.2 Logischer Entwurf . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2.1 Darstellung von Entitytypen als Relationen . . . . . . . . .
4.2.2 Darstellung von Relationshiptypen als Relationen . . . . . .
4.3 SQL-Implementierung . . . . . . . . . . . . . . . . . . . . . . . . .
i
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
31
31
32
33
37
37
37
39
INHALTSVERZEICHNIS
5 Die Programmierumgebung
5.1 FlexX-Datenstrukturen für kombinatorische Bibliotheken
5.2 Das Python-Modul pyflexx . . . . . . . . . . . . . . . . .
5.2.1 Die Programmiersprache Python . . . . . . . . . .
5.2.2 Python Database API . . . . . . . . . . . . . . . .
5.2.3 Interne Kommunikation in FlexX über STREAM s
ii
.
.
.
.
.
43
43
46
46
47
48
.
.
.
.
.
49
49
49
50
53
54
7 Evaluierung
7.1 Views zum Subgraphisomorphismus . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Vergleich von Suchergebnissen mit und ohne Datenbank . . . . . . . . . . . . . .
58
58
68
8 Zusammenfassung und Aussichten
73
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6 Implementierung
6.1 Füllen der statischen Tabelle Atomtype . . . . . . . . . . . . . .
6.2 Zugriff auf die Bibliotheksdaten in den FlexX-Datenstrukturen
6.2.1 Moleküldaten . . . . . . . . . . . . . . . . . . . . . . . .
6.2.2 clib molecule Daten . . . . . . . . . . . . . . . . . . . .
6.3 Datenimport in die Datenbank . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Kapitel 1
Einleitung
Stoffwechselprozesse im Körper werden durch eine Vielzahl von Molekülen - meistens Proteine reguliert. Wenn diese Prozesse fehlerhaft ablaufen, zum Beispiel durch die Wirkung von Viren,
Bakterien oder Autoimmunprozessen, entstehen Krankheiten. Diese kann man medikamentös
behandeln, in dem mit Hilfe von Wirkstoffmolekülen Einfluss auf die oben genannten Regulatoren genommen wird. Die Suche nach neuen Medikamenten ist somit zunächst die Suche nach
geeigneten Wirkstoffmolekülen [H.J96].
Am Beginn dieser Suche nach neuen Wirkstoffmolekülen steht die Identifizierung der defekten
Regulatoren, also der Enzyme bzw. Proteine. Dann sucht man nach kleineren Molekülen, sog.
Liganden, die sich stark genug an das sog. Ziel-Molekül/Protein binden können. Dies setzt die
geometrische und chemische Komplementarität der beiden beteiligten Moleküle voraus. Das
Ergebnis dieser Suche sind sog. Leitstrukturen, die bereits hinreichend starke Wechselwirkung
zeigen, jedoch noch im Hinblick auf einige physische und chemische Eigenschaften optimiert
werden müssen, damit sie die weiteren Vorraussetzungen eines Medikamentes erfüllen können.
In der letzten Phase, der klinischen Untersuchung, wird der Wirkstoff an Patienten erprobt.
Erst dann kann der Wirkstoff als neues Medikament zugelassen werden.
Für die Suche nach Leitstrukturen können experimentelle oder virtuelle Methoden oder auch
eine Kombination aus beiden eingesetzt werden [Cla01, Rar01]. Bei der experimentellen Suche
werden bekannte Verbindungen auf die gewünschte Wirkung getestet. Dazu werden große
Bibliotheken mit Millionen von Verbindungen mit Hilfe von Roboteranlagen automatisch
getestet. Diese Methode ist unter dem Namen High-Throughput-Screening (HTS ) bekannt.
Bei der virtuellen Suche gibt es zwei Szenarien: entweder kennt man bereits - über experimentelle Methoden wie Röntgenkristallographie oder NMR Spektroskopie - die Struktur der
Proteine und versucht die Liganden zu finden, die sowohl geometrisch als auch chemisch zu dem
Protein passen (das Docking Problem) oder man kennt die Struktur nicht und versucht durch
einen Vergleich mit einem bereits bekannten Liganden Rückschlüsse zu ziehen und diesen als
Leitstruktur für einen neuen Wirkstoff zu nutzen (die ligand-basierte Suche). In der virtuellen
Suche liegen die Informationen über Verbindungen in elektronischer Form vor. Somit können sie
zur Suche nach geeigneten Strukturen bei virtuellen Verfahren eingesetzt werden, die virtuelles
Screening genannt werden.
1
KAPITEL 1. EINLEITUNG
2
Die HTS -Methode hat einige Nachteile [Cla01]. Ein wesentlicher Nachteil ist, daß alle Verbindungen, die getestet werden sollen auch verfügbar sein müssen. Dazu müssen sie entweder
synthetisiert oder gekauft und für spätere Tests gelagert werden, wobei sich die Moleküle
während der Lagerung nicht verändern dürfen. Außerdem können Verunreinigungen und
Nebenreaktionen zu fehlerhaften Ergebnissen führen. Der größte Vorteil virtueller Verfahren
ist somit, daß die Moleküle nicht real existieren müssen. Stattdessen werden lektronisch
gespeicherte Daten genutzt. Diese liegen in der Regel in Form von ASCII-Dateien vor. Nur
in Ausnahmefällen sind diese Informationen über die Verbindungen auch in Datenbanken
repräsentiert. Damit braucht man vor allem keine Verbindungen zu kaufen, zu synthetisieren
und zu lagern. Deshalb sind die Kosten solcher Verfahren wesentlich geringer. Aufgrund
der hohen Komlexität der Problemstellung müssen virtuelle Verfahren gezwungenermassen
vereinfacht werden und können Messsungen nicht ersetzen. Virtuelle Methoden können zur
Vorauswahl von geeigneten Verbindugen eingesetzt werden, die später synthetisiert und getestet
werden sollen.
Die zum HTS notwendigen Molekülbibliotheken werden durch Sammlung aller Verbindungen
erstellt, die während der pharmazeutischen Forschung synthetisiert wurden [Rar01, Cla01]. Bei
dieser Methode werden einerseits die Daten- bzw. Substanzmengen immer größer und andererseits kommt es innerhalb dieser Datenmengen zu einem Mißverhältnis bei der Repräsentation
der Molekülklassen. Einige Klassen sind überrepräsentiert während andere wiederum gar nicht
oder kaum vertreten sind. Letzteres Problem wurde bis vor wenigen Jahren durch gezieltes
Hinzukaufen von Verbindungen gelöst. In der Größe der Datenmenge und dem Mißverhältnis
bei der Molekülklassenrepräsentation liegen also die wesentlichen Nachteile dieser Methode.
Während der letzten Jahre konnte sich zur Erzeugung großer Molekülbibliotheken mit strukturell verwandten Molekülklassen eine alternative Technologie etablieren: die kombinatorische
Chemie. Bei dieser Technologie werden ausgewählte Baukästen, die jeweils eine Menge von
Alternativfragmenten enthalten, in unterschiedlicher Kombinationen mittels chemischer Standardreaktionen der Reihe nach aneinander gehängt und zusammenfügt. So lassen in kürzester
Zeit eine große Anzahl strukturell verwandter Substanzen erzeugen.
Im Laufe der rasanten Entwicklung der kombinatorischen Chemie und der Screening-Verfahren
wurde ein neues Szenario für das virtuelle Screening geboren [MR00]. Anders als zu der Zeit, in
der man sich auf die Analyse großer Bibliotheken von Verbindungen stützte, wird heutzutage
die Kombination mehrerer großer, falls möglich virtueller Bibliotheken dazu verwendet. Die
Anwendung virtueller Bibliotheken führt zu neuen Suchproblemen auf dem Gebiet des virtuellen
Screening, vor allem da die Anzahl der gesuchten Verbindungen zur Kombination im Vergleich
zu den klassischen Methoden erheblich größer wurde. Der Vorteil liegt aber darin, daß dadurch
die Suchzeit reduziert werden kann. Für die Suche in einer Menge unstruktuierter Verbindungen
müssen alle Moleküle unabhängig voneinander analysiert werden. Kombinatorische Bibliotheken
dagegen besitzen einen struktuierten Aufbaumechanismus durch eine bestimmte Anzahl von
Baublöcken. Daher können Informationen von anderen, schon analysierten Molekülen für ein
neues Molekül genutzt werden.
Die kombinatorischen Bibliotheken werden zur Zeit unter anderem in Form von ASCII-Datein
oder als enumerierte Moleküle repräsentiert [Cla04]. Letztere eignet sich besser zur Suche
innerhalb der Bibliotheken, hat aber den Nachteil, daß die Molekülzahl sehr groß ist und daher
die Suche unter ihnen zeitlich nicht effizient ist.
KAPITEL 1. EINLEITUNG
3
Aus diesem Grund ist eine Repräsentation in kombinatorischen Bibliotheken wünschenswert, die
auf der einen Seite kompakt und auf der anderen Seite gut durchsuchbar ist. Eine Alternative
kann ein geeignetes Datenbank-Schema für kombinatorische Bibliotheken sein. Das Ziel dieser
Arbeit ist daher die Entwicklung eines solchen Schemas, das die kombinatorische Natur von
kombinatorischen Bibliotheken nutzt und diese in einer geschlossenen Form mit minimaler
Redundanz ablegt. Die Vorteile dieser Vorgehensweise ist, daß so einerseits nicht alle Moleküle
abgelegt werden müssen und damit Platz gespart wird und andererseits die Suche beschleunigt
wird, da man nicht alle Bibliotheksmoleküle - also alle Fragmentkombinationen - durchsuchen
muss, sondern nur die Fragmente selbst.
Eine Datenbank für kombinatorische Bibliotheken kann in mehreren Anwendungsfeldern
benutzt werden [Cla04], unter anderem bei der ligand-basierten Suche nach Wirkstoffmolekülen
oder beim Vergleichen zwischen verschiedenen kombinatorischen Bibliotheken zur Auswahl der
jenigen mit bestimmten Substrukturen.
Die vorliegende Arbeit wurde im Rahmen einer Kooperation zwischen der Arbeitsgruppe
Intelligente Datenbanken von Prof. Dr. Rainer Manthey vom Institut für Informatik III der
Rheinischen Friedrich-Wilhelms-Universität Bonn und der Firma BioSolveIT durchgeführt. Die
Firma BioSolveIT ist ein in den Bereichen Bio- und Chemieinformatik tätiges Unternehmen,
die im Jahre 2001 als Spin-Off der Arbeitsgruppe von Professor Lengauer am GMD-Institut
SCAI (heute Fraunhofer Gesellschaft) gegründet wurde. Sie entwickelt und vermarktet Software
für die pharmazeutische Industrie und biotechnologische Unternehmen. Die Firma BibSolveIT
entwickelte das Tool FlexX [G.K96], das im strukturbasierten Wirkstoffdesign eingesetzt wird.
Ausgehend von der 3-dimensionalen Struktur des Proteins kann mit Hilfe von FlexX die
Geometrie von Protein-Liganden Komplexen vorhergesagt werden. Dieses Tool verfügt über
das zusätzliche Modul FlexXC , das es erlaubt, die kombinatorische Natur kombinatorischer
Bibliotheken effizient beim Docking auszunutzen. FlexXC besitzt bereits Datenstrukturen, um
kombinatorische Bibliotheken in geschlossener Form kompakt abzulegen, eine effiziente Suche
innerhalb von kombinatorischen Bibliotheken ist damit jedoch zur Zeit noch nicht möglich. In
der vorliegenden Arbeit verwende ich die FlexXC Datenstrukturen als Ausgangsbasis. Damit
erübrigt sich das Schreiben eines Parsers für die ASCII-Dateien, da diese bereits in FlexXC
vorliegen.
In Kapitel 2 werden die mathematisch-chemischen Grundlagen erläutert, deren Verständnis für
den Rest dieser Arbeit notwendig ist. Zusätzlich wird hier das Prinzip der kombinatorischen Bibliotheken vorgestellt, auf die diese Arbeit basiert. Kapitel 3 enthält eine allgemeine Einführung
in die Datenbankmodellierung. Dort werden Techniken zum Aufbau einer Datenbank und deren
Manipulation erläutert. Am Ende des Kapitels wird das Datenbank Management System Oracle
vorgestellt, das in dieser Arbeit verwendet wurde. Die im Kapitel 3 diskutierten Modellierungstechniken werden im Kapitel 4 für kombinatorische Bibliotheken umgesetzt. In Kapitel 5 wird
die Programmierumgebung dieser Arbeit vorgestellt. Die Art und Weise, wie die Informationen der ASCII-Dateien aus den FlexX-Datenstrukturen für kombinatorischen Bibliotheken in
die Datenbank importiert werden, wird in Kapitel 6 erörtert. In Kapitel 7 werden zunächst die
Views zur Substruktursuche vorgestellt. Die Ergebnisse dieser Substruktursuche werden dann
anhand realer Daten dokumentiert und mit den Ergebnissen von FlexX verglichen. Am Ende
schließt eine Zusammenfassung und ein Ausblick auf mögliche Erweiterungen die Arbeit ab.
Kapitel 2
Mathematisch-Chemische
Grundlagen
In der vorliegenden Arbeit geht es um kombinatorische Bibliotheken, die aus Molekülen bestehen.
Diese bedürfen einer geeigneten Repräsentation. Besonders geeignet für diese Darstellung sind
Graphen. Zuerst sollen die kombinatorischen Bibliotheken und ihr Inhalt - die Moleküle - vorgestellt werden. Danach werden die Graphen als Darstellungsform eingeführt und gezeigt, wie man
die chemischen Strukturen mit ihrer Hilfe repräsentieren kann. Schließlich wird das Programm
FlexX und dessen Handhabung von Molekülen in kombinatorischen Bibliotheken thematisiert.
Zunächst werden einige wichtige biochemische Begriffe vorgestellt, deren Verständnis für das
weitere Vorgehen innerhalb dieses Kapitels und der gesamten Arbeit unverzichtbar ist. Eine
ausführliche Beschreibung der gesamten Thematik ist zum Beispiel in [H.J96, PK94, Alb90] zu
finden.
2.1
Biochemischer Hintergrund
Moleküle bestehen aus Atomen, die durch kovalente Bindungen miteinander verbunden sind.
Im Organismus kommen die Atome Wasserstoff (H), Kohlenstoff (C), Stickstoff (N), Sauerstoff (O), Phosphor (P) und Schwefel (S) am häufigsten vor. Der Typ der Atombindung
hängt von der Art der Interaktion zwischen den beteiligten Atomen und den freien Valenzen
ab. Die Bindungen können als Einfach-, Mehrfach- und aromatische Bindungen vorkommen. Da einfache Atombindungen leicht um die eigene Achse rotieren können, sind bei einem
solchen Molekül viele verschiedene Konformationen, also räumlichen Strukturvarianten möglich.
Größere Moleküle enstehen durch die Kombination kleinerer Moleküle. Diesen Vorgang der
Verbindung nennt man Reaktion. Bei der Reaktionen werden Atombindungen in beiden Molekülen aufgebrochen und eine neue Bindung zwischen den Molekülen gebildet. Es werden also
von beiden Molekülen Atome abgespalten und an den Bruchstellen entsteht die neue Bindung
zwischen den Molekülen. Die Reaktionen finden nicht an beliebigen, sondern an bestimmten,
prädisponierten Bindungen im Molekül statt.
Die kombinatorische Chemie beruht auf dem Prinzip, daß mit einem Reaktionsschema viele
Moleküle, die alle dieselbe spezifische Atombindung enthalten, untereinander verknüpft werden
können [Cla04]. Die entstandene Moleküle sind strukturell verwandt und enthalten in der Regel
4
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
5
Abbildung 2.1: Schematischer Aufbau einer kombinatorischen Bibliothek mit dem Kern K und
den R-Gruppen R1-R4.
ein Kerngerüst, das bei allen entstandenen Molekülen gleich ist [Rar01]. Dieses bezeichnet man
als Kern (engl. core) (Abbildung 2.1). Mit diesem Kern sind an verschiedenen Positionen, den
sog. R-Gruppen, alternative Molekülfragmente verknüpft. Von einem abstrakten Standpunkt
betrachtet bilden der Kern und die Fragmente eine Art Baukasten, aus der sich kombinatorisch
eine große Zahl von Molekülen zusammensetzen läßt. Der große Vorteil ist daher, daß man aus
einer kleinen Menge von Grundverbindungen eine große Anzahl von Molekülen zusammensetzen
kann, die alle einer gewissen Aufbaustrategie folgen.
Eine kombinatorische Bibliothek ist also ein Reaktionsschema plus einer Menge von verknüpfbaren Molekülen oder abstrakter ausgedrückt sie ist eine Menge von alternativen Fragmenten pro
R-Gruppe sowie eine Verknüpfungsregel [Cla04]. Die Fragmente der R-Gruppen in kombinatorischen Bibliotheken werden auch als Teilmoleküle bezeichnet weil es in diesen Fragmente Atome
gibt, über die beim Zusammenbauen der Bibliotheksmoleküle solche Fragmente mit anderen
Fragmenten verknüpft werden können [Rar01]. Die Art und Weise der Verknüpfung solcher
Fragmente wird in den meisten anwendungsrelevanten Fällen über die Struktur bestimmt, auf
die die kombinatorische Bibliothek aufgebaut ist. Darauf wird im Abschnitt (2.3.1) ausführlicher
eingegangen.
Die Produkträume auf der Basis von Multikomponentenreaktionen in der kombinatorischen
Chemie sind um Größenordnung mächtiger als alle derzeit existierenden Strukturdatenbanken
zusammen, so daß man bis zu 1014 verschiedene Produkte aus etwa 500 Alternativfragmenten
erreichen kann [BK97]. Derartige Mengen von chemischen Strukturen kann man nicht mit
klassischen Datenbanken verwalten.
Da später kurz auf FlexX eingegangen wird, werden im Folgenden einige weitere Begriffe
vorgestellt, die in diesem Zusammenhang wichtig sind:
Proteine sind große Moleküle, deren Entstehung ebenfalls auf dem Prinzip der Kombination
einer definierten Menge von Komponenten beruht. Sie bestehen aus einer Kette mit einer
Kombination von 20 verschiedenen Bausteinen, den Aminosäuren, die über kovalente Bindungen miteinander verbunden sind. Dieser Art der Atombindung ist als Peptidbindung bekannt.
Proteine können sich an andere, kleinere Moleküle legen und mit ihnen in Wechselwirkung
treten. Diese Bindungen sind in manchen Fällen sehr fest, in anderen Fällen aber schwach. In
allen Fällen aber sind sie sehr spezifisch, so daß nur einige wenige Molekülen aus der Umgebung
des Proteins eine solche Bindung eingehen können. Voraussetzung dafür ist, daß die beteiligten
Partner chemisch und geometrisch komplementär zueinander sein müssen wie ein Schlüssel zum
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
6
entsprechenden Schloß das Schlüssel-Schloß Prinzip).
Ligand ist die Bezeichnung für den kleineren Bindungspartner eines Komplexes. Im Prinzip
können es beliebige Moleküle sein, in der Wirkstoffentwicklung sind jedoch meist nur Moleküle
mit höchstens rund hundert Atomen interessant. Im Gegensatz zu Proteinen besitzen Liganden
- aufgrund der hohen Zahl ihrer Konformationsmöglichkeiten - sehr flexible Strukturen, die bei
der Anpassung an das Protein berücksichtigt werden müssen. Eine Bindetasche ist diejenige
Region eines Proteins, in die ein spezifischer Ligand passt.
Die chemischen Bindungen zwischen Protein und Ligand dürfen nicht sehr stark sein, damit die
Produkte nach der Wechselwirkung das Protein wieder verlassen können. Daher kommen hier in
der Regel keine kovalenten Bindungen zustande, sondern basieren meist auf Wechselwirkungen
wie beispielsweise Wasserstoffbrücken. Dabei handelt es sich um gerichtete intermolekulare
Bindungen, in denen ein Wasserstoffatom mit einem Sauerstoff-, Stickstoff- oder Flur-Atom
interagiert.
Ein chemisches Molekül ist in verschiedenen Formen repräsentierbar [Gas03]. Zwei dieser Formen
sind der Graph und ASCII-Dateien. Da im Rahmen dieser Arbeit beide Darstellungsformen für
Moleküle benutzt werden, sollen sie hier vorgestellt werden. Im weiteren wird zunächst eine
allgemeine Einführung in die Graphentheorie gegeben, dann wird das ASCII-Format (C)SLN
vorgestellt.
2.2
Elementare Begriffe der Graphentheorie
Ein Graph ist wie eine Menge oder eine Relation ein mathemathisches Objekt [Sed91, THC99].
Ein Graph ist ein Paar (V, E), wobei V eine endliche Menge und E eine binäre Relation auf
V ist. Die Menge V wird die Knotenmenge (engl. vertex set) und ihre Elemente die Kanten
(engl. vertieces (pl.), vertex (singl.)) genannt. Die Menge E nennt man die Kantenmenge (engl.
edge set) von G. Ist im Graph G = (V, E) jedes Paar (u, v) ∈ E mit u, v ∈ V geordnet, ist G
gerichtet (engl. directed ), sonst ist er ungerichtet (engl. undirected ). Demnach ist der Knoten
v adjazent zu dem Knoten u. Die Adjazenzrelation ist für ungerichtete Graphen symmetrisch,
für gerichtete Graphen hingegen ist dies nicht immer so.
Der Grad (engl. degree) eines Knotens in einem ungerichteten Graphen ist gleich der Anzahl der
sich in ihm treffenden Kanten. In gerichteten Graphen wird für jeden Knoten ein Eingangsgrad
(engl. in-degree) und ein Ausgangsgrad (engl. out-degree) definiert, die gleich der Anzahl von
ein- bzw. ausgegangenen Kanten des Knotens sind.
0
Ein Pfad (engl. path) der Länge k von einem Knoten u zu einem Knoten u in einem Graph
0
G = (V, E) ist eine Sequenz < v0 , v1 , · · · , vk > von Knoten, so daß u = v0 und u = vk und
(vi−1 , vi ) ∈ E for i = 1, 2, · · · , k. Die Pfadlänge ist dann die Anzahl der Knoten im Pfad.
In einem gerichteten Graph bildet ein Pfad < v0 , v1 , · · · , vk > einen Zyklus (engl. cycle), wenn
v0 = vk und der Pfad mindestens eine Kante enthält. In einem ungerichteten Graph bildet der
Pfad < v0 , v1 , · · · , vk > einen Zyklus, wenn v0 = vk und v0 , v1 , · · · , vk disjunkt sind. Ein Graph
ohne Zyklus heißt azyklisch (engl. acyclic). Ein ungerichteter Graph ist zusammenhängend
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
7
(engl. connected ), wenn jedes Knotenpaar mit einem Pfad verbunden ist.
0
0
0
0
Ein Graph G = (V , E ) ist ein Subgraph (engl. subgraph) von G = (V, E), wenn V ⊆ V
0
und E ⊆ E. Die ungerichtete Version (engl. undirected version) eines gerichteten Graphen
0
0
0
G = (V, E) ist ein Graph G = (V, E ), wobei (u, v) ∈ E wenn und nur wenn u 6= v und
(u, v) ∈ E.
In einem gerichteten Graph G = (V, E) ist der Nachbar (engl. neighbor) von einem Knoten u
jeder Knoten, der in der ungerichteten Version von G zu u adjazent ist. Mit anderen Worten ist
v ein Nachbar von u, wenn entweder (u, v) ∈ E oder (v, u) ∈ E. In einem ungerichteten Graph
sind u und v Nachbarn, wenn sie adjazent sind. Ein Wald (engl. forest) ist ein azyklischer,
ungerichteter Graph. Ein zusammenhängender Wald ist dann ein Baum (engl. tree).
2.2.1
Darstellungsformen für Graphen
Zur Repräsentation eines Graphen G = (V, E) gibt es zwei Standardwege: entweder als eine
Sammlung von Adjazenzlisten in einer Adjazenzstruktur oder als eine Adjazenzmatrix. Zwischen
den Beiden wird die Adjazenzstruktur oft bevorzugt, weil sie einen kompakten Weg zur
Darstellung für einen lichten Graph(engl. sparse) bedeutet, bei dem |E| viel kleiner als |V |2
ist. Für einen dichten (engl. dense) Graph hingegen, bei denen |E| nah an |V |2 ist, wird die
Adjazenzmatrix bevorzugt. Da die hier behandelten Graphen ziemlich klein und daher eher
lichte Graphen sind, wird im Folgenden auf deren Darstellung, also die Adjazenzstrukturen
näher eingegangen.
Die Adjazentstruktur eines Graphen G = (V, E) besteht aus einem Array Adj von |V | Adjazenzlisten und zwar eine für jeden Knoten in V . Für jeden u ∈ V enthält die Adjazenzliste Adj[u]
(Zeiger auf) alle Knoten v, so daß es eine Kante der Form (u, v) ∈ E existiert , d.h. Adj[u] enthält
alle Knoten in G, die zu u adjazent sind. Für gerichtete Graphen ist die Summe der Länge aller
Adjazenzlisten gleich |E|, weil die Kante der Form (u, v) nur in der Adj[u] repräsentiert wird.
Für ungerichtete Graphen aber ist die Summe gleich 2|E|, da bei einer ungerichteten Kante wie
(u, v) u in der Adj[v] und auch v in Adj[u] repräsentiert wird .
2.2.2
Suchalgorithmen für Graphen
Die Durchmusterung eines Graphen bedeutet die systematische Verfolgung von Kanten des
Graphen zum Treffen von Knoten des Graphen [THC99]. Zwei populären Durchmusterungsalgorithmen für Graphen sind die Breitensuche (engl. Breadth-first search) und Tiefensuche (engl.
Depth-first search). Diese beide Strategien unterscheiden sich vor allem in der Reihenfolge, nach
der die Knoten des Graphen aufgesucht werden.
Der Ablauf der beiden Algorithmen lässt sich durch den folgenden Algorithmus beschreiben
(übernommen aus [Blu01]):
Algorithmus: Algorithmische Suche
Eingabe: Graph G = (V, E), repräsentiert durch seine
Adjazenzstruktur und Startknoten s ∈ V
Ausgabe: Hängt von der Anwendung ab.
Die von s aus erreichbaren Knoten sind markiert.
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
8
Methode:
for alle v ∈ V
do
H[v] := Adj[v]
od;
Q := {s};
markiere s
while Q 6= ∅
do
wähle v ∈ Q;
if H[v] 6= ∅
then
0
wähle v ∈ H[v];
0
0
H[v] := H[v ] \ {v };
0
if v nicht markiert
then
0
Q := Q ∪ {v };
0
markiere v
fi
else
Q := Q \ {v}
fi
od.
In diesem Algorithmus ist Adj[v] die Adjazenzliste für den Knoten v. Die Menge Q enthält
in jedem Schritt die Knoten des Graphen G, die bisher noch nicht vollständig bearbeitet
worden sind. Möchte man in jedem Schritt dieser Suche einen der bisher noch nicht besuchten
benachbarten Knoten des aktuellen Knoten in Q treffen und ihn zum aktuellen Knoten machen,
verwendet man für Q einen Stapel (engl. stack ). Da diese Suche so weit sie möglich in die Tiefe
des Graphen verläuft wird sie Tiefensuche genannt.
Besucht man in jedem Schritt alle direkt benachbarten Knoten des aktuellen Knotens in Q dann
verwendet man eine Schlange (engl. queue) für Q. Hier verläuft die Suche soweit wie möglich
in die Breite, daher heißt diese Suche Breitensuche. Aufgrund der zugrundeliegenden Datenstrukturen ist die Tiefensuche ein rekursives Verfahren, dagegen ermöglicht die Breitensuche die
Implementierung der einfachen nichtrekursiven Verfahren.
2.3
Darstellung Chemischer Strukturen als Graph
Die Suche in einer Datensammlung nach Chemikalien oder sonstigen beliebigen Objekten
erfordert die maschinlesbare Repräsentation dieser Objekte. Eine Repräsentation chemischer
Strukturen muß Informationen über die Art und Weise der Verknüpfung zwischen den Atomen
und Spezifitäten der Atombindungen liefern können [Gas03]. Dies wird vor allem dann benötigt,
wenn man bestimmte Strukturen innerhalb chemischer Datenbanken sucht oder versucht wird,
innerhalb der Datenbank Strukturen mit bestimmten Substrukturen zu finden.
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
9
Abbildung 2.2: Darstellung eines chemischen Moleküls (rechts) als Graph (links)
Zur Repräsentation chemischer Strukturen in Computersystemen sind mehrere unterschiedliche
Formen benutzt worden [Gas03]. Die Auswahl einer bestimmten Form ist von der Informationsbzw. Datenmenge abhängig, die sie enthalten soll. Auf dem einfachsten Level könnte es
beispielsweise nur die Atom-Repräsentation der Struktur sein. Werden mehr Informationen
benötigt, kann man auch die Konnektivität der Struktur repräsentieren (Abbildung 2.2).
In dieser wird angegeben, welches Atom mit welchem und über welchen Bindungstyp verbunden
ist. Diese Art der Repräsentation wird 2D- oder topologische Strukturrepräsentation genannt.
Das höchste Level der Repräsentation ist jene, in der die 3D-Koordinaten des Atoms in einer
bestimmten räumlichen Struktur des Moleküls angegeben ist. Sie wird 3D- oder topographische
Strukturrepräsentation genannt.
Im Rahmen dieser Arbeit wird - wegen der hohen Komplexität der 3D-Strukturen - auf die
Atomkoordination verzichtet und daher nur die 2D-Struktur benutzt. Eine 2D-Struktur läßt
sich unter anderem in den folgenden zwei Formen darstellen: als Graph oder als lineare Notation
von alphanumerischen Symbolen. Diese beiden Varianten zur Repräsentation von 2D-Strukturen
werden im weiteren Text vorgestellt.
2.3.1
Darstellung kombinatorischer Bibliotheken als Graph
Bereits im Abschnitt (2.1) wurde deutlich, daß eine kombinatorische Bibliothek aus R-Gruppen
besteht, die jeweils über eine Menge von alternativen Fragmenten verfügen. Eine kombinatorische
Bibliothek wird in den meisten Fällen durch einen ungerichteten Baum, also einen speziellen
Graph modelliert [Rar01, MR00](Abbildung 2.3).
Jeder Knoten des Baumes repräsentiert eine R-Gruppe, wobei die Wurzelknoten als R-Gruppe
0 oder Core ausgezeichnet ist. In solchen Modellierungen kann jede R-Gruppe die Rolle des
Cores übernehmen, daher gibt es keinen prinzipiellen Unterschied zwischen dem Core und
anderen R-Gruppen. Dieser legt fest, wie die Molekülfragmente miteinander verknüpft werden
sollen, um ein Molekül der Bibliothek zu erhalten.
Zur Konstruktion eines Moleküls aus der Kombination der in der Bibliothek vorhandenen
Fragmente wählt man zuerst aus dem Core genau ein und aus den anderen R-Gruppen maximal
ein Fragment aus. Sie werden dann über kovalente, einfachen Atombindungen miteinander
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
10
Abbildung 2.3: Die Baum-Darstellung einer kombinatorischen Bibliothek mit einem core und
vier R-Gruppen R1-R4
verknüpft. Die in einer Atombindung zwischen zwei Fragmenten beteiligten Atome werden
durch den Benutzer eindeutig markiert (Abbildung 2.4).
2.4
Subgraphisomorphismus
Beim Subgraphisomorphierproblem betrachtet man zwei Graphen G1 und G2 und versucht
herauszufinden, ob G1 ein Subgraph von G2 ist [THC99]. Eine der Anwendungsmöglichkeiten
des Subgraphisomorphismus in der Chemie ist die Frage, ob eine gegebene chemische Struktur
eine Substruktur einer anderen chemischen Struktur ist [Gas03].
Das Subgraphisomorphierproblem kann anhand einer brute-force-Aufzählungsmethode auf die
Suchbäume gelöst werden, die eigentlich einem Tiefensuchenalgorithmus auf die Suchbäume
entspricht. Eine Verbesserung dieser Methode wurde 1976 von J. R. Ullmann vorgestellt [Ull76].
In dem von ihm vorgestellten Algorithmus kann man die brute-force Methode beschleunigen,
indem es möglich ist unter bestimmten Voraussetzungen einige der noch nicht besuchten Knoten
aus dem Suchbaum zu löschen und dadurch den Suchraum zu verkleinern.
Die Substrukturen kombinatorischer Bibliotheken können in zwei Hauptgruppen - lineare
Ketten und Ringsysteme - aufgeteilt werden, in denen die Knoten Atome und die Kanten die
(a) Vor der Bildung; Links der core,
rechts ein Fragment der R-Gruppe R2
(b) Das fertige Bibliotheksmolekül
Abbildung 2.4: Der Zusammenbau eines Bibliotheksmoleküls.
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
11
Bindungen zwischen diesen Atomen darstellen. Eine lineare Kette kann man als einen linearen
Graphen Kn mit n − 2 Knoten vom Grad 2 und zwei Knoten mit dem Grad 1 definieren
[Gas03]. Ein Ringsystem läßt sich als ein geschlossener Pfad definieren, in dem Anfang- und
Endknoten identisch sind. Diese zwei Subgraphen können dann in allgemeiner Form innerhalb
der Fragmente von kombinatorischen Bibliotheken beliebig miteinander kombiniert vorkommen.
(Abbildung 2.5)
(a) Lineare Ketten
(b) Ringsystem
(c)
Allgemeiner
Form
mit
dem
Verzweigungspunkt
(Branch) B
Abbildung 2.5: Drei Substrukturen kombinatorischer Bibliotheken
2.5
Darstellung chemischer Strukturen als ASCII-Dateien
Wie bereits am Anfang dieses Kapitels erwähnt, ist die lineare Notation eine der Darstellungsformen für chemische Strukturen. Diese lineare Notation kann man als eine Kette alphanumerischer
Symbolen verstehen, durch die eine Strukur als eine Menge mehrerer Substrukturen in einer kompakten Form repräsentiert wird. Im Rahmen dieser Arbeit wurde eine solche Darstellungsform
- das (C)SLN- Format - verwendet, dessen Struktur im folgenden Abschnitt vorgestellt wird.
2.5.1
Das (C)SLN-Dateiformat
Die SYBYL Line Notation, SLN von Tripos inc.[Tri99] ist eine kompakte Repräsentation eines
Moleküls als eine lineare Zeichenkette von alphanumerischen Symbolen. Die Basiskomponenten
zur Spezifikation chemischer Strukturen in SLN sind Atome, Bindungen zwischen Atomen,
Verzweigungen (engl. Branches) zur Identifizierung von Verzweigungspunkten innerhalb der
Struktur, Ringsysteme (engl. Ring Closures) zur Spezifizierung der Bindungen zu den vorher
definierten Atomen und Attribute, die den Atomen, Bindungen und Strukturen spezielle
Eigenschaften zuweisen. (Abbildung 2.6)
Atome werden in SLN mit ihren Elementnamen benannt. Dabei wird der erste Buchstabe
groß und das Zweite, falls vorhanden, klein geschrieben. Die Bindungen hingegen werden durch
spezielle Zeichen zwischen zwei Atomen repräsentiert, beispielsweise steht ”-” für einfache
Bindungen, ”=” für Doppelbindungen, ”:” für aromatische Bindungen. Verzweigungen werden
durch Klammern dargestellt. Innerhalb einer Klammer steht eine Gruppe von Atomen, die an
das Atom unmittelbar vor der Klammer gebunden ist. Das Atom oder die Gruppe unmittelbar
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
12
Abbildung 2.6: Ein chemisches Molekül (oben) und seine SLN-Notation (unten)
Abbildung 2.7: Darstellung einer CSLN-Datei mit 3 R-Gruppen. Kommentarzeilen beginnen
mit #. Die erste unkommentierte Zeile definiert die Aufbauregel der Bibliotheksmoleküle. RGruppen werden mit Y 01, Y 02, Y 03 bezeichnet. Innerhalb jeder R-Gruppe werden die Fragmente durch vertikale Linien voneinander getrennt.
nach der geschlossenen Klammer ist ebenfalls an das Atom unmittelbar vor der öffnenden
Klammer gebunden. Mehrere Atomgruppen, die verschiedene an das Atom gebundenen Gruppen repräsentieren, können in Klammern hinter einem Atom stehen.
Bindungen zu einem vorher schon einmal untersuchten Atom werden als Ringsystem spezifiziert.
Dabei wird dieses Atom zuerst mit einem Label markiert, dann wird das Ringsystem durch
ein ”@” Zeichen repräsentiert, das mit dem Typ der Atombindung davor und dem Label des
gefundenen Atom danach begleitet wird.
Das SLN-Dateiformat ist aufgrund seiner Kompaktheit eine topologische Repräsentation
chemischer Strukturen. Es ist jedoch möglich, den Atomen eines bestimmten Moleküls in einer
bestimmten Konformation Koordinaten zuzuweisen. Dies geschieht über spezielle graphische
Programme, die für eine bestimmte Molekülstruktur in SLN-Form die Atomkoordinaten des
Moleküls berechnen.
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
13
Durch SLN-Dateien kann man auch kombinatorische Bibliotheken repräsentieren. Dabei werden
alle R-Gruppenfragmente der Bibliothek innerhalb einer kombinatorischen SLN-Datei (engl.
Combinatorial SLN, CSLN ) gespeichert, in der die Bindungsstellen (bzw. Bindungsatome) der
Fragmente eindeutig markiert sind (Abbildung 2.7).
2.6
Kombinatorische Bibliotheken im Protein-Ligand-Docking
Wie bereits in der Einführung erwähnt, ist das Docking-Problem einer der Anwendungsfälle
für kombinatorische Bibliotheken. Dabei sucht man - ausgehend von der dreidimensionalen
Struktur des Zielproteins - nach Verbindungen, die geometrisch und mit ausreichender Affinität
an das Protein passen und mit diesem interagieren können. Brauchte man eine große Anzahl
solcher Verbindungen, so kann man sie aus der Kombination mehrerer Baukästen erzeugen, die
jeweils über eine Menge von Alternativfragmenten verfügen.
Beim Docking-Problem wird die Vorhersage der Struktur des Protein-Ligand-Komplexes von
einer Reihe von Freiheitsgraden begleitet [Cla01]. Die Liganden besitzen - aufgrund der hohen
Zahl ihrer Konformationsmöglichkeiten - sehr flexible Strukturen, die bei der Anpassung an das
Protein berücksichtigt werden müssen. Auch die Proteine ändern ihre Form bei der Komplexbildung. Sie sind jedoch wegen der großen Zahl ihrer Atome und den internen Wechselwirkungen
im Vergleich zu den Liganden weitaus weniger flexibel.
2.6.1
Das Docking-Programm FlexX
FlexX ist ein Docking-Programm zur Modellierung von Protein-Ligand-Komplexen. Anhand der
Struktur des Proteins sucht das Programm nach Liganden, die geometrisch in die Bindetasche
des Proteins passen und chemisch eine hohe Affinität zum Protein aufweisen.
Zum Docking nimmt man eine starre Struktur des Proteins an, die Liganden sind allerdings
flexibel [HC01]. Die Flexibilität der Liganden wird durch diskrete Torsionswinkel an den
Einfachbindungen modelliert. Zur Plazierung von Liganden in die Bindetasche benutzt das
Programm einen iterativen greedy-Aufbaualgorithmus (Abbildung 2.8): Im ersten Schritt werden die Liganden azyklischer Bindungen in einzelne Fragmente zerteilt. Dann wird im zweiten
Schritt ein Fragment oder eine Gruppe von Fragmenten als Basisfragment in die Bindetasche
plaziert. Im letzten Schritt werden die weiteren Fragmente entsprechend ihrer Torsionswinkel
iterativ in der Bindetasche angebaut. An dieser Stelle wird eine Bewertungsfunktion zur
Auswahl der besten Fragmentplazierungen für die nächste Aufbaustufe benutzt.
Durch das beschriebene Verfahren läßt sich die Struktur der Protein-Ligand-Komplexe einzeln
vorhersagen. Die Stärke der Dockingalgorithmen liegt aber im Screening, also im Durchsuchen
großer Molekülbibliotheken nach geeigneten Verbindungen [MR01]. In FlexX lassen sich
Protein-Ligand-Komplexe mit potentiellen Wirkstoffmolekülen typischer Größe - 6-10 frei
drehbare Bindungen - mit dem obern beschriebenen Algorithmus in 30 sec. vorhersagen. Damit
können auf einem einzelnen Prozessor 2500-3000 Verbindungen pro Tag gedockt werden. Um
die Effizienz zu steigern, kann man die parallele Hardware nutzen. Dabei verteilt ein Scheduler
die Liganden dynamisch auf mehrere Prozessoren, welche die eigentliche Docking-Berechnung
durchführen und die Ergebnisse zurück an den Scheduler schicken. Auch im Rahmen der FlexX
Software ist ein solcher Scheduler entwickelt worden, womit pro Tag bis zu 250.000 Vergleiche
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
14
auf 100 Computern gemacht werden können.
(a) Auswahl des Basisfragmentes
(b) Plazierung des Basisfragmentes
(c) Inkrementieller Aufbau
des Liganden
Abbildung 2.8: Plazierung von Liganden in der Bindetasche.
In FlexX sind Algorithmen zur Substruktursuche implementiert worden, die im Prinzip auf dem
Algorithmus von Ullmann, worüber im Abschnitt (2.4) berichtet wurde, basiert sind [MR04].
Mit Hilfe dierser Algorithmen kann man innerhalb eines einzelnen Molekül nach bestimmten
Substrukturen suchen, so daß zur Suche innerhalb einer Menge von Molekülen müssen sie nacheinander nach der gewünschten Struktur durchsucht werden.
2.6.2
Das FlexX-Modul FlexXC
Wie weiter oben erwähnt wurde, verfügt FlexX zur Dockingberechnung an kombinatorischen
Bibliotheken über das zusätzliche Modul FlexXC , womit einzelne Fragmente oder eine Kombination von Fragmenten nach derselben Strategie wie in FlexX an das Protein gedockt werden
können. In FlexX ist die Anzahl der R-Gruppen begrenzt, so daß zur Konstruktion eines
Bibliotheksmoleküls außer dem Core bis zu maximal neun weitere Rest-Gruppen ausgewählt
werden dürfen.
Wie bereits in (2.1) erläutert, wird bei der Zusammensetzung der Bibliotheksmoleküle aus
Fragmenten eine ähnliche Aufbaustrategie verfolgt. Dies führt dazu, daß man zum Aufbau
neuer Fragmenten die Informationen von vorherigen, ähnlich struktuierten Fragmenten nutzen
und dadurch die Zeit für die Suche begrenzen kann. Somit ist es möglich - je nach Struktur der
Bibliothek - eine Beschleunigung der Docking-Rechnung um einen Faktor bis zu 50 erzielen.
Beim Bau eines Moleküls in FlexXC werden die Fragmente über die X - und R-Verbindungsatome
aneinander gekoppelt. (Abbildung 2.4) Dabei wird das X -Atom durch das benachbarte Atom
KAPITEL 2. MATHEMATISCH-CHEMISCHE GRUNDLAGEN
15
des R-Atoms und das R-Atom durch das benachbarte Atom des X -Atom ersetzt. Auf Einzelheiten zu diesem Vorgang wird im Kapitel 5 näher eingegangen.
In FlexX können die kombinatorischen Bibliotheken auch nach Substrukturen durchsucht werden. Dazu werden in FlexX die Bibliotheksmoleküle eines nach dem anderen zusammengesetzt
und jeweils geprüft, ob das entsprechende Molekül die gesuchte Substruktur enthält. Diese Methode hat den Nachteil, daß die Suche in großen Bibliotheken mit mehreren Millionen Bibliotheksmolekülen sehr lange dauern kann.
Kapitel 3
Datenbank-Grundlagen
Ein Datenbanksystem ist eine Sammlung von anwendungsspezifischen Daten (Datenbank ) und
einem anwendungsunabhängigen Programm (Datenbank management system, DBMS ) zur
Verwaltung solcher Daten [Man]. Unter Verwaltung von Daten versteht man die Definition von
Strukturen zur Speicherung von Informationen und den Entwurf von Mechanismen zu deren
Manipulation.
Vor der Entwicklung von Datenbanksystemen wurden die Daten in den Betriebsystemdateien
gelagert. Diese Art der Datenerhaltung hat einige wesentliche Nachteile. Einer von ihnen ist
die Datenredundanz, d.h. mehrfache Speicherung gleicher Informationen von unterschiedlichen
Programmen in Dateien mit unterschiedlichen Formaten. Dies wiederum kann zur Dateninkonsistenz führen, wobei einige Kopien derselben Information nicht aktualisiert werden und daher
nicht mehr gültig sind. Auch die Bergung von Informationen wird unter diesen Umständen
schwierig, weil die dazu notwendigen Anwendungsprogramme in unterschiedlichen Formen
geschrieben werden müssen. Möchte man diese Programme später auf nicht vorgesehenen Fälle
erweitern, muss man sie eventuell aktualisieren oder im schlimmsten Fall komplett neu schreiben.
Solche Probleme zusammen mit einer Reihe weiterer Probleme schaffen den Bedarf einer systematischen Datenbearbeitung. Dazu muss eine Datenbank entworfen werden, in die die Informationen aus der realen Welt unter Beibehaltung ihrer Strukturen importiert und dann unter
Kontrolle eines geeigneten DBMS effizient und zuverlässig verwaltet werden.
3.1
Datenbankmodellierung
Die wichtigste Voraussetzung eines Datenbankentwurfes ist eine saubere Modellierung. Es wird
ausdrücklich davor gewarnt, den Datenbankentwurf unvollständig und nicht systematisch zu
machen, denn die daraus resultierenden Probleme sind meistens nicht mehr korrigierbar.[uA01]
Zum Entwurf einer neuen Datenbank verfolgt man, ähnlich wie bei der Erstellung großer
Softwaresysteme, eine Phasenweise-Modellierung, in der die Komplexität des Problems in
mehrere Schichten aufgeteilt wird [uA01, Vos00]. Bei der ersten Phase des Entwurfprozesses, der
Anforderungsanalyse, geht es darum die Anforderungen der zukünftigen Datenbankbenutzer an
die zu entwerfende Datenbank zu analysieren und sie in Form einer Anforderungsspezifikation
(auch Pflichtenheft genannt) zu dokumentieren. Die Hauptbestandteile solcher Dokumen16
KAPITEL 3. DATENBANK-GRUNDLAGEN
17
te sind Objekte und Beziehungen zwischen den Objekten, die jeweils in den Objekttypen
und Beziehungstypen abstrahiert werden, und Attribute, die die Objekte und Beziehungen
identifizieren sollen. Das daraus resultierende Dokument wird in der zweiten Phase, dem
konzeptuellen Entwurf benutzt, um die darin enthaltenen Informationen der zu modellierenden
Welt formal und unabhängig von dem Ziel-DBMS darzustellen. Das hierzu am meisten benutzte Datenmodell ist das Entity-Relationship-Modell (kurz ER-Modell ) [Vos00, uA01, A.S02, Man].
In der dritten Phase, dem logischen Entwurf, erhält man das ER-Schma aus der zweiten Phase
und transformiert es dann in das Datenmodell des zu verwendenden DBMS. Auch hier hat
sich ein Modell, nämlich das relationale Datenmodell seit Mitte der 80-er Jahren als Standard
in kommerziellen DBMS durchgesetzt. Die vierte und letzte Phase des Datenbankentwurfes
ist der physische Entwurf, wobei versucht wird, die Effizienz des geasmten Datenbankschemas
zu steigern, ohne dabei die logische Struktur der Daten verändern zu müssen. Dazu wird
vor allem eine grundlegende Kenntnis des eingesetzten DBMS so wie des dazu verwendeten
Betriebsystems benötigt.
Im folgenden werden die konzeptuellen und logischen Phasen des Datenbankentwurfes bzw. die
dazugehörigen Datenmodelle Entity-Relationship-Modell und relationales Modell näher betrachtet, da sie den Kern eines Datenbankdesigns ausmachen. Einzelheiten zur ersten und vierten
Phase des Entwurfprozesses können z.B. [Vos00, uA01, A.S02] entnommen werden.
3.1.1
Das Entity-Relationship-Modell
Das Entity-Relationship-Modell wurde 1976 von Peter Chen vorgeschlagen. Dieses Modell
spielt eine wichtige Rolle, sowohl bei der Datenbankimplementierung als auch auf anderen
Gebieten der Informatik, wo es darum geht, die Gesetzmäßigkeiten der zu modellierenden Welt
auf eine abstrakte Ebene zu übertragen [Vos00]. Im Bezug auf den Datenbankentwurf hat dieses
Modell unter anderem die Vorteile, daß es erstens unabhängig von einem bestimmten DBMS ist
und zweitens seine Grundkonstrukte sehr natürliche Ausdrucksmittel sind, die auch in vielen
Anwendungen ausreichend sind. Beim Entwurf einer relationalen Datenbank trifft der zweite
Punkt besonders zu. Zwar verfügt das relationale Modell mit seiner Normalisierugstheorie über
algorithmische Möglichkeiten zum Datenbankentwurf, aus den o.g. Gründen wird aber das
ER-Modell bevorzugt.
Die Grundkonstrukte des ER-Modells sind die Gegenstände (engl. Entities) und Beziehungen
(engl. Relationships) zwischen den Entities. Entities sind wohlunterscheidbare physisch oder
gedanklich existierende Konzepte der zu modellierenden Welt [uA01]. Ähnliche Entities werden
zu Entitytypen zusammengefasst, die graphisch als Rechtecke dargestellt und mit einem eindeutigen Namen beschriftet werden. Ein Entity gehört mindestens einem Entitytyp an. Damit wird
es eine Instanz dieses Typs genannt. Jedes Entity besitzt ein oder mehrere Attribute, durch
deren Werte es eindeutig identifiziert wird. Sie werden dann Schlüsselattribute des Entities
genannt. Wurden keine Schlüsselattribute explizit vorgegeben, wird die Menge aller Attributen
als Schlüsselattribut genommen.
Die Entities eines ER-Modells stehen miteinander in Beziehung. Auch hier werden gleichartige
Relationships zu Relationshiptypen zusammengefasst, die graphisch als Rauten beschriftet
mit einem Namen repräsentiert werden. Folglich ist eine Instanz eines Relationshiptyps eine
KAPITEL 3. DATENBANK-GRUNDLAGEN
18
Relationship zwischen einzelnen Entities der in der Relationship beteiligten Entitytypen. Die
Relationships können wie Entities Attribute besitzen, jedoch keine Schlüsselattribute. Der
Grund liegt darin, daß jede Relationship in seiner Existenz abhängig von den in der Beziehung
beteiligten Entities ist und daher über deren Schlüsselattribute charakterisiert wird.
Die Funktion eines Entities in einer Relationship wird als Rolle des Entities bezeichnet, die auf
der Kante zwischen dem Entity und Relationship geschrieben wird. Solange jedes Entity nur
einmal an einer Relationship beteiligt ist, ist die Rolle des Entities auch implizit. Andernfalls,
zum Beispiel bei rekursiven Relationships, wo ein Entitytyp mehrfach in der Relationship
vorkommt, muss die Art der Beteiligung extra angegeben werden.
Ein weiterer wichtiger Punkt, die man bei der Modellierung der realen Welt unbedingt beachten
muss, sind die Integritätsbedingungen, die immer gelten müssen. Möchte man zum Beispiel
ausdrücken, daß ein Entity in einer Beziehung sich eingeschränkt beteiligen darf, so kann man
eine solche Bedingung im ER-Modell über die Funktionalitäten ausdrücken, die in Form von
Annotationen an den Verbindugskanten zwischen den Entity- und Relationshiptypen geschrieben
werden. Hinsichtlich der Fuktionalitäten kann man einen binären Beziehungstyp R zwischen den
Entitytypen E1 und E2 in vier verschiedene Formen aufteilen:
• 1 : 1-Beziehung, wenn jede Instanz e1 ∈ E1 mit maximal einer Instanz e2 ∈ E2 und
umgekehrt jede e2 ∈ E2 mit maximal einer Instanz e1 ∈ E1 in Beziehung steht.
• 1 : N -Beziehung, wenn jede Instanz e1 ∈ E1 mit vielen Instanzen e2 ∈ E2 aber jede e2 ∈ E2
nur mit maximal einer Instanz e1 ∈ E1 in Beziehung stehen darf
• M : 1, ist ähnlich wie bei den 1 : N -Beziehungen
• M : N -Beziehung, stellt den allgemeinen Fall dar, wobei jede Instanz e1 ∈ E1 mit beliebig
vielen Instanzen e2 ∈ E2 , und umgekehrt jede Instanz e2 ∈ E2 mit vielen Instanzen e1 ∈ E1
in Beziehung stehen darf. Wenn für einen Relationshiptyp keine Funktionalität angegeben
ist, ist dieser Fall gemeint.
Ähnlich wie bei den binären Relationshiptypen können solche Funktionalitäten auf die
n-stelligen Relationshiptypen erweitert werden, die dann als mehrere partielle Funktionen
angesehen werden. (Für weitere Details siehe [uA01, A.S02]).
Die bis jetzt diskutierten Entitäten waren alle autonom existierende Objekte, die innerhalb ihrer Entitymenge über ihre Schlüsselattribute identifiziert werden können. Daneben
gibt es Entitäten, die selber keine Schlüsselattribute besitzen. Ihre Existenz ist von einer
weiteren, übergeordneten Entität abhängig und sie sind oft nur in Kombination mit dem
Schlüsselattribut der übergeordneten Entität identifizierbar. Sie werden im ER-Modell als
schwache Entities bezeichnet und werden graphisch meist als Rechtecke mit doppelten
Linien dargestellt. Auch die Beziehung zu dem übergeordneten Entitytyp wird durch eine
Verdopplung der Raute und der Linie zwischen der Raute und dem schwachen Entitytyp gezeigt.
Im ER-Modell sind noch zwei weitere Konzepte - Generalisierung und Aggregation - vorgesehen,
die zur besseren Strukturierung des gesamten Schemas gedacht sind. Bei der Generalisierung
handelt es sich um eine Abstraktion auf der Entitytyp-Ebene, indem die gemeinsamen Attribute
ähnlicher Entitytypen einem Obertyp zugeordnet werden und die nicht-gemeinsamen Attributen
KAPITEL 3. DATENBANK-GRUNDLAGEN
19
bei den Untertypen verbleiben. Dadurch ist jede Instanz eines Untertyps auch eine Instanz des
Obertyps.
Die Generalisierungsbeziehung wird durch die spezielle is a Beziehung zwischen den beteiligten
Entitytypen modelliert und wird in dem ER-Schema anders als normale Beziehungen oft als
Sechseck dargestellt. Anders als bei der Generalisierung wird bei der Aggregation die Abstraktion auf der Instanzebene realisiert, indem die Instanzen eines Obertyps aus den Instanzen der
unterschiedlichen Untertypen zusammengesetzt werden. Diese Beziehung zwischen den Instanzen, die als is part of bezeichnet wird, ist eine spezielle Form der allgemeinen Relationships.
Hingegen ist die is a Beziehung keine Relationship, weil sie eine Relationship zwischen den Entitytypen ist und nicht zwischen den Entities selbst.
3.1.2
Das relationale Datenmodell
Die Idee vom relationalen Modell wurde im Jahre 1970 von E. F. Codd in einem Paper A
Relational Model of Data for Large Shared Data Banks vorgestellt [Man]. In den bisherigen
Datenmodellen, wie dem Netzwerkmodell oder dem hierarchischen Modell, wurden die Informationen in Form von Datensätzen über Referenzen miteinander verbunden. Im Gegensatz dazu
werden im relationalen Modell die Informationen mengenorientiert verarbeitet.
Grundlage des relationalen Datenmodells ist die Relation. Eine Relation R über die nicht unbedingt unterschiedlichen Mengen D1 , · · · , Dn - d.h. für ∀i, j ∈ [1, n] mit i 6= j ist Di = Dj erlaubt
- wird definiert über folgende Formel:
D1 × · · · × Dn = {(d1 , · · · , dn )|di ∈ Di }
Die Mengen D1 , · · · , Dn nennt man Domäne, das Elemente (d1 , · · · , dn ) Tupel und n die
Stelligkeit oder den Grad der Relation R. Somit kann man eine Relation als eine Tupelmenge
ansehen.
Relationale Datenbanken basieren auf Relationen, die in den meisten kommerziellen Systemen
auch als Tabellen bezeichnet werden, weil deren Instanzen optisch als flache Tabellen vorstellbar
sind [uA01]. Die Zeilen dieser Tabellen sind die Relationstupeln und die Spalten die Domänen der
Relation, die Attribute genannt werden. Innerhalb einer Tabelle müssen die Attribute eindeutige
Namen tragen, somit werden alle Komponenten eines Tupels eindeutig benannt. Trotz dieser
Analogie unterscheiden sich Tabellen und Relationen in einigen Punkten. Der wichtigste ist, daß
die Relationen keine Duplikate erlauben, während in Tabellen Einträge mehrfach vorkommen
dürfen.
3.1.3
Abbildung des Entity-Relationship-Modells in das relationale Datenmodell
Im Gegensatz zum ER-Modell, wo die Konzepte der zu modellierenden Welt auf zwei Hauptkonstrukte - Entity und Relationship - übertragen werden, steht im relationalen Datenmodell
ein einziges Konstrukt, nämlich die Relation. Damit müssen zur Umsetzung des ER-Modells
in das relationale Datenmodell die Entity- und Relationshiptypen in Relationen bzw. Tabellen
überführt werden.
KAPITEL 3. DATENBANK-GRUNDLAGEN
20
Die Abbildung der Entitytypen in Tabellen ist relativ einfach: pro Entitytyp erzeugt man
eine Tabelle, die als Tabellennamen die Beschriftung und als Spaltennamen die Attribute des
Entitytyps trägt, wobei die Schlüsselattribute des Entitytyps auf Primärschlüsselspalten der
Tabelle abgebildet werden.
Die Abbildung von Relationshiptypen geschieht in zwei Schritten. Zuerst wird jeder Relationshiptyp ähnlich wie bei den Entitytypen auf eine Tabelle abgebildet, dann werden unter
Umständen einige dieser Tabellen in andere Tabellen eingebettet. Bei der Umsetzung des
Relationshiptyps in die dazugehörige Tabelle werden die Schlüsselattribute aller beteiligten Entitytypen als Fremdschlüssel neben den eigenen Attributen des Relationshiptyps übernommen.
Dadurch können die Tupeln der an der Beziehung beteiligten Entitytypen innerhalb der Tabelle
eindeutig identifiziert werden.
In jeder Tabelle gibt es ein einziges oder eine minimale Menge von Attributen, deren Werte jedes
Tupel der Tabelle eindeutig identifizierbar machen. Sie werden Schlüsselattribute der Tabelle
genannt. Gibt es mehrere solcher Schlüsselattribute wird eines von ihnen als Primärschlüssel
gewählt.
Wie bereits erwähnt, kann man in bestimmten Fällen einige der Relationshiptabellen innerhalb
anderer Tabellen repräsentieren und dadurch auf eine eigene Tabelle verzichten. Dies geschieht
bei den 1 : 1-, 1 : N - oder N : 1-Beziehungen. Der Grund läßt sich wie folgt beschreiben:
Sei R eine N : 1-Beziehung zwischen den Entitytypen E1 und E2 . In diesem Fall kann R als
eine Funktion der Form R : E1 → E2 verstanden werden. Damit wird die Relation R durch E1
eindeutig identifizierbar. Das bedeutet, daß die Relation R dieselben Primärschlüssel besitzt
wie E1 . Somit lassen sich die beiden Relationen ohne Informationsverlust zusammenfassen.
Dasselbe gilt auch für die 1 : N -Beziehungen.
Für die 1 : 1-Beziehungen können die Beziehungsinformationen entweder in der einen oder in der
anderen Relation dargestellt werden. Ebenso könnte man auch mit n-stelligen Relationshiptypen
verfahren. Es ist jedoch etwas komplizierter und kann unter Umständen zu Schwierigkeiten
führen [Man].
Das relationale Datenmodell bietet keine Möglichkeit zur Modellierung von Generalisierungen
aus dem ER-Modell. Dies läßt sich aber mit Hilfe von Sichten in SQL lösen, was im Abschnitt
(3.2.2) näher diskutiert wird.
3.2
Relationale Anfragesprachen
Der nächste Schritt nach der Modellierung bei der Datenbankimplementierung ist die Einsetzung der Konzepte des Modells in ein DBMS, welches das jeweilige Modell unterstützt. Dazu
wird vor allem eine Sprache zur Kommunikation mit dem DBMS benötigt, die im allgemeinen
als Anfragesprache (engl. query language) bezeichnet wird. Für relationale Systeme gibt es eine
Reihe von Anfragesprachen. Einige von ihnen, wie Relationenalgebra oder Relationenkalkül,
sind formal und dienen als Basis für eine weitere, praxisorientierte Sprache. Eine solche ist
SQL, die sehr weit verbreitet ist und von fast allen relationalen DBMS unterschtützt wird.
Im Folgenden werden zunächst die Grundprinzipien der beiden Sprachen Relationenalgebra und
KAPITEL 3. DATENBANK-GRUNDLAGEN
21
Relationenkalkül erläutert. Dann wird die Sprache SQL ausführlicher vorgestellt.
3.2.1
Relationenalgebra und Relationenkalkül
Wie bereits in (3.1.2) erwähnt, geschieht die Datenbearbeitung im relationalen Datenmodell
Mengenweise. Daher ist zur Erläuterung aller relationalen Sprachen ein Grundverständnis
der Mengenlehre unabdingbar. In diesem Abschnitt wird daher eine kurze Einführung in die
Grundbegriffe der Mengenlehre gegeben:
Eine Menge aus mathematischer Sicht läßt sich am besten mit einem Satz von Georg Cantor,
dem Begründer der Mengenlehre, definieren [Man]:
Unter einer Menge verstehen wir eine Zusammenfassung von bestimmten wohl unterschiedenen Objekten unserer Anschauung oder unseres Denkens zu einem Ganzen.
Zwei Mengen können über die vier Basisoperatoren Vereinigung ∪, Durchschnitt ∩, Differenz /
und Produkt × verknüpft werden. Da das Ergebnis dieser Operationen wiederum Mengen sind,
kann man das Ergebnis einer Mengenoperation als Eingabe für andere Mengenoperationen
verwenden. Daher können mehrere Mengen über Mengenoperatoren verknüpft werden. Eine
spezielle Verknüpfung ist es, wenn man die Mengen D1 , · · · , Dn über den Produktoperator ×
verbindet. Dann ensteht eine Relation, deren Definition bereits im Abschnitt (3.1.2) vorgestellt
wurde.
Wie bereits erwähnt, sind die Ergebnisse einer Mengenoperation wiederum Mengen. Das entspricht der Definition einer Algebra in der Mathematik, wo ein System von Operatoren auf eine
Trägermenge operieren und die Ergebnisse nochmals derselben Menge angehören. Demensprechend ist eine Mengenalgebra die Algebra, bei der die Trägermenge aus Mengen besteht, auf die
die vier oben genannten Operationen (∪, ∩, / und × ) operieren. Die Relationenalgebra RA ist
eine spezielle Form der Mengenalgebra, bei der die Trägermenge aus speziellen Mengen - nämlich
Relationen - besteht. Es ist zu beachten, daß die Resultate der Operationen in der Relationenalgebra zwar immer Mengen sind, sie sind jedoch nicht immer Relationen. Nur Relationen mit
gleichem Grad und gleichen Spaltentypen können vereinigt, geschnitten und subtrahiert werden.
Die Relationenalgebra bietet zusätzlich zu den vier Grundoperatoren noch zwei weitere einstellige Operatoren, nämlich die Projektion π und Selektion σ zum Extrahieren von Spalten bzw.
Zeilen. Diese beiden Operatoren können dann mit den Grundoperatoren kombiniert werden
und dadurch weitere abgeleitete Operatoren bilden, wie etwa Varianten der Produktbildung,
die verschiedene Formen von join-Operatoren darstellen.
Eine Alternative zur Relationenalgebra bietet die Sprache Relationenkalkül. Im Gegesatz zu der
eher prozedural aufgebauten Sprache Relationenalgebra, bei der man einen Abarbeitungsplan
erstellen kann, ist die Sprache Relationenkalkül eine deklarative Sprache, bei der die Anfragen
über logische Ausdrücke aus der Prädikatenlogik erster Stufe formuliert werden. Bei letzterer
gibt man an, welche Kriterien die Daten erfüllen müssen, damit sie als Ergebnis in Frage
kommen. Es gibt zwei verschiedene Varianten des Relationenkalküls, die sich jedoch hinsichtlich
ihrer Mächtigkeit nicht unterscheiden: diese sind der relationale Tupelkalkül (ensl. tupel
relational calculus, TRC ) und der relationale Bereichs- oder Domänenkalkül (engl. domain
relational calculus, DRC ). Da die Relationenalgebra wegen ihres prozeduralen Charakters bei
KAPITEL 3. DATENBANK-GRUNDLAGEN
22
der Realisierung von Datenbanksystemen eher in Frage kommt als der Relationenkalkül, wird
an dieser Stelle auf weitere Einzelheiten über die Sprache Relationenkalkül verzichtet und näher
auf die Relationenalgebra eingegangen. Details zum Relationenkalkül können zum Beispiel in
[uA01, A.S02] gelesen werden.
Die Relationenalgebra wird mittlerweile als eine vollständige relationale Sprache betrachtet.
Es geht sogar so weit, daß zur Messung der Ausdrückfähigkeit anderer relationaler Sprachen
diese mit ihr verglichen werden. Eine Sprache ist relational volständig, wenn sie für jeden
RA-Ausdruck eine äquivalente Darstellung besitzt. Die Kalkülsprachen DRC und TRC sind
relational vollständig [Man].
Relationale Algebra und Kalkülsprachen sind theoretische Sprachen, die in der Praxis jedoch
nicht zum Einsatz kommen. SQL ist eine weitere relational vollständige Sprache, deren Ausdruckfähigkeit jedoch weit über die der beiden genannten Sprachen hinausgeht. Sie besitzt
unter anderem arithmetische Operatoren und Aggregatfunktionen, Gruppierungs- und Sortierungsmöglichkeiten und built-in-Operatoren, die nicht in den o.g. formalen Sprachen vorgesehen
sind.
3.2.2
SQL
SQL ist die am häufigsten verwendete Anfragesprache für relationale Datenbanksysteme. Sie
ist eine deklarative Sprache, wobei man bestimmt, welche Informationen man haben möchte,
ohne zu wissen, wie sie ausgewertet werden [Mel03b].
Die Erfindung der Sprache SQL führt zurück zum Beginn der 70-er Jahren, in denen die
Firma IBM die Sprache Structured English Query Language (SEQEL) für das relationale
Prototyp-DBMS System R entwickelte. Diese Sprache hat sich im Laufe der Zeit weiterentwickelt und wurde schließlich in Structured Query Language (SQL) umbenannt. Im Jahr 1986
haben das American National Standard Institut (ANSI) und die International Organisation
for Standardization (ISO) die erste SQL-Norm, SQL-86 vorgelegt. Eine Reihe zusätzlicher
Erweiterungen folgten später: SQL-89 (1989), SQL-92 oder SQL 2 (1992) und die aktuellsten
Versionen SQL:1999 oder SQL 3.
Die Sprache SQL besteht aus zwei Teilsprachen: Data-Definition Language, DDL zur Definition
und Manipulation von Datenbankschemata und Data Manipulation Language DML zur Formuliernug von Anfragen an die Datenbankinstanzen und deren Manipulation. Beide Teilsprachen
bieten eine Reihe von Befehlen, die die Ausführung der o.g. Operationen ermöglichen.
Ein Datenbankschema wird in SQL über den Befehl CREATE SCHEMA mit folgender Syntax erzeugt:
CREATE SCHEMA
[schema-name]
[AUTHORIZATION user-name]
[DEFAULT CHARACTER SET character-set]
[list-of-schema-elements]
Von den soeben genannten Feldern sind nur Schemaname und Benutzerautorisierung unbedingt
KAPITEL 3. DATENBANK-GRUNDLAGEN
23
erforderlich. Elementare Bestandteil des obigen Befehls sind die sogenannten Schemaelemente
(list-of-schema-elements), worunter die domain-, table-, view -, privilege-, constraint-,
character set-, collation- und translation-Definitionen stehen.
Der vielleicht wichtigste Befehl der DDL ist der CREATE TABLE-Befehl zum Erzeugen einer neuen
Tabelle. Die Syntax lautet:
CREATE TABLE table-name
column_1_name column_1_type [column-constraint_1],
...
column_n_name column_n_type [column-constraint_n],
[table-constraints]
Die Tabellendefinition kann man in zwei Teile aufteilen: Spaltendefinitionen und Tabelleneinschränkungen. Bei der Spaltendefinition wird für jede Spalte ein eindeutiger Name column-name
und der Typ des Wertebereiches der jeweiligen Spalte column-type festgelegt. Zusätzlich besteht die Möglichkeit für die Werte jeder Spalte Einschränkungen column-constraints zu setzen, die wie folgt aussehen können:
[NOT NULL | UNIQUE]
[PRIMARY KEY]
[DEFAULT {literal | NULL}]
[REFERENCES table name]
[CHECK condition]
Diese Einschränkungen lassen sich auf ähnliche Art und Weise wie bei den Spalten über Tabelleneinschränkungen definieren. Ihre Syntax lautete dann:
[NOT NULL | UNIQUE]
[PRIMARY KEY]
[DEFAULT {literal | NULL}]
[REFERENCES table name]
[CHECK condition]
Tabelleneinschränkungen sind optional und gelten i.a. für mehrere Spalten. Bei den Spalteneinschränkungen handelt es sich hingegen immer um die gerade betrachtete Spalte.
Die Spalten- und Tabelleneinschränkungen, die auch als Integritätsbedingungen bezeichnet
werden, sind wichtige Bestandteile jedes CREATE TABLE-Befehls, die für die Konsistenzerhaltung
der Datenbankzustände sorgen. Daher soll im folgenden auf sie genauer eingegangen werden.
In einer Tabelle ist eine Spalte oder eine Kombination aus mehreren Spalten ein Kandidatenschlüssel, wenn keine Zeilen dieser Spalten dieselben Werte haben. Solche Spalten gibt werden
mit UNIQUE-Optionen ausgezeichnet. Die als UNIQUE ausgezeichneten Spalten dürfen mehrfach
NULL-Werte enthalten. Das kann aber durch die Option NOT NULL verhindert werden.
KAPITEL 3. DATENBANK-GRUNDLAGEN
24
Für jede Tabelle kann einer der Kandidatenschlüssel als Primärschlüssel deklariert werden. Der
Primärschlüssel wird eindeutig über die PRIMARY KEY-Option in den Spalten- oder Tabelleneinschränkungen der Tabelle markiert. Im Gegensatz zu Kandidatenschlüssel, die NULL-Werte
enthalten dürfen, sind bei dem Kandidatenschlüssel, der als Primärschlüssel definiert wurde
keine NULL-Werte erlaubt. Trotzdem ist ein Primärschlüssel nicht prinzipiell mit einem UNIQUE
NOT NULL-Kandidatenschlüssel gleichzusetzen, da der Primärschlüssel eine eindeutige Rolle
innerhalb der Tabelle spielt, die nicht einfach durch diese Definition ersetzbar ist. Die Option
DEFAULT dient zur Einsetzung von Standardwerten für eine Spalte, wenn dazu explizit keine
Angabe bei der Eingabe der jeweiligen Zeile gemacht wurde. Die CHECK-Option prüft, ob die in
condition formulierte Bedingung in jedem Datenbankzustand gilt.
Oft referenzieren die Spalten der neu deklarierten Tabelle die Primärschlüssel einer zweiten Tabelle. Diesen Fall, der auch referenzielle Integrität genannt wird, kann man entweder innerhalb
der Tabelleneinschränkung oder als Spalteneinschränkung formulieren. Bei der Ersten wird die
Bedingung über die FOREIGN KEY-Option formulieren, wobei table-name den Tabellennamen
der referenzierten Tabelle und die optionale Liste - list-of-column-names - die Zielspalten
festlegt. Gibt man keine Liste der Zielspalten an, werden die Primärschlüssel der Referenztabelle
als Referenzspalten angenommen. Bei letzterer wird die Integritätsbedingung durch die Option
REFERENCES ausgedrückt. Auch hier ist der table-name der Name der Referenztabelle.
Wie bereits erwähnt, handelt es sich bei der DML Sprache um den Teil der Sprache SQL, der
sowohl für Anfragestellungen an, als auch die eigentliche Manipulation von Datenbankinstanzen
verantwortlich ist. Dementsprechend kann man die DML-Befehle in zwei Gruppen aufteilen:
Befehle zu Anfrageformulierungen und Befehle zur Durchführung von Änderungsoperationen.
Die SQL-Anfragen basieren auf den drei Klauseln SELECT , FROM und WHERE mit der folgenden
Syntax:
SELECT (list-of-column-names)
FROM (list-of-talbe-names)
WHERE (condition)
Bei der Ausführung dieser Anweisungen wird zuerst im FROM-Teil das kartesische Produkt zwischen den in list-of-table-names aufgelisteten Tabellen gebildet, dann wird im WHERE-Teil
die Bedingung - condition - für die aus dem Produkt resultierenden Zeilen geprüft und die
gewünschten Zeilen selektiert. Am Ende werden aus den Spalten der selektierten Zeilen die in
list-of-column-names aufgelisteten Spalten herausprojeziert, die in Form einer abgeleiteten
Tabelle dargestellt werden.
Die drei Klauseln SELECT, FROM und WHERE der SQL-Anfragen modellieren die Operatoren
Produkt, Selektion und Projektion aus der Relationenalgebra. Weitere RA-Operatoren wie
Vereinigung, Durchschnitt, Minus und Join werden jeweils über union, intersect, minus und
join in SQL vertreten. Diese kann man auch in kombinierter Form benutzen, um komplexe
Anfragen zu formulieren.
Innerhalb von SQL-Anfragen kann man auch Bedingungen zu deren Auswertung in Form
von booleschen Ausdrücken formulieren, die entweder als Auswahlkriterien im WHERE-Teil der
Anfrage oder als Integritätsbedingung in der CHECK-Klausel formuliert werden. Jede Bedingung
KAPITEL 3. DATENBANK-GRUNDLAGEN
25
läßt sich in zwei allgemeine Formen aufteilen: Vergleichsbedingungen zum Vergleich von Spalten
einzelner Zeilen mit konstanten Werten oder den Werten anderer Spalten und Existenzbedingungen zum Test, ob die Antworttabelle einer Unteranfrage leer ist. Vergleichsbedingungen
werden durch booleschen Operatoren und die Operatoren LIKE und BETWEEN realisiert. Diese
können auch zusammen mit weiteren AND-, OR- und NOT-Operatoren kombiniert benutzt werden.
Die Existenzbedingungen werden innerhalb von (NOT)EXISTS- und (NOT)IN-Klauseln formuliert.
Änderungsoperationen in SQL werden in drei Hauptgruppen unterteilt: INSERT zum Einfügen,
UPDATE zum Ändern und DELETE zum Löschen von Zeilen. Der INSERT-Befehl hat folgende
Syntax:
INSERT INTO <table-name> [(<list-of-columns>)] <table-expression>
Der UPDATE-Befehl hat folgende Syntax:
UPDATE <table-name>
SET <list-of-assignmets>
[WHERE <conditional-expression>]
Der DELETE-Befehl hat folgende Syntax:
DELETE FROM <table-name>
[WHERE <conditional-expression>]
Sichtendefinition
Sichten (engl. views) sind abgeleitete, virtuelle Relationen, bei deren Definition keine neue Tabelle abgelegt, sondern nur ein Ausschnitt aus den in den statischen Tabellen enthaltenen Informationen repräseniert (daher virtuell) wird. Sichten werden durch den Befehl CREATE VIEW
erzeugt:
CREATE VIEW view-name AS
query expression
Die Sichtendefinition enthält eine SQL-Anfrage, die durch die Definition einen eindeutigen Namen bekommt. Wird eine Anfrage auf eine Sicht gestellt, so wird der AS-Teil der Sichtdefinition
statisch an der Stelle eingesetzt, wo die Sicht aufgerufen wurde.
Eine der Anwendungen von Sichten erfolgt bei der relationalen Modellierung von Vererbung.
Hierzu gibt es zwei Möglichkeiten: entweder existiert der Obertyp als Relation bzw. Tabelle
und die Untertypen werden als Sicht modelliert oder die Untertypen liegen physisch vor und der
Obertyp wird als Sicht definiert. In beiden Fälle gibt es Vor- und Nachteile, die eine entscheidende
Rolle bei der Auswahl einer der beiden Varianten spielen. Diese können in [uA01, Man] gelesen
wereden.
Datentypen in SQL
Der SQL-Standard bietet eine Vielfalt von vordefinierten Datentypen, die man im Allgemeinen
in drei Gruppen aufteilen kann: Zahlen, Zeichenketten und Zeit/Datum. Zu Zahlen gehören
KAPITEL 3. DATENBANK-GRUNDLAGEN
26
die Datentypen numeric(p, d) zur Darstellung p-stelliger Zahlen, wovon d-Stellen als Nachkommastellen reserviert sind, integer oder int, die für Zahlen ohne Nachkommastellen stehen,
und float(n) für Fliesskommazahlen mit einer mindestens n-stelligen Präzision. Zeichenketten
sind entweder vom Typ char (n) bzw. character (n) zur Darstellung von Zeichenketten mit der
festen Länge n oder varchar (n) bzw. character variying(n) zur Darstellung von Zeichenketten
mit maximaler variabler Länge n. Zum Zeit/Datum-Datentyp gehören die Datentypen date zur
Darstellung von Jahr, Monat und Tag, time zur Darstellung der Zeit in Stunden, Minuten und
Sekunden und timestamp als eine Kombination von beiden.
Viele kommerzielle Datenbanksysteme bieten zusätzlich zu den Grunddatentypen noch weitere
Datentypen wie Large OBjects (LOBs) zur Speicherung von großen Daten oder user-defined
types (UDTs) zum Aufbau komplexer Datentypen, die dann als Attributtypen verwendet werden
können. Mehr zum Thema Datentypen in SQL können z.B. bei [Mel03b, uA01, A.S02] gelesen
werden.
Erweiterungskonzepte in SQL
In den 90-er Jahren erlebte die IT-Branche einige wichtige Ereignisse wie zum Beispiel die
Weiterentwicklung des Internets von akademischen Netzwerken zu e-commerce und e-business
und die Entstehung des ”World Wide Web” als ein Medium für die Geschäftswelt. Alle dieser
Vorgänge haben ein gemeinsames Element, nämlich die relationale Datenbanktechnologie
zusammen mit DBMS-Produkte, die auf der Sprache SQL basiert sind.
Im Gegensatz zu der Zeit, als die IT-Organisationen der relationalen Datenbanktechnologie als
Grundlage für ihre Informationssysteme äußerst skeptisch gegenüber standen, setzt man mittlerweile voraus, daß fast alle neuen datenintensiven Programme auf eine relationale Datenbank
gesetzt werden, deren Inhalt dann über SQL erreichbar ist. Daher mußte auch SQL an die neuen Anforderungen solcher Programme angepaßt und demensprechend erweitert werden [Mel03a].
Die letzte Version des SQL-Standard - SQL:1999 - bringt einige wesentliche neue Eigenschaften
mit sich. Darunter ist die Bereicherung der Sprache durch benutzerdefinierten Datentypen(engl.
user-defined types) am effizientesten. Sie wird auch als objektorientierte Erweiterung von SQL
bezeichnet und wurde bereits in der Praxis von einigen kommerziellen Systemen eingesetzt.
Dafür wird bei den meisten Systemen kein neues objektorientiertes System entwickelt, sondern
die objektorientierungskonzepte werden um den relationalen Kern solcher Systeme aufgebaut,
die dann zumeist als objekt-relational bezeichnet werden.
Das SQL Objektmodell, für das es im Gegensatz zu den objektorientierten Sprachen kein universelles Objektmodell gibt, enthält zwei unterscheidbare Komponenten: die struktuierten benutzerdefinierten Datentypen (engl. structured user-defined types oder structured UDTs), und die
Typtabellen (engl. typed tables). Die struktuierten benutzerdefinierten Datentypen sind eine der
drei Formen von UDTs in SQL, die Möglichkeiten zum Definieren neuer, möglicherweise komplizierterer Datentypen als SQL built-in Datentypen wie INTEGER, DATE oder BLOB bieten.
Eine Typtabelle ist eine Tabelle, deren Zeilen die Instanzen eines bestimmten struktuierten UDT
sind, mit dem die Tabelle explizit verbunden wurde. Erst durch die Kombination von struktuierten UDTs und Typtabellen kann man ein richtiges Objektmodell in SQL repräsentieren. Ein
SQL UDT beinhaltet nicht nur die Daten, sondern auch die Möglichkeit, mit ihnen in Form von
KAPITEL 3. DATENBANK-GRUNDLAGEN
27
SQL-aufrufbaren Routinen zu operieren, worauf im folgenden Abschnitt eingegangen wird.
SQL-invoked Routines
Eine SQL-aufrufbare Routine (engl. SQL-invoked Routine) wird im SQL:1999 Standard als
ein Ausdruck definiert, der über SQL-Codes aufrufbar ist. Die SQL-aufrufbaren Routinen
können sowohl in SQL als auch in anderen Programmiersprachen geschrieben werden, die
dann entweder als SQL routines oder als external routines bezeichnet werden. Als möglichen
externen Programmiersprachen sind in SQL neun Sprachen vorgesehen. Es gibt jedoch kein
Datenbanksystem, das alle diese Sprachen einsetzt oder andere Sprachen außer den neun
vorgesehenen benutzt [Mel03a].
Die SQL-aufrufbaren Routinen werden in drei Klassen - Prozedur (engl. procedure), Funktion
(engl. function) und Methode (engl. method) - unterteilt. Trotzdem wird diese Unterscheidung
nicht in allen Systemen so klar eingesetzt. Eine Prozedur ist ein Unterprogramm, das in einem
SQL-Code über eine call -Anweisung (engl. call statement) aufgerufen wird. Prozeduren sind
Routinen ohne Rückgabewerte außer über explizite Parameter oder result sets. Daher können
sie Parameter für Eingabe, Ausgabe oder beides besitzen (IN, OUT und INOUT Parameter).
Funktionen unterscheiden sich von Prozeduren in drei Punkten: sie benötigen keine spezielle
Anweisung zum Aufruf innerhalb des SQL-Codes, jede Funktion hat einen Rückgabewert und
sie besitzen nur IN Parameter.
In SQL:1999 wird die Methode als eine spezielle Funktion definiert, die einem bestimmten bentzerdefinierten Datentyp (UDT) angehört. Man unterscheidet zwischen drei Typen von Methoden: Instanzmethoden (engl. Instance methods) sind Methoden, die an bestimmten Instanzen
eines UDT operieren, Konstruktormethoden (engl. constructor methods), die jeder neu erzeugten Instanz ihre Initialwerte zuweisen und statische Methoden (engl. static methods), die nicht
einer konkreten Instanz des UDT angehören, sondern dem UDT selbst. Solche Methoden kann
man mit class methods in manchen objekt-orientierten Programmiersprachen vergleichen.
3.3
Das Oracle DBMS
Nachdem Codd sein relationales Konzept vorgestellt hat, entwickelte IBM den System RPrototyp zur Untersuchung dieses Konzeptes. Danach brachte Oracle - ebenfalls in den siebziger
Jahren - als erste Firma ein kommerzielles relationales DBMS auf den Markt, das auf dem IBM
System R Modell basierte. In diesem Produkt setzte Oracle die Sprache SQL zum ersten Mal
ein. Mit der Version 8 hat Oracle das traditionelle relationale System um objekt-orientierte
Konzepte erweitert, die in der aktuellen Version 9i diese Konzepte noch weiter entwickelt
worden sind.
Oracle 9i unterstützt, außer bei einigen Ausnahmen wie etwa distinct data types, alle Kernfähigkeiten von SQL:1999 [SD02, Kyt01]. Außerdem bietet Oracle einige Oracle-spezifische Konstrukte wie zum Beispiel connect by zum Traversieren von Baumstukturen in einen einzigen
SQL-Befehl oder die Upsert-Operation als eine Kombination des update- und insert-Befehls
[OrS01a].
KAPITEL 3. DATENBANK-GRUNDLAGEN
28
PL/SQL
Wie bereits im vorherigen Abschnitt erläutert, kann man die SQL-aufrufbaren Routinen auch
in anderen Programmiersprachen als in SQL schreiben. Dazu bietet Oracle unter anderem mit
procedural language/SQL (PL/SQL) eine eigene prozedurale Sprache. Sie ist die prozedurale
Erweiterung von SQL in Oracle, die an die Programmiersprache Ada angelehnt ist [OrP02].
Der größte Vorteil von PL/SQL liegt daran, daß sie, anders als die meisten anderen prozeduralen
Sprachen, keine spezielle Schnittstelle zur Kommunikation mit der Datenbank braucht, sondern
direkt in das System in Form von Prozeduren, Funktionen, Paketen oder Trigger integriert und
ausgeführt wird.
Als Datentyp bietet PL/SQL eine Reihe vordefinierter Datentypen. Sie werden strukturell in
vier Gruppen eingestuft: Scaler Types wie INTEGER oder CHAR, die keine internen Komponenten
haben, Composite Types wie RECORD oder TABLE, die manipulierbare interne Komponente
besitzen, Reference Types wie REF CURSOR, die ähnlich wie Zeiger in C oder Pascal auf einem
bestimmten Speicherbereich zeigen und LOB Types zur Speicherung von bis zu vier Gigabyte
großen Daten.
Syntaktisch basieren die PL/SQL Programme auf Blocks. Das sind die kleinsten Einheiten in
den PL/SQL-Codes mit dem folgenden Syntaxformat
[DECLARE <declaration>]
BEGIN <statement>
[EXCEPTION <handlers>]
END;
Hier werden im optionalen DECLARE-Teil Konstanten und Variablen definiert. Im BEGIN-Teil
stehen Anweisungen. Dort können unter anderem Kontrollstrukturen wie IF...THEN...ELSE
-Anweisungen sowie FOR - und WHILE-Schleifen eingesetzt werden. Ausnahmefälle werden im
optionalen EXCEPTION-Teil behandelt. Schließlich wird ein Block mit END geschlossen. Die Blöcke
sind autonom ausführbare Programmeinheiten. Man kann sie auch in Form von Prozeduren und
Funktionen benennen und sogar parametrisieren und dann für spätere Anwendungen im System
registrieren.
SQL∗ Plus
SQL∗ Plus ist ein Tool zur Kommunikation mit dem Oracle DBMS. Damit kann der Benutzer
(client) sich mit einem Oracle Server verbinden und seine SQL und PL/SQL Skripte ausführen
lassen und darauf die Ergebnisse zurückbekommen [OrS01b]. Dabei kann der Server sich entweder auf derselben Maschine oder auf einer anderen Maschine innerhalb des Netzwerkes befinden.
SQL∗ Plus ist ein freies Tool und wird mit jedem Oracle DBMS geliefert. Es bietet dem Anwender
zudem eine Reihe weiterer Möglichkeiten, wie sie im Detail z.B. in ([SD02]) nachgelesen werden
können.
3.3.1
Objekt-Relationale Konzepte in Oracle
Oracle brachte mit der Version 8 einige Objekt-Orientierte-Konzepte (OO-Konzepte), mit
denen man zusätzlich zu den vordefinierten Datentypen auch die UDTs definieren und neben
KAPITEL 3. DATENBANK-GRUNDLAGEN
29
den relationalen Kerneingenschaften des Systems benutzen kann. Diese erste Version der Oracle
Objektfunktionalität war nicht ganz das, was die Programmierer erwartet hatten [SD02]. Es
fehlten dabei vor allem Schlüsseleigenschaften wie Vererbung und Polymorphismus. Mit der
Version 9i machte Oracle große Fortschritte in seinem Objekt-relationalen Modell, worin dann
auch die einfache Vererbung und der Polymorphismus implementiert wurden.
Wie im SQL:1999 Standard vorgesehen, kann man innerhalb jeder UDT Routinen definieren,
die auf die Daten operieren. Diese Routinen können entweder in SQL oder in einigen anderen
Sprachen geschrieben werden. Bis zur Version 8.0 waren SQL und PL/SQL die einzigen
Programmiersprachen im Oracle DBMS. In Oracle 8.0 hat PL/SQL es ermöglicht, die externen
C-Funktionen innerhalb ihrer Codes zur Verfügung zu stellen, die dann auch von den SQL-Codes
erreichbar sind.
Mit Version 8.1 bietet Oracle eine spezielle Schnittstelle, die call specification, [OrA02, OrC02]
über die in anderen Programiersprachen geschriebene externe Funktionen -external procedures
oder auch manchmal external routines genannt- aufgerufen werden können. Der Zweck dieser
Schnittstelle ist die interne Kommunikation zwischen SQL, PL/SQL, C und Java. Sie ist daher
von allen Sprachen erreichbar, die diese vier Basissprachen aufrufen können.
Eine external procedure ist eine Prozedur, die in Form einer dynamic link library (.dll) - oder
im Fall von Java-Methoden einer libunit - als eine Betriebsystemdatei gespeichert ist. Diese
können dann später für spezielle Zwecke vom PL/SQL-Code dynamisch zur Laufzeit aufgerufen
werden.
Zur Benutzung einer external procedure, müssen nacheinander drei Schritte gemacht werden. Zuerst muß man in der LOAD-Phase muss man das Programm für den PL/SQL-Codes verfügbar
machen, indem man es als Betriebsystemdatei ablegt und die nötigen Anpassungen in den Konfigurationsdateien von Oracle für den Zugriff auf das Programm vornimmt. Danach wird in der
zweiten, der PUBLISH -Phase die external procedure über eine call specifiation spezifiziert. Hier
wird festgehalten, sowohl in welcher Sprache das Programm geschrieben und in welcher Betriebsystemdatei das Programm abgelegt ist, als auch wie die external procedure innerhalb des
Programms heißt und welche Parameter sie besitzt. Dann wird in der dritten und letzten Phase,
CALL-Phase genannt - die external procedure über einen call statement aufgerufen. Die call
specifications und call statements dürfen nur in bestimmten Positionen innerhalb des PL/SQLCodes eingesetzt werden. So dürfen die call specifications nur in PL/SQL-Paketdefinitionen bzw
-Bodies, Objekt-Typ-Deklarationen und Object-Typ-Bodies benutzt werden. Auch die call statements dürfen nur in anonymen PL/SQL-Blöcke, Unterprogrammen, Methoden der Objekttypen,
Trigger und SQL-Anweisungen vorkommen.
3.3.2
Oracle Data-Cartridges
Zur Modellierung von komplexen Objekten der realen Welt in einer Datenbank reichen zumeist
die Basisdatentypen allein nicht aus. Daher muss man sie mit zusätzlichen Datentypen, wie
zum Beispiel benutzer-definierten Objekttypen oder LOBs, ergänzen. Diese kann man dann
zusammen mit weiteren Konzepten wie die Möglichkeit zur Anwendung externer Routinen
(engl. external Routines), erweiterbare Indexierungen (extensible Indexing) oder Erstellung von
Kostenfunktionen in einem Softwarepaket namens Data Cartridges definieren [OrC02]. Diese
KAPITEL 3. DATENBANK-GRUNDLAGEN
30
können dann zur Erweiterung der Leistungsfähigkeit des Oracle-Servers in diesen eingesteckt
werden.
Diese Erweiterung ist deshalb machbar, weil der Oracle-Server über eine Erweiterungsschnittstelle (engl. extensibility interface) verfügt, die wiederum Funktionen enthält, die der
Cartridge-Entwickler für seine Anwendungen implementieren kann. Möchte zum Beispiel einen
eigenen Indextyp anlegen, muss man dafür einen Objekttyp definieren, in der die Funktionen
der extensible indexing interface als statische Methoden des Objekttyps realisiert sind.
Jede Data Cartridge besteht grundsätzlich aus einem oder mehreren Objekttypen, die man
auch in Paketen (engl. packages) zusammenpacken kann. Diese können in den komplexeren Data
Cartridges mit weiteren Diensten der extensibility interface - wie benutzerdefinierten-Indextypen
oder Optiemierungsfunktionen - ergänzt werden.
Kapitel 4
Modellierung kombinatorischer
Bibliotheken
Bei der Modellierung kombinatorischer Bibliotheken geht es zunächst darum, die Konzepte
der kombinatorischen Bibliotheken als Entity-Relationship-Modell auf einer abstrakten Ebene
in Form von Entity- und Relationshiptypen mit ihren Attributen zu modellieren und danach
diese Strukturierungskonzepte im relationalen Datenmodell in Relationen abzubilden. Letzlich
werden die Relationen über die relationale Anfragesprache SQL in das relationale DBMS Oracle
umgesetzt. Wie bereits in Kapitel 3 beschrieben, beginnt eine Modellierung mit der Anforderungsanalyse. Dabei werden die Informationen über Objekttypen, Beziehungen zwischen ihnen
und deren jeweiligen Attributen dokumentiert, die aus den Gesprächen mit den zukünftigen
Anwendern gewonnen werden konnten.
Bereits in den vorherigen Kapiteln wurde deutlich, daß in der Welt der kombinatorischen Bibliotheken die R-Gruppen, die darin enthaltenen Molekülfragmente und die Atome, aus denen
die Moleküle bestehen, wesentliche Objekte dieser Welt sind. Dagegen sind die Atombindungen
in ihrer Existenz abhängig von Molekülen und können daher nicht als Objekte dieser Welt
betrachtet werden.
In diesem Kapitel werden - analog der Reihenfolge in den Abschnitten (3.1) und (3.2) - zuerst die
Grundprinzipien der Welt der kombinatorischen Bibliothek in das Entity-Relationship Modell
transformiert. Die aus der ersten Phase resultierenden Entity- und Relationshiptypen werden
dann in der zweiten Phase zusammen mit ihren Attributen in den Relationen bzw. Tabellen
abgebildet.
4.1
Konzeptueller Entwurf
Ein Bibliotheksmolekül (d.h. ein Molekül, das auf dem Prinzip von kombinatorischen Bibliotheken aufgebaut ist) kann man aus zwei Sichtenweisen betrachten. Aus der ersten Sicht ist
es ein Molekül, das aus der Kombination von mehreren weiteren kleineren Molekülen unter
Beachtung bestimmter Vorschriften aufgebaut ist. Aus der zweiten Sicht ist es ein chemisches
Molekül, das wie alle anderen Moleküle aus einer Menge von Atomen besteht, die durch
Atombindungen aneinander gebunden sind. Genauso kann man auch das Entity-Relationship
Modell für kombinatorische Bibliotheken in zwei Teilschemata entwerfen, die man dann im
31
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
32
Abbildung 4.1: Die Entitytypen Atomtype und Atom stehen über den Relationshiptyp
Atom has Atomtype in einer 1 : N Beziehung.
globalen Schema zusammenfügt.
Der erste Teil des Modells repräsentiert die Modellierung des Aufbauprinzipes eines chemischen
Moleküls im Allgemeinen, wobei unter anderem die Modellierung der Atome und Atombindungen zusammen mit ihren Eigenschaften innerhalb der Moleküle thematisiert wird. Danach wird
im zweiten Teil des Modells die Modellierung der kombinatorischen Logik von kombinatorischen
Bibliotheken repräsentiert. Dabei geht es im wesentlichen darum, die Baumstruktur der kombinatorischen Bibliotheken zu abstrahieren, in der die Verknüpfung der Molekülfragmente aus
den R-Gruppen festgelegt ist.
4.1.1
Modellierung eines chemischen Moleküls
Wie bereits in (2.1) beschrieben, besteht jedes chemische Molekül aus wohldefinierten, voneinander unterscheidbaren Bausteinen. Diese sind die Atome, die über Atombindungen aneinander
gebunden werden. Es liegt daher nahe, die Atome über einen eigenen Entitytyp Atom zu
modellieren.
Jedes Atom besitzt eine Reihe von Eigenschaften, die es von anderen Atomen unterscheidbar
machen. Die vielleicht wichtigste Eigenschaft jedes Atoms ist sein Typ, der wiederum über
die spezifische Zusammensetzung einer Reihe von weiteren Merkmalen charakterisiert wird.
Eine mögliche Modellierungsform für Atomtypen im ER-Modell bietet das Konzept der
zusammengesetzten Attribute. Dabei wird das Attribut als Zusammensetzung mehrerer Felder
definiert. Der Nachteil dieser Modellierungsart ist, daß unter Umständen die Daten mehrfach
gespeichert werden können. Dies geschieht dann, wenn das gleiche zusammengesetzte Attribut
als Attribut für mehrere Entities des jeweiligen Entitytyps benutzt wird. In solchen Fällen
lassen sich die zusammengesetzten Attribute auch als separate Entitytypen modellieren, die
dann mit dem jeweiligen ursprünglichen Entitytyp in Beziehung stehen. Aus demselben Grund
wird der Typ des Atoms im ER-Modell als ein separater Entitytyp Atomtype modelliert,
denn es ist durchaus möglich, daß mehrere Atome denselben Atomtyp besitzen. Der Entitytyp
Atomtype steht dann über den Relationshiptyp Atom has Atomtype mit dem Entitytyp Atom
in einer 1 : N Beziehung (Abbildung 4.1).
Die Moleküle selbst werden über den Entitytyp Fragment modelliert, denn sie sind - wie Atome ebenfalls wohldefinierte Objekte der kombinatorischen Bibliotheken. Die Informationen darüber,
welche Fragmente aus welchen Atomen bestehen, ist im Relationshiptyp Atom in fragment
zwischen den Entitytypen Atom und Fragment festgehalten. Dieser Relationshiptyp stellt eine
allgemeine binäre M : N Beziehung dar (Abbildung 4.2).
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
33
Abbildung 4.2: Die Entitytypen Atom und Fragment stehen über den Relationshiptyp
Atom in Fragment in einer M : N Beziehung.
Aufgrund der Tatsache, daß die Existenz der Atombindungen innerhalb der Fragmente
abhängig von der Existenz der Fragmente ist (es gibt also keine Atombindung innerhalb eines
Fragmentes, ohne die Existenz des Fragmentes), kann man sie prinzipiell nicht als autonome
Objekte und daher auch nicht als Entitytypen darstellen. Stattdessen können sie entweder als
schwacher Entitytyp oder als Beziehungstyp modelliert werden. Die Entscheidung für einen
der beiden Typen hängt von deren Anwendung innerhalb des Modells ab. Wenn man - ähnlich
wie bei den Atomeigenschaften - die Eigenschaften von Atombindungen als einen separaten
Entitytyp modellieren wollte, müßte man diese als schwachen Entitytyp definieren, weil es im
ER-Modell keine Beziehung mit der Beteiligung von Relationshiptypen geben darf. Da hier
die Atombindungen nur atomare Attribute besitzen und nicht mit weiteren Entitytypen in
Beziehung stehen sollen, werden sie als ein Relationshiptyp Atombond in fragment zwischen
den Entitytypen Atom und Fragment modelliert. Diese Beziehung ist eine allgemeine ternäre
M : N : L Beziehung, in der jedes Atom entweder die Rolle des ersten Atoms (Atom A) oder
des zweiten Atoms (Atom B ) in der Atombindung übernimmt (Abbildung 4.3).
Abbildung 4.3: Atombindungen werden als Relationshiptyp Atombond in fragment zwischen den
Entitytypen Atom und Fragment in der allgemeinen ternären M : N : L Beziehung modelliert.
Jedes Atom übernimmt entweder die Rolle des ersten (Atom A) oder zweiten Atoms (Atom B ).
4.1.2
Modellierung der kombinatorischen Natur der Bibliotheken
Vor der Erklärung dieses Teilschemas soll noch einmal daran erinnert werden, daß eine
kombinatorische Bibliothek eine Sammlung von mehreren R-Gruppen ist. Mit anderen Worten
ist sie eine Menge der Menge von Fragmenten, die in R-Gruppen zusammengesetzt sind.
Kombinatorische Bibliotheke werden über den Entitytyp Combinatorial Library repräsentiert.
Die R-Gruppen der Bibliotheken werden ebenso über einen eigenen Entitytyp Fragment List
modelliert, da sie innerhalb jeder Bibliothek autonome Einheiten sind, die auch nach der
Auflösung der Bibliothek weiterhin existieren. Wäre dieses nicht so, wären also die R-Gruppen
mit der Auflösung der jeweiligen Bibliothek verschwunden, müßten sie zum Beispiel als schwacher Entitytyp definiert werden, der dann in seiner Existenz abhängig vom übergeordneten
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
34
Entitytyp Combinatorial Library wäre.
Der Relationshiptyp Fragment List in CombilLib bietet dem Anwender die Möglichkeit herauszufinden, aus welchen R-Gruppen die jeweilige Bibliothek besteht.
Da jede Bibliothek aus beliebig vielen R-Gruppen bestehen kann und auch jede R-Gruppe in
verschiedenen Bibliotheken benutzt werden darf, ist diese Beziehung eine allgemeine M : N
Beziehung (Abbildung 4.4).
Abbildung 4.4: Der Relationshiptyp Fragment List in CombilLib ist eine allgemeine M : N
Beziehung. Er bietet dem Anwender die Möglichkeit herauszufinden, aus welchen R-Gruppen
die Bibliothek besteht.
Wie bereits in (2.6.2) erwähnt, ist ein Bibliotheksmolekül eine Kombination von bis zu zehn
R-Gruppen. Davon ist eine R-Gruppe (R-Gruppe 0) Core und bis zu neun weitere sind
Rest-Gruppen, wobei zum Zusammensetzen eines solchen Moleküls aus dem Core genau ein und
aus weiteren R-Gruppen maximal ein Fragment ausgewählt werden darf. Die so ausgewählten
Fragmente werden dann über Atombindungen aneinander gebunden.
Mit derselben Begründung wie bei den Atombindungen innerhalb der Fragmente in (4.1.1)
werden auch die Atombindungen zwischen den Fragmenten der Bibliotheksmoleküle über den
Relationshiptyp Atombond between Fragments modelliert. Dabei wird ein Atom (Atom A)
aus dem Vorgänger-Fragment (predecessor ) mit einem Atom (Atom B ) aus dem NachfolgerFragment (successor ) verbunden. Solche Verbindungsatome können prinzipiell auch in anderen
Fragmenten als Verbindungsatom benutzt werden. Ebenso können die Bindungsstellen eines
Fragmentes variieren, daher ist der Relationshiptyp Atombond between Fragments eine allgemeine quartäre M : N : K : L Beziehung (Abbildung 4.5).
Wie man hier sieht, besteht jedes Bibliotheksmolekül nicht aus den eigentlichen R-Gruppen,
sondern aus den Alternativfragmenten der R-Gruppen. Eines dieser Fragmente - das Fragment
aus der R-Gruppe 0 - bildet das Core-Fragment und die weiteren - aus den übrigen R-Gruppen
- bilden die Rest-Fragmente des jeweiligen Moleküls. Die Bibliotheksmoleküle werden über den
Entitytypen CLib Molecule modelliert.
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
35
Abbildung 4.5: Atombindungen zwischen Fragmenten der Bibliotheksmoleküle werden über den
Relationshiptyp Atombond between Fragments - eine allgemeine quartäre M : N : K : L Beziehung - modelliert. Ein (Atom A) des Vorgänger-Fragments (predecessor ) wird mit einem
(Atom B ) des Nachfolger-Fragments (successor ) verbunden.
Die Core- und Restfragmente der Bibliotheksmoleküle werden über zwei ternäre Relationshiptypen - Is Core Of und Is Rest Of - zwischen den Entitytypen CLib Molecule, Fragment und
Fragment List modelliert (Abbildung 4.6). Der Grund für die Modellierung dieser Konzepte als
Relationships liegt darin, daß die Core und Restfragmente eines Bibliotheksmoleküls solange
existieren, wie das Molekül selbst noch vorhanden ist. Löst man ein Bibliotheksmolekül auf,
existieren zwar die Fragmente als einzelne Objekte (daher die Modellierung der Fragmente
als Entitytypen), nicht aber als Core- oder Restfragmente eines bestimmten Bibliotheksmoleküls.
Abbildung 4.6: Die Core- und Restfragmente werden über zwei ternäre Relationshiptypen Is Core Of und Is Rest Of - zwischen den Entitytypen CLib Molecule, Fragment und Fragment
List modelliert.
Die Einschränkungen der Anzahl der in den Beziehungen Is Core Of und Is Rest Of beteiligten
Entitäten werden jeweils über M : 1 : 1 und M : 1 : N Funktionalitäten ausgedrückt. Damit
kann man diese Beziehungen als eine partiellen Funktion auffassen, die sich wie folgt beschreiben
läßt:
Is Core Of : CLib Molecule × Fragment List → Fragment
Is Core Of : CLib Molecule × Fragment
→ Fragment List
Is Rest Of : CLib Molecule × Fragment List → Fragment
Wie weiter oben erwähnt, werden die Fragmente eines Bibliotheksmoleküls über Atombindungen
paarweise miteinander veknüpft. Da an dieser Stelle noch keine Informationen über die Modellierung von Atomen vorliegen, wird die Art und Weise der Modellierung von Atombindungen
zwischen den Fragmenten erst im nächsten Abschnitt erläutert.
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
36
Für jeden der bis jetzt vorgestellten Entitytypen wird lediglich ein einziges Attribut vorgesehen,
dessen Wert das zugeordnete Entity eindeutig innerhalb aller Entities seines Typs identifizierbar
macht, daher kann das auch als Schlüsselattribut angesehen werden. Für die Relationshiptypen
wurde hingegen keine zusätzlichen Attributen vorgesehen.
Wie bereits in (2.1) erwähnt, ist ein Fragment ein spezielles, offenes Molekül. Auch ein
Bibliotheksmolekül kann man als ein besonderes Molekül ansehen, das durch die Kombination
von Fragmenten zustande kommt. Um das Schema besser zu struktuieren, kann man diesen speziellen Entitytypen über Generalisierung einen Obertyp Molecule zuweisen. Damit sind sowohl
Fragment als auch CLib Molecule vom Typ Molecule, die zusätzlich zu den Molecule-Attributen
auch ihre eigenen Attribute besitzen können (Abbildung 4.7).
Abbildung 4.7: Generalisierung des speziellen Entitytyps über einen Obertyp Molecule. Damit
sind sowohl Fragment als auch CLib Molecule vom Typ Molecule und können zu den MoleculeAttributen auch ihre eigenen Attribute besitzen.
Zusätzlich zu den bislang vorgestellten Entity- und Relationshiptypen kann man im ER-Schema
noch zusätzlich erweiterte Relationshiptypen (engl. extended relationships) definieren. Damit
kann man die Entity- und Relationshiptypen mit anderen schon modellierten erweiterten Relationshiptypen transitiv auf verschiedenste Art und Weise verbinden und dadurch weitere neue
Relationshiptypen gewinnen.
Die bisher beschriebenen Komponenten werden nun kompakt in einem globalen Schema
abgebildet (Abbildung 4.8).
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
4.2
37
Logischer Entwurf
Bereits im Abschnitt (3.1.2) wurden ausführlich die Prinzipien zur Umsetzung des Ergebnisses
der ER-Modellierung in das relationale Datenmodell diskutiert. Es wurde deutlich, daß die zwei
wesentlichen Konzepte des ER-Modells - die Entity- und Relationshiptypen - im relationalen
Datenmodell in Relationen abgebildet werden. Hier wird die Transformation des Ergebnisses
der ER-Modellierung gemäß der dort beschriebenen Regeln vorgestellt.
4.2.1
Darstellung von Entitytypen als Relationen
Wie in (3.1.2) beschrieben, wird jeder Entitytyp in eine Relation abgebildet. Diese werden hier
vorgestellt:
Combinatorial Library
Fragment List
CLib Molecule
Fragment
Atom
Atomtype
:
:
:
:
:
:
{[Name]}
{[Name]}
{[Name]}
{[Name]}
{[nof H, f charge, chirality, donor acceptor, p charge]}
{[element, nof bonds, hybridization, free valence,
coordination nr, vdW radius]}
Hier wird in den eckigen Klammern angegeben, welche Attribute für die einzelnen Tupeln
vorhanden sind. Die geschweiften Klammern drücken aus, daß es sich bei einer Instanz einer
Relation um eine Menge von Tupeln handelt. Eine Instanz einer Relation ist dann als Menge
von Tupeln {[...]} aufzufassen. Im Übrigen wird der Primärschlüssel der Relation durch
Unterstreichung gekennzeichnet.
An dieser Stelle wurde die Modellierung der Generalisierung von Fragment und CLib Molecule zu
Molecule nicht vorgestellt, weil das relationale Modell über keine Vererbungskonstrukte verfügt.
Dazu könnte man zwar die verfügbaren Strukturen zur Imitation des Generalisierungskonzeptes
nutzen, jedoch wird dabei nicht die volle Information verfügbar sein. (Für weitere Informationen,
siehe [uA01]). Später wird diese Modellierung mit Hilfe des Sichtenkonzeptes in SQL erklärt.
4.2.2
Darstellung von Relationshiptypen als Relationen
Zur Umsetzung der Relationshiptypen in das relationale Schema wird jeder Typ im InitialEntwurf ähnlich wie die Entitytypen in eine Relation abgebildet. Einige dieser Relationen können
dann bei der Schemaverfeinerung in andere Relationen eingebettet und damit eliminiert werden.
Somit ergeben sich bei dem Initial-Entwurf folgende Relationen:
Atombond between Fragments : {[nof H a, f charge a, chirality a, donor acceptor a,
nof H b, f charge b, chirality b, donor acceptor b,
predec fragment name, succec fragment name, type,
rotatibility]}
Is Core of
: {[clib molecule name, fragment name, fragment list name]}
Is Rest of
: {[clib molecule name, fragment name, fragment list name]}
Fragment in Fragment List
: {fragment name, fragment list name]}
Fragment List in CombiLib
: {[fragment list name, combilib name]}
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
Atombond in Fragment
Atom in Fragment
Atom has Type
38
: {[nof H a, f charge a, chirality a, donor acceptor a,
nof H b, f charge b, chirality b, donor acceptor b,
fragment name, type, rotatibility]}
: {[nof H, f charge, chirality, donor acceptor,
fragment name]}
: {[nof H, f charge, chirality, donor acceptor,
element, nof bonds, hybridization]}
Auch in diesem Relationenschema sind die Schlüssel durch Unterstreichung gekenzeichnet. Da
hier jede Relation nur eine einzige Attributmenge als Schlüssel besitzt, ist diese gleichzeitig
auch der Primärschlüssel der Relation.
Zuerst werden die Umsetzung der allgemeinen Beziehungen Fragment in Fragment List,
Fragment List in CombiLib,
Atom in Fragment,
Atombond in Fragment
und
Atombond between Fragments betrachtet. Generell bildet in allen Relationen die Menge aller Fremdschlüsselattribute den Schlüssel der jeweiligen Relation. Die Beziehungen Atombond in Fragment
und Atombond between Fragments sind rekursive M : N : L und M : N : K : L Beziehungen. Bei
der relationalen Modellierung von Atombond in Fragment wurden die Rollen des ER-Schemas,
nämlich die Atom A und Atom B als Attributnamen gewählt. Da es sich hier um eine allgemeine
Beziehung handelt, werden im Schlüssel der Relation Atombond in Fragment beide Attribute
{Atom A, Atom B } vertreten sein. Genauso ist es auch bei der relationalen Umsetzung von
Atombond between Fragments, in der die Menge {Atom A,Atom B, predecessor,successor } eine
Teilmenge der Schlüsselmenge der Relation bildet.
Anders als die relationale Umsetzung obiger Beziehungen verläuft die Umsetzung der Relation Atom has Type. Da ein Atom nur einen Atomtyp besitzt, hat die zugehörige Relation
Atom has Type den Schlüssel {nof H, f charge, chirality, donor acceptor}. Dies kann sich auch
aus der funktionalen Sichtweise ergeben, bei der man die obige Beziehung als eine partielle
Funktion der folgenden Form auffassen kann:
Atom has Type : Atom → Atomtype
Diese Ähnlichkeit in der Argumentation kann man auch bei der relationalen Umsetzung der
Relationen Is Core of und Is Rest of benutzen, deren funktionale Formen im letzten Abschnitt beschrieben wurden. Somit besitzen die entsprechenden Relationen jeweils die Schlüssel
{clib molecule name} und {clib molecule name, fragment list name}.
Schemaverfeinerung
Im Abschnitt (3.1.3) wurde ersichtlich, daß die Relationen der 1 : 1, 1 : N und N : 1 Beziehungen aus dem Initialentwurf eines relationalen Schemas in andere Relationen des Schemas
eingeführt werden können. Dabei werden einige der Relationen aus dem Initial-Entwurf gelöscht.
Das geschieht hier bei der Relation Atom has Type. Im Initialentwurf gab es die drei Relationen:
Atom has Type : {[nof H, f charge, chirality, donor acceptor,
element, nof bonds, hybridization]}
Atomtype
: {[element, nof bonds, hybridization,
free valence, coordination nr, vdW radius]}
Atom
: {[nof H, f charge, chirality,
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
39
donor acceptor, p charge]}
Nach den in (3.1.3) beschriebenen Regeln kann man die Relationen Atom und Atom has Type
zusammenfassen, so daß von diesen drei Relationen nur zwei Relevante übrig bleiben:
Atomtype : {[element, nof bonds, hybridization,
free valence, coordination nr, vdW radius]}
Atom
: {[nof H, f charge, chirality,
donor acceptor, p charge, element, nof bonds, hybridization]}
Hier stellt die Menge {element, nof bonds, hybridization} einen Fremdschlüssel auf die Relation Atomtype dar. Da jedes Atom nur einen Typ besitzen kann, gibt es für jedes Tupel aus
Atom nur ein einziges Tupel aus Atomtype, das über die Attributmenge {element, nof bonds,
hybridization} referenziert wird.
4.3
SQL-Implementierung
Nachdem das relationale Schema fertig entworfen ist, könne jetzt die Tabellen (Relationen) definiert werden. Nach der Definition eines Datenbankschemas mittels des CREATE SCHEMA-Befehls
können die Tabellen über den CREATE TABLE-Befehl erzeugt werden. Exemplarisch wird die Erzeugung der Tabelle Atom hier dargestellt:
1: CREATE TABLE Atom(
2:
nof_H
NUMBER(2),
3:
f_charge
NUMBER(3,2),
4:
chirality
NUMBER(2),
5:
donor_acceptor NUMBER(2),
6:
p_charge
NUMBER(4,3),
7:
element
VARCHAR2(2),
8:
nof_bonds
NUMBER(2),
9:
hybridization NUMBER(2),
10: PRIMARY KEY
(nof_H,f_charge,chirality,donor_acceptor),
11: FOREIGN KEY
(element,nof_bonds,hybridization)
12: REFERENCES
Atomtype (element,nof_bonds,hybridization)
13: );
Das Erzeugen einer neuen Tabelle beginnt mit der ersten Zeile, in der nach dem Befehl CREATE
TABLE der Name Atom für die Tabelle festgelegt wird. Dann folgt zwischen den Zeilen 2 bis 9
die Liste der Atribute und ihrer Typen, die jeweils durch Komma getrennt werden. Nach der
Typangabe könnte hier noch zusätzlich die NOT NULL Integritätsbedingung folgen. In Zeile 10
wird die Integritätsbedingung PRIMARY KEY definiert, womit die Menge der Schlüsselattribute
für die Tabelle festlegt wird. Die Zeilen 11 und 12 definieren zusammen den Fremdschlüssel der
Tabelle Atom, über den mit Hilfe der Attributenmenge {element, nof bonds, hybridization}
aus der Tabelle Atom die Tabelle Atomtype referenziert wird. Schließlich wird die Definition in
der 13. Zeile beendet. Es ist zu beachten, daß die Tabelle Atom später um eine weitere Spalte
id erweitert wurde. Auf den Grund für diese Erweiterung wird im Kapitel 6 eingegangen.
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
40
Es wurde in diesem Kapitel bereits erklärt, daß das relationale Datenmodell über keine Vererbungskonstrukte verfügt. Diese kann man aber - wie bereits in (3.2.2) beschrieben - mit Hilfe
von Sichten in SQL modellieren. Dazu gibt es prinzipiell zwei Möglichkeiten: entweder existiert
der Obertyp als Tabelle bzw. Relation und die Untertypen werden als Sicht modelliert oder die
Untertypen liegen physisch vor und der Obertyp wird als Sicht definiert. Hier liegen die beide
Tabellen CLib Molecule und Fragment vor, daher wird der Obertyp Molecule über die folgende
Sichtendefinition definiert:
CREATE OR REPLACE VIEW Molecule AS
SELECT name
FROM Fragment
UNION
SELECT name
FROM CLib_Molecule;
Der Vorteil dieser Art von Modellierung ist, daß es zu keiner Duplizierung der Attributwerte
kommt. Der Nachteil liegt jedoch darin, daß der Zugriff auf die Attribute des Obertyps
Molecule - wegen der Vereinigung der Attribute von CLib Molecule und Fragment über
einen UNION-Operator - langsam ist.
Auch die erweiterten Relationshiptypen werden mit Hilfe von Sichten realisiert. Zur Definition
eines neuen erweiterten Relationshiptyps zwischen zwei Typen des Schemas kombiniert man alle
Entity- und (erweiterten) Relationshiptypen auf dem Pfad zwischen den beiden Typen in Form
einer SQL-Anfrage, die dann mit Hilfe einer Sicht dargestellt wird.
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
41
Abbildung 4.8: Globales ER-Schema für kombinatorische Bibliotheken: erweiterte Relationshiptypen sind durch gestrichelte, normale Relationshiptypen durch durchgezogene Linien dargestellt.
KAPITEL 4. MODELLIERUNG KOMBINATORISCHER BIBLIOTHEKEN
42
Abbildung 4.9: Die SQL-Implementierung des relationalen Schemas für kombinatorische Bibliotheken.
Kapitel 5
Die Programmierumgebung
Nachdem das Datenbankschema bereit ist, kann es nun mit den entsprechenden Informationen
gefüllt werden. Um dieses Ziel zu erreichen muß man zunächst die Daten der kombinatorischen
Bibliotheken, die in Form von ASCII-Dateien zur Verfügung stehen, zum Schreiben in die Datenbank vorbereiten. Eine Lösung ist, die Bibliotheksdaten direkt über einen Parser aus den
ASCII-Dateien zu lesen um sie dann in die Datenbank zu schreiben. Dies erfordert vor allem
ein Parser-Programm, das die o.g. Aufgabe erfüllen kann. Eine zweite Variante ist die Nutzung
der FlexX-spezifischen Datenstrukturen für kombinatorische Bibliotheken. Wie bereits in (2.6.2)
erwähnt, verfügt FlexX mit dem Modul FlexXC über die Möglichkeit, Dockingberechnungen an
kombinatorischen Bibliotheken durchzuführen. Dazu liest FlexX die Bibliotheksdaten aus den
ASCII-Dateien, fügt ihnen weitere physiko-chemische Eigenschaften hinzu und legt sie dann in
seinen entsprechenden Datenstrukturen ab (Abbildung 5.1). Unter diesen Daten befinden sich
auch jene, die für die Datenbanktabellen benötigt werden. In der vorliegenden Arbeit habe ich
mich vor allem deshalb für die zweite Variante entschieden, weil die Zusammensetzung von
Bibliotheksinformationen aus den ASCII-Dateien über spezifische, zum Teil komplizierte Verfahren geschieht, die schon in FlexX realisiert wurden. Daher werden in diesem Kapitel zuerst
die Datenstrukturen vorgestellt, deren Verständnis für die Implementierung eines Programms
zum Zugriff auf diese Daten nötig ist. Danach werden die Programmiersprache Python und das
in dieser Sprache eingebettete Modul pyflexx vorgestellt, die vor allem die Möglichkeit zum
Datentransport in die Datenbank bietet.
5.1
FlexX-Datenstrukturen für kombinatorische Bibliotheken
Die Architektur der Datenstrukturen in FlexX ist auf drei Ziele ausgerichtet. Erstens: man
behandelt die Bibliotheken in ihrer geschlossenen Form, d.h. sie werden statt über eine durchnummerierte Liste ihrer Moleküle über ihre R-Gruppen-Fragmente repräsentiert. Das führt
zur Zeitersparnis beim Generieren von Molekülen, indem man nur die tatsächlich benötigten
Moleküle der R-Gruppen generiert. Zweitens: die Datenstrukturen müssen zur effizienten
Konstruktion von Bibliotheksmolekülen geeignet sein. Dazu müssen sie in der Lage sein alle
physiko-chemischen Daten behandeln zu können, die zur Dockingberechnungen nötig sind.
Drittens: die Datenstrukturen müssen eine effiziente Transformation der Dockingergebnisse
eines Moleküls der Bibliothek zu einem anderen erlauben. Zum Erreichen dieser Ziele wurden
folgende Datenstrukturen für kombinatorische Bibliotheken in FlexX implementiert:
43
KAPITEL 5. DIE PROGRAMMIERUMGEBUNG
44
Abbildung 5.1: Interaktion zwischen FlexX, pyflexx und der Datenbank.
Ein Molekül wird in FlexX durch ein Netz von Listen gespeichert (Abbildung 5.2).
Jede Liste enthält Informationen über spezifische Objekte wie Atome (Datenstruktur atom),
Atombindungen (Datenstruktur bond ) oder Ringsysteme (Datenstruktur ringsystem). Jedes
Objekt wird im Laufe der Strukturinitialisierung mit physiko-chemischen Daten markiert. Das
Fragment eines Cores oder einer R-Gruppe wird intern ähnlich wie ein komplettes Molekül
behandelt mit zusätzlichen Informationen über die Verbindungsatome. Die Sequenz der
Fragmente eines Bibliotheksmoleküls wird in der Datenstruktur intlist gespeichert. Diese ist
eine einfache verkette Liste, die nur Integerwerte enthält. So verweist das 0. Element der Liste
auf das Core-Fragment und das i-te Element der Liste auf das i-te Fragment des jeweiligen
Bibliotheksmoleküls.
Die Bibliotheksdaten in FlexX werden in der Datenstruktur combilib abgelegt (Abbildung 5.3).
Diese besteht aus den Datenfeldern, die die interne Repräsentation einer kombinatorischen
Bibliothek in FlexX in geeigneter Weise ermöglichen. Hier sind unter anderem der Name der
kombinatorischen Bibliothek, die Anzahl und Namen der R-Gruppen der Bibliothek und die
Anzahl der Fragmente jeder R-Gruppe enthalten. Das Lesen der Bibliotheksdaten aus den
ASCII-Dateien erfolgt über die read -Operation in FlexXC . Diese liest die ASCII-Dateien, zerlegt
sie in einzelne Informationsteile und vervollständigt sie dann mit weiteren physiko-chemischen
Informationen. Das Zerlegen der ASCII-Dateien geschieht über das Parser-Programm, das
spezifisch für das Format der ASCII-Dateien ist. Das Einlesen von Bibliotheksdaten wird dann
über die close-Operation beendet.
Nachdem die Bibliotheksdaten vollständig in der Datenstruktur combilib gespeichert wurden,
KAPITEL 5. DIE PROGRAMMIERUMGEBUNG
45
Abbildung 5.2: Der Aufbau der Datenstruktur molecule
kann man jetzt daraus einzelne Moleküle durch das Kombinieren von Fragmenten zusammenbauen und sie dann wie einzelne Moleküle bei den Dockingberechnungen verwenden. Das so
entstandene Molekül wird dann in FlexX in der Datenstruktur clib molecule abgespeichert
(Abbildung 5.4). Die clib molecule-Datenstruktur verfügt außerdem über einige Datenfelder, die
sämtliche Informationen über das jeweilige Bibliotheksmolekül enthalten. Innerhalb der beiden
Datenstrukturen combilib und clib molecule gibt es Verweise auf die zwei Basis-Datenstrukturen
molecule und atom.
FlexXC verfügt über die extend -Operationen, die eine virtuelle Synthese von Bibliotheksmolekülen ermöglichen. Diese fügt ein R-Guppenfragment entweder zum Core oder einem partiell
synthetisierten Bibliotheksmolekül. Eine weitere Operation, die remove-Operation, macht das
Gegenteil der extend -Operation, d.h. durch sie wird die entstandene Atombindung gelöscht,
die X - und R-Atome werden wieder in den bond - und ring system-Listen eingefügt und die
Verknüpfung zwischen den Listen wieder aufgelöst. Somit wird nur die letzte hinzugefügte
R-Gruppe entfernt.
Anhand dieser Datenarchitektur kann man ein kombinatorisch aufgebautes Molekül als einen
Stapel (engl. stack ) von selektierten R-Gruppenfragmenten ansehen. Mit jeder extend -Operation
wählt man eine R-Gruppe und ein Fragment dieser R-Gruppe und legt es auf den Stapel. Mit der
remove-Operation ist man in der Lage das R-Gruppenfragment vom obersten Level des Stapels
zu entfernen. Damit kann man durch das Entfernen einiger R-Gruppenfragmente und Hinzufügen
neuer Fragmente von einem Molekül der Bibliothek zum anderen Molekül wechseln. Die R-
Abbildung 5.3: Der Aufbau der Datenstruktur combilib
KAPITEL 5. DIE PROGRAMMIERUMGEBUNG
46
Abbildung 5.4: Der Aufbau der Datenstruktur clib molecule
Gruppenfragmente, die innerhalb dieses Prozesses unverändert bleiben stellen den gemeinsamen
Teil zwischen zwei Molekülen dar. Die Plazierungsinformationen, die für diesen Teil berechnet
wurden, können für das neue Molekül ohne Modifizierung benutzt werden.
5.2
Das Python-Modul pyflexx
Um die Konstrukte einer Script-Sprach für die FlexX-Anwendungen nutzen zu können, wurde
der FlexX-Code als ein autonomes Modul in der Script-Sprache Python eingebettet. Das entsprechende Python-Modul wurde pyflexx genannt. Im folgenden wird diese Script-Sprache und
danach das Pyhton Database API kurz vorgestellt, die über die DCOracle2-Schnittstelle eine
Möglichkeit zur Kommunikation mit der DBMS Oracle bietet (ausführlicherre Informationen
über Python sind in [Mar03, MA02] zu lesen).
5.2.1
Die Programmiersprache Python
Python ist eine dynamische, objekt orientierte, plattformunabhängige Programmiersprache.
Sie läuft unter allen Hauptbetriebsystemen, wodurch es bei der Nutzung dieser Sprache keine
Einschränkung gibt. Python lässt sich in mehreren Stellen eines Softwareentwicklungsprozesses
einetzen, unter anderem in Analyse, Design, Kodierung, Testing, Fehlersuche, Dokumentation
und vieles mehr.
Python benutzt - im Vergleich mit klassischen Hochsprachen wie C/C++ oder Fortran - einen
höheren Level der Abstraktion. Daher ist sie eine zum Lernen einfache Sprache, die aber
gleichzeitig mächtig genug für anspruchsvolle Aufgaben ist.
Python ist eine objekt-orientierte Sprache. Gleichzeitig bietet sie dem Programmierer die
Möglichkeit, neben den objekt-orientierten Konzepten auch die traditionellen prozeduralen
Konzepte einzusetzen und beide miteinander zu kombinieren.
Zusätzlich zu der Sprache selbst verfügt man in Python über Standard-Bibliotheken und andere
Erweiterungsmodule, die zur effektiven Verwendung von Sprache meist genauso wichtig sind
KAPITEL 5. DIE PROGRAMMIERUMGEBUNG
47
wie die Sprache selbst.
Die Standard-Bibliotheken in Python enthalten Module, die komplett in Python geschrieben
sind. Sie enthalten unter anderem Module zur Daten- und Textverarbeitung, Interaktion
mit dem File- und Betriebsystem und Webprogrammierung. Da diese Module alle in Python
geschrieben sind, sind sie überall verwendbar, wo Python eingesetzt werden kann. Die Erweiterungsmodule der Standard-Bibliothek oder von anderen Bibliotheken ermöglichen es den
Pythonapplikationen, die Funktionalität anderer Softwarekomponenten wie etwa graphische
Benutzerschnittstellen (GUIs), Datenbanksysteme und Netzwerke nutzen zu können.
Pythonprogramme können zwischen mehreren Programmiersprachen komunizieren, so daß damit
mehrere Softwarekomponenten miteinander verbunden werden können, die möglicherweise in
verschiedenen Sprachen geschrieben sind.
5.2.2
Python Database API
Die Python Standard-Bibliothek enthält keine Schnittstelle zu einem relationalen DBMS.
Trotzdem gibt es eine Reihe von frei verfügbaren Module, die die Kommunikation zwischen
den Pythonapplikationen und einem bestimmten RDBMS ermöglichen. Diese Module basieren
meistens auf dem Python Database Application Programmers Interface 2.0 -Standard (kurz
DBAPI ) basiert. Die am meisten benutzte Oracle-Schnittstelle für Python ist die DCOracle2 Schnittstelle, die unter [Zop] frei verfügbar ist.
Das Prinzip von Python API ist relativ einfach. Nach dem Importieren eines DBAPI-verträglichen Modules ruft man die connect-Funktion des Moduls mit entsprechenden Variablen auf,
die eine Instanz der Klasse Connection zurück liefert. Diese repräsentiert eine Verbindung zu
einem DBMS und bietet die Methoden commit und rollback zur Handlung mit Transaktionen,
eine close-Methode zum Schließen der Verbindung mit dem DMBS und eine cursor -Methode,
die eine Instanz der Klasse Cursor liefert. Diese Instanz liefert dann alle Methoden, die man
für die Datenbankoperationen benutzt.
Zusätzlich zu den o.g. Diensten bieten solche Modulen noch weitere Klassen und Attribute wie
zum Beispiel die exception Klasse zum Abfangen und Behandeln von möglichen Fehlern bei der
Ausführung von den DBMS-Operationen.
Ein Beispiel
Zum besseren Verständnis der Funktionsweise einer DBAPI soll das folgende Beispiel dienen,
das eine SELECT-Anfrage modelliert:
Als erstes wird eine Verbindung mit der Datenbank hergestellt:
con = DCOracle2.connect(’user/password@schema’)
dann wird ein cursor erzeugt:
cur = con.cursor()
die DB-Anfrage wird in Form eines Strings formuliert:
sql = ’SELECT * FROM my_table t WHERE t.field = %s’ % value
KAPITEL 5. DIE PROGRAMMIERUMGEBUNG
48
hier wird vor allem die Möglichkeit gezeigt, wie man Parameterwerte in den SQL-Anfragen
einsetzen kann. Dazu gibt es mehrere Möglichkeiten die bei z.B. [Mar03] nachgelesen werden
können. Die SQL-Anfrage wird zur Ausführung an die execute-Methode weiter gegeben:
cur.execute(sql)
Auf das Ergebnis der Anfrage wird über die Methoden fetchone auf nur ein Ergebnis, mit fetchall
auf alle Ergebnisse oder über fetchmany auf einige bestimmte Ergebnisse zugegriffen:
result = cur.fetchone()
der so entstandene Parameter result ist dann eine Liste, die im Falle von fetchone ein bzw. im
Falle von fetchall oder fetchmany mehrere Ergebniswerte enthält.
5.2.3
Interne Kommunikation in FlexX über STREAM s
Jedes nichttriviale Programm verwendet viele eigene Datentypen und die Ein- und Ausgabe von
Werten dieser Typen muß auf irgendeine Art verwaltet werden. Eine Ein-/Ausgabe-Technik sollte vor allem einfach, bequem, effizient, flexibel und vollständig sein. Eine dieser Techniken ist die
Anwendung von I/O-Streams, womit man unter anderem die Daten innerhalb eines Programms
von einem Ort zum anderen transportieren kann. In FlexX ist dazu die Datenstruktur STREAM
entwickelt worden, die fast die gesamten Funktionalitäten eines I/O-Streams in den bekannten
Programmiersprachen wie beispielsweise C anbietet. Der eigentliche Vorteil von STREAM in
FlexX ist aber, daß er Plattform- und sprachunabhängig ist. Somit können die Daten innerhalb verschiedener Sprachen transportiert werden. Diese Funktionalität von FlexX kann man
vor allem dazu benutzen, um die Werte von FlexX-Datentypen an Python zu übergeben und
umgekehrt.
Kapitel 6
Implementierung
Das Datenbankschema für kombinatorische Bibliotheken wurde bereits im Kapitel 4 vorgestellt
und die FlexX-Datenstrukturen, die die Daten der kombinatorischen Bibliotheken enthalten,
im Abschnitt (5.1) diskutiert. Hier sollen Programme vorgestellt werden, die einerseits auf die
Bibliotheksdaten in FlexX zugreifen und diese andererseits in der gewünschten Form über eine
Datenbankschnittstelle in die Datenbanktabellen hineinschreiben.
Zur Verwirklichung des ersten Ziels wurde in der vorliegenden Arbeit ein Compiler-Programm
in der Sprache C geschrieben, dessen Prinzip in diesem Kapitel vorgestellt werden soll. Zum
Importieren der Daten in die Datenbank braucht man eine Datenbank-Applikation, die eine
Verbindung zwischen dem Source-Code und dem DBMS Oracle ermöglicht. Da das CompilerProgramm in C geschrieben ist, müsste man die Verbindung entweder als eingebettete SQL in C
oder über die Oracle Call Interface-API erstellen [McC96]. Eine zweite Möglichkeit ergibt sich
daraus, daß es FlexX auch als das Python-Modul pyflexx gibt. Da diese Sprache (wie beschrieben
in 5.2.2) selber über eine Datenbankschnittstelle verfügt, kann man sie zur Kommunikation
zwischen dem Compiler und der Datenbank verwenden. Zuerst wird das Füllen der statischen
Tabelle Atomtype beschrieben.
6.1
Füllen der statischen Tabelle Atomtype
Wie bereits im Abschnitt (4.2.1) beschrieben, wurde für die Atomtypen der kombinatorischen Bibliotheken eine Extra-Tabelle vorgesehen. Diese ist eine statische Tabelle, Deren Inhalt manuell
von den Chemikern vorgegeben ist. Ihr Inhalt bleibt also für alle kombinatorischen Bibliotheken
unverändert. Es ist jedoch nicht auszuschliessen, daß in einigen Ausnahmefällen innerhalb der
Bibliotheken einige Atome gefunden werden können, deren Typen nicht in dieser Tabelle vorgesehen sind. Solche Fälle werden abgefangen und in einer log-Datei protokolliert. Beim Prüfen
dieser Datei kann man also feststellen, ob es Atome gibt, deren Typen nicht in der Tabelle
Atomtype enthalten sind.
6.2
Zugriff auf die
Datenstrukturen
Bibliotheksdaten
in
den
FlexX-
Bereits im Abschnitt (5.1) wurde beschrieben, daß in FlexX eine kombinatorische Bibliothek
über die read -Operation aus den ASCII-Dateien in das System geladen und nach der Ver49
KAPITEL 6. IMPLEMENTIERUNG
50
Abbildung 6.1: Interaktion zwischen FlexX, pyflexx und der Datenbank und den in dieser Arbeit
entwickelten Komponenten (grau unterlegt).
vollständigung ihrer Fragmente mit den weiteren physiko-chemischen Eigenschaften in den
jeweiligen Datenstrukturen zur Verfügung gestellt wird. Wie bereits weiter oben erwähnt,
wurde für diese Arbeit ein Compiler-Programm zur Sammlung und Zusammenstellung der
Bibliotheksdaten geschrieben, dessen Ablauf im Folgenden vorgestellt wird.
Als erstes sieht der Compiler für jede Datenbanktabelle einen STREAM vor, in denen jeweils
später die Datensätze der entsprechenden Tabelle geschrieben werden. Der eigentliche Vorgang
beginnt mit der Vorbereitung der Daten für die Tabelle Combinatorial Library. Dazu wird für die
kombinatorische Bibliothek ein Identifikator erstellt, wofür der Bibliotheksname benutzt wird.
Der Grund für die Nutzung des Names als Identifikator ist die Analogie mit dem Primärschlüssel
name der Tabelle Combinatorial Library, in die später dieser Identifikator geschrieben wird. In
der Datenstruktur combilib ist ein name-Feld vorgesehen, das den Bibliotheksnamen enthalten
soll. Da jedoch in den ASCII-Dateien meist kein Name für die Bibliothek vorhanden ist, ist das
Feld name von combilib leer und es wird der Bibliothek daher manuell ein clib name gegeben.
6.2.1
Moleküldaten
Nachdem der Compiler die Daten für die Tabelle Combinatorial Library in den jeweiligen
STREAM geschrieben hat, startet er im nächsten Schritt eine Schleife S über den R-Gruppen der
Bibliothek mit 0 ≤ S ≤ M AX N OF RGROU P S wobei M AX N OF RGROU P S der maximal
erlaubten Anzahl von R-Gruppen in der Bibliothek entspricht, also M AX N OF RGROU P S =
9 (Abbildung 6.2) . Für jede R-Gruppe wird überprüft, ob sie keine Fragmente enthält. Wenn
KAPITEL 6. IMPLEMENTIERUNG
51
dies der Fall ist, wird die Suche in der nächsten R-Gruppe fortgesetzt. Enthält die R-Gruppe
jedoch Fragmente, wird zuerst der R-Gruppe ein eindeutiger Identifikator mit der folgenden
Syntax zugewiesen:
<fragment_list_name>::=<clib_name>_R<R-group_nr>
Hier entspricht clib name dem Namen der Bibliothek, R einem Bezeichner für die R-Gruppe
und R-group nr der Nummer der aktuellen R-Gruppe innerhalb der Bibliothek.
Danach greift das Programm in einer zweiten Schleife nacheinander auf die Fragmente der aktuellen R-Gruppe zu. Auch hier wird für jedes Fragment einen Identifikator zusammengestellt:
<fragment_name>::=<clib_name>_R<R-group_nr>_<fragment_nr>
Im Vergleich mit dem fragment list name besteht fragment name aus einem weiteren
fragment nr-Feld, das der Nummer des Fragmentes innerhalb der R-Gruppe entspricht. Wie
bereits in (5.1) beschrieben, sind die Informationen über Atome und Atombindungen jedes
Moleküls in zwei Listen - atom und bond - enthalten. Um diese für jedes Fragment erreichen zu
können, werden nacheinander zwei Schleifen, jeweils eine für Atome und eine für Atombindungen
des aktuellen Fragmentes gestartet, die die Liste aller Atome und Atombindungen innerhalb
eines Fragmentes durchgehen. Zuerst wird nun die Atom-Schleife betrachtet:
Im Laufe des Entwicklungsprozesses wurde festgestellt, daß nicht alle Atome der kombinatorischen Bibliothek über ihre Primärschlüsseln in die Tabellen Atom in Fragment, Atombond in Fragment und Atombond between Fragments importiert werden können. Da ich die
Ursache für dieses Problem nicht herausfinden konnte, habe ich beschlossen, für die Atome
einen Identifikator zu definieren, dessen Wert für jedes Atom der Bibliothek eindeutig ist. Der
einfachste Identifikator kann hier eine generische Nummer sein, die man sehr einfach jedem
Atom zuweisen kann. Alternativ dazu kann man selber - wie bei den übrigen oben definierten
Identifikatoren - für jedes Atom einen Identifikator definieren:
<atom_id>::=<clib_name>_R<R-group_nr>_<fragment_nr>_<atom_nr>
wobei im Vergleich mit dem fragment name das neu dazugekommene Feld <atom nr> der
Nummer des Atoms innerhalb des Fragmentes entspricht. Hier wurde die zweite Variante
gewählt, weil zum Einen alle bis dahin definierten Identifikatoren demselben Prinzip folgen und
zum Anderen aus dem so definierten Identifikator mit einem Blick das Fragment, die R-Gruppe
und Bibliothek des Atoms festgestellt werden kann. Dies ist besonders beim Debugging der
späteren Datenbank-Anwendung von großem Vorteil.
Bereits in (5.1) wurde erläutert, daß die Bindungstellen der R-Gruppen-Fragmente als spezielle
Verbindungsatome - X - und R-Atome - markiert werden, über die Atombindungen zwischen
den Fragmenten zustande kommen. Da diese Atome nur Platzhalter für die tatsächlichen Verbindungsatome sind und keine weitere Rolle innerhalb des Fragmentes spielen, müssen sie von
der Suche ausgeschlossen werden. Daher wird in jedem Suchschritt geprüft, ob das gefundene Atom ein R- oder X -Atom ist. Trifft dies zu, dann wird das Atom übergangen und zum
nächsten Atom innerhalb der Kette gesprungen. Die Datenstruktur atom enthält die Felder hybrid, nof bonds, f charge, stereo und charge, die jeweils den Attributen hybridization, nof bonds,
f charge, chirality und p charge der Tabelle Atom entsprechen. Daher werden deren Werte für
KAPITEL 6. IMPLEMENTIERUNG
52
das Atom übernommen. Im Feld element der atom-Datenstruktur liegt das Element des jeweiligen Atoms als eine Integer-Zahl vor. Dagegen ist das Attribut element der Atom-Tabelle vom
Typ char. Die Abbildung der Zahlen in die jeweiligen Element-Bezeichner geschieht über eine
switch-case-Anweisung, die jede Zahl dem entsprechenden Bezeichner zuweist. Für die zwei
übrig gebliebenen Attribute nof H und donor acceptor der Atom-Tabelle gibt es keine direkten
Felder in der Datenstruktur atom. Sie müssen stattdessen indirekt über weitere Datenstrukturen
bestimmt werden. Das Attribut nof H der Tabelle Atom entspricht der Anzahl der am Atom
direkt gebundenen Wasserstoffatome. Um diese Zahl zu bestimmen, geht man folgendermaßen
vor:
for (b_p=atom_p->bondlist; b_p; b_p = b_p->next)
{
if (!b_p->to->r_x_atom_marker && b_p->to->element==1){nof_H_ctr++;}
}
Ausgehend von dem Atom, auf das mit atom p gezeigt wird, geht man die Liste seiner
Atombindungen bondlist durch. Ist das an der Bindung beteiligte Atom ein nicht als X - oder
R- Atom markiertes Wasserstoffatom (element==1), inkrementiert man den Zähler nof H ctr.
Ob ein Atom Donor- oder Akzeptor ist erkannt man, indem man für das Atom in der Liste
m interact den Typ seiner Interaktionen prüft. Nachdem alle Werte für das aktuelle Atom
gefunden wurden, werden sie in derselben Reihenfolge in den atom stream geschrieben, nach der
die Werte später als eine Zeile in die Tabelle Atom geschrieben werden sollen. Die in den übrigen
Iterationen gefundenen Werte für die weiteren Atome werden alle in denselben atom stream
geschrieben. Sie werden jedoch durch ein Trennzeichen voneinander getrennt gehalten, damit
man sie später beim Schreiben in die Datenbank-Tabelle wieder in die einzelnen Datensätze
zerlegen kann. Auch der für die Tabell Atom in Fragment vorgesehene atom in fragment stream
wird nach demselben Prinzip wie bei atom stream dargestellt, mit den ensprechenden Werte
gefüllt.
Hat man alle Atome des aktuellen Fragmentes durchsucht, beginnt man mit der Suche innerhalb
der Atombindungen des aktuellen Fragmentes. Bereits aus (5.1) ist bekannt, daß ein X - oder RAtom nur als Platzhalter für die Bindungsatome eines Fragmentes dient und auf das tatsächliche
Bindungsatom verweist. Dieses ist das Atom, mit dem es in Verbindung steht. Hier betrachtet
man die Atompaare in zwei Haupgruppen: Paare ohne X - oder R-Atom und solche mit einem X oder R-Atom. Für die erste Gruppe werden die Werte der für die Tabelle Atombond in Fragment
relevanten Felder aus den Datenstrukturen atom und bond in den bond in stream geschrieben.
Die hierzu relevante Menge der Felder der atom-Struktur ist eine Untermenge der Felder, die
weiter oben für die Tabelle Atom benutzt wurden. Neu dazu kommen die beiden Felder type und rotatable der Datenstruktur bond, die jeweils den Attributen type und rotatibility der
Tabelle Atombond in Fragment entsprechen. Auch die Werte dieser Felder werden für die jeweilige Atombindung in den für die o.g. Tabelle vorgesehenen bond in stream geschrieben. Ebenso
werden hier die Werte weiterer Atombindungen in denselben bond in stream getrennt durch
Trennzeichen hineingeschrieben. Über die zweite Gruppe der Bindungspaare kann man die Attributwerte einzelner Atombindungen zwischen den Fragmenten bestimmen und sie zum Schreiben in der Tabelle Atombond between Fragments vorbereiten. Dafür geht man folgendermaßen
vor: Zuerst wird geprüft, ob die jeweilige R-Gruppe ein Core ist. Ist dies der Fall, werden die
Atombindungen wie oben beschrieben durchsucht und auf die Bindungen mit dem R-Atom als
Bindungspartner verzichtet. Ist die aktuelle R-Gruppe kein Core, dann wird zuerst das X -Atom
KAPITEL 6. IMPLEMENTIERUNG
53
des aktuellen Fragmentes durch sein Partneratom ersetzt. Danach werden auch die R-Atome
aller Fragmente der Vorgänger-R-Gruppe durch ihre Partneratome ersetzt. Über die so entstandenen neuen Atome kann das aktuelle Fragment der aktuellen R-Gruppe an die Fragmente der
Vorgänger-R-Gruppe gebunden werden. Mit dieser Methode können die Informationen über alle
Atombindungen zwischen den Fragmenten gewonnen und dann in den bond between stream geschrieben werden. Am Ende werden die für die weiteren Tabellen vorgesehenen STREAMS mit
den jeweiligen Werten gefüllt und schließlich alle zusammen zum Schreiben in die Datenbank an
die Datenbank-Schnittstelle weitergegeben.
6.2.2
clib molecule Daten
Als nächstes müssen die Attributwerte aller Bibliotheksmoleküle zum Importieren in die dazu
vorgesehenen Tabellen CLib Molecule, Is Core of und Is Rest of vorbereitet werden. Dafür
benutzt der Compiler eine Funktionalität in FlexX, die ausgehend von einem existierenden
clib molecule alle weiteren Bibliotheksmoleküle aufzählt. Hier werden die Moleküle eins nach
dem anderen aufgebaut, ohne daß für sie weitere Berechnungen durchgeführt werden. Der
Compiler greift auf diese Informationen folgendermaßen zu (Abbildung 6.3):
Zuerst wird ein clib molecule mit Hilfe der extract-Operation in FlexXC aus den 0. Fragmenten
aller R-Gruppen zusammengesetzt. Für dieses Molekül wird dann ein Identifikator mit folgender
Syntax erstellt:
<clib_mol_name>::=<clib_name>_<cl_molecule->m->name>
Das Feld clib name entspricht - wie bei den, im vorherigen Abschnitt beschriebenen Identifikatoren - dem Bibliotheksnamen. Das Feld cl molecule->m->name repräsentiert den Namen
des Bibliotheksmoleküls. Dabei ist m ein Zeiger auf die Datenstruktur molecule, in der das Feld
name den Namen des Biliotheksmoleküls enthält. Diesen Identifikator schreibt man dann in den
clib mol stream.
Im nächsten Durchgang wird die Liste list der Fragmente des Bibliotheksmoleküls geprüft (5.1),
in der das erste Element das Core-Fragment und die weiteren die Rest-Fragmente des Moleküls
sind. In jeder Iteration werden für das jeweilige Fragment zwei String-Werte erzeugt:
<clib_fragment_list_name>::=<clib_name>_R<list_pos>
<clib_fragment_name>::=<clib_name>_R<list_pos>_<fragment_name>_<fragment_nr>
Hier ist das Feld list pos die Position des aktuellen Fragmentes des Bibliotheksmoleküls innerhalb der Liste list, fragment name der Name und fragment nr die Nummer des aktuellen Fragmentes in der jewiligen R-Gruppe der Bibliothek. Der Grund für das Hinzufügen der
fragment nr zum fragment name ist, daß die Fragmentnamen innerhalb der Bibliotheken nicht
unbedingt eindeutig sind, so daß es Fälle gibt, wo mehrere Fragmente innerhalb eines Fragmentes mit demselben Namen versehen sind. Sobald die Werte erzeugt sind, werden sie nacheinander in den clib mol core stream und clib mol rest stream geschrieben, wobei die Werte jedes
Durchlaufes von den anderen mit einem Trennzeichen getrennt gehalten werden. Sobald die
gesamten Bibliotheksmoleküle konstruiert und deren Informationen sowie die Core- und Restfragmentinformationen in die jeweiligen Streams geschrieben wurden, werden die Streams an die
Datenbankschnittstelle weitergeleitet.
KAPITEL 6. IMPLEMENTIERUNG
6.3
54
Datenimport in die Datenbank
Nachdem alle STREAMs mit den jeweiligen Datensätze gefüllt wurden, kann man jetzt beginnen,
diese in die Datenbank zu importieren. In der vorliegenden Arbeit wurde zur Kommunikation
mit der Datenbank die Python-Datenbankschnittstelle DCOracle2 genutzt. Wie damit einen
Schreibzugriff auf die Datenbank erfolgt, wird anhand eines Beispiels verdeutlicht:
Beispiel
In diesem Beispiel wird das Schreiben der Atom-Daten in die Tabelle Atom exemplarisch dargestellt. Es ist zu beachten, daß die hier gezeigte Python-Funktion stark vereinfacht wurde, damit
das Prinzip des Vorgehens deutlicher wird.
1: import DCOracle2 as dbapi2
2: class DB_ACCESS:
3:
con=dbapi2.connect(’user/password@schema’)
4:
def write_atom(name, str):
5:
cur=con.cursor()
6:
records=str.split(";")
7:
for r in records:
8:
sql="INSERT INTO %s VALUES (%s)"%(name,r)
9:
try:
10:
cur.execute(sql)
11:
con.commit()
12:
except:
Zunächst wird in der 1. Zeile das Modul DCOracle2 in das Programm importiert und über
den Alias dbapi2 repräsentiert. Nachdem in 2. Zeile die Klasse DB ACCESS definiert wurde,
erfolgt die Verbindung mit der Datenbank in der 4. Zeile über die connect-Funktion der Klasse
Connection des Modules DCOracle2. Als Parameter nimmt connect in der gezeigten Form
den Benutzernamen user, das Password password und den Namen des Schemas schema, in
dem die Tabellen definiert sind. In der 3. Zeile wird die Funktion write atom mit den zwei
Parameter name und str definiert, die jeweils dem Namen der Zieltabelle (hier Atom) und
der Zeichenkette entsprechen. In str sind die Daten aus dem für die Zieltabelle bestimmten
STREAM (hier atom stream) enthalten.
Nachdem in der 5. Zeile die Instanz cur der Klasse Cursor erzeugt wurde, muss man vor der
Ausführung des INSERT-Befehls zunächst über diese Instanz die lange Zeichenkette str der
Atom-Datensätze im atom stream auseinandernehmen, um dann jeden einzelnen Datensatz als
eine Zeile in der Tabelle schreiben zu können. Werden die Datensätze in str mit einem Semikolon von einander getrennt gehalten, so kann man sie - wie in der 6. Zeile gezeigt - über die
split-Funktion in Python auseinandernehmen und die Datensätze als einzelne Felder in der
Liste records ablegen. Daraufhin kann in der 7. Zeile eine for-Schleife gestartet werden, die
die Liste records durchgeht. Bei jedem Durchlauf wird in der 8. Zeile eine INSERT-Abfrage
als string formuliert, in dem der Name der Zieltabelle Atom und der zu importierende Datensatz eingesetzt werden. Die Ausführung des INSERT-Befehls geschieht in der 10. Zeile über die
execute-Methode der Klasse Cursor, die dann über die commit-Funktion der Klasse Connect
in der 11. Zeile abgeschlossen wird. Um mögliche Fehler bei dieser Transaktion abzufangen, kann
KAPITEL 6. IMPLEMENTIERUNG
55
man die Transaktion zwischen den Zeilen 9 bis 12 in einen try/except-Block setzen und die
möglichen Fehler dann beliebig bearbeiten.
KAPITEL 6. IMPLEMENTIERUNG
56
Abbildung 6.2: Flußdiagramm zur Darstellung des Zugriffes auf die Moleküldaten der kombinatorischen Bibliotheken in den FlexX-Datenstrukturen.
KAPITEL 6. IMPLEMENTIERUNG
57
Abbildung 6.3: Flußdiagramm zur Darstellung des Zugriffes auf die Struktur der Bibliotheksmoleküle der kombinatorischen Bibliotheken in den FlexX-Datenstrukturen.
Kapitel 7
Evaluierung
Wie bereits in der Einleitung erwähnt, besteht eine der Anwendungsmöglichkeiten für die
mittlerweile implementierte Datenbank in der Suche nach spezifischen chemischen Substrukturen innerhalb von kombinatorischen Bibliotheken, deren Informationen mittlerweile in der
Datenbank als Tabellen vorliegen. In Kapitel 2 wurde deutlich, daß der Graph eine mögliche
Datenstruktur zur Repräsentation chemischer Strukturen ist. Liegt eine chemische Struktur
als Graph vor, kann man zur Suche innerhalb der Strukturen auf die für Graphen bekannten
Suchalgorithmen, die bereits in (2.2.2) vorgestellt wurden, zurückgreifen und sie für seine
Operationen benutzen. Bereits in (2.3) wurde deutlich, daß eine kombinatorische Bibliothek
als ein Baum, also einem speziellen Graph, darstellbar ist. Wird die zu suchende Substruktur
ebenfalls als Graph repräsentiert, kann man sie mit Hilfe der Suchalgorithmen für Graphen
innerhalb der kombinatorischen Bibliotheken aufsuchen.
In diesem Kapitel wird zunächst die Realisierung der Views zum Subgraphenisomorphismus
auf der Datenbankebene vorgestellt, die eine Breitensuche modelliert. Danach werden die Testergebnisse des Subgraphenisomorphismus in FlexX und auf der Datenbankebene miteinander
verglichen.
7.1
Views zum Subgraphisomorphismus
In (2.4) wurde dargestellt, daß man die chemischen Substrukturen in zwei Hauptgruppen einfache Ketten und Ringsysteme - aufteilen kann, die im Allgemeinen miteinander kombiniert
werden können. Die einfachen Ketten und Ringsysteme sind sich sehr ähnlich, indem beide
eine Sequenz von Atomen darstellen, die im ersten Fall offen und im zweiten Fall geschlossen
ist. Aus diesem Grund wird zuerst die Suche nach einfachen Ketten realisiert, denn die Suche
nach einem Ringsystem läßt sich mit einer leichten Modifikation bei der Modellierung der
Substruktur, nämlich der Gleichsetzung des Anfags- und Endatoms, auf die Suche nach einer
einfachen Kette zurückführen.
Vor der Implementierung der Suchalgorithmen für linearen Ketten innerhalb der Datenbank
muss diese zunächst in der für die Suche geeigneten Weise innerhalb der Datenbank vorbereitet
werden. Wie bereits in (2.2.1) verdeutlicht, kann man zur Berechnung bzw. zum Operieren auf
den Graphen im Computer diesen entweder als eine Adjazenzmatrix oder als eine Sammlung von
Adjazenzlisten in Form einer Adjazenzstruktur repräsentieren. Da das relationale Datenmodell
58
KAPITEL 7. EVALUIERUNG
59
Abbildung 7.1: Darstellung einer Kette der Form A-B-C als Tabelle mit dem Anfangsatom A.
auf Mengen basiert, wird die Kette in der Datenbank in Form einer Adjazenzstruktur modelliert.
Die zu suchende Kette ist ein gerichteter Graph, da man bei der Suche die Atome der Kette
von einem Ende zum anderen Ende nacheinander in einer bestimmten Richtung durchläuft
und damit für diese Kette eine bestimmte Richtung definiert. Damit wird die Kette in der
Datenbank als eine Tabelle subgraph definiert. Diese Tabelle besitzt mindestens vier Spalten:
zwei zur Repräsentation der an der Bindung beteiligten Atome, eine - die bond nr -Spalte um die Nummer der aktuellen Atombindung innerhalb der Substruktur darzustellen und die
bond type-Spalte zur Repräsentation des Bindungstyps zwischen den beteiligten Atomen. In
dieser Tabelle entspricht dann jede Zeile einer Adjazenzliste mit den gesamten Informationen
über die aktuellen Atombindung (Abbildung 7.1).
In Kapitel 4 wurde dargestellt, daß ein Atom in der Datenbank durch eine Menge von Attributen
eindeutig charakterisiert wird. Eigentlich müßten also die beiden Atom-Spalten der Tabelle
subgraph die gesamten Atomattribute enthalten. Das ist hier jedoch nicht der Fall, denn bei der
ersten Implementierung der Substruktursuche sind lediglich die Sequenzen von Atom-Elementen
interessant und es reicht daher, wenn jedes Atom durch sein Element vertreten wird. In den
Erweiterungen kann man später die weiteren Atommattribute berücksichtigen, indem man z.B.
die Tabelle subgraph um zusätzlichen Spalten erweitert, die diese Atommatribute enthalten.
Aus diesem Grund wurden die Atom-Spalten mit element a und element b benannt (Siehe
Abbildung subgraph-table).
Der Suchraum, in dem nach den gewünschten Substrukturen gesucht werden soll, enthält alle
Informationen über die Atome und Atombindungen innerhalb der Fragmente sowie über die
Atombindungen zwischen den Fragmenten der kombinatorischen Bibliotheken. Wie bereits in
Kapitel 4 beschrieben, werden diese gesamten Informationen in den Tabellen Atom in Fragment,
Atombond in Fragment und Atombond between Fragments gespeichert. Diese Tabellen enthalten jedoch nicht alle Informationen über die Atomattribute, die in der Tabelle Atom enthalten
sind. Die übrigen Informationen kann man im Suchraum mit dem Joinen der Tabelle Atom
mit den o.g Tabellen erreichen. Alternative kann man für jedes Atom in diesen Tabellen
das dazugehörige Element direkt in die Tabelle übernehmen. Da das Joinen der Tabellen
unter Umständen zur Verlangsamung des Suchprozesses führen kann und weil hier nur das
KAPITEL 7. EVALUIERUNG
60
Element als einziges Atomattribut verwendet werden soll, wird an dieser Stelle auf das Joinen
der Tabellen verzichtet. Die Atom-Elemente werden in den Tabelle Atom in Fragmentdurch
die zusätzliche Spalte atom element und in den Tabellen Atombond in Fragment und Atombond between Fragments durch die zusätzlichen Spalten atom element a und atom element b
für die jeweiligen Bindungspartner A und B repräsentiert.
Aufgrund der vorgegebenen Richtung für Atombindungen in den ASCII-Dateien und der
definierten Reihenfolge, in der die R-Gruppen der Bibliotheken aneinander gebunden werden,
sind diese Atombindungen innerhalb der o.g. Tabellen gerichtet abgelegt. Daher kann man
ausgehend von einem Atom nur in der vorgegebenen Richtung navigieren. Das ist bei der Suche
innerhalb des Suchraumes ein Hindernis, da man in jedem Suchschritt wissen müßte, ob die
Suche in der eine oder andere Richtung fortgeführt wird.
Um diese Einschränkung aufzuheben und die Suche zu flexibilisieren, wurden die vorgegebenen Richtungen für die Atombindungen aufgehoben. Die Realisierung wurde mit Hilfe der beiden Sichten atom pairs in und atom pairs between erreicht, die für jede Atombindung die
Bindungspaare der beiden Bindungstabellen in der vorgegeben und der umgekehrten Richtung
ansehen (Abbildung 7.2).
1: CREATE OR REPLACE VIEW atom_pairs_in AS
2: SELECT
3:
a1.atom_id
AS atom_id_a,
4:
a1.atom_element
AS atom_element_a,
5:
a2.atom_id
AS atom_id_b,
6:
a2.atom_element
AS atom_element_b,
7:
a1.fragment_name
AS fragment_name,
8:
fif.fragment_list_name AS fragment_list_name,
9:
aif.type
AS bond_type
10: FROM
11: atom_in_fragment
a1,
12: atom_in_fragment
a2,
13: atombond_in_fragment
aif,
14: fragment_in_fragment_list fif
15: WHERE (
16: aif.atom_id_a
= a1.atom_id
AND
17: aif.atom_id_b
= a2.atom_id
AND
18: aif.fragment_name = fif.fragment_name)
19: OR (
20: aif.atom_id_b
= a1.atom_id
AND
21: aif.atom_id_a
= a2.atom_id
AND
22: aif.fragment_name = fif.fragment_name);
In der Sicht atom pairs in wird aus dem Joinen der Tabellen atom in fragment und
atombond in fragment (11. bis 13. Zeile) eine ungerichtete Version der Atombindungen
innerhalb der Fragmente erzeugt. Das Joinen dieser Tabellen geschieht über die Spalten atom id der Tabelle atom in fragment und atom id a sowie atom id b der Tabelle
atombond in fragment (16. und 17. sowie 20. und 21. Zeile ), die vom gleichen Typ sind. In
KAPITEL 7. EVALUIERUNG
61
der 16. Zeile wird der erste Bindungspartner atom id a aus der Tabelle atombond in fragment
mit dem Atom atom id der Tabelle atom in fragment gleich gesetzt. Das so gefundene Atom
sowie dessen Element werden dann in den Zeilen 3 und 4 als atom id a und atom element a
zur Verfügung gestellt. Der andere Bindugspartner - also atom id b (17. Zeile) - wird zusammen mit seinem Element nach demselben Prinzip in den 5. und 6. Zeilen als atom id b und
atom element b repräsentiert.
Umgekehrte geschieht es in den Zeilen 20 und 21. Dort wird der zweite Bindungspartner - atom id b aus der Tabelle atombond in fragment - mit dem Atom atom id der
Tabelle atom in fragment und der erste Bindungspartner - atom id a aus der Tabelle
atombond in fragment - mit dem Atom atom id der Tabelle atom in fragment gleich
gesetzt. Diese werden dann jeweils zusammen mit ihren Elementen in den Zeilen 3 bis 6 als
atom id a und atom element a sowie atom id b und atom element b repräsentiert. Damit
ist eine gerichtete Atombindung der Form A → B in der Tabelle Atombond in Fragment
über die Sicht atom pairs in sowohl als A → B als auch als B → A repräsentiert. Von den
gesamten Atomattributen werden hier zwar nur atom id und atom element aus der Tabelle
atom in fragment selektiert, jedoch sind die übrigen Atomttribute genauso erreichbar.
In der Sicht atom pairs in ist ein weiteres Join zwischen den Tabellen atombond in fragment
und fragment in fragment list (18. sowie 22. Zeile) über die in beiden Tabellen gleichnamigen Spalten fragment name vorgesehen. Damit kann man für die Atome der Atombindungen
feststellen, in welcher R-Gruppe diese enthalten sind (Zeile 8.). Diese Information wird später
bei der Realisierung der Suchalgorithmen benötigt, was weiter unten näher erläutert wird.
Die Informationen über die Atombindungen zwischen den Fragmenten kann man ähnlich wie bei
der atom pairs in-Sicht über die Sicht atom pairs between erhalten.
1: CREATE OR REPLACE VIEW atom_pairs_between AS
2: SELECT
3:
a1.atom_id
AS atom_id_a,
4:
a1.atom_element
AS atom_element_a,
5:
a2.atom_id
AS atom_id_b,
6:
a2.atom_element
AS atom_element_b,
7:
abf.predec_fragment_name AS fragment_name_a,
8:
abf.succec_fragment_name AS fragment_name_b,
9:
fif1.fragment_list_name AS fragment_list_name_a,
10: fif2.fragment_list_name AS fragment_list_name_b,
11: abf.type
AS bond_type
12:FROM
13: atom_in_fragment
a1,
14: atom_in_fragment
a2,
15: atombond_between_fragments abf,
16: fragment_in_fragment_list fif1,
17: fragment_in_fragment_list fif2
18:WHERE (
19: abf.atom_id_a
= a1.atom_id
AND
20: abf.atom_id_b
= a2.atom_id
AND
KAPITEL 7. EVALUIERUNG
62
Abbildung 7.2: Die Kombination der beiden Sichten atom pairs in und atom pairs between
in der atom pairs-Sicht.
21: abf.predec_fragment_name
22: abf.succec_fragment_name
23: OR(
24: abf.atom_id_b
25: abf.atom_id_a
26: abf.succec_fragment_name
27: abf.predec_fragment_name
= fif1.fragment_name AND
= fif2.fragment_name)
=
=
=
=
a1.atom_id
AND
a2.atom_id
AND
fif1.fragment_name DAND
fif2.fragment_name);
Die Vorgehensweise ist genau dieselbe wie bei der Sicht atom pairs in. Aus dem Joinen
der zwei Tabellen atom in fragment und atombond between fragments über die Spalten atom id der Tabelle atom in fragment und atom id a sowie atom id b der Tabelle
atombond between fragments (19. und 20. sowie 24. und 25. Zeilen) kann man wiederum
erreichen, daß eine Atombindung der Form A → B in der Tabelle Atombond between fragments
über die Sicht atom pairs between sowohl als A → B als auch als B → A dargestellt wird.
Die Fragmente der Atome werden in den 7. und 8. Zeilen repräsentiert.
Es ist sogar möglich, die beiden Sichten über den UNION-Operator in Form einer einzigen
atom pairs-Sicht miteinander zu kombinieren.
Damit erhält man einen einzigen Suchraum, in dem alle Bindungspaare enthalten sind, egal
KAPITEL 7. EVALUIERUNG
63
ob sie sich in oder zwischen den Fragmenten befinden. Dies hat den großen Vorteil, daß man
sich bei der Suche nicht in jedem Suchschritt darum kümmern muß, ob die Suche innerhalb des
aktuellen Fragmentes oder in einer der benachbarten R-Gruppen fortgesetzt werden soll.
1: CREATE OR REPLACE VIEW atom_pairs AS
2: SELECT
3:
atom_id_a,
4:
atom_element_a,
5:
atom_id_b,
6:
atom_element_b,
7:
fragment_name
AS fragment_name_b,
8:
fragment_list_name AS fragment_list_name_b,
9:
bond_type
10:FROM atom_pairs_in
11:UNION
12:SELECT
13: atom_id_a,
14: atom_element_a,
15: atom_id_b,
16: atom_element_b,
17: fragment_name_b,
18: fragment_list_name_b,
19: bond_type
20:FROM atom_pairs_between;
In der atom pairs-Sicht werden aus den beiden Sichten nur diejenigen Attribute ausgewählt,
die für die weiteren Anwendungen relevant sind.
Nach diesen ersten Vorbereitungen kann jetzt die Suche mit der folgenden PL/SQL-Prozedur
beginnen:
1: CREATE OR REPLACE PROCEDURE search IS
2:
MIN_BOND_NR INTEGER;
3:
MAX_BOND_NR INTEGER;
4:
BEGIN
5:
MIN_BOND_NR := 1;
6:
SELECT MAX (bond_nr) INTO MAX_BOND_NR FROM subgraph;
7:
INSERT INTO results SELECT * FROM first_match;
8:
INSERT INTO seen_fragment_lists SELECT * FROM seen_first_frag_lists;
9:
FOR l_bond_step in MIN_BOND_NR..MAX_BOND_NR LOOP
10:
INSERT INTO results
11:
SELECT *
12:
FROM
next_match
13:
WHERE step = l_bond_step;
14:
INSERT INTO seen_fragment_lists
15:
SELECT *
16:
FROM
seen_next_frag_lists
17:
WHERE step = l_bond_step;
KAPITEL 7. EVALUIERUNG
64
Abbildung 7.3: Der Ablauf des ersten Suchschrittes.
18:
END LOOP;
19:END;
Nach der Prozedur-Definition in der 1. Zeile werden in den Zeilen 2 und 3 zwei Parameter
- MIN BOND NR und MAX BOND NR - definiert, die für die Suchschritte als Unter- bzw. Obergrenze gelten. Diese Grenzwerte entsprechen den Werten der ersten und der letzten Zeile der
bond nr -Spalte der Tabelle subgraph. Diese Werte werden dann in den Zeilen 5 und 6 den o.g.
Parametern zugewiesen.
Die Suche beginnt in der 7. Zeile mit dem Aufrufen der Sicht first match, die wie folgt definiert
wird (Abbildung 7.3):
1: CREATE OR REPLACE VIEW first_match AS
2: SELECT
3:
0
AS step,
4:
api.atom_element_a
AS atom_element,
5:
api.atom_id_a
AS atom_id,
6:
’NONE’
AS predec_atom_id,
7:
api.fragment_name
AS fragment_name,
8:
api.fragment_list_name AS fragment_list_name,
9:
api.atom_id_a
AS list_id
KAPITEL 7. EVALUIERUNG
10:FROM
11: subgraph
12: atom_pairs_in
13:WHERE
14: sg.bond_nr
15: api.atom_element_a
65
sg,
api
= 1
AND
= sg.element_a;
Hier wird aus der Tabelle subgraph das element a der ersten Zeile gelesen (Zeile 14).
Ausgehend von diesem Element wird über die Sicht atom pairs in innerhalb der Fragmente der Bibliothek nach denjenigen Atomen gesucht, die vom selben Element sind wie das
element a(Zeile 15). Hat man solche Atome bzw. Teillösungen gefunden, werden für jede
Teillösung die Informationen im SELECT-Teil der first match-Sicht zur Verfügung gestellt.
Für jede Teillösung wird dann eine Liste erstellt, die mit dem Identifikator list id eindeutig
markiert wird.
Nun werden die übrigen Schritte der Prozedur searchdargestellt. Nachdem die Ergebnisse der
first match-Sicht in der Tabelle results geschrieben (materialisiert) sind, fährt das Programm mit der 8. Zeile fort, wo die Ergebnisse der Sicht seen first frag lists in die Tabelle
seen fragment lists geschrieben werden.
1: CREATE OR REPLACE VIEW seen_first_frag_lists AS
2: SELECT
3:
res.step,
4:
res.list_id,
5:
aif.fragment_name,
6:
fif.fragment_list_name
7: FROM
8:
results
res,
9:
atom_in_fragment
aif,
10: fragment_in_fragment_list fif
11:WHERE
12: res.atom_id
= aif.atom_id
AND
13: aif.fragment_name = fif.fragment_name;
Die Sicht seen first frag lists findet für jedes Atom in der results-Tabelle das Fragment
und die R-Gruppe, in der das Atom sich befindet (Abbildung: 7.3). Auf den Grund der Markierung des Fragmentes und der R-Gruppe für jedes Atom wird weiter unten näher eingegangen.
Die Suche wird in den Zeilen 9 bis 18 der Prozedur search weiter fortgesetzt. Dort wird die
subgraph-Tabelle von der ersten bis zur letzten Zeile in einer Schleife durchlaufen. In jedem
Durchlauf wird in der 12. Zeile die Sicht next match aufgerufen (Abbildung 7.4):
1: CREATE OR REPLACE VIEW next_match AS
2: SELECT
3:
sg.bond_nr
AS step,
4:
ap.atom_element_b
AS atom_element,
5:
ap.atom_id_b
AS atom_id,
KAPITEL 7. EVALUIERUNG
66
Abbildung 7.4: Der Ablauf der nächsten Suchschritte.
6:
ap.atom_id_a
7:
ap.fragment_name_b
8:
ap.fragment_list_name_b
9:
res.list_id
10: FROM
11: subgraph sg,
12: atom_pairs ap,
13: results res
14: WHERE
15: sg.bond_nr
=
16: ap.atom_element_b
=
17: ap.atom_id_a
=
18: ap.bond_type
=
19: NOT EXISTS(
20:
SELECT *
21:
FROM
results
22:
WHERE
list_id
=
23:
ap.atom_id_b=
24: NOT EXISTS(
25:
SELECT *
AS
AS
AS
AS
predec_atom_id,
fragment_name,
fragment_list_name,
list_id
res.step+1
sg.element_b
res.atom_id
sg.bond_type
AND
AND
AND
AND
res.list_id
atom_id)
AND
AND
KAPITEL 7. EVALUIERUNG
67
Abbildung 7.5: Bei der Suche der Kette 1-...-6 im Suchraum soll die rot gekennzeichnete Verbindung 5-6 von Fragment List 2 zu Fragmen List 1 vermieden werden.
26:
27:
29:
30:
FROM
WHERE
seen_fragment_lists sfl
list_id
= sfl.solution_id
AND
ap.fragment_list_name_b = sfl.fragment_list_name AND
ap.fragment_name_b
!= sfl.fragment_name);
Hier wird zunächst aus der subgraph-Tabelle (11. Zeile) das element b der aktuellen Zeile
gelesen. Welche Zeile der Tabelle subgraph als aktuelle Zeile betrachtet werden soll, wird in
Zeile 13 der search-Prozedur und danach in Zeile 15 der next match-Sicht festgelegt. Dann
werden in der Sicht next match (12. Zeile) über die atom pairs-Sicht diejenigen Atome im
Suchraum gesucht, die drei Kriterien erfüllen: erstens müssen sie vom selben Element sein wie
das aktuell gesuchte Atom aus der subgraph-Tabelle (16. Zeile), Zweitens muss im Suchraum
eine Atombindung zwischen dem gefundenen Atom und einem Atom der letzten Stufe in der
Liste der jeweiligen Teilösung bestehen (17. Zeile), Drittens dürfen die gefundenen Atome nicht
bereits in der Liste der jeweiligen Teillösung enthalten sein. Das zweite Kriterium stellt sicher,
daß nicht jedes Atom des gesuchten Elements im Suchraum erfasst wird, sondern nur jene, deren
direktes Nachbaratom bereits in der Liste der jeweiligen Teillösung vorhanden ist. Die letzte
Bedingung gewährleistet, daß die Suche immer in einer Richtung voran geht und damit die
bereits betrachteten Atome jeder Liste nicht noch einmal abgesucht werden. Diese Bedingung
wird in der next match-Sicht über die erste NOT-EXISTS-Einschränkung erfüllt (18. bis 22. Zeile).
Eine weitere Einschränkung kann sich noch aus dem spezifischen Aufbaumechanismus der kombinatorischen Bibliotheken ergeben. Bereits in (2.3.1) wurde deutlich, daß bei der Konstruktion
eines Bibliotheksmoleküls in einer Bibliothek aus jeder R-Gruppe nicht mehr als ein Fragment
benutzt werden darf. Es kann aber durchaus vorkommen, daß man bei der Suche nach dem
nächsten Atom für eine Teillösung die bereits durchsuchte R-Gruppe im Suchraum in Richtung einer neuen R-Gruppe verlässt und dann im nächsten Suchschritt über das dann aktuelle
Atom im Suchraum wieder zu einem anderen Fragment der vorherigen R-Gruppe zurückkehrt
(Abbildung 7.5).
Dieses kann vermieden werden, indem in jeder Teillösung für jedes Atom das Fragment und die
R-Gruppe bzw. Fragment List des jeweiligen Atoms gespeichert wird. Dafür schreibt man sie in
der 8. und in den Zeilen 14 bis 18 der search-Prozedur über die Sichten seen first frag lists
und seen next frag lists in die Tabelle seen fragment listes.
KAPITEL 7. EVALUIERUNG
68
1: CREATE OR REPLACE VIEW seen_next_frag_lists AS
2:
SELECT
3:
res.step,
4:
res.list_id,
5:
aif.fragment_name,
6:
fif.fragment_list_name
7:
FROM
8:
results
res,
9:
atom_in_fragment
aif,
10:
fragment_in_fragment_list fif
11: WHERE
12:
res.atom_id
= aif.atom_id AND
13:
aif.fragment_name = fif.fragment_name;
Stehen diese Informationen nun zur Verfügung, kann man in der Sicht next match über die
zweite NOT EXISTS-Bedingung testen, ob das neue Atom entweder immer noch demselben
Fragment dieser R-Gruppe oder einer neuen, noch nicht besuchten R-Gruppe angehört. Wenn
ein neu gefundenes Atom diese Bedingungen erfüllt, wird es in der Liste der jeweiligen Teillösung
der results-Tabelle gespeichert.
Mit dem Erreichen des Endes der subgraph-Tabelle ist auch der Suchprozess beendet. Die
results-Tabelle enthält jetzt die Listen aller Teillösungen, die im Laufe des Suchprozesses
gefunden wurden. Von diesen Teillösungen sind aber nur diejenigen interessant, die die komplette Substruktur enthalten. Das trifft auf solche zu, in deren Listen in der results-Tabelle es
mindestens einen Eintrag auf der letzten Stufe der Tabelle gibt (Abbildung 7.6).
Um die vollständigen Teillösungen bzw. die Fragmente, in denen sie enthalten sind aus der
results-Tabelle herauszuholen, muss man die Liste jeder dieser Teillösungen voim Suchraum n
der letzten Stufe bis zu ihrem Anfang zurückverfolgen. Der hier vorgestellte Suchalgorithmus ist
ein Breitensuche-Algorithmus, der in jedem Suchschritt eine Menge von Atomen als Ergebnis
zurückliefert. Da hier keine Möglichkeit besteht, für jedes Atom einer Teillösung das VorgängerAtom zu bestimmen, muss man selber für jedes Atom solche Referenzen setzen, über die dann die
Listen der Teillösungen von den Blättern zur Wurzel durchlaufen werden können. Eine mögliche
Lösung hierfür ist, daß man im Suchprozess ebenfalls das Vorgänger-Atom für jedes gefundene
Atom in der results-Tabelle speichert. So kann man - ausgehend von jedem Atom (außer den
Anfangsknoten) - das jeweilige Vorgänger-Atom erreichen.
7.2
Vergleich von Suchergebnissen mit und ohne Datenbank
Das Ziel dieses Testes ist es, bestimmte Substrukturen innerhalb derselben kombinatorischen
Bibliothek einerseits in FlexX und andererseits - mit Hilfe der oben beschriebenen Implementierungen - innerhalb der Datenbank zu suchen und somit die Vor- und Nachteile der beiden
Ansätze miteinander zu vergleichen.
Als Datensatz zum Testen der oben beschriebenen Algorithmen wurde die CSLN-Bibliothek
Methotrexate Analoga ausgewählt. Methotrexat ist ein Medikament zur Behandlung von
Tumoren und Rheumatischen Erkrankungen [H.J96]. Der Grund zur Auswahl dieser Bibliothek
KAPITEL 7. EVALUIERUNG
No.
subgraph
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
O=C-O
C-N=N
O=S=O
O=S-N
Cl-C-C-C=O
C=C=O
C-O
O-C-O
O-C-C-O
O-C-C-C-O
O=P-C
O=P-O-P=O
N-C-C-O-S=O
O=S-N-C=O
O=C-N-C
O=C-O-C
C-C≡N
C-S-C≡N
C=C-C=C-C=C
O=C-C-S=O
69
vorwärts
[m:s]/gefunden
0:31/OK
>5/0:14/OK
0:14/OK
0:21/OK
0:21/(0,1)
2:24/OK
0:29/OK
0:51/OK
1:32/OK
0:22/OK
0:22/(0,1,2)
>5/0:27/OK
0:48/(0,1,2)
0:42/OK
>5/1:09/(0,1,2)
>5/0:41/(0,1,2,3)
rückwärts [m:s]
[m:s]/gefunden
0:38/OK
0:14/OK
0:14/OK
0:14/OK
0:55/OK
0:55/(0,1)
0:21/OK
0:29/OK
0:51/OK
1:32/OK
0:22/OK
0:22/(0,1,2)
0:27/(0,1,2,3,4)
0:39/(0,1,2)
>5/>5/1:14/OK
0:19/(0,1)
>5/0:24/(0,1,2,3)
Tabelle 7.1: Die Tabelle enthält in den Spalten vorwärts und rückwärts Informationen über
die Suchzeit und darüber, ob die Kette gefunden wurde. Gefundene Ketten werden mit ”OK”
bezeichnet, wurden sie nicht gefunden repräsentiert ein Tupel die gefundenen Atome. Die Suchezeiten länger als Min. werden mit >5 gezeigt.
liegt in ihrer typischen Größe im Bereich Wirkstoffdesign. Diese Bibliothek besteht aus drei
R-Gruppen R0, R1 und R2 mit jeweils 1, 775 und 1748 Fragmenten, aus deren Kombinationen
bis zu 1354700-Bibliotheksmoleküle kombinierbar sind. Als gesuchte Substrukturen wurden 20
verschiedenen Ketten von unterschiedlicher Länge ausgewählt (Tabelle 7.1). Die Tests wurden
auf einer ”Intel(R) Pentium(R) 4 CPU 2.53 GHz” Maschine durchgeführt.
Bereits in (2.y) wurde erwähnt, daß FlexX zur Substruktursuche innerhalb kombinatorischer
Bibliotheken die Bibliotheksmoleküle eines nach dem anderen zusammensetzt und dann unter
diesen Molekülen - unabhängig voneinander - nach der gewünschten Struktur sucht. Bei
der Suche der hier verwendeten Substrukturen hat man festgestellt, daß die Suche für fast
alle Substrukturen konstant um 1 Stunde und 25 Minuten dauert. Die Suchzeit für dieselben
Substrukturen innerhalb der Datenbank dauert dagegen lediglich 14 Sekunden bis 2:25 Minuten.
Somit ist die Suche auf der Datenbank bei der Betrachtung der Laufzeit bis zu gut 300-mal
schneller. Die Ursache für diesen Unterschied kann man folgendermaßen darstellen: FlexX
braucht den größten Teil der Zeit dafür, alle Bibliotheksmoleküle der R-Gruppenfragmente
zusammenzusetzen. Die Suche innerhalb der Bibliotheksmoleküle verläuft für alle Substrukturen
gleich lang und mit akzeptabler Geschwindigkeit. In der Datenbank dagegen findet die Suche
nicht in allen Bibliotheksmolekülen statt, sondern in einer kompakten Menge von nur 2524
Bibliotheksfragmenten statt, daher ist der Suchraum wesentlich kleiner als in FlexX.
KAPITEL 7. EVALUIERUNG
70
Element
# atom in fragment
# atom pairs in
# atom pairs
C
O
N
S
Cl
P
19669
4517
4050
254
195
37
68806
6672
9002
657
195
146
71329
6672
11521
657
195
146
Tabelle 7.2: Häufigkeitsverteilung von Substruktur-Atomen innerhalb
atom in fragment und Sichten atom pairs in sowie atom pairs.
der
Tabelle
Wie weiter oben erwähnt, ist die Suchzeit innerhalb der Datenbank von einer Substruktur zu
anderer unterschiedlich. Es wurde festgestellt, daß die Suche bei denjenigen Substrukturen
schneller ist, deren erstes Atom-Elemente weniger häufig in der Bibliothek vorkommen als andere
Atom-Elemente (Tabelle 7.2). Zum Beispiel dauert die Suche bei der 7. Substruktur der Tabelle
(7.1) - angefangen vom C-Atom - 2:24 Minuten. Dieselbe Substruktur kann man nur dann
innerhalb von 23 Sekunden finden, hätte man die Suche vom anderen Ende, dem O-Atom der
Kette begonnen. Bei einigen Substrukturen ist dieser Unterscheid sogar noch wesentlich größer.
Ein solches Beispiel ist die 2. Substruktur der Tabelle (7.2). Für die Suche nach dieser Kette ausgehend von C - bräuchte man länger als 5 Minuten. Dieselbe Kette kann man um ein Faktor von mind. 20 schneller finden, wenn man die Suche aus dem anderen Ende der Kette beginnt.
Ein zweiter Faktor, die bei der Suchzeit eine entscheidende Rolle spielt ist die Häufigkeit einer
Atombindung im Suchraum (Tabelle 7.3). Als Beispiel werden wieder die 2. und 7. Substruktur
der Tabelle (7.1) betrachtet. Für die Suche nach N ausgehend von C in der Atombindung C-N
der 2. Substruktur wird mehr als 5-Minuten gebraucht (Die Suchzeit für die N=N Atombindung
ist im Vergleich zu C-N sehr gering). Bei der 7. Substruktur wird dagegen die Atombindung
C-O innerhalb von 2:24 Min. gefunden. Bei dem Vergleich der Häufigkeit beider Atombindungen
in der Tabelle (7.3) stellt man fest, daß die Atombindung C-N im Suchraum doppelt vorkommt
wie der Atombindung C-O (Spalte atom pairs).
Der Grund Für diese Laufzeitunterschiede wird über die Art und Weise der Suche innerhalb
der Datenbank ersichtlich. Im letzten Abschnitt dieses Kapitels wurde deutlich, daß die Suche
nach einer Substruktur mit der Suche nach Atomen innerhalb des Suchraumes beginnt, deren
Element dem ersten Element der Substruktur gleichen. Wurden solche Atome gefunden, wird
für jedes Ergebnis eine Liste reserviert. In den nächsten Suchschritten wird dann für jede Liste ausgehend vom letzten Element der Liste - die Suche fortgesetzt. Dabei wird für dieses Atom im
Suchraum nach allen nach allen seiner Nachbaratome gesucht. Es ist naheliegend festzustellen,
je kleiner die Menge der gefundenen Atome im ersten Suchschritt und je kleiner die Menge der
Nachbaratome, desto es weniger Listen zur weiteren Suche gibt es.
Ein weiterer, großer Vorteil des im Rahmen dieser Arbeit entwickelten Suchalgorithmus liegt in
der Art und Weise, wie die gefundenen Substrukturen repräsentiert werden. In FlexX hat man lediglich die Möglichkeit, diejenigen Bibliotheksmoleküle zurückzugeben, in denen die Substruktur
gefunden wurde. Informationen darüber, in welchen Fragmenten des jeweiligen Bibliotheksmolekül die Substruktur enthalten ist, sind nicht zugänglich. Ein Beispiel hier wäre der Fall, in dem
KAPITEL 7. EVALUIERUNG
Atombindung
O-C
C-O
O=C
C=O
C-N
N-C
C≡N
N≡C
C-S
S-C
C-C
C=C
N=N
O-S
S-O
O=S
S=O
S-N
N-S
Cl-C
C-Cl
O-P
P-O
O=P
P=O
P-C
C-P
# atombond in
fragment
1004
2049
0
1974
1263
3532
86
0
204
199
8850
325
8
0
8
0
155
21
39
0
195
6
61
0
36
11
31
71
# atombond between
fragments
0
0
0
0
2519
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
# atom pairs
3053
3053
1974
1974
7314
7314
86
86
403
403
17770
650
16
8
0
155
155
60
60
195
195
67
67
36
36
42
42
Tabelle 7.3: Häufigkeitsverteilung von Substruktur-Atombindungen innerhalb der Tabellen
atombond in fragment und atombond between fragments sowie der Sicht atom pairs.
eine Substruktur nur innerhalb des Core-Fragmentes gefunden wird. Da FlexX nicht erkennen
kann, in welchem Fragment des Bibliotheksmoleküls die Substruktur enthalten ist, werden alle Bibliotheksmoleküle als Ergebnis zurückgegeben, die das Core-Fragment enthalten, also die
gesamten Bibliotheksmoleküle. Dagegen werden die Resultate des Suchalgorithmus in der Datenbank in der results-Tabelle in getrennten Listen gespeichert. Diese enthalten die komplette
Information über den Pfad der jeweiligen Teillösung innerhalb der gesamten Bibliothek. Damit
kann man - ohne die Bibliotheksmoleküle komplett zu betrachten - sehr leicht erkennen, in welchen Fragmenten einzelner Moleküle die Substrukturen enthalten sind. Somit würden im obigen
Beispiel nur die Listen als Ergebnis zurückgeliefert, die den Pfad der gefundenen Substruktur
innerhalb des Core-Fragmentes beschreiben.
KAPITEL 7. EVALUIERUNG
72
Abbildung 7.6: Exemplarische Darstellung der Suche nach der Kette A-B-C. Das Ergebnis im
Dritten Schritt ist grau unterlegt.
Kapitel 8
Zusammenfassung und Aussichten
Im Rahmen der vorliegenden Arbeit wurde ein Datenbank-Schema für kombinatorische Bibliotheken in der Biochemie entwickelt, das eine kompakte Repräsentation dieser Bibliotheken
mit minimaler Redundanz ermöglicht. Eine Anwendung für die entwickelte Datenbank wurde
für die Suche nach spezifischen chemischen Substrukturen in Form von einfachen Ketten
innerhalb einer bestimmten kombinatorischen Bibliothek vorgestellt. Diese wurden mit Hilfe
eines (PL/)SQL-Programms realisiert. Die Effizienz der entwickelten Suchalgorithmen wurde
mit den Suchalgorithmen für Substrukturen im Tool FlexX verglichen.
Es gelang, die Ketten innerhalb einer kombinatorischen Bibliothek unter den Fragmenten und
über die Fragmentgrenzen hinweg zu suchen. Basis für die Evaluierung waren eine kombinatorische Bibliothek mit einer im Bereich Wirkstoffdesign typischen Größe und 20 ausgewählten
Substrukturen, die von Chemikern ausgewählt wurden.
Die erzielten Ergebnisse bei der Suche nach den Substrukturen belegen, daß diese Suche in
den meisten Fällen in der Datenbank sehr viel schneller als in FlexX abläuft. Es wurde jedoch
ebenfalls deutlich, daß die Suchzeit - abhängig von der Substruktur - unterschiedlich ist. Dabei
wurde festgestellt, daß diese Laufzeitunterschiede von der Häufigkeit der gesuchten Substruktur
in der Bibliothek abhängt. In einigen Fällen konnte beobachtet werden, daß die Suche nach
derselben Kette sehr viel schneller werden kann, wenn man von dem Ende der Kette zu suchen
beginnt, dessen Atom weniger häufig in der Bibliothek vorkommt. Derartige Atomstatistiken
können daher für eine effizientere Suche genutzt werden.
Eine weitere Effizienzsteigerung kann mit Hilfe von Indexierungen erreicht werden. Dabei
können häufig benutzten Datensätze, wie zum Beispiel Atom-Daten mit Zusatzinformationen
gespeichert werden, mit deren Hilfe die Suche erheblich schneller werden kann.
Die Suche nach Ringsysteme kann mit einer leichten Modifikation auf die Suche nach einfachen
Ketten zurückgeführt werden. Dazu muß in der Subgraph-Tabelle das letzte Atom der Kette
ebenfalls als Anfangsatom abgelegt werden. Somit ist gewährleisten, daß die Anfangs- und
Endknoten der Substruktur gleich sind. Die Suche nach den Ringsystemen kann ebenfalls
durch eine Art Indexierung beschleunigt werden. Dazu kann man in einem preprocessing alle
Ringsysteme einer kombinatorischen Bibliothek absuchen und sie in Form einer Tabelle physisch
ablegen. Dann kann für die weitere Suche - anstatt jedes Mal die Ringe innerhalb der Bibliothek
73
KAPITEL 8. ZUSAMMENFASSUNG UND AUSSICHTEN
74
zu durchsuchen - auf die soeben definierte Tabelle zugegriffen werden. Eine weitere Möglichkeit
bietet das Modul FlexXC über seine Datenstruktur ringsystem, in der die Informationen über
die Ringsysteme der kombinatorischen Bibliothek enthalten sind. Diese kann man nutzen, um
die o.g. Tabelle mit den jeweiligen Informationen zu füllen.
Für die Suche nach allgemeinen Substrukturen, die aus der Kombination von einfachen Ketten
und Ringsystemen entstehen, müssen sie zuerst in geeignter Weise in der Datenbank repräsentiert
werden. Eine Lösungsmöglichkeit bietet sich durch die Nested Tables in PL/SQL ([OrP02]).
Damit ist es möglich, die Zeilen der Nested Tables als eindimensionale Arrays zu definieren,
deren Länge dynamisch wachsen kann. Somit läßt sich für jedes Atom der Substruktur eine
Adjazenzliste in einer Zeile dieser Tabellen ablegen. Die Suchalgorithmen können dann mit Hilfe
von PL/SQL Konstrukten realisiert werden.
Literaturverzeichnis
[Alb90]
B. Alberts. Molekularbiologie der Zelle. VCH, Basel;Cambridge;New York, 2. Auflage,
1990.
[A.S02]
S.Sudarshan A.Silberschatz, H.Korth. Database System Concepts. Mc Graw Hill, New
York, 7th ed., 2002.
[BK97]
Ulrich Epperlein Bernhard Koppenhoefer. Chemie und Informatik. Shaker Verlag,
Aachen, 1997.
[Blu01]
Norbert Blum. Theoretische Informatik: eine anwendungsprientierte Einführung. Oldenburg, München; Wien: Oldenburg, 2. überarb. Auflage, 2001.
[Cla01]
Holger Claußen. Effizientes Protein-Ligand-Docking mit flexiblen Proteinstrukturen,
disseration, rheinische friedrich-wilhelms-universität bonn, 2001.
[Cla04]
Holger Claußen. persönliche mitteilung, 2004.
[Gas03]
Johann Gasteiger. Handbook of Chemoinformatics. WILEY-VCH Verlag GmbH, Weinheim, 2003.
[G.K96] M. Rarey B. Kramer T. Lengauer G.Klebe. A fast flexible docking method using an
incremental construction algorithm, j. mol. biol., 261(3):470-489, 1996.
[H.J96]
H.Kubinyi H.J.Böhm, G.Klebe. Wirkstoffdesign. Spektrum Akademischer Verlag
GmbH, Heidelberg.Berlin.Oxford, 1996.
[Kyt01]
Thomas Kyte. Expert One-on-One Oracle. Wrox Press, Birmingham, UK, 2001.
[MA02]
Alex Martelli and David Ascher. Python Cookbook. O’Reilly, Sebastopol, USA, 2002.
[Man]
Rainer Manthey. Vorlesung Informatiossysteme, ws 03/04 , institut für informatik iii,
rheinische friedrich-wilhelms-universität bonn.
[Mar03] Alex Martelli. Python in a Nutshell. O’Reilly, Sebastopol, USA, 2003.
[McC96] David McClanahan. Oracle Developer’s Guide. McGraw-Hill, Berkley, USA, 1996.
[Mel03a] Jim Melton. Advanced SQL:1999. Morgan Kaufmann Publishers, San Francisco, CA
94104-3205, 2003.
[Mel03b] Jim Melton. SQL:1999. Morgan Kaufmann Publishers, San Francisco, CA 94104-3205,
2003.
75
LITERATURVERZEICHNIS
[MR00]
76
Thomas Lengauer Mathias Rarey. A recursive algorithm for efficient combinatorial
library docking, perspectives in drug discovery and design 20, 63?81, 2000.
[OrA02] Oracle9i application developer’s guide-fundamentals, release 2 (9.2), 2002.
[OrC02] Oracle9i data cartridge developer’s guide, release 2 (9.2), 2002.
[OrP02] Pl/sql user’s guide and reference, release 2 (9.2), 2002.
[OrS01a] Oracle9i sql reference, release 1 (9.0.1), 2001.
[OrS01b] Sql*plus user’s guide and reference, release 9.0.1, 2001.
[PK94]
Jan Koolman Peter Karlson, Detlef Doenecke. Kurzes Lehrbuch der Biochemie für
Mediziner und Naturwissenschaftler. Georg Thieme Veralg, Stuttgart.New York, 14.
Auflage, 1994.
[Rar01]
Mathias Rarey. Algorithmen für den computergestützten Wirkstoffentwurf, habilitationsschrift , gmd-forschungszentrum informationstechnik gmbh, 2001.
[SD02]
Thomay Kyte Sean Dillon, Christopher Beck. Beginning Oracle Programming. Wrox
Press, Birmingham, UK, 2002.
[Sed91]
Robert Sedgewick. Algorithmen. Addison-Wesley Verlag, Bonn;München, 1. Nachdruck, 1991.
[THC99] Ronal L. Rivest Thomas H. Cormen, Charles E. Leiserson. Introduntion to Algorithms.
The MIT Press, Cambridge, Massachusetts, 1999.
[Tri99]
SLN Manual, tripos inc. http://www.tripos.com, 1999.
[uA01]
A. Kemper und A.Eickler. Datenbanksysteme: eine Einführung. Oldenburg, München;
Wien: Oldenburg, 4. überarb. und erw. Auflage, 2001.
[Ull76]
J. R. Ullmann. An Algorithm for Sungraph Isomorphismus, journal of the association
for computer machinery, vol.23:31-43, 1976.
[Vos00]
Gottfried Vossen. Datenmodelle, Datenbanksprachen und Datenbankmanagementsysteme. Oldenburg, München; Wien: Oldenburg, 4. korrigierte und erg. Auflage, 2000.
[Zop]
http://www.zope.org/members/matt/dco2.
LITERATURVERZEICHNIS
77
Hiermit versichere ich, daß ich meine Diplomarbeit selbständig durchgeführt und keine anderen
als die angegebenen Quellen und Hilfsmittel benutzt sowie Zitate kenntlich gemacht habe.
Bonn, den 20.09.2004
Herunterladen