SASHERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken

Entwurf und Implementierung eines Prototyps

DIPLOMARBEIT zur Erlangung des akademischen Grades eines Magisters der Sozial- und Wirtschaftswissenschaften im Diplomstudium Wirtschaftinformatik

eingereicht von Georg Lengenfelder

Angefertigt am Institut für anwendungsorientierte Wissensverarbeitung Abteilung für Datenbanken und Expertensysteme Betreuung und Beurteilung: a. Univ.-Prof. Dr. Josef Küng

August 2015 Eidesstattliche Erklärung

Ich erkläre an Eides statt, dass ich die vorliegende Diplomarbeit selbständig und ohne fremde Hilfe verfasst, andere als die angegebenen Quellen und Hilfsmittel nicht benützt bzw. die wörtlich oder sinngemäß entnommenen Stellen als solche kenntlich gemacht habe. Die vorliegende Diplomarbeit ist mit dem elektronisch übermittelten Textdoku- ment identisch.

Georg Lengenfelder Wien, August 2015 Widmung

Diese Arbeit ist meinen Eltern Heribert und Helga Lengenfelder gewidmet, die mich während all der verschieden intensiven Phase meines Wirtschaftsinfor- matik-Studiums auf vielfältige Weise unterstützt haben.

Danksagung

Prof. Josef Küng, vom Institut für Anwendungsorientierte Wissensverarbeitung an der JKU Linz danke ich für den Themenimpuls zu dieser Arbeit, die Freiheiten bei der Gestaltung des Prototyps, sein scharfsinniges Feedback dazu; nicht zuletzt auch noch für die Anleitung bei der Erstellung dieser wissenschaftlichen Arbeit und sein Entgegenkommen bezüglich des zeitlichen Verlaufs der Fertigstellung. Horst Trixl, technischer Mitarbeiter an der TU-Wien danke ich für Einrich- tung und zur Verfügungsstellung eines Diplomanden-Arbeitsplatzes, an dem ein Teil des Prototyps entstanden ist. Christiane Gschirr, meiner wundervollen Partnerin danke ich sehr herzlich für die Unterstützung in der Endphase meines Studiums und für die Ermutigung zur Bildungskarenz um diese Arbeit und das Studium (doch noch) abzuschließen. Paul und Clemens Lengenfelder, meinen Brüdern danke ich von ganzem Herzen für Alles, was wir gemeinsam unternommen und erlebt habt – die Kinder- und Jugendjahre und meine frühe Studentenzeit in Linz. Zudem noch ein kleines Extra Dankeschön für Pauls Ratschläge und Ermunterungen, was die Arbeitsweise zur Erstellung dieser Arbeit betrifft. Wolfram Weineck und Christian Topf meinen langjährigen Freunden danke ich für die schöne, gemeinsame Studentenzeit in Linz und deren nachdrückliche Aufforderungen das Studium ordentlich abzuschließen. Nina Mühlberger, meiner langjährigen Freundin, danke ich für die gemein- same Zeit und die Unterstützung nach der Übersiedlung nach Wien.

0 Abstract

Since the success of WWW-search engines like Google, Yahoo! and others, key- word-based search became a very popular form of human-computer-interaction. A user enters some keywords of interest, and (s)he gets some web-pages that sat- isfies his/her need for information. The contents of billions of webpages already are accessible by this easy way of interaction. In contrast to this, to retrieve data, that is stored in relational databases, users must be familiar with the use of a query language like SQL and the structure of the database itself. HCI-studies came to the conclusion that SQL is powerful but not appropriate for casual-users. To overcome this problem, many different approaches and systems have emerged over the last decades, like user-interfaces that are based on forms, examples, natural language or graphical representation. In recent years a couple of ap- proaches that translate keywords into SQL added to that list. In this paper, frist I’ll outline some of the approaches and prototype-systems that provide keyword-based querying of relational database systems. Second I’ll present a prototype-system called “SASHERD” (A simple ad-hoc for relational databases), and its development. Therefore, this diploma-thesis is composed of two sections. The first section (chapters 1-3) is structured as follows: Chapter 1 gives an introduction including the goals of this diploma thesis. In chapter 2 technical foundations are intro- duced: relational database systems and search engines. Chapter 3 starts with an outline of alternatives to SQL, followed by a survey of other prototype-systems that have been studied in related work. In the second section the development of the prototype-system is described. Chapter 4 contains the specification and the testing-environment including some test-cases. The architecture, design and algorithms used, are described in detail in chapter 5. Chapter 6 gives a brief insight in the components and Java classed used for implementation. In chapter 7, the use of SASHERD is demonstrated using the testcases from the specification. Finally a summary and some useful extensions make up chapter 8.

SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken I 0 Inhaltsverzeichnis

0 Abstract ...... I 0 Inhaltsverzeichnis ...... II 0 Abbildungsverzeichnis ...... IV 1 Einleitung...... 1 1.1 Motivation, Problemstellung 1 1.2 Ziele der Arbeit 2 1.3 Gliederung der Arbeit 3 2 Technische Grundlagen...... 5 2.1 Relationale Datenbanksysteme 5 2.1.1 Grundbegriffe 5 2.1.2 Relationale Datenbanksysteme 8 2.1.3 Relationale Algebra und SQL 9 2.2 Suchmaschinen 12 2.2.1 Information Retrieval 12 2.2.2 Internet-Suchmaschinen 16 3 Begriffsbasierte Suche in relationalen Datenbanken ...... 27 3.1 Datenabfragen mit SQL: Defizite und alternative Ansätze 27 3.1.1 Assistenten und Formulierungshilfen 29 3.1.2 Abfragemasken 30 3.1.3 Systeme zur visuellen Datenabfrage 32 3.1.4 Natürlich-sprachliche Benutzerschnittstellen 36 3.1.5 Unscharfe Abfragen 40 3.1.6 Begriffsbasierte Abfragen 42 3.2 Ansätze zur begriffsbasierten Suche in relationalen Datenbanken 48 4 Spezifikation ...... 57 4.1 Basisanforderungen 57 4.2 Zusätzliche Anforderungen 58 4.3 Rahmenbedingungen 59 4.4 Testumgebung 59 4.4.1 Testdatenbank 59 4.4.2 Testfälle 60 5 Entwurf...... 64 5.1 Allgemeiner Lösungsansatz 64 5.1.1 Systemkomponenten 65 5.2 Lösungsalternativen zum Suchmodul 66 5.2.1 Lösungsalternative A: Wort-Index + Views + Datensatz-Ids 67

II SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 5.2.2 Lösungsalternative B: Wort-Index + Views + Zugriffspfade 72 5.2.3 Lösungsalternative C: Ad-hoc Suche + Joins + Zugriffspfade 75 5.3 Entwurfsentscheidung 83 5.4 Problembereiche und Erweiterungen 84 5.4.1 ad Suchmodul: ad-hoc Suche 85 5.4.2 ad Suchmodul: Bildung der SQL-Anfragen 102 5.4.3 ad Suchmodul: Schnittstelle 122 5.4.4 ad Ergebnispräsentation 125 5.4.5 Interne Datenstrukturen 129 6 Implementierung...... 133 6.1 Systemarchitektur 133 6.2 Hauptkomponenten 134 6.2.1 Benutzerschnittstelle 134 6.2.2 AdHocDBSearchEngine 138 6.2.3 DataDictionary 138 6.2.4 ViewBuilder 139 6.3 Hilfsklassen 139 6.3.1 DBAccessPath 139 6.3.2 HitDBAccessPath 139 6.3.3 SearchResult 140 6.3.4 DBResultView 140 6.3.5 ERGraph 141 6.3.6 ListUtils 141 6.4 Entwicklungsumgebung 142 7 Proof-of-Concept ...... 143 7.1 Start von SAHSERD 143 7.2 Testfälle 143 7.2.1 Einfache Anfragen mit einem Suchbegriff 144 7.2.2 Einfache Abfragen mit mehreren Suchbegriffen 146 7.2.3 Komplexe Abfragen 148 8 Schlussbetrachtung ...... 155 8.1 Zusammenfassung 155 8.1.1 Untersuchungsbereich 155 8.1.2 Prototyp SAHSERD 156 8.2 Ausblick 157 8.2.1 Erweiterungsmöglichkeiten für SAHSERD 157 0 Literaturverzeichnis ...... 159 0 Anhang ...... 164 Anhang A: Testdatenbank UniLinz 164 Anhang B: SAHSERD Datenstrukturen 185

SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken III 0 Abbildungsverzeichnis

Abbildung 1: Komponenten eines DBMS (übernommen aus [Ullm08]) ...... 7 Abbildung 2: Tabellendarstellung einer Relation und ihre Elemente mit Beispiel...... 8 Abbildung 3: Architektur eines IR-Systems...... 13 Abbildung 4: Term-document Incidence Matrix ...... 14 Abbildung 5: Dokument- und Abfragevektoren im Vektorraum...... 15 Abbildung 6: Schematische Architektur einer (WWW-)Suchmaschine ...... 23 Abbildung 7: Autovervollständigung im SQL Editor von SQuirreL ...... 29 Abbildung 8: Assistenten zur Abfrageerstellung aus SAS SQL Query Window ...... 30 Abbildung 9: Beispiel für ein Suchformular der Bibliothek der JKU Linz ...... 30 Abbildung 10: Einfaches QBE-Beispiel: Alle Studenten mit Geburtsort Linz, die vor 1985 geboren sollen angezeigt werden. (P. steht für das Kommando „print“)...... 31 Abbildung 11: QBE-Abfrage mit Verknüpfung mehreren Tabellen: Titel, Semester und Note aller LVAs, welche die Studentin „Julia Jobst“ besucht, hat sollen angezeigt werden...... 31 Abbildung 12: Abfragebeispiel aus QBD* (aus [Cata97]): Eine Verknüpfung (Bridge) zwischen Person und State (links) wurde hergestellt. Rechts ist der Editor zum Bearbeiten der Bedingung („Person.Name = State.S_Name“) dargestellt...... 34 Abbildung 13: Komposition aus Teilabfragen: Im IconicBrowser durch überlappende Icons dargestellt (aus [Cata97]) ...... 34 Abbildung 14: Abfragen via Suchmuster: Ein Beispiel aus dem System G+/GraphLog. Die Ergebnisse können auf verschiedene Art angezeigt werden (aus [Cons92])...... 35 Abbildung 15: Abfrage mittels Von-Bis Intervallen: Ein Beispiel aus Dynamic Query, wo Schiebereglern zur Direkten Manipulation von Abfrageparametern dienen...... 36 Abbildung 16: Beispiel für eine NLI-Sitzung (übernommen aus [Andr00])...... 36 Abbildung 17: Die typische Architektur eines NLDBI-Systems (aus [Andr00]) ...... 38 Abbildung 18: Beispiel einer Similarity Relation (aus [Küng97]) ...... 40 Abbildung 19: Beispiel einer NCR-Tabelle (angelegt an [Küng97])...... 41 Abbildung 20: Formale Definition der Abfrage (aus [Schr01]) ...... 44 Abbildung 21: „Phrasen Suche“ mit zwei Beispielabfragen (aus [Schr01])...... 45 Abbildung 22: Beispiel zu einer Metadatenabfrage im System „ASK“ (aus [Thom83])...... 46 Abbildung 23: Konzeptionelles Schema der Testdatenbank "UniLinz" ...... 60 Abbildung 24: Testfälle für einfache Anfragen mit einem Suchbegriff ...... 61 Abbildung 25: Testfälle für einfache Anfragen mit mehreren Suchbegriffen...... 62 Abbildung 26: Testfälle für komplexe Suchanfragen ...... 63

IV SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 27: Systemarchitektur einer Suchmaschine für relationale Datenbanken (schematische Darstellung)...... 65 Abbildung 28: Wort-Index mit Datensatz-IDs...... 69 Abbildung 29: Wort-Index mit Zugriffspfaden ...... 73 Abbildung 30: Vereinfachter ER-Graph für die Datenbank "UniLinz"...... 78 Abbildung 31: Ein abstrakter ER-Graph zur Demonstration ...... 80 Abbildung 32: Kürzeste Verbindung zwischen Knoten "A" und "H" ...... 81 Abbildung 33: Minimale Join-Bäume zwischen den Knoten "B", "G", und "F"...... 82 Abbildung 34: Entscheidungstabelle zur Bildung einer Abfragebedingung ...... 94 Abbildung 35: Ergebnisse der ad-hoc Suche je nach Suchschärfe...... 101 Abbildung 36: Um „Institutsvorstand“ erweiterter ER-Graph von UniLinz ...... 114 Abbildung 37: Vereinfachtes ER-Diagramm ...... 116 Abbildung 38: Ausschnitt aus dem Suchmaschinen-internen Data-Dictionary ...... 131 Abbildung 39: Ausschnitt aus dem Suchmaschinen-internen Alias-Verzeichnis...... 132 Abbildung 40: Erweiterte schematische Architektur des Prototyps...... 133 Abbildung 41: Vereinfachtes Klassendiagramm für SAHSERD...... 134 Abbildung 42: Web-basierte Benutzerschnittstelle von SAHSERD ...... 135 Abbildung 43: Kommandozeilen-basierte Benutzerschnittstelle von SAHSERD ...... 137 Abbildung 44: Ergebnis der Suchanfrage „0056410“ ...... 144 Abbildung 45: Ergebnis der Suchanfrage „0056410“ mit erweiterten Suchoptionen ...... 144 Abbildung 46: Ergebnis der Suchanfrage „Informationssysteme“...... 145 Abbildung 47: Ergebnis der Suchanfrage „Informationssysteme“ mit erw. Suchoptionen 146 Abbildung 48: Ergebnis der Suchanfrage „Durchwahl“, „Wagner“ ...... 146 Abbildung 49: Ergebnis der Suchanfrage „Küng“, „9856588“ ...... 147 Abbildung 50: Ergebnis der Suchanfrage „9856588“, „9956627“, „0055880“ ...... 147 Abbildung 51: Ergebnis der Suchanfrage „9856588“, „9956627“, „0055880“ mit erweiterten Suchoptionen...... 148 Abbildung 52: Ergebnis der Suchanfrage „Informatik“ ...... 149 Abbildung 53: Ergebnis der Suchanfrage „Informatik“ mit erw. Suchoptionen ...... 149 Abbildung 54: Ergebnis der Suchanfrage „Informatik“ bei unscharfer Suche ...... 150 Abbildung 55: Ergebnis der Suchanfrage „Informatik“ bei unscharfer Suche und erweiterten Suchoptionen ...... 151 Abbildung 56: Ergebnis der Suchanfrage „LVAs“, „Heinrich“ ...... 152 Abbildung 57: Ergebnis der Suchanfrage „LVAs“, „Heinrich“ mit erw. Suchoptionen...... 153 Abbildung 58: Ergebnis der Suchanfrage „LVAs“, „Berger“ ...... 153 Abbildung 59: Ergebnis der Suchanfrage „LVAs“, „Berger“ bei unscharfer Suche ...... 154

SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken V

KAPITEL 1

1 Einleitung

1.1 Motivation, Problemstellung

Zur performanten Verwaltung von strukturierten Daten, als abstrahierte Abbil- dung eines Ausschnitts der realen Welt, haben sich in der Praxis relationale Da- tenbanken sehr bewährt. Relationale Datenbanksysteme (RDBS) gehören nun- mehr seit Jahrzehnten zu den Basistechnologien für die Datenhaltungsschicht der meisten Informationssysteme. Dementsprechend sind bereits unzählige Daten in RDBS gespeichert und täglich kommen große Mengen hinzu. Zu den elementaren Funktionen jedes Datenbanksystems gehören das (per- sistente) Speichern (storage) und das Wiederauffinden (retrieval) von Informatio- nen/Daten andererseits. Zur Abfrage und Datenmanipulation bieten RDBS die formale Sprache SQL (Structured Query Language), die stark an die relationale Al- gebra angelehnt ist. Um ein RDBS mit SQL abzufragen, sind einerseits Kenntnisse über die SQL-Sprachbefehle selbst (Syntax) und über das der Datenbank zugrun- deliegende Datenmodell, das in der Regel komplex ist, nötig. Für Endbenutzer ist SQL als Benutzerschnittstelle zur (Wieder-)Auffindung von Daten in einer relationalen Datenbank aus folgenden Gründen ungeeignet:

¾ Mangelhafte Kenntnis des zugrundeliegenden relationalen Datenmodells

¾ Datenbankschema ist (großteils) unbekannt

¾ Kein Verständnis für Datentypen und deren Besonderheiten

¾ Oft nur Grundkenntnisse über die Syntax des SQL-Select-Befehls

¾ Ungeübtheit in der Verwendung von booleschen Operatoren (NOT, AND, OR) und Klammersetzung

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 1 Daraus entstehen einerseits syntaktisch falsche Abfragen, die zur Frustration des Endbenutzers führen und andererseits semantisch falsche Abfragen, die zu schließlich zu falschen Annahmen über die gespeicherten Daten führen.

Dies hat zur Folge, dass an alternativen Benutzerschnittstellen zur Abfrage von re- lationalen Datenbanken geforscht wird. Exemplarisch seien hier die Richtungen: Query-By-Example, fehlertolerante SQL-Erweiterungen und Dialekte, grafische Abfragewerkzeuge, begriffsbasierte Suche und natürlichsprachliche Anfragen ge- nannt. Dazu kommt, dass Endbenutzer durch die Informationssuche im World Wide Web (WWW) mittels Suchmaschinen mit begriffsbasierten Benutzerschnittstellen mittlerweile gut vertraut sind1. Eine äquivalente Suche nach Begriffen ist in relati- onalen Datenbanksystemen nicht möglich da in SQL keine entsprechenden Sprachkonstrukte vorgesehen sind. D.h. Abfragen wie „Wagner“ (im Sinne „Was ist alles zu ‚Wagner’ gespeichert?“) sind nicht möglich, oder nur mit großem Auf- wand und Expertenwissen über die RDB. Noch schwieriger gestaltetet sich eine Suchabfrage die mehrere Schlüsselworte beinhaltet, beispielsweise: „Wagner“ „In- stitut“ „Telefonnummer“.

1.2 Ziele der Arbeit

Zunächst sollen in dieser Arbeit die (technischen) Grundlagen für begriffsbasierte Suche in relationalen Datenbanken untersucht werden. Auf deren Basis ist das Hauptziel dieser Arbeit der Entwurf und die Implementierung eines einfachen, web-basierten funktionstüchtigen Prototypen der begriffsbasierte Suche in relati- onalen Datenbanken ermöglicht. Dabei soll im Speziellen die Charakteristik des relationalen Modells berück- sichtigt werden: das Entitäten als „normalisierte“ Daten auf Tabellen verteilt ge- speichert sind. Der Prototyp soll sowohl Suchanfragen mit einem einzigen Such- begriff als auch solche mit zwei oder mehreren Suchbegriffen beantworten kön- nen.

1 Im Sprachgebrauch hat sich für die Informationssuche im WWW mittlerweile die Phrase „etwas googlen“ eingebürgert.

2 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 1.3 Gliederung der Arbeit

Im Teil 1 dieser Arbeit, dem Untersuchungsbereich beleuchte ich in Kapitel 2 Technische Grundlagen: Relationale Datenbanken und Suchmaschinen. Kapitel 3 befasst sich mit vorangegangenen Forschungsarbeiten im Bereich begriffsbasier- ter Suche in relationalen Datenbanken. Schwerpunkt dieser Arbeit ist der Gestaltungsbereich im Teil 2. In den Kapi- teln 4-6 schreibe ich über die Spezifikation, den Entwurf und die Implementie- rung des Prototypen SAHSERD. Im Kapitel 7, dem Proof-of-Concept werden dann exemplarisch einige Testfälle dokumentiert. Schließlich folgt in Kapitel 8 die Schlussbetrachtung mit der Zusammenfassung und einem Ausblick.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 3 Teil 1

Untersuchungs- bereich

4 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken KAPITEL 2

2 Technische Grundlagen

In diesem Kapitel werden kurz die wichtigsten technischen Grundlagen für den zweiten Teil dieser Arbeit behandelt: Relationale Datenbanksysteme, SQL sowie Suchmaschinen und ihre Vorläufer.

2.1 Relationale Datenbanksysteme

Datenbanksysteme, insbesondere relationale gehören zu den Kernthemen der In- formatik. Sie wurden in den letzten Jahrzehnten sehr ausführlich erforscht. An dieser Stelle beschränke ich mich daher auf eine kurze Einführung. Für detaillier- te Informationen möchte ich auf die umfangreiche Literatur zum Thema Daten- banksysteme verweisen, stellvertretend seien hier folgende Lehrbücher genannt: [Ullm08], [Garc08], [Elma11] und [Voss08].

2.1.1 Grundbegriffe

Im Allgemeinen versteht man unter einer Datenbank eine elektronisch organi- sierte Datensammlung zu einem thematisch/organisatorisch umgrenzten Gebiet, die für eine längere Zeit (bis zu mehreren Jahren) besteht. Im engeren Sinn ist ei- ne Datenbank nur der Datenbestand der von einem Datenbankmanagementsys- tem (DBMS) verwaltet wird. Eine Datenbank dient dazu, beliebige Objekte der realen (oder konstruierten) Welt (z.B.: Personen, Gegenstände, abstrakte/geistige Produkte, Vorgänge etc.) zu Verwaltungs- und/oder Informationszwecken abzubilden. Vor allem dann, wenn es sich um in großer Zahl auftretende oder häufig wiederkehrende Einheiten glei- cher bzw. zusammengehörender Objekte handelt. Zur Erfassung dieser Objekte in einer konsistenten Weise, müssen eindeutige Eigenschaften bestimmt werden, die

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 5 die Objekte entsprechend des Verwendungszwecks charakterisieren. Gleichartige oder zusammengehörende Objekte bilden eine Objektklasse (z.B.: Zeugnisse, Ge- bäude, Bauteile, sozialversicherte Personen etc.). In einer Datenbank können die Objekte und ihre Beziehungen nach einem zugrundeliegenden Datenmodell ab- gebildet werden. Ein Datenbankmanagementsystem (DBMS) ist ein mächtiges, hochspeziali- siertes Softwareprodukt zur Verwaltung einer oder mehrerer Datenbanken, wel- ches gegenüber traditionellen Dateisystemen durch die logische und physische Datenunabhängigkeit folgende Vorteile bietet1:

¾ Benutzer können neue Datenbanken erstellen und mittels einer speziellen Notation, der Data-definition Language (DDL) die logische Struktur der Da- ten (sogenannte Schemas) definieren.

¾ Benutzer können die Daten abfragen (Queries erstellen) und modifizieren. Dazu stellt das DBMS eine Abfragesprache bzw. Data-manipulation Language (DML) zur Verfügung.

¾ Unterstützung der Speicherung/Verwaltung von sehr großen Datenmengen (einige Terabytes und mehr) über eine lange Zeit und effizienten Möglichkei- ten des Zugriffs auf die bzw. Änderung der Daten.

¾ Möglichkeit zur Wiederherstellung der Datenbank(en) im Falle eines Ausfalles bzw. Fehlers (aus verschiedensten Gründen) oder beabsichtigten Missbrauch.

¾ Mehrere Benutzer können gleichzeitig auf die Daten zugreifen ohne sich ge- genseitig unerwartet zu beeinflussen (Isolation) und ohne das Aktionen auf den Daten nur teilweise (nicht vollständig) ausgeführt werden (Atomität). Folgende Abbildung soll einen Überblick über die Komponenten eines DBMS ge- ben und deren (komplexe) Zusammenhänge aufzeigen:

1 Diese Liste basiert auf [Ullm08] „1.1 The Evolution of Database Systems“ Seite 1f.

6 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 1: Komponenten eines DBMS (übernommen aus [Ullm08])

Zusammen bilden Datenbank und DBMS ein Datenbanksystem. Die Art und Wei- se, wie ein solches System Daten speichert und verwaltet, wird durch das Daten- bankmodell festgelegt. Nach dem Datenmodell2 werden die Datenbanksysteme unterschieden in:

2 Ein Datenmodell kann als logische Organisation von Objekten, die für eine bestimmte Anwendung von Interesse sind (Entitäten), inklusive der Spezifikation deren Eigenschaften und der Beziehun- gen zwischen den Objekten und Regeln für diese Beziehungen (Constraints) definiert werden.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 7 a) das hierarchische Modell, basierend auf Baum-artigen Datenstrukturen; b) das Netzwerk Modell, basierend auf der Organisation der Daten mit Graphen c) das relationale Datenmodell, das auf der Mengen-orientierten Datenorgani- sation basiert. Wobei seit einigen Jahren eigentlich nur mehr relationale DBS (und Erweiterun- gen davon) relevant sind.

2.1.2 Relationale Datenbanksysteme

Codd hat 1970 das relationale Modell vorgestellt [Codd70], bei dem die Objekte der realen Welt als (zwei-dimensionale) Tabellen, sogenannte Relationen abgebil- det werden. Die tatsächliche Abbildung der Relationen auf physische Speicher- strukturen bleibt dabei letztlich Sache des DBMS. Der Benutzer kann unabhängig davon mit der relationalen Algebra auf bzw. mit den Relationen arbeiten.

Abbildung 2: Tabellendarstellung einer Relation und ihre Elemente mit Beispiel

Wie in obiger Abbildung dargestellt, werden die Tabellenzeilen „Tupel“ genannt und repräsentieren jeweils eine konkrete Instanz der entsprechenden Entität oder Beziehung. Die Tabellenspalten stellen die „Attribute“ (Eigenschaften oder Merk- male) einer Relation dar. Die Attribute der Relation „Student“ sind beispielsweise „Matrikelnummer“, „Vorname“, „Nachname“. Die einzelnen Tabellenzellen wer- den als „Attributwerte“ bezeichnet. Die Menge aller möglichen Attributwerte die in einer bestimmten Spalte vorkommen können werden als „Domäne“ bzw. Wer- tebereich eines Attributs bezeichnet. Der Wertebereich des Attributs „Schulnote“ würde beispielsweise die Zahlen {1, 2, 3, 4, 5} umfassen. In der Regel enthält ein Relationenschema mehrere Relationen. Die Objekte der realen Welt (z.B.: z.B.: Studenten, Lehrveranstaltungen, Lektoren etc.) und ihre Beziehungen (Inskription, LVA-Zeugnis etc.) werden nach gewissen Regeln in Re- lationen überführt. Die angesprochenen Regeln sorgen dafür, dass das entste- hende Relationenschema bestimmten Normalformen genügt. Zur Vereinfachung

8 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken dieser (semantischen) Datenmodellierung hat P. Chen [Chen76] das sogenannte „Entity-Relationship-Modell“ eingeführt. Dabei werden die in einem sogenannten E-R-Diagramm alle Entitäten und ihre Beziehungen (Relationship) abgebildet und dann schrittweise in ein relationales Datenmodell überführt.

2.1.3 Relationale Algebra und SQL

Die relationale Algebra (basierend auf der Mengenlehre) kennt folgende Operati- onen3: Selektion, Projektion, Vereinigung (Join). Zur einfacheren Darstellung ver- wende ich im Folgenden die Tabellenform statt der mathematisch-relationalen Schreibweise. Als Beispiel sollen die Relationen Lektor und Lehrveranstaltung dienen:

Lektor Lehrveranstaltung Personalnr Vorname Nachname Wohnort Titel ECTS- Personalnr Credits 4892 Hans Huber Linz Informationssysteme I 4 3911 2055 Gina Gruber Gmunden Makroökonomie 2,5 2764 3911 Ingo Innkreuz Linz Grundlagen der BWL 4 2055 2764 Julia Jobst Wels

Mit einer Selektions-Operation werden alle Zeilen aus einer Tabelle ausgewählt, die einer bestimmten Bedingung genügen, beispielsweise alle Lektoren mit dem Wohnort = Linz:

Lektor (Wohnort=Linz) Personalnr Vorname Nachname Wohnort 4892 Hans Huber Linz 3911 Ingo Innkreuz Linz

Mit einer Projektions-Operation werden bestimmte Spalten einer Tabelle ausge- wählt, beispielsweise LVATitel und ECTS-Credits aus der Relation Lehrveranstal- tung:

Lehrveranstaltung (Titel, ECTS-Credits) Titel ECTS- Credits

3 Die relationale Algebra hatt überdies noch die Operatoren: Schnittmenge (intersection), Differenz (minus), Verbund (union) und Division (quotient). In der Praxis werden aber hauptsächlich (und in dieser Arbeit ausschließlich) Selektion, Projektion und Join verwendet.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 9 Informationssysteme I 4 Makroökonomie 2,5 Grundlagen der BWL 4

Mit einer Join (Vereinigungs)-Operation können zwei Relationen zu einer neuen Relation vereinigt werden. Grundsätzlich können folgende Join-Varianten unter- schieden werden: Cross Join (Kartesisches Produkt), Inner Join (=Equi(valent) Join), Theta Join (=Non-Equivalent-Join), Left/Right/Full Outer Join, Union Join und Self-Join4. Als Beispiel wird der Inner Join von Lektor und Lehrveranstaltung dargestellt. Wie ersichtlich werden die Zeilen deren PersonalNr übereinstimmt vereint, nicht passende Zeilen der Relationen (hier Lektor „Huber“) werden beim Inner Join im Ergebnis nicht berücksichtigt:

Inner Join(Lektor, Lehrveranstaltung) Personalnr Vorname Nachname Wohnort Titel ECTS- Personalnr Credits 2055 Gina Gruber Gmunden Grundlagen der BWL 4 2055 3911 Ingo Innkreuz Linz Informationssysteme I 4 3911 2764 Julia Jobst Wels Makroökonomie 2,5 2764

SQL (als Abfragesprache)

SQL ist eine Datenbanksprache mit deren Hilfe ein Benutzer oder ein Anwen- dungsprogramm mit dem Datenbanksystem kommunizieren kann. Sie dient zur Definition, Abfrage und Manipulation von Daten in relationalen Datenbanken5. SQL (als Abkuޠrzung für Structured Query Language), hat sich aus der „Struc- tured English Query Language“ (SEQUEL) entwickelt, die von IBM in den 1970er Jahren als Abfragesprache entwickelt wurde6. Mittlerweile hat sich SQL zu einer universalen Datenbanksprache entwickelt und ist von ANSI und ISO standardi- siert7 und wird von fast allen gängigen RDBMS unterstützt.

4 In [Kelz98] findet man eine detaillierte Auflistung und Erklärung aller Join-Typen mit Beispiel. 5 Seit SQL:2006 stehen auch Sprachkonstrukte zur Verfügung, um auch nicht rationale Datenstruktu- ren wie beispielsweise XML-Dokumente zu bearbeiten und abzufragen. 6 Aus Marken-rechtlichen Gründen musste SEQUEL zu SQL umbenannt werden. Deshalb hat sich die alternative Aussprache SEQUEL („sikwel“) für SQL bis heute erhalten. 7 1992 wurde SQL als SQL/92 zum „International Standard ISO/IEC 9075:1992, Database Language SQL“. Seither wurde der Sprachstandard von 1992 wie folgt weiterentwickelt: SQL:1999, SQL:2003, SQL:2006, SQL:2008. Die derzeit aktuelle Revision ist SQL:2011.

10 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Die Sprachsyntax von SQL ist relativ einfach aufgebaut und an die englische Umgangssprache angelehnt. SQL stellt eine Reihe von Befehlen zur Definition von Datenstrukturen nach der relationalen Algebra, zur Manipulation von Datenbe- ständen (Einfügen, Bearbeiten und Löschen von Datensätzen) und zur Abfrage von Daten zur Verfügung. Diese SQL-Befehle/Sprach-Elemente lassen sich zu fol- genden Teilbereichen zusammenfassen8: a) Datendefinition (Data Definition Language: DDL) b) Datenmanipulation (Data Manipulation Language: DML) c) Ablaufsteuerung (Transaction Control Language: TCL) d) Zugriffsrechte (Data Control Language: DCL) Der SQL-Teilbereich DML besteht aus den Befehlen (Statements): SELECT, INSERT, UPDATE und DELETE. Für diese Arbeit ist hauptsächlich das SELECT- Statement von Bedeutung, weil es zur Datenabfrage dient. Es hat in seiner Grund- form folgende Syntax:

SELECT [ALL | DISTINCT] SpaltenListe FROM TabellenListe [WHERE BedingungsAusdruck] [GROUP BY SpaltenListe [HAVING BedingungsAusdruck] ] [UNION [ALL] Abfrage] [ORDER BY SpaltenListe] Unbedingt erforderlich sind demnach das „SELECT“, eine Liste von Spalten (oder der Platzhalter “*“, der für alle Spalten steht), „FROM“ und eine Liste von Tabel- len. Wie die zugrundeliegende relationale Algebra arbeitet SQL grundsätzlich mengenorientiert, d.h. das Ergebnis einer Abfrage ist immer eine Menge aus null, einem oder mehreren Datensätzen. Die oben gezeigten relationalen Operationen: Selektion, Projektion und Join können wie folgt in SQL formuliert werden:

-- Selektion: WHERE-Klausel SELECT * FROM Lektor WHERE Wohnort=’Linz’ -- Projektion: SpaltenListe SELECT Titel, ECTSCredits FROM Lehrveranstaltung

8 Eine ausführliche Darstellung der Datenbanksprache SQL und ihrer Befehle ist nicht Gegenstand dieser Arbeit. Dazu möchte ich examplarisch auf das Lehrbuch [Date98] verweisen.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 11 -- (Inner) Join: TabellenListe SELECT * FROM Lektor as L INNER JOIN Lehrveranstaltung as LVA on (L.PersonalNr = LVA.PersonalNr)

2.2 Suchmaschinen

Obwohl der Begriff „Suchmaschine“ längst zur Alltagssprache gehört, sind dieser und die technischen Konzepte erst in der jüngeren Geschichte der Informatik ent- standen. (Internet oder WWW-)Suchmaschinen haben sich auf Basis der Konzep- te aus dem Bereich Information Retrieval (für Hypertext-Dokumente) heraus entwickelt.

2.2.1 Information Retrieval

Information Retrieval (IR) beschäftigt sich mit der computergestützten Suche nach Dokumenten. Der Begriff Information Retrieval wurde 1950 erstmals von Mooers verwendet. Aber bereits fünf Jahre zuvor beschrieb Bush [Bush45] das fik- tive System „Memex“, das die Nutzung des vorhandenen Wissens auf ein neues Niveau heben sollte. Zentrales Element waren Wissensspeicher, die einerseits alle Arten von Wissen speichern können und andererseits eine gezielte Suche und Stöbern ermöglichen. Als wichtiger Beschleuniger bei der Begründung der Informationswissen- schaften wird der sogenannte „Sputnikschock“9 genannt. Seit den 1960er Jahren jedenfalls sind Information Retrieval Systeme Untersuchungsgegenstand der In- formatik, Informationswissenschaft und Computerlinguistik. Es folgt daher nur eine kurze Einführung in das Thema. Für detaillierte Informationen möchte ich auf die umfangreiche Literatur zum Thema Information Retrieval verweisen, stell- vertretend seien hier folgende Lehrbücher genannt: [Salt83], [Baez99], [Mann09] und [Stoc07].

9 Als die Sowjetunion im Jahre 1957 mit den ersten Satelliten erfolgreich in die Erdumlauf- bahn brachte, wurde der Rückstand der USA in der Weltraumforschung offensichtlich. Dies führte u.a. zum Start des Apollo-Programms. Aus Sicht der der Informationswissenschaft ist jedoch inte- ressant, dass es ein halbes Jahr dauerte, bis der Signalcode des Satelliten entschlüsselt war, obwohl der Entschlüsselungscode in einer russischen Zeitschrift abgedruckt war, die auch in den US- Bibliotheken auflag.

12 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Architektur eines Information Retrieval Systems

Zweck eines IR-Systems ist, aus seiner großen Menge von Dokumenten, diejeni- gen herauszufinden, die am besten zur Suchanfrage passen. Eine Suchanfrage be- steht in der Regel aus einer Liste von Suchbegriffen. Um in akzeptabler Antwort- zeit zu einem Suchergebnis zu gelangen, werden die Dokumente nicht linear durchsucht, sondern ein vorab aufgebauter Index. In folgender Abbildung ist die Architektur eines IR-Systems schematisch dargestellt:

Abbildung 3: Architektur eines IR-Systems10

Die Dokument-Sammlung kann dabei nur die Dateien auf einem einzigen PC (man spricht dann von Personal IR z.B.: Mac OSX Spotlight, Windows Instant Search), oder alle Dokumente auf einer Menge von vernetzten Datenspeichern (z.B. Intranet in einer Organisation) umfassen. Parallel dazu lässt sich auch nach der Heterogenität der Themen (der Dokument-Sammlung) unterscheiden. Klassi- sche IR-Systeme umfassen meist nur ein bestimmtes Themengebiet, beispiels- weise Gesetzestexte, Patente, Medizinische Dokumente etc. Weiters kann unter- schieden werden, ob die Dokumente im Volltext vorliegen oder bereits verdichtete Repräsentationen (Abstracts, Schlagwörter). Zentrales Element und zugleich Datenspeicher eines IR-Systems ist ein In- dex11, der im IR-Umfeld als „invertierter Index“ bezeichnet wird. Dieser Index enthält die Begriffe und die dazugehörigen Quellen (Stellen im Dokument). Ein

10 Angelehnt an Abbildung 7.5 „a complete search system“ in [Mann09] 11 In der Praxis verwenden IR-Systeme mehrere bzw. mehrstufige Indizes.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 13 einfaches IR-System (siehe Boolesches Retrieval Modell) speichert hier zu einem Begriff12 alle Fundstellen (z.B. als Dokument-Ids) in denen dieser vorkommt.

Retrieval-Modelle

Die einfachste Lösung für das Finden aller Dokumente zu einem Wort ist eine bi- näre Wort-Dokument-Matrix (auch incidence matrix). Wie in folgender Abbildung dargestellt, entspricht eine Zeile einem Begriff (term) und eine Spalte einem Do- kument (document). Enthält das Dokument den Begriff enthält das Element (t, d) den Wert 1 sonst 0.

Dokument d1 d2 d3 d4 d5 Begriff apple 1 0 1 1 1 almond 0 1 0 0 1 cake 0 1 1 0 1 cocolate 0 1 0 0 0 computer 1 0 0 1 0 dough 0 1 1 0 0 :

Abbildung 4: Term-document Incidence Matrix

Die Suchabfrage nach „apple and cake and not computer“ kann nun einfach in 10111 and 01101 and not 10010 umgeformt werden. Verknüpft man nun diesen booleschen Ausdruck bitweise erhält man: 00101. Die ‚1’er im Ergebnis kenn- zeichnen nun die Dokumente, welche die Abfragebedingung erfüllen, hier also die Dokumente d3 und d5. Mit diesem booleschen Retrieval-Modell, können prinzipiell alle Suchanfragen beantwortet werden, in als boolesche Ausdrücke for- muliert werden können: t1 {and|or [not] tn}

Ein weiteres, grundlegendes Retrieval-Modell ist das sogenannte Vektorraummo- dell. Bei diesem werden sowohl die Dokumente in Vektoren (in einem hochdi-

12 Ein Begriff (engl. Term) kann ein Wort sein oder ein Eigenname, der eventuell auch Leer- und/oder Sonderzeichen enthält, beispielsweise „Bad Gastein“, „World War II“, „TI-30“ etc. Was als Begriff er- kannt wird bzw. werden soll, wird durch den Parser gesteuert, der sowohl die Dokumente als auch die Suchanfrage zerlegt. In der Regel ignoriert der Parser eines IR-Systems sogenannte Stoppwörter wie „und“, „ist“, „ein“, „der“ etc. Zudem werden die Begriffe im Zuge des Parse-Vorgangs zumeist auch auf ihre Stammform normiert, d.h. aus „gehen“, „ging“, „gegangen“ etc. wird „gehen“, aus „Mutter“, „Mütter“, „Mutters“ etc. wird „Mutter“.

14 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken mensionalen Raum) übersetzt, als auch die Suchanfragen. Die Relevanz eines Do- kuments für die Suchanfrage wird durch Ähnlichkeit von Dokumentvektor mit dem Anfragevektor ermittelt. Auf Basis der Relevanz kann dann auch eine Rang- reihung der gefundenen (ähnlichen) Dokumente erfolgen. Beim Vektorraummodell wird die Wichtigkeit eines Terms für ein Dokument berücksichtigt. Ein einfacher Ansatz hierzu verwendet beispielsweise die Term- frequenz: wie oft ist Term t in einem Dokument d enthalten. Hierbei werden die Reihenfolge und die Position des Begriffs im Dokument vernachlässigt. Deshalb bezeichnet man dies Repräsentation oft auch als ‚bag of words’.

Abbildung 5: Dokument- und Abfragevektoren im Vektorraum13

In der obigen Abbildung ist ein zweidimensionaler Vektorraum (für die Terme t1 und t2) dargestellt, in dem die Dokumente d1 bis d6 und ein Abfragevektor q ein- gezeichnet sind. Definiert man Ähnlichkeit nun über die Nähe der durch die Vek- toren beschriebenen Punkte, ist d5 gefolgt von d3 am ähnlichsten zu q. Dem ge- genüber ist d4 am ähnlichsten zu q, wenn man die Richtung in welche die Vekto- ren zeigen, zur Bestimmung der Relevanz verwendet. Ein Vektor enthält die Gewichte der Terme für das Dokument/die Anfrage; je- der Term stellt eine Dimension im Vektorraum dar. In der klassischen, „TD-IDF“ genannten Variante werden die Term-Gewichte über die Kennziffern Termfre- quenz (TD) und inverse Dokumentfrequenz (IDF) berechnet. Hinter der IDF steckt der Ansatz, dass Terme, die in vielen oder fast allen Dokumenten auftreten

13 In Anlehnung an Abbildung 5.1 in [Gott09]

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 15 nicht sonderlich hilfreich bei der Suche nach relevanten Dokumenten sind. Sol- che Terme sollen demnach niedriger gewichtet werden. Zur Berechnung der Ähn- lichkeit von Vektoren wird bei der TD-IDF-Variante der eingeschlossene Winkel verwendet (cosine similarity). Neben den beiden hier kurz vorgestellten Retrieval-Modellen gibt es noch zahlreiche hiervon erweiterte Varianten, sowie Modelle, die auf ganz anderen An- sätzen/Ideen basieren, wie beispielsweise das Probabilistische IR-Modell, das Clustermodell, das Fuzzy-Set-Modell etc. Aus Platzgründen verzichte ich auf eine weitere Betrachtung derselben und verweise auf die einschlägige Fachliteratur (siehe oben).

2.2.2 Internet-Suchmaschinen

Um die Funktionsweise und den technischen Aufbau einer Suchmaschine zu ver- stehen, muss man einerseits die Herausforderungen verstehen, die durch die Größe, Wachstum und die Änderungsrate des Internets bzw. des World Wide Web (WWW) gegeben sind und traditionelle Ansätze aus dem Information Retrieval unpraktikabel machen. Weiters muss die historische Entwicklung der Internet- Suchmaschinen auch im zeitlichen Zusammenhang mit der Verbreitung und dem Wachstum des WWW und seiner Vorläufer betrachtet werden.

Archie, Veronica und WAIS: Suchdienste aus der Prä-WWW-Ära des Internet

Vor dem großen Internet-Boom Mitte der 90er Jahre halfen Internet-Suchdienste wie „Archie“, „Veronica“ und „WAIS“ den Internet-Benutzern beim Auffinden von Informationen bzw. Dateien im Netz. Sie gelten heute als Vorläufer der WWW- Suchmaschinen.

Suche mit Archie in FTP-Archiven „Archie“ [Emta92, Deut00], der Name leitet sich vom englischen „archive“ ab, gilt als die erste Internet-Suchmaschine und wurde 1989 an der McGill University in Kanada entwickelt um Lokalisierung von Dateien in den öffentlich zugänglichen

16 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Archiven auf FTP-Servern14 zu vereinfachen. Der Archie-Server liest dazu in re- gelmäßigen Abständen automatisch das Inhaltsverzeichnis von öffentlichen Be- reichen15 der FTP-Server aus und erstellt bzw. aktualisiert einen Index über alle darin enthaltenen Dateien. Neben dem ursprünglichem Archie-Server am Com- puting Center der McGill Universität (archie.cs.mcgill.ca) entstanden 1992 bereits erste Mirrors16 in Finnland und Australien. Im November 1993 waren bereits über 2.100.000 Dateien von über 1.200 FTP-Servern im Index gespeichert und über 30 replizierte Archie-Server, geografisch über die Erde verteilt, erreichbar (in Öster- reich beispielsweise unter archie.univie.ac.at). 1995 waren dann schon über 60 Server online und die Suche mit Archie und „whatis“17 gehörte unter den Inter- net-Benutzer bereits längst zum Handwerkzeug. Zur Suche nach Dateien können die Archie-Server über Telnet-Sitzungen in- teraktiv bedient werden oder eine Anfrage per E-Mail beantworten. Nach und nach entstanden auch eigene Client-Programme wie „XArchie“ und „WS_Archie“ und schließlich konnte Archie auch über Gopher-Clients und WWW-Gateways (HTML-Formulare) befragt werden.

Suche in Informationsdatenbanken mit WAIS WAIS (Wide Area Information System) wurde Ende 1989 unter der Leitung von Kahle (Thinking Machines) zur Suche und Indizierung von Dokumenten entwi- ckelt, die verteilt auf mehrere, vernetzte Server gespeichert sind [Pfei95]. Gegen- über der Volltextsuche mit den UNIX-Tools „man“, „find“ und „grep“ ermöglichte dies eine wesentlich performantere Suche in einer (sehr) großen Anzahl von Do- kumenten. Wesentliche Architektur-Merkmale von WAIS waren: a) Verwendung einer Client/Server-Architektur mit zustandslosem Kommunikationsprotokoll b) Verwendung des Vektorraummodells (siehe oben).

14 Als Internet-Benutzer benötigt man zum Herunterladen einer Datei von einem FTP-Server (mit „GET“) drei Informationen: 1) die (IP-)Adresse des FTP-Servers, 2) den Verzeichnispfad und 3) den Namen der gesuchten Datei. 15 Der Zugriff auf einen öffentlichen FTP-Server erfolgt über den Benutzer „anonymus“ (ohne Pass- wortbafrage) und wird deshalb auch „Anonymus FTP“ genannt. 16 „Mirror“ ist die Bezeichnung für replizierte Server(bereiche) im Kontext des Internet. Neben dem Aspekt der Datensicherung sollen damit vorrangig Zugriffe auf netzwerk-technisch bzw. geogra- fisch nahe am Benutzer gegelegene Server-Kopien verteilt/umgelenkt werden. 17 Mit dem „whatis“-Befehl kann die gleichnamige Datenbank (auch als „Software Description Data- base“ bekannt) durchsucht werden, welche die teilweise freiwillig bereitgestellten Beschreibun- gen/Kommentare zu den verfügbaren FTP-Dateien verwaltet. Als Bestandteil des Archie-Dienstes war damit die eingeschränkte Suche nach Dateien zu einem bestimmten Schlagwort möglich.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 17 Voraussetzung für die Suche in einem Vektorraum-Modell ist, dass die Vekto- ren für alle Dokumente berechnet werden und ein entsprechender Index aufge- baut wird. WAIS stellte hierzu das Kommandozeilentool „waisindex“ zur Verfü- gung, mit dem eine Indexdatei für alle Dokumente (eines bestimmten, anzuge- benden Typs) in einem Verzeichnis erstellt werden konnte. Aus dem Dokument- typ konnte WAIS ableiten, wie der Dokumenttitel ermittelt werden kann. WAIS kannte eine Reihe von Standardformaten, wie plaintext, mail, BibText, netnews uvm., konnte aber auch durch Eigenentwicklungen erweitert werden. Aus dem Ergebnis der Indizierungsvorgänge konnte man WAIS-Datenbanken aufbauen und einen lokalen WAIS-Server betreiben. Zur Suche standen als WAIS-Clients neben dem Kommandozeilentool „waisq“ auch bald grafische Benutzerschnittstellen auf diversen Plattformen zur Verfügung. Mit dem sogenannten „directory-of-servers“, einem Verzeichnis von WAIS-Servern, das bei quake.think.com zentral gehostet wurde, konnte man sich einen Überblick über die vorhandenen WAIS-Server verschaffen. Mittels einer Source-Description, die zu jeder Datenbank vorhanden war, erhielt man Informa- tionen zum Inhalt der einzelnen WAIS-Datenbanken, sowie den URL des WAIS- Servers. So wurde es erstmals möglich mit einer einheitlichen Nutzeroberfläche unterschiedliche, im Netz verteilte Datenbestände zu durchsuchen. WAIS wurde, u.a. weil es erweiterbar war und als Public Domain-Paket zur Verfügung stand, ein sehr populäres System. Unglücklicherweise wurde statt dem schlichten „HTTP“ das komplexe ANSI-Proktoll „Z39.50“ eingesetzt, welches ur- sprünglich für die Recherche in Bibliothekssystem entwickelt wurde und weit mehr geboten hat, als für WAIS-Systeme nötig war. Zusammen mit der Architek- tur-Entscheidung, auf ein eigenes, proprietäres Dokumentformat zu setzen, statt auf MIME-Typen, erschwerte dies die Weiterentwicklung. In der Folge entstanden einige Spin-Offs, wie beispielsweise das populäre „freeWAIS-SF“, dessen Parser auch Stoppwörter und Stammformen erkannte. „htDig“, ein Tool, das aktuell ger- ne die Suchfunktion auf einem Webserver bereitstellt, sowie „Gopher“ und „Vero- nica“ (siehe unten) basieren auf dem Suchalgorithmus von WAIS und sind in ge- wissem Sinne dessen Nachfahren.

18 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Suche im Gopherspace mit Veronica Vor dem Durchbruch des WWW surften die Internet-Benutzer im sogenannten „Gopherspace“18, der die Gesamtheit aller Gopher-Ressourcen im Internet be- zeichnet. Der erste Gopher-Server ist 1991 an der University of Minnesota ent- standen, mit dem Ziel ein einfaches, universitätsweites Online- Informationssys- tem zu schaffen. Jeder Gopher-Server verwaltet die Gopher-Ressourcen (Dateien) als Hierarchie von verschachtelten Menüs. Menü-Einträge stellen Verweise auf lo- kal vorhandene oder auf anderen Servern zugängliche Ressourcen dar. Zur Navi- gation im Gopherspace benötigt man ein Client-Programm den „(Internet-) Go- pher“, der in verschiedenen Versionen für viele Betriebssysteme frei und kom- merziell verfügbar ist. So können einige Clients selbst Bilder anzeigen oder Au- diodateien abspielen oder so konfiguriert werden, dass externe Anwendungen (sogenannte „Viewer“) zur Präsentation bestimmter Ressourcen (beispielsweise HTML-, PostScript-, PDF- oder RTF-Dokumente) benutzt werden. Die einfache Verfügbarkeit der Gopher-Clients und die unkomplizierte Installation und Verwal- tung eines Gopher-Servers führte zu einem explosionsartigen Anstieg der Go- pher-Server im Internet – im November 1993 waren es schon über 2200. Der größte Beitrag zur raschen Ausbreitung des Gopherspaces wird aber dem mächtigen Gopher-Suchdienst „Veronica“ zugesprochen [Cour95], der als Menü- punkt „Search titles in Gopherspace using veronica“ von allen Gopher-Clienten erreichbar war19. Die erste Version dieser Suchmaschine entstand 1992 in Anleh- nung an den FTP-Suchdienst Archie (siehe oben) am Rechenzentrum der Univer- sität Nevada durch Barrie und Foster [Fost95] und erhielt später den Namen Vero- nica20. Der Suchdienst indizierte im Monatsrhythmus die Menüs aller Gopher- Server, die beim „mother gopher“ (an der University of Minnesota) registriert wa- ren. Veronica erlaubte die Angabe von mehreren, durch boolesche Operatoren (AND, OR, NOT) verknüpfte Suchbegriffen (vlg. [Haje96]). Besonders hervorzuhe- ben ist aber die Präsentation der Suchergebnisse. Die Treffer wurden nämlich als

18 Der Begriff „gopher“ leitet sich vom englischen „(to) go for (something)“ ab. 19 Neben Veronica fand auch noch der Gopher-Suchdienst „Jughead“ Einzug in die Gopher-Clienten. Mit Jughead konnte man die Suche auf einen selbst gewählten Gopher-Server beschränken. Die Su- che nach Gopher-Ressourcen lieferte damit im Vergleich zu Veronica schneller ein Ergebnis. 20 Der Name „Veronica“ ist dem eigenartigen Sinn für Humor der Softwareentwickler zu verdanken. Er wurde in Anlehnung an den bekannten FTP-Suchdienst Archie gewählt, da „Veronica“ der Name von Archies Freundin in der gleichnamigen Comicserie ist. Später wurde Veronica zur Abkürzung für „Very Easy Rodent-Oriented Net-wide Index to Computerized Archives“, die einen Hinweis auf das Nagetier (englisch: „rodent“) „Gopher“ enthält.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 19 Liste von anwählbaren Menüpunkten aufbereitet. Damit war der Suchdienst nahtlos in den Gopher-Client integriert und die Benutzer konnten die entspre- chenden Gopher-Ressourcen wie gewohnt anwählen. Obwohl die Anzahl der indizierten Informationseinheiten für heutige Ver- hältnisse klein erscheint – im November 1994 verzeichnete Veronica über 10.000.000 Gopher-Dokumente auf über 6.000 Servern – wurden damals schon folgende Punkte an der Suche mit Veronica kritisiert [Zabi95]:

¾ Gopher-Dokumente deren Host-Server nicht beim „mother gopher“ regist- riert ist, werden nicht indiziert

¾ Da der Index nur einmal pro Monat aktualisiert wird, verweisen Suchergeb- nisse oft auf veraltete Informationen oder bereits ungültige Adressen im Gopherspace

¾ Überlastet durch viele Anfragen war die Suche mit Veronica oftmals langsam oder nicht erreichbar. Benutzer wichen auf Veronicas in anderen Zeitzonen aus.

¾ Zu viele Treffer im Suchergebnis machen es unüberschaubar

¾ Suchmöglichkeiten und –methoden sind auf das in Veronica angebotene Ausmaß beschränkt

1993 bis 1994 bestanden Gopherspace und das gerade neu entstehende World- Wide-Web [Bern94] noch nebeneinander. Gopher-Clients konnten HTML- Dokumente anzeigen und WWW-Browser Gopher-Menüs. Nach und nach wurden Gopher-Ressourcen aber in HTML-Dokumente umgewandelt, Gopher-Clients durch WWW-Browser21 und Gopher-Server durch WWW-Server verdrängt. HTML bot mit Hyperlinks im Gegensatz zu den hierarchischen Gopher-Menüs mehr Freiheit bei der Organisation von Ressourcen und mehr Gestaltungsmöglichkei- ten bei der Erstellung von Dokumenten durch spezielle Tags für Textformatierung, Grafiken, Tabellen, Listen uvm. Heute gibt es mangels erreichbarer Gopher-Server keinen Gopherspace mehr und Archie-Server werden vereinzelt nur noch aus historischen Gründen gepflegt. Durch die rasante Ausbreitung von WWW-Sites im Internet wurden auch neuarti- ge Suchdienste für deren Inhalte benötigt.

21 Mit dem 1993 am „National Center for Supercomputing Applications“ entwickelten „(NCSA) Mo- saic“ war der erste grafischen WWW-Browser frei für viele Betriebssystem verfügbaren.

20 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken WWW-Suchmaschinen

Grundsätzlich kann man WWW-Suchdienste in zwei Hauptgruppen unterteilen22. Einerseits existieren Kataloge oder Verzeichnisse, die von Menschen redaktionell betreut werden und die vorhandenen WWW-Inhalte zu verschachtelten Katego- rien organisieren. „Yahoo“ (www.yahoo.com) entstand 1994, als David Filo und Jerry Yang von der Stanford University ihre Sammlung der „besten“ Web-Adressen veröffentlichten. Als weitere Vertreter dieser Kategorie sind beispielsweise das „Open Directory“ (dmoz.org) und „www.web.de“ zu nennen. Die zweite Gruppe bilden die Such-Maschinen im engeren Sinn. Darunter fal- len alle sogenannten Roboter-basierten Suchdienste die den Inhalt des WWW vollautomatisch durchsuchen und indizieren. Im Folgenden beschränke ich die Ausführungen auf diese Gruppe.

Wichtige Meilensteine: vom WWW-Wanderer zu Google Der erste WWW-Such-Roboter „World Wide Web Wanderer“ [Gray93] wurde von Mathew Gray im Frühjahr 1993 am MIT entwickelt um neue WWW-Server und Si- tes im Internet zu entdecken und zu katalogisieren23. Michael L. Mauldin von der Carnegie Mellon University fügte dann eine Retrieval-Komponente namens „Wandex“ hinzu, um die gesammelten Daten auch durchsuchen zu können. Mit „“, „Jumpstation“, „World Wide Web Worm“ und „RBSE Spider“ entstanden 1993 noch weitere Suchmaschinen, die mittlerweile aber nicht mehr verfügbar sind. RBSE Spider war die erste Suchmaschine, die als Suchergebnis ei- ne nach einem errechneten Ranking sortierte Liste der Treffer lieferte. Im April 1994 ging der an der University of Washington entwickelte „Webcrawler“ online und im Juli 1994 der von Mauldin entwickelte Suchdienst „“ [Maul97]. Neu an dieser Suchmaschine war, dass nicht nur die Worthäufigkeit innerhalb einer Seite sondern auch die Nähe von Suchbegriffen untereinander ausgewertet wur- de.

22 Die Trennung wird in der Praxis aber zunehmend schwieriger, da einerseits Suchmaschinen wie Google zusätzlich auch Treffer in Verzeichnissen in ihr Suchergebnis einbeziehen und andererseits Kataloge wie Yahoo Abfragen (auf Wunsch) auch an interne bzw. kooperierende externe Suchma- schinen weiterleiten. Angesichts dieser Entwicklung muss man zunehmend von „hybriden Such- maschinen“ sprechen. 23 Im Juni 1993 zählte der Wanderer 130 Web-Sites im Dezember 1993 bereits 620. Bis 1996 durchwan- derte der Suchroboter dann zweimal pro Jahr das Internet und lieferte damit statistisches Material über Größe und Wachstum des WWW.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 21 Im Jahr 1995, als das Internet langsam das Bewusstsein der nicht- akademischen Öffentlichkeit erreichte, gingen mit „“, „Architex“ (mitt- lerweile als „“ bekannt) und „Altavista“ (in der genannten Reihenfolge) die ersten kommerziellen Suchmaschinen ans Netz, die sich durch Anzeigen (soge- nannte Werbe-Banner) finanzieren sollten. 1996 wurde die Fa. „“ gegrün- det und die gleichnamige Suchmaschine zur Grundlage für „HotBot“. Sergey Brin und Larry Page entwickelten an der Stanford University unter dem Namen „BackRub“ eine neue Suchmaschine [Brin98]. 1998 wurde sie in „Google“24 umbenannt und in eine private Firma gleichen Namens eingebracht. Mittlerweile gehört www.google.com zu den meistbesuchten Seiten im WWW. We- sentlichen Anteil am großen Zuspruch der Internet-Benutzer wird einerseits dem neuen Ranking-Algorithmus „PageRank“ zugerechnet, der auch bei komplizierten Anfragen bereits unter den ersten Treffern hervorragende Ergebnisse liefert. Laut [ILSt15] hatte Google Mitte 2012 die riesige Zahl von 30 Billionen (30 x 1012) Do- kumente indiziert und beantwortete 100 Milliarden Suchanfragen pro Monat. Der gesamte Index der Google-Datenbank umfasst mehrere Terabyte und wird fort- laufend aktualisiert.

Architektur einer WWW-Suchmaschine

Die erste Suchmaschine, die Suchroboter und Module zur Indizierung mit einer basierend auf einer verteilten Architektur realisierte war „Harvest“ im Jahr 1994. Mit Harvest [Bowm95] wurde zwei neue Elemente in die Architektur eingeführt: sogenannte ‚gatherers’ und ‚brokers’. Mit den Gatherers wurden die für die Indi- zierung nötigen Informationen eines Web-Servers gesammelt. Dieses „abernten“ erfolgte in periodischen Abständen, wie der Name „Harvest“ (engl. Ernte) nahe- legt. Broker-Module/Server hatten einerseits die Aufgabe die gesammelten Daten zu Indizieren. Anderseits waren die Broker auch für die Beantwortung einer Such- anfrage zuständig. Broker konnten Daten untereinander austauschen und für be- stimmte Themenbereiche spezialisiert werden. Das Harvest-System verfügte auch über einen „Objektcache“ (zur Verringerung der Netzwerklast und der I/O- Zugriffe) sowie einen Mechanismus zur Replikation, der auf einem gemeinsamen

24 „Google“ wurde vom Begriff „Googol“ abgeleitet, der im englischsprachigen Raum für die Zahl 10100 steht. Damit sollte verdeutlicht werden, dass es sich hier um eine Suchmaschine für eine sehr große Zahl an Dokumenten handelt.

22 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Dateisystem „mirror-d“ und einem eigenen Kommunikationssystem „flood-d“ basierte. Über die Architektur einer modernen Suchmaschine gibt es wenig Literatur, weil viele Techniken in Unternehmen (weiter)entwickelt wurden und werden und diese teilweise durch Patente geschützt sind. In [Aras01] wird jedenfalls ein brauchbarer, einfacher, schematischer Aufbau vorgestellt, der in folgender Abbil- dung dargestellt ist:

Textindex Sucha nfra ge Query Engin e Suchroboter Repos ito ry Indexer Rankingmodul WWW Struktur index Suchergebnis Steuerungsm o du l Hilfsindex

Abbildung 6: Schematische Architektur einer (WWW-)Suchmaschine25

Folgende Module, die im Folgenden näher betrachtet werden, bestimmen den Aufbau und die Funktionsweise einer WWW-Suchmaschine: Suchroboter (craw- ler), Indizierungsmodule (indexer) und die Funktionseinheit zur Abwicklung von Suchabfragen (query engine).

Suchroboter Grundlage jeder Suchmaschine sind die „Suchroboter“ (Crawler), die das Daten- material für alle weiteren Operationen liefern. Suchroboter sind kleine Program- me die im Auftrag der Suchmaschine durch das WWW surfen. Tatsächlich, auch wenn synonyme Bezeichnungen wie beispielsweise „Wanderer“, „Spider“ oder „Worm“ das Traversieren von Knoten zu Knoten im Netz nahe legen, „bewegt“ sich der Roboter ausschließlich dadurch, indem er immer wieder von anderen Stellen im WWW liest. Dazu verwaltet jeder Suchroboter eine Liste von URLs die er der Reihe nach abarbeitet. Entdeckte Links werden an diese Liste einfach ange- fügt. Je nachdem, ob die Suche primär möglichst vielen Dokumenten eines be- stimmten Knotens oder möglichst vielen verschiedenen Knoten gilt, kann man

25 Angelehnt an an Fig 1 „General search engine architecture“ in [Aras01]

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 23 die Suchstrategie als Tiefen- respektive Breitensuche bezeichnen.26 Ein Roboter wandert solange durchs Netz bis das Abbruchkritierum, meistens eine vorgege- bene Anzahl an Dokumenten oder eine definierte Speicherplatz-Obergrenze er- reicht ist. Die gesammelten Daten werden in einem „Page-Repository“ gespei- chert und stehen dort für die Indizierungsmodule bereit. Bedingt durch die Größe und Änderungsrate des WWW müssen bei der Aus- gestaltung des Suchroboter-Moduls einer Suchmaschine jedenfalls folgende Fra- gen beantwortet werden [Aras01]:

¾ Welche Webseiten sollen die Suchroboter (zuerst) besuchen?

¾ Mit welcher Strategie sollen die Webseiten im Repository aktualisiert werden?

¾ Wie kann die durch Suchroboter erzeugte Last auf den besuchten Webseiten möglichst niedrig gehalten werden?

¾ Wie können der Suchvorgang parallelisiert und die Suchroboter gesteuert werden?

Um in einem Suchlauf eine möglichst viele Webseiten zu erreichen, werden meist viele Roboter gleichzeitig eingesetzt. Sowohl der intiale Startpunkt und die Steue- rung werden über ein Kontrollmodul der Suchmaschine festgelegt. Damit soll ge- währleistet werden, dass neben bereits bekannten Web-Seiten auch „weiße Fle- cken“ im (noch) nicht-indizierten Bereich des WWW erforscht werden. Das Surf- verhalten eines Suchroboters kann außerdem durch die Autoren bzw. den Web- Master einer Web-Site beeinflusst werden. Einerseits wurde dazu das „Robots Exc- lusion Protocol“ [Kost03, Sear03] geschaffen, das garantieren soll, dass Suchrobo- ter die Informationen in der Datei „robots.txt“ im Hauptverzeichnis der Web-Site berücksichtigen. Darin kann u.a. angegeben werden welche Bereiche des Web- Servers (nicht) durchsucht werden dürfen. Andererseits existiert ein spezieller HTML-Metatag „robots“ der von Suchrobotern ausgelesen werden kann. Mit die- sen Maßnahmen soll vor allem verhindert werden, dass sensible Daten der Web- Sites in den Index einer Suchmaschine kommen. 27

26 Viele Suchmaschinen beginnen einen Suchlauf im WWW mit Suchrobotern die zunächst möglichst viele Host-Adressen sammeln sollen (Breitensuche). Die gesammelten Adressen werden dann an andere Suchroboter weitergegeben welche die Knoten dann im Detail erfassen (Tiefensuche). 27 Bei den angegebenen Möglichkeiten verlässt man sich darauf, dass sich die Suchroboter an diese freiwillige „Internet-Etikette“ beim Besuch von Web-Sites halten. In der Regel ist dieses Vertrauen auch berechtigt. Allzu neugierige Crawler und generell unerwünschte Besucher können schließlich ohnehin durch restriktive Firewall-Regeln bereits auf TCP-Ebene vom Web-Server „ferngehalten“ werden.

24 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Indizierungsmodul Das Indizierungsmodul erstellt eine Reihe von Indizes zu den im Repository ge- sammelten Webseiten. Die wichtigsten beiden sind a) ein Inhaltsbasierter Index (text index) und b) ein Struktur-Index (link index). In der Regel werden noch wei- tere Hilfsindizes angelegt, die beim Ranking oder speziellen Suchanfragen be- nutzt werden (können). Der Text Index wird ähnlich dem invertierten Index aus dem Information Ret- rieval aufgebaut (siehe oben) und bildet die Basis zur Identifizierung der relevan- ten Seiten zu einer Suchanfrage. Mit dem Struktur Index werden die Verknüpfungen der Webseiten unterein- ander als Graph modelliert. Die Webseiten sind darin Knoten und Weblinks wer- den zu gerichteten Kanten28. Dieser Struktur-Graph (oder Teile davon), im spe- ziellen die Anzahl der ein- und ausgehenden Kanten eines Knotens, kann nun zur Bestimmung der Relevanz einer Seite verwendet werden. Die größte Herausforderung beim Aufbau und der Aktualisierung der Indizes einer Suchmaschine stellt die sehr große (und weiter ansteigende) Anzahl der Webseiten dar. Hierzu werden spezialisierte, verteilte und hoch skalierbare Da- tenstrukturen eingesetzt und weiterentwickelt.

Abfrage-Funktionseinheit Die Aufgabe der Abfrage-Funktionseinheit (query engine) einer Suchmaschine ist rasch potentiell relevante Webseiten zur Suchanfrage des Benutzers zu retournie- ren. Wie bereits mehrfach erwähnt, gibt es zu einer Suchanfrage, die aus wenigen Begriffen besteht, durch die riesige Menge an indizierten Webseiten, eine große Zahl von Treffern. Die gefundenen Seiten variieren jedoch bezüglich der Qualität der enthaltenen Informationen stark. Zudem sind Webseiten (im Gegensatz zu Dokumenten) zumeist nicht ausreichend selbstbeschreibend29. Manche Autoren platzieren oftmals auch (populäre) Begriffe auf ihren Webseiten, die mit dem In- halt nichts zu tun haben, mit dem Ziel deren Relevanz künstlich zu erhöhen. Dies wird in der Literatur als cheating oder spamming bezeichnet.

28 In der Literatur hat sich hierfür der Begriff „Inverted Web Graph“ etabliert. Invertiert deshalb, weil es interessanter ist, welche Links auf eine bestimmte Seite zeigen (incoming), als wohin der Link von einer Seite verweist (outgoing). 29 [Klei99] illustriert dies mit der beispielhaften Suche nach dem Begriff „Suchmaschine“. Die Websei- ten der Suchmaschinen enthalten in der Regel den Begriff „Suchmaschine“ nicht und würden so bei einer rein text-basierten Suche als wenig/nicht relevant berücksichtigt.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 25 Um in diesem Umfeld tatsächlich relevante Webseiten zu finden, mussten die klassischen Ansätze und Techniken aus dem Bereich Information Retrieval erwei- tert werden. Dazu kommen Techniken zum Einsatz, welche die Verknüpfung der Webseiten untereinander berücksichtigen - sogenannte „link-based techniques“. Zwei wichtige Ansätze in diesem Bereich sind PageRank und HITS. Beim PageRank-Ansatz [Page99] wird aus den Verknüpfungen der Webseiten untereinander ein globaler Rang, der sogenannte „PageRank“ errechnet. Hierzu werden grob gesprochen die Verweise gezählt (und global normiert) die auf eine Webseite zeigen. Zusätzlich wird hierbei auch die Wichtigkeit der Seite selbst be- rücksichtigt, wobei sich diese teilweise wiederum aus der Anzahl der Verweise auf die Seite selbst ergibt. Die PageRanks für die Knoten im Graphen werden iterativ mit Matrizen-Operationen berechnet. Bei der Berechnung werden sowohl in sich abgeschlossene Cluster von Webseiten („rank sink“), als auch Seiten/Knoten ohne ausgehenden Link („rank leak“) entsprechend berücksichtigt. Beim HITS-Ansatz [Klei99] (steht für „Hypertext Induced Topic Search“) wer- den zwei Ergebnisse für eine Suchanfrage berechnet, der sogenannte „Authority“ und der „Hub“-Wert. Unter einer Authority-Webseite wird eine Seite verstanden, die tatsächlich relevante Informationen zu einem Suchbegriff/einer Suchabfrage enthält. Hub-Webseiten sind im Gegensatz hierzu, Seiten die auf viele Authority- Webseiten verweisen. Die Beziehung zwischen Hub und Authority-Seiten ist selbstverstärkend: je mehr Hubs auf eine Authority zeigen bzw. je mehr Verweise eine Hub-Seite beinhaltet desto relevanter werden diese. Der HITS-Algorithmus identifiziert auf Basis der Anfrage zuerst einen Sub-Graph (dazu genügen ein paar tausend Web-Seiten) und berechnet dann für diesen die Hub und Authority- Werte. Bei der Berechnung ist es jedoch nicht nötig die Werte exakt zu berechnen. Nach einigen Iterationen ist bereits eine ausreichend gute Annäherung erreicht.

26 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken KAPITEL 3

3 Begriffsbasierte Suche in relationalen Datenbanken

In diesem Kapitel werden verschiedene Ansätze/Konzepte vorgestellt, die sich zur begriffsbasierten Suche in relationalen Datenbanken in den letzten Jahren entwi- ckelt haben. Einleitend werden die Defizite von SQL als Abfragsprache für Endbe- nutzer besprochen und einige alternative Konzepte bzw. Abfragewerkzeuge im Überblick vorgestellt, die zur Verbesserung der Interaktion entstanden sind.

3.1 Datenabfragen mit SQL: Defizite und alternative Ansätze

Für das Speichern, Löschen, die Manipulation und das (Wieder)Abrufen von Da- ten in/aus relationalen Datenbanken steht die Sprache SQL zur Verfügung (siehe Kap. 2). Obwohl der Sprachdialekt an der englischen Satzstruktur orientiert ist und nur über wenige Konstrukte verfügt, benötigt ein Datenbankanwender be- reits für eine einfache Abfrage ausreichende SQL-Kenntnisse und Wissen über die relationalen Strukturen (das Datenbankschema) der Datenbank. Die einfache Ab- frage von Informationen zur Person Namens „Roland Wagner“ muss der Benutzer beispielsweise wie folgt in SQL formulieren:

(a) SELECT * FROM Lehrveranstaltung WHERE LVALeiter = 'Wagner, Roland'; (b) SELECT * FROM Mitarbeiter WHERE Vorname = 'Roland' AND Nachname = 'Wagner'; (c) SELECT * FROM Author WHERE FName = 'Roland' AND LName = 'Wagner';

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 27 (d) SELECT * FROM Student WHERE Vorname = 'Roland' AND Nachname = 'Wagner'; (e) SELECT * FROM Entlehner WHERE Name = 'Roland Wagner';

Alle angeführten Beispiele sind syntaktisch und semantisch korrekt. Die Unter- schiede in der Formulierung ergeben sich aus dem jeweiligen Datenbanksystem und seinem Datenmodell. Dieses ist davon abhängig, zu welchem Zweck die Da- tenbank (als Persistenzschicht eines Informationssystems) Personendaten ver- waltet. Beispielabfragen a) und d) könnten aus einem Informationssystem stam- men, das Lehrverstaltungen verwaltet; b) aus einem (universitären) Personalver- waltungsystem; c) und e) aus einem Bibiliothekssystem. Bereits an diesem einfachen Abfragebeispiel zeigt sich, dass abgesehen von der formal korrekten Schreibweise einer SQL-Abfrage („SELECT … FROM … WHERE …“) ausreichendes Wissen über das Datenbankschema nötig ist, um Daten aus relati- onalen Datenbanken abrufen/abfragen zu können. Für (Gelegenheits-)Benutzer stellt dies oftmals eine große Hürde dar. Das Datenbankschema ist in der Regel sehr komplex und oft nicht (in brauchbarer Form dokumentiert) einsehbar.

Auf Grund dieser einfach nachvollziehbaren Defizite (und noch einigen Gründen mehr) entwickelte sich sowohl in Praxis als auch in der wissenschaftlichen For- schung die Erkenntnis, dass SQL für (Datenabfragen durch) Endbenutzer nicht geeignet ist. Im Laufe der Zeit entstand eine Vielzahl an alternativen Ansätzen zur Benutzerinteraktion mit relationalen Datenbanken, vor allem was die Datenab- frage betrifft. Einige werden im Folgenden kurz vorgestellt, wobei die hier getrof- fene Auswahl weder vollständig noch überschneidungsfrei ist:

a) Assistenten und Formulierungshilfen b) Abfragemasken c) Systeme zur visuellen Datenabfrage d) Natürlichsprachliche Benutzerschnittstellen e) Unscharfe Abfragen f) Begriffsbasierte Abfragen

28 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 3.1.1 Assistenten und Formulierungshilfen

Die Erstellung einer formal korrekten SQL-Abfrage ist nicht trivial, vor allem wenn mehrere Tabellen verknüpft werden (müssen), mehrere Bedingungen berücksich- tigt werden sollen und/oder Aggregation verwendet werden. Zur besseren Unter- stützung entstanden einige Tools und Ansätze die dem Anwender bei der Formu- lierung einer SQL-Abfrage Hilfestellung geben. Um Tippfehler zu vermeiden, verfügen die meisten SQL-Editoren ein Wörter- buch in dem die Namen der Tabellen und deren Attribute der relationalen Daten- bank abgelegt sind und bieten dem Anwender auf Tastendruck eine Autovervoll- ständigung an. Teilweise können dabei auch Attributwerte für die Erstellung ei- ner Abfragebedingung aus einer Liste ausgewählt werden und das Tool kümmert sich um die syntaktisch korrekte Delimitierung je nach Datentyp. Die folgende Abbildung zeigt einen Screenshot aus der Anwendung „SQuirreL“ [Squi15]:

Abbildung 7: Autovervollständigung im SQL Editor von SQuirreL

Einen ähnlichen Ansatz verfolgen vollständig Menü-/Assistenten-gestützte Be- nutzerschnittstellen, bei denen die einzelnen Teile eines SELECT-Statements über Menüs/Dropdown-Listen ähnlich einem Baukastensystem sukzessive aus- gewählt und zusammengesetzt werden. Je nachdem welche Klausel der Abfrage bearbeitet wird, werden nur syntaktisch mögliche SQL-Sprachelemente bzw. gül- tige Namen von Tabellen/Attributen angeboten. Attributwerte können teilweise ebenso je nach Typ via Liste, Kalender, Zahlenachse etc. ausgewählt werden. Fol- gende Abbildung zeigt einen Screenshot aus der Anwendung „SAS SQL Query Window“ [SAS15]:

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 29 Abbildung 8: Assistenten zur Abfrageerstellung aus SAS SQL Query Window

Gemein ist diesen Ansätzen, dass die SQL-Abfrage weiterhin im Mittelpunkt der Benutzerinteraktion steht. Nachdem der Anwender hierbei ausschließlich bei der Formulierung unterstützt/angeleitet wird, ist diese Art der Interaktion vor allem bei Datenbankexperten und Anwendungsentwicklern beliebt.

3.1.2 Abfragemasken

Eine einfache Alternative zur Formulierung von SQL-Abfragen ist die Verwendung von Formularen/Masken zur Datenabfrage. Abfragemasken (auch Suchmasken genannt) stehen zumeist als integrierter Teil eines (OLTP-)Informationssystems für Datenabfragen zur Verfügung. Mit solchen vordefinierten, statischen Abfra- gemasken können wichtige/häufig verwendete, vorab bekannte Datenabfragen ausprogrammiert werden und ohne Kenntnisse von SQL oder des Datenbank- schemas von Endanwendern benutzt werden.

Abbildung 9: Beispiel für ein Suchformular der Bibliothek der JKU Linz

In [Jaya08] wird ein interessanter Ansatz zur automatischen Erstellung von Suchmasken beschrieben, der auf dem Datenbankschema einer Datenbank und

30 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken einer errechneten Metrik namens „queriability“ basiert. Hinter der queriability steht die Wahrscheinlichkeit dass ein Feld des Datenbankschemas abgefragt wird. Die Autoren zeigen schließlich anhand von drei unterschiedlich komplexen und großen Datenbanken, dass mit ihrem Ansatz ein Großteil aller möglichen Abfra- gen abgedeckt werden kann, bei minimalem Aufwand für die Programmie- rung/Administration.

Einen anderen, vollständig auf dynamischen Suchmasken basierenden Ansatz stellt Query-by-Example (QBE) dar, das unter der Leitung von Moshe Zloof in den 1970ern bei IBM entwickelt wurde [Zloo77]. QBE hat im Gegensatz zu SQL eine graphische Benutzerschnittstelle, mit der Anwender Abfragen1 schreiben, indem sie sogenannte Tabellengerüste („example tables“) erstellen/ausfüllen. Ein Tabel- lengerüst hat folgenden Aufbau: In der ersten Zeile stehen der Name der Tabel- le/Relation, gefolgt von den Namen der einzelnen Feldern/Attribute. In den Zei- len unterhalb der Tabelle kann der Anwender nun angeben, welche Datensätze aus derselben angezeigt werden sollen. Dies erfolgt mit Kommando-Kürzel und/oder Bedingungen, wie in folgender Abbildung exemplarisch dargestellt:

Student MatrikelNr Vorname Nachname GebOrt GebJahr P. Linz < 1985

Abbildung 10: Einfaches QBE-Beispiel: Alle Studenten mit Geburtsort Linz, die vor 1985 geboren sollen angezeigt werden. (P. steht für das Kommando „print“)

Abfragen über mehrere Relationen können mit QBE wie folgt geschrieben werden:

Student Matri- Vorname Nach- LVA S_Matrik Titel Semester Note kelNr name elNr _M Julia Jobst _M P. P. P.

Abbildung 11: QBE-Abfrage mit Verknüpfung mehreren Tabellen: Titel, Semester und Note aller LVAs, welche die Studentin „Julia Jobst“ besucht, hat sollen angezeigt werden.

Der Verknüpfung/Join der beiden Relationen erfolgt über eine frei definierbare Variable, hier _M, die in beiden Tabellen in der Spalte MatrikelNr angegeben wurde. QBE bietet noch viele weitere Möglichkeiten wie Sortierung, komplexe Bedingun-

1 QBE trägt zwar ‚Query’ im Titel, man kann damit analog zu SQL jedoch auch Daten(sätze) einfügen, löschen und verändern. Hierzu stehen die Kommandokürzel: I., D., U. zur Verfügung.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 31 gen und Aggregationsfunktionen die beispielsweise in [Rama03] ausführlich vor- gestellt werden. QBE-ähnliche Benutzerschnittstellen sind durch ihr intuitives Bedienungs- konzept bis heute beliebt und weitverbreitet. Als zusätzliche Alternative zu SQL sind sie in einigen kommerziellen Datenbanktools integriert. Beispielsweise sei hier IBMs Query Management Facility (QMF), Borlands Paradox und das populäre Microsoft Access angeführt. In [Ozso93] werden weitere, teilweise auf QBE basie- rende, Beispiel-basierte (graphische) Benutzerschnittstellen zur Datenabfrage vorgestellt.

3.1.3 Systeme zur visuellen Datenabfrage

Unter Systemen zur visuelle Datenabfrage („Visual query systems“) sollen hier Systeme verstanden werden, bei denen die Informationen und Metainformatio- nen einer Datenbank graphisch (beispielsweise als E-R-Diagramm) repräsentiert werden und der Endanwender seine Abfragen auch über die direkte Manipulation von (diesen) graphischen Elementen erstellen kann, wobei u.a. Interaktionstech- niken wie: Zeigen (pointing), Auswählen (selecting), Durchstöbern (browsing), Filtern (filtering) und Zoomen zum Einsatz kommen. In den letzten Jahren sind hierzu viele Ansätze und Prototypen entstanden, so dass man durchaus von einem eigenen Forschungsbereich sprechen kann, der im Bereich zwischen Datenbanken und HCI liegt. Catarci et al. haben in [Cata97] ei- ne Übersicht über ca. 80 verschiedene Ansätze2 zusammengestellt und diese in Klassen eingeteilt. In diesem Abschnitt möchte ich Auszüge aus deren Arbeit be- züglich der verschiedenen Ansätze zur Interaktion kurz vorstellen. Der Prozess der Datenanfrage durch den Endbenutzer kann in zwei Aktivitä- ten gegliedert werden: a) Verstehen der abgebildeten Realität (understanding the reality of interest) und b) Erstellung der Abfrage (formulating the query).

2 Bei den betrachteten Ansätzen handelt es sich ausschließlich um Konzepte/Prototypen zur Abfrage von alphanumerischen Daten. Abfragen in Multimediadatenbanken (mit Ton, Bild, Video-Daten) werden nicht berücksichtigt. Unter den Ansätzen sind etwa zu finden: SUPER, PICASSO, ISIS, GORDAS, GUIDE, G+, QBD*, VQL, Living in the Database, HIQUEL, QBI uvm.

32 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Verstehen der abgebildeten Realität

In erster Linie geht es bei dieser Aktivität um die präzise Definition des Aus- schnitts aus dem Datenbankschema, welcher (später) für die Abfrage gebraucht wird. Hierzu müssen die Elemente/Konzepte identifiziert werden. Hierzu gibt es drei Strategien: a) Top-Down b) Durchstöbern und c) Vereinfachung des Schemas. Ein Verständnis für die in der Datenbank abgebildete Realität aufzubauen ist eine komplexe Aufgabe, vor allem wenn das Schema aus hunderten Tabellen, Be- ziehungen und Feldern besteht und Millionen von Instanzen beinhaltet. Eine Möglichkeit zur Filterung der aus Anwendersicht relevanten Informationen kann durch die Top-Down Strategie erreicht werden. Hier startet man bei allgemei- nen/generellen Aspekten der Realität und arbeitet sich zu deren Details vor. Dies kann entweder iterativ erfolgen, von einer Ebene zur nächst-detaillierteren. Eine andere Interaktionsmöglichkeit hierzu bietet ein hierarchisches oder selektives Zoomen, bei der je nach Ebene, die Elemente von darunterliegenden Ebenen ausgeblendet werden. Eine weitere etablierte Technik den Informationsgehalt eines Schemas he- rauszufinden ist Durchstöbern (browsing). Ein Benutzer, der wenig Wissen über die Datenbank und die Abfragetechniken hat, kann hier mit der Untersuchung ei- nes Elements beginnen und von dort dessen Nachbarschaft erkunden. Dabei kann der Anwender entweder nur das konzeptuelle Schema der Datenbank, oder nur die konkreten Ausprägungen oder eine Mischform davon durchstöbern. Bei der Vereinfachung des Schemas (schema simplification) wird eine Abfrage durch Transformation und Aggregation des Originalschemas erstellt, wodurch ei- ne Teilansicht (view) entsteht.

Erstellung der Abfrage

Im Prozess der Datenabfrage ist die Erstellung der Abfrage die wichtigste Tätig- keit. Hierfür bieten Systeme zur visuellen Datenabfrage folgende Herangehens- weisen an. Beim Ansatz Navigation im Schema (schema navigation), wird ausgehend von einem Element zu relevanten/interessanten Elementen weiternavigiert und die Elemente gegebenenfalls mit Bedingungen versehen. Basis für die Navigation ist zumeist das Entity-Relationship-Diagramm (ER-Diagramm), eine Darstellung des Datenbankschemas als Graph, bei dem die Entitäten Knoten und die Kanten

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 33 die Relationen sind. Die meisten VQS, die auf den Navigations-Ansatz setzen, bie- ten hierbei die Möglichkeit entlang von bestehenden Verbindungen zu navigie- ren. Einige Systeme ermöglichen dem Anwender zusätzlich Outer-Join- Verbindungen und/oder Verbindungen von Elementen für die Datenabfrage her- zustellen, die gar nicht explizit verbunden sind. In folgender Abbildung ist ein Beispiel aus QBD* dargestellt:

Abbildung 12: Abfragebeispiel aus QBD* (aus [Cata97]): Eine Verknüpfung (Bridge) zwi- schen Person und State (links) wurde hergestellt. Rechts ist der Editor zum Bearbeiten der Bedingung („Person.Name = State.S_Name“) dargestellt.

Ein zweiter Ansatz zur Erstellung der Abfrage ist die Verwendung von Teilabfragen (query formulation by subqueries), der in einigen graphischen Abfragesystemen zum Einsatz kommt, in denen die Elemente als Icons dargestellt werden. Die Ab- frage wird durch die Komposition von Elementen erstellt und weiter verfeinert. In folgender Abbildung ist Beispiel aus dem System IconicBrowser dargestellt, das die Abfrage „Zeige alle Hi-Fi Videorekorder deren Preis kleiner-gleich 600 USD ist und hiervon denjenigen mit dem geringsten Gewicht“ darstellt. Die verschiede- nen, sich überlappenden Icons stellen die einzelnen Teilabfragen dar.

Abbildung 13: Komposition aus Teilabfragen: Im IconicBrowser durch überlappende Icons dargestellt (aus [Cata97])

Ein weiterer Ansatz zur Erstellung der Abfrage ist die Verwendung von Suchmus- tern (by pattern-matching), bei dem der Anwender einen Teil eines Graphs als

34 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Suchmuster angibt und das System die Ergebnisse hierzu anzeigt. In folgender Abbildung ist ein Beispiel hierzu aus dem System „G+/GraphLog“ dargestellt, bei der ausgehend von der Stadt Toronto Flugverbindungen gesucht werden, die durchgehend von der Gesellschaft „Canadian Pacific (CP)“ betrieben werden:

Abbildung 14: Abfragen via Suchmuster: Ein Beispiel aus dem System G+/GraphLog. Die Ergebnisse können auf verschiedene Art angezeigt werden (aus [Cons92])

Ein weiterer Ansatz zur Formulierung der Abfrage ist die Verwendung von Von-Bis Intervallen (by range-selection). Die Abfrage erfolgt durch die direkte Manipula- tion von graphischen Elementen, wie Buttons, Sliders oder Listen, die jeweils ein Schlüsselattribut repräsentieren. Die folgende Abbildung zeigt den Prototypen „Dynamic Query“ mit dem die Elemente des Periodensystems abgefragt werden können. Die Manipulation jedes Reglers wirkt sich unmittelbar auf das Abfrageer- gebnis aus.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 35 Abbildung 15: Abfrage mittels Von-Bis Intervallen: Ein Beispiel aus Dynamic Query, wo Schiebereglern zur Direkten Manipulation von Abfrageparametern dienen.

3.1.4 Natürlichsprachliche Benutzerschnittstellen

Natural language interface (NLI)-Systeme erlauben dem Anwender in natürlicher Sprache mit dem System zu interagieren. Ein wichtiger Bereich in dem Bereich der Human-Computer-Interaction (HCI)-Forschungsrichtung erforscht die Inter- aktion mit Datenbanksystemen. Der Anwender formuliert seine Anfragen und tippt diese als Text ein und erhält das Abfrageergebnis3. Folgende Sitzung soll das beispielhaft demonstrieren:

> Who is the youngest employee in the sales department? John Smith > What is his salary? $25.000 > Does any employee in the sales department earn less than John Smith? Yes, George Adams.

Abbildung 16: Beispiel für eine NLI-Sitzung (übernommen aus [Andr00]).

Androutsopoulos und Ritchie haben in [Andr00] und [Andr94] einen Überblick über Natürlichsprachliche Benutzerschnittstellen für relationale Datenbanken (NLDBI) zusammengestellt. Auf deren Arbeiten basiert dieser Abschnitt.

Die ersten NLDBIs sind in den 1960er Jahren entstanden. LUNAR (mit Daten zur chemischen Analyse von Mondgestein der Apollo-Missionen), ist das bekannteste

3 Neuere Entwicklungen im Bereich NLI-Systeme erforschen die Spracheingabe (und –ausgabe) via Audio, dies wird in dieser Arbeit aber nicht weiter ausgeführt.

36 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken System aus dieser Zeit, mit dem überzeugend demonstriert wurde, dass verwend- bare NLDBI-Systeme tatsächlich entwickelt werden können. In den 1970ern ent- standen weitere Systeme wie RENDEVOUS, TORUS, PLANES, LADDER uvm. CHAT-80, entwickelt in den frühen 1980er Jahren, führte neue Ansätze und Tech- niken ein, die zu einem defacto-Standard wurden und u.a. die Basis für ein eben- falls wichtiges System: MASQUE/SQL bildeten. In Folge wurde der Forschungsbe- reich immer populärer, so dass viele weitere Systeme und Prototypen entstanden, wie beispielweise TEAM, ASK, JANUS, DATALOG uvm. Zudem sind in den 80er Jahren auch die ersten kommerziellen Systeme entstanden. Deren Erfolg wurde jedoch durch andere in dieser Zeit entstandene Ansätze zur Benutzerinteraktion überflügelt (siehe oben). Die meisten aktuellen NLDBI-Systeme basieren auf einer Architektur, die in der folgenden Abbildung schematisch dargestellt ist:

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 37 Abbildung 17: Die typische Architektur eines NLDBI-Systems (aus [Andr00])

Im Modul „Linguistic Front End“ erfolgt zuerst ein „pre-processing“, bei dem die Eingabe des Benutzers in Token zerlegt und die einzelnen Begriff/Wörter mor- phologisch analysiert werden. Mit Hilfe eines Wörterbuchs werden die syntakti- schen und semantischen Eigenschaften der Wörter ermittelt. Eigennamen aus der Datenbasis müssen dabei durch Mustererkennung und Datenbank-Lookups er- kannt werden. Beim „Parsing und semantische der Analyse“ entsteht daraus ein Ausdruck in der sogenannten „meaning representation language“ (MRL), die typischerweise eine Art Logik hat und definiert, welche Konstrukte das NLDBI-System versteht.

38 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Beispielsweise wird die Anfrage „What is the capital of each country bordering Greece?“ im System MASQUE/SQL zu folgendem MRL-Ausdruck transformiert: Answer([Capital, Country]):- Is_country(Country), borders(Country, greece), capital_of(Country, Capital). In der Phase des „semantischen post-processing“ werden anaphorische Ausdrü- cke wie beispielsweise „sie/er, sein(e), diese(r)“ aufgelöst, die der Anwender even- tuell in einer nachfolgenden Anfrage verwendet (siehe Eingangsbeispiel). Das Modul „Database-Backend“ hat nun die Aufgabe den vollständig aufge- lösten MRL-Ausdruck in SQL-Abfragen zu übersetzen. Manchmal erfolgt zuvor noch eine Übersetzungszwischenstufe, in eine theoretische Datenbank-Sprache wie den relationalen Calculus. Schließlich gilt es noch die Rohergebnisse der SQL- Abfragen aufzubereiten und daraus eine Antwort zu generieren. Hierbei bieten modern NLDBIs neben textuellen Antworten, Listen- und Tabellendarstellung auch anschauliche Grafiken en, wie beispielsweise Torten- oder Balkendiagram- me. Obwohl NLDBI-System seit ihren Anfangstagen große Fortschritte gemacht haben gibt es aktuell folgende Herausforderungen:

¾ Portabilität/Universalität: Die Systeme sind meist auf spezifische Wissensbe- reiche zugeschnitten

¾ Mehrsprachigkeit: einige natürliche Sprachen haben komplexere Grammati- ken als andere

¾ Mächtigkeit der Sprache (des NLDBI-Systems) ist dem Anwender nicht be- kannt

¾ Abfragen die Zeitpunkten/Intervalle beinhalten: der Zeit-Begriff ist ein kom- plexes Thema. „Gestern, vor zwei Wochen, im nächsten Jahr, während X der Abteilung Y vorstand“ verstehen die meisten NLDBI-System gar nicht oder nur eingeschränkt.

¾ Meta-Abfragen und modale Abfragen: Beispielsweise „Welche Informationen enthält die Datenbank?“ oder „Können Angestellte jünger als 18 Jahre sein?“

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 39 3.1.5 Unscharfe Abfragen

Unscharfe Abfragen – auch vage Abfragen genannt – stellen eine Erweiterung des Ansatzes dar, dass eine zweiwertige Wahr-falsch Logik wie in der Informatik üb- lich, für viele Datenabfragen nicht unbedingt geeignet ist. Unter bestimmten Um- ständen ist es von Vorteil, wenn der Wahrheitswert einer Abfragebedingung meh- rere graduelle Abstufungen zwischen Wahr und Falsch zulässt. Sogenannte Fuzzy- Sets, ein theoretischer Ansatz von Lofti Zadeh in den 1960-70er Jahren formuliert und verfeinert, bieten diese Möglichkeit. In den 1980er und 90er Jahren entstan- den erste Anwendungen von Fuzzylogik im Bereich Datenbanken. Die meisten, dieser Systeme sind der Klasse „Crisp Data, Fuzzy Query, Fuzzy Result“4 zuzu- rechnen. Es sind aber auch einige Ansätze und Prototypen entstanden, die zur für diesen Arbeit interessanteren Klasse „Crisp Data, Crisp Query und Fuzzy Result“ zählen, wie beispielsweise ARES, VAGUE und VQS, die nur kurz vorgestellt wer- den. Das System ARES (Associativ Information Retrieval System) von Ichikawa und Hirakawa aus dem Jahr 1986 [Ichi86] lieferte zu einer exakt formulierten Ab- frage ein unscharfes Ergebnis, wenn der neu eingeführte Operator “similar to” bzw. „approximately-equal“ verwendet wurde. Im Hintergrund musste hierfür ei- ne Tabelle mit Ähnlichkeiten von zwei Attributwerten gepflegt werden. Eine soge- nannte „Similarity Relation“ hat etwa folgenden Aufbau:

Jobtitle A Jobtitle B Similarity

Technician Technician 0 Technician Programmer 1 Technician Assembler 1 Technician Clerk 2 Technician Manager 2 Technician Seller 4

Abbildung 18: Beispiel einer Similarity Relation (aus [Küng97])

4 Küng und Palkoska haben in [Küng97] folgende Klassifizierung von Fuzzy System für Datenbanken vorgeschlagen: a) „Crisp Data, Crisp Query und Crisp Result“: Konventionelles DBMS. b) „Crisp Data, Fuzzy Query und Fuzzy Result“: Abfragen mit Wörtern wie „klein, groß, billig“ etc. sind hier möglich. c) „Fuzzy Data, Fuzzy Query und Fuzzy Result“: wie c) nur sind hier auch die Daten un- scharf. d) „Crisp Data, Crisp Query und Fuzzy Result“: Diese Systeme liefern zu einer exakt formu- lierten Abfrage wie select * from employee where salary is-about 5000 auch Ergebnisse die unge- fähr übereinstimmen. („is-about“ stellt hier den fuzzy-Operator dar)

40 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Der Anwender konnte in ARES auch einen Grad der erlaubten Mehrdeutig- keit/Ungenauigkeit einstellen, der bei der Abfrage angewendet werden soll. Das von Motro 1988 entwickelte System VAGUE [Motr88] führte das Tilde- symbol „~“ als Vergleichsoperator für unscharfe Übereinstimmung bzw. „ähnlich zu“ ein. Für die Bestimmung der Ähnlichkeit der Attribute definierte der Autor folgende Metriken: Berechnete (computational), Tabellarisch (tabular), Referen- ziell (referential) und Standard (Wahr-Falsch). VAGUE unterstützte die Verwen- dung von mehreren Metriken für einen Wertebereich/eine Domäne. Der Anwen- der konnte im Verlauf des Abfragedialogs sogar die Metrik auswählen, die ver- wendet werden soll, sowie die Gewichte, die einzelnen Attributen bei der Berech- nung einer referentiellen Metrik zukommen soll. Küng und Palkoska formulierten Ende der 1990er Jahre [Küng97] mit den so- genannten „NCR-Tabellen“ einen Ansatz zur Berechnung der Ähnlichkeit von Att- ributwerten, der auf alle nicht numerischen Attributwerte anwendbar ist5 und zeigten seine Anwendung im Prototyp VQS (Vague Query System). Eine „Nume- ric-Coordinate-Representation (NCR)“ Tabelle enthält die Attributwerte im NCR- Schlüsselfeld, sowie weitere Felder welche die Dimensionen repräsentieren- Die Werte in den Dimensionen sind numerisch. Somit kann mittels der euklidischen Distanz die Ähnlichkeit von zwei Attributwerten berechnet werden. Folgende Ta- belle veranschaulicht den Aufbau einer NCR-Tabelle am Beispiel von Farben. Als Dimensionen werden hier die Farbwerte für Rot, Grün und Blau verwendet:

Farbname Rot Grün Blue

Schwarz 0 0 0 Blau 0 0 255 : Cyan 0 255 255 Dunkelblau 0 0 139 : Weiß 255 255 255

Abbildung 19: Beispiel einer NCR-Tabelle (angelegt an [Küng97])

NCR-Tabellen haben gegenüber der Similarity Relation (siehe ARES) oder der ta- bellarischen Metrik (siehe VAGUE) den Vorteil, dass sie mit weniger Einträgen

5 Die (relative) Ähnlichkeit von numerischen Attributwerten kann ohnehin direkt aus dem Vergleich mit dem Minimum und Maximum-Werten berechnet werden.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 41 auskommen (n statt n²). Weiters können neue Einträge leichter hinzugefügt wer- den, weil hierfür genau ein neuer Eintrag in der NCR-Tabelle genügt. Damit mehrere Bedingungen in einer Abfrage berücksichtigt werden können, werden anhand der Extremwerte einer NCR-Tabelle alle Einträge auf das Intervall [0, 1] normalisiert. So kann für mehrere Attributwerte einfach ein Durchschnitt errechnet werden. VQS erlaubt zusätzlich Gewichte für bestimmte Attribute zu vergeben. So kann vom Anwender bestimmt werden, ob bei der Abfrage: „Unter- künfte in Wien-Umgebung und Preis kleiner 100,- EUR“ die Nähe zur Stadt Wien wichtiger ist als das Preiskriterium.

3.1.6 Begriffsbasierte Abfragen

Von einer begriffsbasierten Suche kann man sprechen, wenn der/die Anwen- der(in) die Anfrage durch Angabe von einem/mehreren Suchbegriffen „formu- liert“. Für eine derartige Suche in relationalen Datenbanken gibt es folgende An- sätze: a) Begriffsbasierte Suche mittels Abfrageformularen b) Begriffsbasierte Suche mittels natürlichsprachlichen Abfragen c) Begriffsbasierte Suche in publizierten Datenbanken d) Begriffsbasierte Suche im engeren Sinn

Begriffsbasierte Suche mittels Abfrageformularen

Eine einfache Art der begriffsbasierte Suche ist oftmals in proprietären Informati- onssystemen zu finden und dort mittels Abfrageformularen realisiert (von 4GL- Masken bis hin zu HTML-Formularen in Web-basierten Benutzerschnittstellen). Wird eine Abfragemaske mit mehreren Suchfelder verwendet, müssen die Suchbegriffe vom Anwender dort eingegeben werden, wo eine Übereinstimmung vermutet wird. Daraus lässt sich direkt eine SQL-Abfrage zusammenstellen, die folgenden Aufbau hat: SELECT * FROM WHERE = { AND = } Beispielsweise: SELECT * FROM publication WHERE author1 = 'brin' AND author2 = 'page' AND year = 1999

42 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Bleiben Suchfelder leer, weil der Anwender dort nichts eingibt, wird die entspre- chende Bedingung übersprungen und nicht an die WHERE-Klausel angehängt. Ebenso können mehrfache Eingaben in einem Suchfeld wie folgt in der Bedin- gung berücksichtigt werden: … { AND IN ( {, } ) } Beispielsweise: SELECT * FROM publication WHERE author in ('brin', 'page') AND year = 1999 Bei der zweiten Variante der begriffsbasierte Suche mittels Abfrageformularen steht der/dem Anwender(in) zur Eingabe der Suchbegriffe nur genau ein Einga- befeld zur Verfügung. Hier können die Begriffe demnach nicht direkt bestimmten Feldern zugeordnet werden, so dass in allen Feldern gesucht werden muss. Eine SQL-Abfrage hat hier folgenden Aufbau: SELECT * FROM WHERE IN ( {, } ) { OR IN ( {, } ) } Beispielsweise: SELECT * FROM publication WHERE author in ('brin', 'page', 1999) OR title in ('brin', 'page', 1999) OR year in ('brin', 'page', 1999) Zusammengefasst weist die begriffsbasierte Suche mittels Abfrageformularen ge- genüber der begriffsbasierte Suche im engeren Sinne folgende Vorteile (+) und Nachteile (-) auf: – Anwender muss ein zu seiner Abfrage passendes Abfrageformular auswählen – Die Suche ist nur in vorweg präparierten Formularen möglich – Bei nur einem einzigen Eingabefeld ist oftmals nicht transparent, in welchen Attributen gesucht bzw. in welchen nicht gesucht wird – Die logische Verknüpfung von mehreren Suchbegriffen (AND vs. OR) ist für den Anwender weder transparent noch beeinflussbar – Komplexe Abfrage sind nicht möglich oder nur dann, wenn eine entspre- chende Abfragemaske samt passender Vorlage/Programmierlogik für die Er- stellung der SQL-Abfrage vorbereitet wurde + Bei mehreren Eingabefelder ist für den Anwender einsichtig, welche Felder durchsucht werden können

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 43 + Einfach zu realisieren da nur geringer Programmieraufwand nötig + Gut für Anwender geeignet, die mit Eingabemasken vertraut und/oder mit den Wertebereiche der Felder vertraut sind

Begriffsbasierte Suche mittels natürlichsprachlichen Abfragen

Natürlichsprachliche Benutzerschnittstellen sind auch für die begriffsbasierte Su- che in relationalen Datenbanken geeignet. Zwei Ansätze hierzu sind a) Umfor- mung einer NL-Anfrage in begriffsbasierte Suche, sowie b) Meta-Abfragen in NL- Systemen. Der Ansatz zur Umformung einer Abfrage in natürlicher Sprache zu einer beg- riffsbasierte Anfrage wurde beispielsweise von Schraml 2001 untersucht und als Prototyp implementiert [Schr01]. Die Anwender können Abfragen in der folgen- den, einfachen Grammatik, die an natürliche Sprache angelehnt ist, formulieren:

Abbildung 20: Formale Definition der Abfrage (aus [Schr01])

Beispielsweise kann damit die Anfrage „Name der Studenten mit Wohnort in Linz“ ans System gestellt werden. Stoppwörter werden im ersten Schritt aus der Eingabe des Anwenders entfernt, wodurch hier „Name Studenten Wohnort Linz“ übrig bleibt. Nun wird die verbleibende Anfrage syntaktisch, gemäß der Gramma- tik geparst, wobei intern eine Synonymtabelle zur Auflösung von Namen von Re- lationen und Attributen verwendet wird. Die SQL-Abfrage wird auf Basis der mi-

44 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken nimalen Universalrelation erstellt, die alle Abfrageteile enthält. Schließlich wird das Ergebnis der SQL-Abfrage angezeigt. Folgende Abbildung zeigt die Benutzer- schnittstelle des Prototyps „Phrasen Suche“ mit zwei Beispielabfragen:

Abbildung 21: „Phrasen Suche“ mit zwei Beispielabfragen (aus [Schr01])

Ein anderer Ansatz um begriffsbasierte Suche mittels natürlichsprachlichen Be- nutzerschnittstellen zu realisieren sind Systeme, die sogenannte Metaabfragen unterstützen. Unter Abfragen zu Metawissen werden Fragestellungen verstanden, die sich auf das konzeptuelle Schema, die Organisation und/oder die Eigenschaf- ten der Daten beziehen. Das NLDBI-System „ASK“ [Thom83] konnte beispiels- weise die Fragestellung zu einer Datenbank mit Schiffen: „What is know about ships?“ beantworten und lieferte folgendes Ergebnis:

>What is known about ships?

Some are in the following classes: Navy freighter old tanker all have the following attributes: destination home port some have the following attributes: cargo all have the following number attributes: age some have the following number attributes: speed length

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 45 beam

Abbildung 22: Beispiel zu einer Metadatenabfrage im System „ASK“ (aus [Thom83])

Diese Abfrage könnte in folgende begriffsbasierte Abfrage „übersetzt“ werden „Ships“ und vice versa. Eine Anfrage aus mehreren Begriffen, könnte in einem NLDBI als „What have and in common“ oder „List entries for and “ formuliert werden. Die Vorteile (+) und Nachteile (-) von begriffsbasierte Suche mittels natürlich- sprachlichen Abfragen gegenüber der begriffsbasierte Suche im engeren Sinne lassen sich wie folgt zusammenfassen: – NLDBI-Systeme sind sehr komplexe Systeme, die für genau ein Gebiet und ein Datenbanksystem spezialisiert werden. Die Portierung auf ein DBS aus einer anderen Domäne ist vergleichsweise aufwändig. – Eine Anfrage muss in natürlicher Sprache ausformuliert werden, begriffsba- sierte Suche ist hier wesentlich prägnanter + Anwender kann die Anfrage in einer vertrauten, nämlich seiner Sprache for- mulieren und muss dabei formale Kriterien nur minimal berücksichtigen + Unter Umständen kann der Anwender durch die Formulierung in natürlicher Sprache Mehrdeutigkeiten bei der Interpretation der Abfrage vermeiden

Begriffsbasierte Suche in publizierten Datenbankinhalten

Wie im Abschnitt 2.2.2 ausgeführt wurde, sind die Suchroboter einer WWW-Such- maschine darauf ausgelegt, den Inhalt von Dokumenten (vorwiegend HTML- Seiten) zu indizieren. An den Inhalt von Datenbanken kommen sie Mangels Zu- gangsinformation und für diese Zwecke geeigneter Schnittstelle nicht heran. Der überwiegende Großteil der per WWW zugänglichen Information ist aber nach wie vor in (relationalen) Datenbanken gespeichert. Dieser Datenbereich wird auch als „Deep/Hidden/Invisible Web“ genannt. Zur Überwindung dieser „Zugangsbarriere“ bildeten sich ein paar Ansätze, die darauf setzen die Relationen der Datenbank als HTML-Seiten öffentlich auf einem Web-Server zu publizieren. Einerseits waren die Tabelleninhalte damit für Suchmaschinen erreichbar und konnten somit indiziert werden. Andererseits ging bei diesem Schritt aber auch semantische Information über das zugrunde-

46 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken liegende Datenbanksystem verloren, vor allem was die Beziehungen der Tabellen zueinander betrifft. Diese Technik des Publizierens ist vor allem für Datenbanken geeignet, die ohnehin nur wenige Tabellen und/oder ein einfaches Datenmodell haben, bei- spielsweise Adressverzeichnisse, Produktkataloge oder ähnliches. Nachteile dieses Ansatzes sind der zusätzliche Platzbedarf, der für die publizierte Version der Da- ten nötig ist und die Problematik bei Änderungen an den Quelldaten mit diesen synchron zu bleiben. In gewissem Sinne stellen aktuelle Ansätze, das Deep Web für Suchmaschinen verfügbar zu machen, eine Weiterentwicklung der Grundidee des Inhalte- Publizierens dar. Als Beispiele seien hierzu Googles WebTables und DeepWebCraw- ler [Cafa11], sowie Arbeiten zum Thema „Linked Data“ [Heat11] genannt.

Begriffsbasierte Suche in RDBen im engeren Sinn

Ansätze und Prototypen die ich zur Klasse der begriffsbasierten Suche in RDB im engeren Sinn zähle, haben im Gegensatz zu den bislang in diesem Abschnitt an- geführten Systemen jedenfalls folgende Hauptmerkmale:

¾ Die Benutzerschnittstelle besteht eingabeseitig aus einem einzigen Eingabe- feld in dem der/die Anwender(in) die Anfrage als mehr oder weniger lose Fol- ge von Begriffen eingeben kann.

¾ Das Backend-Modul der Suchmaschine, generiert dynamisch eine SQL- Abfrage und verwendet dabei die Fremdschlüssel-Abhängigkeiten zur Ver- knüpfung der Tabellen.

¾ Die Ausgabe der Suchergebnisse erfolgt in tabellarischer Form Darüber hinaus weisen viele Systeme einige der folgenden Merkmale auf:

¾ Die Ergebnisse sind anhand einer Relevanz-Metrik oder ähnlichem geordnet.

¾ Der Anwender kann einzelne oder alle Zwischenschritte bei der Generierung des Suchergebnisses (optional) einsehen, insbesondere die SQL-Abfragen.

¾ Die Benutzerschnittstelle ist als Web-basiertes System implementiert

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 47 Im folgenden Abschnitt werden einige Ansätze und Prototypen vorgestellt, welche zur Klasse der Systeme zur begriffsbasierten Suche in RDBen im engeren Sinne zählen6.

3.2 Ansätze zur begriffsbasierten Suche in relationalen Datenbanken

Bergamaschi, Guerra und Simonini geben in ihrer Arbeit [Berg14] einen Überblick über die Ansätze und Merkmale von neun bekannten Systemen zur begriffsba- sierten Suche in relationalen Datenbanken (u.a. DISCOVER, BANKS, DBXplorer)7. Dabei stellen sie die existierenden Ansätze zu den drei Phasen einer Suche: a) Übernahme und Interpretation der Suchanfrage des Anwenders b) Die eigentliche Suche aller bzw. der zu den Suchbegriffen der passenden Att- ributwerten bzw. Teile des Datenbankschemas c) Anzeige der Ergebnisse gegenüber und zeigen jeweils die gegenwärtig offenen Fragestellungen auf. Aus Platzgründen stelle ich im Folgenden, nur einige, aus meiner Sicht wich- tige und oft zitierte Arbeiten zur begriffsbasierten Suche in relationalen Daten- banken vor.

Queries from Tokens

Amihai Motro hat 1986 [Motr86] einen Ansatz zu einer „Art neuen Benutzer- schnittstelle für Datenbanken“ formuliert. Aus ein paar Begriffen – die er Token nennt – werden passende Abfragen und Ergebnisse generiert. Als Motivation führt er an, dass eine Abfragesprache ein Anwender dazu anhält, einerseits ein konkre- tes Ziel bei der Datenabfrage verfolgen zu müssen und andererseits voraussetzt mit der Organisation der Daten in der Datenbank (dem Datenmodell) vertraut zu sein. Für die meisten (End-)Anwender trifft dies jedoch nicht zu. Er schlägt des- halb vor dem Anwender eine Benutzerschnittstelle anzubieten mit der er/sie für bruchstückhafte Anfragen sowohl Ergebnisse als auch deren Interpretation erhält.

6 Stellvertretend für einen Ansatz/Prototyp der zwar begriffsbasierte Suche in relationalen Daten- banken unterstützt jedoch keine Zusammenhänge zwischen mehreren Tabellen/Tupel herstellen kann sei hier [Dwiv14] angeführt. 7 Die Autor(inn)en verweisen für eine noch ausführlichere Untersuchen des Themas auf die Arbeiten von Yu, Qin und Chang: [Yu09, Qin09]

48 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Letzteres soll beim weiteren Ausformulieren bzw. Konkretisieren der Abfrage un- terstützen. Der Anwender lernt so mit jeder Abfrage die Elemente Datenbank und deren Struktur besser kennen. Sein System verwendet eine Hilfstabelle „Lexicon“ um die Suchtoken auf Att- ributwerte bzw. Tabellen-/Attributnamen der Datenbank umschlüsseln zu kön- nen. Die Generierung der Abfrage basiert auf den Fremdschlüsselabhängigkeiten und wird mit minimal spannenden Bäumen, ein bekanntes Graph-Problem über- führt und gelöst. Motro zeigt in seiner Arbeit weiters auf:

¾ dass ein Suchtoken mehrere gleichwertige Zuordnungen im Lexikon haben kann, weil verschiedene semantische Bedeutungen dazu existieren (bei- spielsweise: Schwarz als Familienname oder Farbe),

¾ dass es gegebenenfalls mehrere gleichlange minimal spannende Bäume ge- ben kann und

¾ dass es mehrere Interpretationsmöglichkeiten zu einem konkreten Baum ge- ben kann. Zur Lösung von Mehrdeutigkeiten schlägt er drei Ansätze vor die auch im Proto- typ zum Einsatz kommen: a) Selbständiges Herausfinden der richtigen Interpreta- tion, b) Entscheidung dem Anwender überlassen und c) alle Interpretationsmög- lichkeiten weiterverfolgen. Schließlich macht er sich auch noch Gedanken, wie man das System „Queries from Tokens“ noch sinnvoll erweitern könnte: a) Einführung von arithmetischen Vergleichsoperatoren b) Die Hilfstabelle Lexicon sollte im Idealfall nicht der Anwender pflegen son- dern wie ein Tabellenindex automatisch vom DBMS aktualisiert werden c) Der Algorithmus zur Berechung der minimal spannenden Bäume könnte mit einer Obergrenze an maximal zu verbindenden Knoten/Kanten beschränkt werden Zusammengefasst lässt sich festhalten, dass Motro bereits 1986 die wichtigsten Eckpunkte des Aufbaus und der Algorithmen eines Systems zu begriffsbasierten Suche aufzeigt. Bemerkenswerterweise wird seine Arbeit in der Literatur zu die- sem Thema selten zitiert. Eventuell liegt dies auch daran, dass hier SQL als Query Language eingesetzt wurde, sondern eine eigene „dependency language“.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 49 Jungle

Ende der 1990er Jahre wurde von Böhlen, Bukauskas und Dyreson [Böhl99] eine der ersten Suchmaschine für Datenbanken entwickelt. Das System Jungle extra- hiert und indiziert hierzu Daten und Metadaten aus den zugänglichen Datenban- ken. Die dabei gesammelten Informationen werden dann zur Beantwortung der Benutzerabfragen herangezogen. Abfragen müssen vom Anwender in der Abfra- gesprache „AQUA“ formuliert werden, wobei die Autoren in sogenannte „vertika- le“ und „horizontale“ Abfragen unterscheiden:

Vertikale Abfragen Betrachtet man eine Datenbank als Hierarchie von Ebenen, deren oberste die Da- tenbank selbst ist und über Relationen, deren Attribute hinunter zu einzelnen Werten reicht, dann wird eine Abfrage, die sich an diese Reihenfolge hält in AQUA als „vertikal“ bezeichnet. Für die einzelnen Ebenen stehen die vier Bezeichner "DB:", "TAB:", "COL:" und "VAL:" zur Verfügung. Einzelne Ebenen der Hierarchie können in vertikalen Abfragen auch weggelassen werden. Beispielsweise liefert DB: "library" TAB: "publication" VAL: "Java" alle Datensätze in der Tabelle Pub- likationen der Datenbank Bibliothek, in den ein beliebiger Attributwert mit „Java“ übereinstimmt. Die Abfrage VAL: "Java" liefert ebenfalls Datensätze bei denen ein beliebiger Attributwert gleich „Java“ ist, diesmal jedoch ohne Beschränkung auf eine bestimmte Spalte, Tabelle und/oder Datenbank. Der Anwender kann mit die- sem Sprachkonstrukt festlegen auf welcher Hierarchieebene Jungle suchen soll.

Horizontale Abfragen Beinhaltet eine Abfrage Suchbegriffe, die zur gleichen Hierarchieebene gehören, so wird sie in AQUA als horizontale Abfrage bezeichnet. Beispielsweise kann die Beziehung von (Niklaus) Wirth zu Java mit der Abfrage VAL: "Wirth" AND VAL: "Java" herausgefunden werden. Das Jungle-Modul „AQUA Query Evaluation En- gine“ verknüpft die zur Beantwortung der Abfrage benötigten Tabellen mittels Fremdschlüsselabhängigkeiten, die via JDBC aus den Datenbanken ausgelesen werden.

Architektur Jungle besteht im Wesentlichen aus zwei Hauptmodulen, dem „Robot“ und der „Query evaluation engine“ für die Abfragesprache AQUA. Robot, das Jungle-

50 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Suchmodul hat die Aufgabe, alle erreichbaren8 Datenbanken zu besuchen und folgende Schritte auszuführen. Zuerst wird das Datenbankschema ausgelesen. Die extrahierten Metadaten werden indiziert. Die dabei gewonnen Informationen dienen später dem zweiten Modul zur Überführung der angegebenen Suchbegrif- fe in das entsprechende Objekt der Datenbank. Die Metadaten werden dann im zweiten Schritt dazu verwendet, um die in der Datenbank enthaltenen Attribut- werte auszulesen. Die SQL-Abfragen hierfür werden automatisch generiert. Über die ausgelesenen Attributwerte wird ebenfalls ein Index gebildet, wobei Zeichen- ketten in einzelne Wörter zerlegt werden. Numerische Attributwerte werden nicht klassisch indiziert, hier werden nur Minimal- und Maximalwert des entsprechen- den Attributs gespeichert. Robot liest schließlich noch die Fremdschlüssel- abhängigkeiten der Datenbank aus. Diese Informationen werden später von der Query Evaluation Engine verwendet werden, um die Joins für horizontale Abfra- gen zu bilden.

Zusammengefasst lässt sich über Jungle sagen, dass es als eines der ersten Syste- me zur begriffsbasierten Suche in relationalen Datenbanken:

¾ eine (heute übliche) Web-Oberfläche mit Suche via Eingabefeld und tabellari- scher Ergebnisdarstellung hatte,

¾ die Integration mehrerer Datenbanksysteme ermöglichte,

¾ dem Anwender Hyperlinks im Abfrageergebnis zur Verfügung stellte, mit de- nen er/sie weiternavigieren bzw. das Datenbanksystem durchstöbern konnte.

¾ den Anwender jedoch dazu zwang, seine Abfragen in der Abfragesprache AQUA zu formulieren, ihm/ihr jedoch hierdurch auch die Möglichkeit gab, die Suche auf bestimmte Teile der Datenbank einzuschränken.

Begriffsbasierte Suche mittels Reflective SQL

Der Ansatz von Maserman und Vossen [Mase00a] aus dem Jahr 2000 setzt, ähnlich wie AQUA (siehe oben) zur begriffsbasierten Suche in relationalen Datenbanken auf eine Abfragsprache: Reflective SQL (RSQL), das eine Erweiterung von SQL dar-

8 Dazu benötigt Robot jeweils entsprechende Zugangsinformationen, das sind (IP-)Adresse des Da- tenbankservers, Name der Datenbank, Benutzername und Passwort.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 51 stellt. In RSQL können Abfragen mittels folgenden Sprachkonstrukten formuliert werden: keyword-expr = simple-keyword-expr | keyword-expr ( 'AND' | 'OR' ) keyword-expr simple-keyword-expr = [ 'NOT' ] [ attributname ] operator keyword operator = ('LIKE' | '=' | '<' | '>' | '>=' | '<=' ) Damit sind beispielsweise Abfragen wie a) ='Küng', b) NOT 'Informationssysteme' AND ECTS > 3.5 sowie c) Name LIKE 'Wagn%' möglich. Der Anwender muss hier demnach nur mehr jene, vereinfachten Teile der (WHERE-Klausel einer) SQL- Abfrage angeben, die Bedingungen sind. Die begriffsbasierte Suche mittels RSQL verwendet als Zwischenstufe eine Repräsentation der Abfrage als SISQL-Abfrage. SISQL steht für „schema inde- pendent querying“ und stammt von denselben Autoren [Mase00b]. Die SISQL- Abfragen werden dann mittels der „data dictionary view“, in der die Metadaten eines konkreten RDBS abgebildet sind, auf eine konkrete, klassische SQL-Abfrage übersetzt und ausgeführt.

BANKS

Bhalotia et al. stellen 2002 in [Bhal02] einen Prototypen namens BANKS (Browsing and keyword search) vor, bei dem zur begriffbasierten Suche alle Tupel des DBS zu Knoten in einem Graph überführt und mittels Kanten verbunden werden, wobei letztere den Fremdschlüsselabhängigkeiten der Tabellen untereinander entspre- chen. Die Antwort auf eine Suchanfrage ist dann ein Subgraf, der die gesuchten Tupel bzw. Attribute verbindet. Zur Bestimmung, welche Subgrafen eine höhere Relevanz im Ergebnis haben, werden Knoten und Kanten Gewichte zugeordnet, die auf der Anzahl der (ein- und ausgehenden) Verbindungen untereinander basieren (siehe Ranking im Ab- schnitt Suchmaschinen). Ausgehend von den Gewichten der einzelnen Teile eines Subgrafs kann dessen insgesamte, relative Relevanz errechnet und somit fürs Ranking der Suchergebnisse heranzogen werden. Neben der begriffsbasierten Suche bietet die Web-Benutzerschnittstelle von BANKS dem Anwender auch die Möglichkeit die Ergebnisse zu durchstöbern und in Hypertext-manier zu anderen Tupel bzw. Tabellen zu navigieren.

52 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken DISCOVER

Der Prototyp DISCOVER, ist ein weiterer Ansatz zur begriffsbasierten Suche in re- lationalen Datenbanken und wurde 2002 von Hristidis und Papakonstantinou vorgestellt [Hris02]. Die Suchbegriffe werden in einem sogenannten „Master in- dex“ nachgeschlagen, der wiederum ein Set an Tupel liefert, in denen die Such- begriffe als Attributwerte vorkommen. Der Schwerpunkt der Arbeit sind Überle- gungen (mitsamt deren theoretischer Basis) zur Generierung eines „(minimal) joi- ning networks“, welches die Tupel via Fremdschlüsselabhänigkeiten verbindet. Der daraus resultierende Algorithmus kann mit einer Obergrenze der maximal zu verwendenden Joins beschränkt werden. Die Anzahl der Joins, die in der SQL- Abfrage zur Beantwort der Suchanfrage enthalten bzw. nötig sind, wird später auch zu deren Ranking verwendet, wobei das Suchergebnis nur für das minimale Joining-Network angezeigt wird. DISCOVER wurde später von den Autoren [Hris03] weiterentwickelt, indem u.a. eine Ranking-Funktion für die Suchbegriffe eingeführt wurde, die auf Ansätze aus dem Information Retrieval basieren.

DBXplorer

Agrawal, Chaudhuri und Das präsentierten 2002 [Agra02] mit dem System DBXplorer einen weiteren Prototyp zur begriffsbasierten Suche in relationalen Datenbanken. Den Schwerpunkt ihrer Arbeit bilden Überlegungen zur (perfor- manten) Implementierung der „Symboltabelle“, die im ersten Schritt der Suche zum Nachschlagen der Suchbegriffe herangezogen wird. Nach Untersuchung der beiden Varianten, die Referenzen auf die Tupel (rechte Seite der Symboltabelle) entweder auf der Granularität Spaltenebene (qualifizierter Attributname) oder auf Zeilenebene (rowid) zu verwenden, schlagen sie schließlich einen hybriden An- satz vor. Der Attributname wird verwendet, wenn ein Index für das Tabellenfeld vorhanden ist, sonst wird die rowid verwendet. Die Bildung der Abfrage erfolgt im DBXplorer mittels Ermittlung der Subgra- fen in dem Graph, der das DBS mit seinen Fremdschlüsselabhängigkeiten abbil- det. Hier kommt ein Algorithmus zum Einsatz der den Graphen solange verklei- nert, bis der übrig gebliebene Subgraf keine überflüssigen Knoten/Kanten mehr enthält. Im Vergleich zu anderen Ansätzen erfolgt dies nicht durch Konstruktion, sondern durch Reduktion. Die ermittelten Subgrafen, die Join-Bäume darstellen,

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 53 werden nach ihrer Gesamtlänge (Anzahl der enthaltenen Kanten) absteigend ge- ordnet. Die Benutzerschnittstelle von DBXplorer ist Web-basiert und erfordert vom Anwender nach der Eingabe der Suchbegriffe noch folgende Interaktionsschritte. Zuerst muss der Anwender eine Datenbank auswählen, in der die Suche weiter- verfolgt werden soll. Dieser Schritt kann entfallen, wenn nur ein Datenbanksys- tem publiziert wurde. Dann werden die gefunden Join-Bäume für das ausgewähl- te DBS angezeigt. Der Anwender wählt schließlich einen Join-Baum aus, und DBXplorer präsentiert (erst dann) das Ergebnis der entsprechenden SQL-Abfrage. Die Ergebnisse und Zwischenergebnisse sind teilweise mit Hyperlinks hinterlegt, die zur weiteren Navigation zur Verfügung stehen.

Neuere Ansätze und Prototypen

Kargar et al. haben 2014 „MeanKS“ (Meaningful Keyword Search) [Karg14] einen weiteren Prototypen vorgestellt, der hauptsächlich folgenden Aspekt der begriffs- basierten Suche in relationalen Datenbanken untersucht: die Behandlung von Mehrdeutigkeiten bei der Bestimmung von passenden „joining networks“. Hierzu erarbeiten die Autoren die Metrik „Instantiation Fraction“ welche die relative Relevanz einer Verbindung von zwei Tabellen im Schema angibt. Berech- net wird diese Kennzahl verkürzt gesprochen, auf Basis der Häufigkeitsverteilung der Fremdschlüssel-Primärschlüssel-Paare. MeanKS bietet dem Anwender die Möglichkeit eines der zur Abfrage passenden joining networks, das eine semanti- sche Interpretation der Suchanfrage darstellt, explizit auszuwählen. Zudem kann er/sie zur Sortierung der Ergebnisse neben Instantiation Fraction auch aus ande- ren Ranking-Modellen auswählen, beispielsweise sei hier das Ranking nach An- zahl der Joins genannt, das von DISCOVER und anderen verwendet wird (siehe oben).

Die Arbeit von Zeng et al. [Zeng14] beschäftigt sich mit dem Aspekt der Rangrei- hung der Suchergebnisse. Die Autoren stellen den Ansatz „pathRank“ vor, bei dem, basierend auf dem „Object-Relational-Mixed (ORM)“-Datengraf (der eben- falls von den Autoren stammt), vier Typen von semantischen Pfaden identifiziert werden. Jeder Typ stellt eine unterschiedliche Interpretation einer Abfrage bzw.

54 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken eines Abfrageergebnisses dar. „Simple Path“ und „Palindrom Path“ werden dabei höhere Relevanz zugeordnet als den Typen „Recursive Path“ und „Complex Path“ Auf Basis eines Datenbanksystems mit einem einfachen Datenmodell, das ca. 65.000 Publikationen und 105.000 Zitierungen enthält, zeigen die Autoren, dass das Ranking mittels pathRank präzisere Ergebnisse liefert als Modelle die auf An- zahl der Joins (beispielsweise DISCOVER, siehe oben), Bedeutung und Nähe (bei- spielsweise BANKS, siehe oben) oder auf TD-IDF-Ähnlichkeit von Abfrage und Er- gebnis (beispielsweise [Liu06]) basieren.

Tata und Lohman haben in [Tata08] untersucht wie sich der Ansatz der begriffs- basierte Suche erweitern lässt, um auch „aggregate queries“ beantworten zu kön- nen und zeigen dies anhand des Prototyps SQAK (SQL Aggregates using Key- words). Blunschi et al. [Blun12] zeigen mit ihrem Prototyp SODA (Search over Da- ta warehouse), wie sich begriffsbasierte Suche (inkl. aggregate queries) in Datawa- rehouse-Datenbanken für Business User einsetzen lässt.

Der Prototyp SASHERD, zur begriffsbasierten ad-hoc Suche in relationalen Da- tenbanken, der im Rahmen dieser Diplomarbeit entstanden ist, wird ausführlich im restlichen Teil dieses Dokuments vorgestellt.

Eine einfache ad-hoc Suchmaschine für relationale Datenbanken: SAHSERD 55 Teil 2

Prototyp „SAHSERD“

56 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken KAPITEL 4

4 Spezifikation

Das Hauptziel dieser Arbeit ist der Entwurf und die Implementierung eines einfa- chen, funktionsfähigen Prototyps, der wesentliche Merkmale der begriffsbasier- ten Suche in relationalen Datenbanken erfüllt. (vgl. hierzu 3.1.6) Hier gilt es nun, diese Merkmale in Form von Anforderungen zu konkretisie- ren, wobei in Basisanforderungen, welche die Kernfunktionalität des Prototyps betreffen und in zusätzliche Anforderungen, die sinnvolle Erweiterungen darstel- len, unterschieden wird. Außerdem umfasst die Spezifikation noch allgemeine Rahmenbedingungen und die Darstellung der Testumgebung.

4.1 Basisanforderungen

Web-basierte Benutzerschnittstelle

a1 Die Suchmaschine muss über einen Web-Browser bedienbar sein. Die Ein- gabe der Suchbegriffe erfolgt mittels HTML-Formular, die Ausgabe der Suchergebnisse in (HTML-)Tabellenform. a2 Alle (erweiterten) Optionen zur Suche, müssen ebenfalls im Eingabebereich der Suchmaschine dargestellt und konfigurierbar sein.

Suchanfrage, -begriffe

a3 Eine Suchanfrage kann aus einem oder mehreren Suchbegriffen bestehen. a4 Als Suchbegriffe sind alphanumerische Zeichenfolgen erlaubt, wobei nicht zwischen Groß-/Kleinschreibung unterschieden wird.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 57 a5 Suchbegriffe, die numerische Werte darstellen, müssen als einfache Zahlen angegeben werden. Numerische Werte in wissenschaftlicher Schreibweise (z.B.: "2,34E-2") werden nicht unterstützt.

Eigentliche Suche

a6 Die Suchmaschine durchsucht eine einzige Datenbank. a7 Die Suche in den Attributwerten der Datenbank muss, soweit es möglich ist, unabhängig vom physischen Attribut-Typ erfolgen. a8 Folgende ANSI/ISO SQL92-Datentypen müssen unterstützt werden1: a) String-Typen: "CHAR", "VARCHAR", "TEXT" b) numerischen Typen: "NUMERIC", "DECIMAL", "INTEGER", "SMALLINT", "FLOAT", "REAL" und "DOUBLE PRECISION".

4.2 Zusätzliche Anforderungen

a9 Soweit dies möglich und sinnvoll ist, sollen die Metadaten der Datenbank bei der Suche einbezogen werden. a10 Ein Verzeichnis mit Synonymen für Tabellen- und Attributbezeichnungen soll bei der Suche berücksichtigt werden. a11 Die Suche soll so konfigurierbar sein, dass neben exakten Übereinstimmun- gen auch „unscharfe“ Treffer angezeigt werden. a12 Die Ausgabe des Suchergebnisses sollte hinsichtlich Detaillierungsgrad kon- figurierbar sein. Jedenfalls soll es eine Möglichkeit geben, die verschiedenen Suchschritte und deren Zwischenergebnisse (inkl. der verwendeten SQL- Abfragen) anzuzeigen. a13 Vor allem aus Gründen der Vertraulichkeit bestimmter Daten sollte die Suchmaschine so konfigurierbar sein, dass die Suche auf bestimmte Attribu- te beschränkt bzw. bestimmte Attribute (bzw. ganze Relationen) generell von der Suche ausgeschlossen werden können.

1 Datentypen die Datums-/Zeitangaben betreffen (DATE, TIME, TIMESTAMP) sowie andere nicht angeführte Datentypen werden nicht unterstützt.

58 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 4.3 Rahmenbedingungen

r1 Hauptaugenmerk beim Entwurf und der Implementierung des Prototyps liegen auf der Umsetzung der angegebenen Anforderungen (Sachziele). Per- formance, Wiederverwendbarkeit des Sourcecodes und anderen Formalziele wird hingegen relativ wenig Beachtung geschenkt. r2 Der Prototyp soll primär für den Einsatz mit sehr kleinen Datenbanken aus- gelegt sein, damit werden Datenbanken verstanden, deren physische Ge- samtgröße (= Nutzdaten + Indizes + Metadaten) max. 50 MB beträgt. r3 Die Implementierung erfolgt in der Programmiersprache Java. r4 Als DBMS kommt MySQL zum Einsatz, der Prototyp soll soweit möglich aber auch mit anderen DBMS einsetzbar sein.

4.4 Testumgebung

4.4.1 Testdatenbank

Zur Veranschaulichung und Test der Funktionsweise von SAHSERD in dieser Ar- beit dient die Datenbank "UniLinz". Sie bildet den einen kleinen, überschaubaren Teilbereich der Universitätsverwaltung der Johannes Kepler Universität Linz, der zur Ausstellung von Lehrveranstaltungs-Zeugnissen nötig ist, vereinfacht ab. Ein LVA-Zeugnis in der Testdatenbank hat die den simplen Inhalt: Student, Lehrver- anstaltung (LVA), Prüfer und Note2. In der folgenden Abbildung ist das konzeptionelle Schema von "UniLinz" dargestellt. Daraus ist ersichtlich, dass neben den oben angeführten Objekten auch noch Informationen über LVA-Leiter, Studienrichtungen, Inskriptionen und Institute und ihre Mitglieder in der Datenbank verwaltet werden. Dies ist nötig um bestimmte Test-Konstellationen herstellen zu können.

2 Um das Datenmodell möglichst einfach zu halten, enthält das LVA-Zeugnis beispielsweise keine Angaben über das Semester und das Prüfungsdatum.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 59 Abbildung 23: Konzeptionelles Schema der Testdatenbank "UniLinz"

Das konzeptionelle Schema der Testdatenbank "UniLinz" wurde im Zuge des physischen Datenbankentwurfs in folgende 9 Relationen überführt3: Institut(InstNr, Name, VorstandPersNr, Adresse) LVA(LVANr, Titel, StdAnzahl, ECTSCredits, LVATyp) Student(MatrikelNr, Nachname, Vorname, GebDat, Geschlecht, Adresse) Studienrichtung(SKZ, Bezeichnung) WissPersonal(PersNr, Titel, Nachname, Vorname, Geschlecht) Inskription(MatrikelNr, SKZ) InstMitglied(PersNr, InstNr, Position, TelefonNr) LVALeiter(LVANr, PersNr) LVAZeugnis(LVANr, MatrikelNr, Pruefer, Note) Primärschlüssel-Attribute sind fett, Fremdschlüssel-Attribute kursiv und Attribute die Teil eines Index sind, sind unterstrichen dargestellt.

4.4.2 Testfälle

Die nachfolgenden Testfälle, sollen vor dem Hintergrund der Testdaten in „Uni- Linz“ die erwarteten Suchergebnisse (Output) zu gegebenen Suchanfragen (In- put) beschreiben. Dadurch wird einerseits das gewünschte Verhalten der Such- maschine konkretisiert und man erhält rasch einen Eindruck davon, was der Pro- totyp SAHSERD leisten soll. Konkrete Ergebnisse zu ausgewählten Testfällen wer- den in Abschnitt 7.2 dargestellt und erläutert. Die Suchergebnisse sind in Standardergebnisse (StdErg) und erweiterte Er- gebnisse (ErwErg) unterteilt. Letztere sollen nur bei entsprechend konfigurierter

3 Das vollständige ER-Diagramm von UniLinz ist in Anhang A angeführt.

60 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Suchtiefe angezeigt werden. Wenn nicht anderes angegeben, gelangen nur exakte Übereinstimmungen mit den Suchbegriffen ins Ergebnis. a) Einfache Anfragen mit einem Suchbegriff

Einfache Suchanfragen, die aus einem einzigen Suchbegriff bestehen, könnte man in natürlicher Sprache als Frage „Was4 ist über/zu Suchbegriff (in der Daten- bank "UniLinz") gespeichert?“ an die Suchmaschine formulieren.

Suchanfrage Suchergebnis

StdErg: Stammdaten des Student "Michael McGregor" (MatrikelNr "0056410") a1) "0056410" ErwErg1: Studienrichtungen, die Hr. McGregor belegt hat ErwErg2: LVA-Zeugnisse die für Hr. McGregor ausgestellt wurden StdErg: Stammdaten von Prof. Roland Wagner ErwErg1: Instituts-Mitgliedschaften von Prof. Wagner a2) "Wagner" ErwErg2: LVAs die von Prof. Wagner (mit-)geleitet werden ErwErg3: LVA-Zeugnisse die Prof. Wagner (als Prüfer) ausgestellt hat StdErg: LVAs mit dem Titel "Informationssysteme" ErwErg1: LVA-Zeugnisse zu LVAs mit dem Titel "Informationssysteme" wenn die unscharfe Suche aktiviert ist: a3) "Informationssysteme" StdErg: LVAs die "Informationssysteme" im Titel tragen, z.B.: "Informationssysteme für WIN" ErwErg1: LVA-Zeugnisse zu LVAs mit "Informationssysteme" im Titel

Abbildung 24: Testfälle für einfache Anfragen mit einem Suchbegriff

b) Einfache Abfragen mit mehreren Suchbegriffen

Einfache Suchanfragen, die aus mehreren Suchbegriffen bestehen, könnte man in natürlicher Sprache wiederum als Frage „Was ist über/zu Suchbegriff1...N (in der Datenbank "UniLinz") gespeichert?“ an die Suchmaschine formulieren. Alternativ oder zusätzlich lässt sich die Frage auch als „Welchen Zusammenhang gibt es zwi- schen den Suchbegriffen Suchbegriff1...N?“ stellen, wodurch SAHSERD gezwun- gen wird, selbst (Quer-)Verbindungen herzustellen – eine zentrale Anforderung an eine Suchmaschine für relationale Datenbanken.

Suchanfrage Suchergebnis

4 „Was“, steht vor dem Hintergrund, dass eine relationale Datenbank durchsucht wird, für „welche Datenbanke-Objekte“, das sind Tabellen, Attribute, Attributwerte bzw. Datensätze.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 61 b1) "Durchwahl" "Wagner" StdErg: Instituts-Mitgliedschaften5 von Prof. Roland Wagner Dazu gibt es keine exakten Übereinstimmungen. SAHSERD liefert fol- b2) "Telefon" "Institut" "So- gende Ergebnisse nur wenn die unscharfe Suche aktiviert ist: ziologie" StdErg: Institutsmitglieder des „Instituts für Soziologie“ StdErg: LVA-Zeugnisse die Prof. Josef Küng (als Prüfer) für den Stu- b3) "Küng" "9856588" dent „Fritz Fischer“ (MatrikelNr "9856588") ausgestellt hat StdErg: Stammdaten von "Prof. Josef Küng", "Prof. Wolfram Wöß" und "DI Albrecht Wöß" ErwErg1: Instituts-Mitgliedschaften von Prof. Küng oder Prof. Wöß und DI Wöß b4) "Küng" "Wöß" ErwErg2: LVAs die von Prof. Küng oder Prof. Wöß geleitet werden ErwErg3: LVAs die von Prof. Küng und Prof. Wöß gemeinsam geleitet werden ErwErg4: LVA-Zeugnisse die von Prof. Küng oder Prof. Wöß (als Prüfer) ausgestellt wurden StdErg: Stammdaten der Studenten "Fritz Fischer (9856588)", "Ingo b5) "9856588" "9956627" Igler (9956627)" und "Otto Oswald (0055880)" "0055880" ErwErg1: Inskriptionen der Studenten Fischer, Igler und Oswald ErwErg2: LVA-Zeugnisse der Studenten Fischer, Igler und Oswald

Abbildung 25: Testfälle für einfache Anfragen mit mehreren Suchbegriffen

c) Komplexe Anfragen

Unter komplexen Suchanfragen werden hier Suchanfragen verstanden, die mehr- deutige Suchergebnisse liefern. Das bedeutet, dass zu mindestens einem Such- begriff Übereinstimmungen in verschiedenen Tabellen gefunden werden. Außerdem sind hier auch Testfälle angeführt die zu sogenannten „Metadaten- Ergebnissen“ führen. Das bedeutet, dass alle angegebenen Suchbegriffe mit Be- zeichnungen von Tabelle und/oder Attributen der Datenbank übereinstimmen6.

Suchanfrage Suchergebnis

StdErg1: Stammdaten des Student "Stefan Student" (MatrikelNr "0155304") c1) "Student" ErwErg1: Metadaten-Ergebnis: Tabelle "Studenten" ErwErg2: Studienrichtungen, die Hr. Student belegt hat ErwErg3: LVA-Zeugnisse die für Hr. Student ausgestellt wurden

5 Die Tabelle "InstMitglied" enthält u.a. das Attribut "TelefonNr", siehe Datenmodell. 6 Siehe Abschnitt 5.4

62 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken StdErg: Stammdaten zur Studienrichtung "Informatik" ErwErg1: Inskriptionen zur Studienrichtung "Informatik" wenn die unscharfe Suche aktiviert ist: StdErg1: Studienrichtungen die "Informatik" im Bezeichnungsfeld tra- gen: "Informatik", "Wirtschaftsinformatik" StdErg2: LVAs die "Informatik" im Titel tragen z.B.: "Angewandte In- c2) "Informatik" formatik in Wirtschaft und Verwaltung", "Management von Informatikprojekten" etc. StdErg3: Institute die "Informatik" im Namen tragen, z.B.: "Institut für Wirtschaftsinformatik", "Institut für Angewandte Informatik" ErwErg1: Inskriptionen zu Studienrichtungen die "Informatik" im Be- zeichnungsfeld tragen ErwErg2: LVA-Zeugnisse zu LVAs die "Informatik" im Titel tragen ErwErg3: Mitglieder der Institute die "Informatik" im Namen tragen StdErg1: LVA-Zeugnisse für den Studenten "Fritz Fischer" StdErg2: LVA-Zeugnisse die Prof. Fischer (als Prüfer) ausgestellt hat c3) "Zeugnisse" "Fischer" ErwErg1: LVA-Zeugnisse die Prof. Fischer (als Prüfer) für den Student "Fritz Fischer" ausgestellt hat StdErg1: LVAs deren Vortragende mit Vornamen "Heinrich" heißen StdErg2: LVAs deren Vortragende mit Nachnamen "Heinrich" heißen c4) "LVAs" "Heinrich" ErwErg1: LVA-Zeugnisse für Prüfer mit dem Vornamen "Heinrich" ErwErg2: LVA-Zeugnisse für Prüfer mit dem Nachnamen "Heinrich" ErwErg3: LVA-Zeugnisse für Studenten mit dem Vornamen "Heinrich" Dazu gibt es keine exakten Übereinstimmungen. SAHSERD liefert fol- gende Ergebnisse nur wenn die unscharfe Suche aktiviert ist: StdErg1: LVA-Zeugnisse für Studenten die "Berger" im Nachnamen tragen, z.B.: "Helga Hamberger", "Ulla Unterberger" c5) "LVAs" "Berger" StdErg2: LVAs die Vortragende mit "Berger" im Nachnamen leiten, z.B: "Prof. Gustav Pomberger", "Prof. Bruno Buchberger" ErwErg1: LVA-Zeugnisse für Prüfer mit "Berger" im Nachnamen ErwErg2: LVA-Zeugnisse die Prüfer mit "Berger" im Nachnamen für Studenten mit "Berger" im Nachnamen ausgestellt haben StdErg1: LVA-Zeugnisse die Studenten der Studienrichtung "Informa- tik" abgelegt haben wenn die unscharfe Suche aktiviert ist: StdErg1: Institute die "Informatik" im Namen tragen, siehe c2) ErwErg1: Mitglieder der Institute die "Informatik" im Namen tragen c6) "Institut" "Informatik" ErwErg2: LVAs die Mitglieder der Institute, die "Informatik" im Namen tragen, leiten ErwErg3: LVA-Zeugnisse deren Prüfer Mitglieder der Institute, die "In- formatik" im Namen tragen, sind ErwErg4: LVA-Zeugnisse inkl. Institutsmitgliedschaft der Prüfer von Studenten, die eine Studienrichtung inskribiert haben, die "Informatik" im Namen trägt ErwErg: Metadaten-Ergebnis: Verbindung(en) zwischen Tabelle „LVA“ c7) „LVA“ „Matrikel#“ und dem Attribut „MatrikelNr“: LVA-Zeugnis

Abbildung 26: Testfälle für komplexe Suchanfragen

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 63 KAPITEL 5

5 Entwurf

Auf Basis der Spezifikation wird in diesem Kapitel die Entwurfsphase dokumen- tiert. Zunächst wird die allgemeine Systemarchitektur für eine Suchmaschine für relationale Datenbanken dargestellt, dann werden grundsätzliche Ansätze zur Lö- sung der formulierten Anforderungen vorgestellt und bewertet. Vor diesem Hin- tergrund erfolgt die Entwurfsentscheidung für eine bestimmte Lösungsvariante, auf deren Grundlage, zusammen mit einigen Erweiterungen, der Prototyp SAHSERD basiert. Zudem werden an einigen Stellen dieses Kapitels spezielle Al- gorithmen und Datenstrukturen erarbeitet, die zur Erfüllung der spezifizierten Anforderungen benötigt werden.

5.1 Allgemeiner Lösungsansatz

Eine Suchmaschine für relationale Datenbanken muss zur Überführung der Suchanfrage in ein entsprechendes Suchergebnis mehrere Schritte ausführen. Der entsprechende Datenfluss ist in folgender Abbildung anhand der Systemarchitek- tur dargestellt:

64 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 27: Systemarchitektur einer Suchmaschine für relationale Datenbanken (schematische Darstellung)

Das Suchmodul – die Suchmaschine im engeren Sinn – ist eingangsseitig (im Sin- ne des Datenflusses) ans Modul 'Abfrageparser' und ausgangsseitig ans Modul 'Ergebnisaufbereitung' angeschlossen, die jeweils die Ein- bzw. Ausgabeschnitt- stelle der Suchmaschine zum Benutzer bilden.

5.1.1 Systemkomponenten

Abfrageparser

Das Suchmodul der Suchmaschine erwartet als Eingabe eine Liste von Suchbeg- riffen (Wörter oder Phrasen), wobei deren Reihenfolge keinen Einfluss auf das Suchergebnis hat. Der Abfrageparser für diese Minimal-Grammatik hat daher die einfache Aufgabe, den Eingabestrom (Zeichenkette) in eine Liste von Suchbegrif- fen zu zerhacken und mehrfache angegebene Suchbegriffe auszufiltern. Input: Zeichenkette Output: Liste von Suchbegriffen

Suchmodul (Suchmaschine im engeren Sinn)

Das Suchmodul ist der Kern des Systems und erledigt die eigentliche Aufgabe der Suchmaschine: die Überführung der Liste der Suchbegriffe in entsprechende SQL-Abfragen (SELECT-Statements). Diese Aufgabe wird in zwei Teilschritten (Such-Phasen) erledigt. Zuerst müssen zu den Suchbegriffen Übereinstimmungen mit DB-Objekten (darunter werden hier Tabellen, Attribute, Attributwerte ver- standen) gesucht werden, für die dann im zweiten Schritt entsprechende SQL- Abfragen erstellt werden. Im nächsten Abschnitt werden verschiedene Lösungsal- ternativen für die beiden Teilschritte im Detail dargestellt und ihre Vor- und Nachteile abgewogen. Input: Liste von Suchbegriffen Output: SQL-Abfragen (= SELECT-Statement)

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 65 Ergebnisaufbereitung

Das Ergebnis aus der Ausführung der SELECT-Statements (das Suchergebnis) wird hier als HTML-Text in Tabellen-Form formatiert. Input: SELECT-Statements Output: Abfrageergebnisse als HTML(-Tabellen)

5.2 Lösungsalternativen zum Suchmodul

Ziel des Suchmoduls ist die Überführung der Suchanfrage in entsprechende SE- LECT-Statements. Die Lösung dieser Aufgabe kann in zwei Teilschritte aufgeteilt werden: a) "DB-Objekte" zu den Suchbegriffen/-phrasen ermitteln b) SELECT-Statements zu den Datensätzen bzw. DB-Objekten erstellen Im Folgenden werden nun verschiedene Lösungsalternativen zu den beiden Teil- schritten und deren Schnittstelle vorgestellt und ihre Vor- und Nachteile bespro- chen.

Überblick

Lösungsalternativen zu Teilschritt 1: a) Suche mittels Wort-Index b) ad-hoc Suche in der Datenbank Lösungsalternativen zu Teilschritt 2: a) Views: vorhandene Views benutzen b) Joins: entsprechende Views (temporär) aus den Tabellen konstruieren Alternativen zur Schnittstelle 1 o 2: A) Row-IDs bzw. Primärschlüssel B) Zugriffspfade

Daraus ergeben sich theoretisch folgende 8 Kombinationsmöglichkeiten: 1a-2a-A, 1a-2a-B, 1a-2b-A, 1a-2b-B, 1b-2a-A, 1b-2a-B, 1b-2b-A, 1b-2b-B Folgende drei Kombinationen sollen weiter untersucht werden: Lösungsalternative A: Wort-Index + Views + Datensatz-Ids (1a-2a-A) Lösungsalternative B: Wort-Index + Views + Zugriffspfade (1a-2a-B) Lösungsalternative C: Ad-hoc Suche + Joins + Zugriffspfade (1b-2b-B)

66 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Die jeweilige Ablauflogik soll anhand folgender Suchabfragen (siehe 4.4.2 Testfälle a2 und b3 aus der Spezifikation) demonstriert werden:

Suchbeispiel 1

Suchbegriff: „Wagner“ Suchergebnis: SELECT-Statement, das folgendes Ergebnis liefert:

Tabelle/View: WissPersonal

PersNr Titel Nachname Vorname Geschlecht Mag., Dr. MA., Ph.D., 1202 Wagner Franz M Ass.Prof. 1203 Mag., Dr. Wagner Helga W 1204 Dipl.Ing., Dr., Univ.Prof. Wagner Roland M 1205 Dr., a.Univ.Prof. Wagner Wolfgang M

Suchbeispiel 2

Suchbegriffe: „Küng“, „9856588“ Suchergebnis: SELECT-Statement, das folgendes Ergebnis liefert:

Tabelle/View: LVAZeugnis

LVA-Nr LVA-Typ LVA-Titel ECTS Prüfer Matrikel# Name Note Josef Fatima 351001 VO Informationssysteme 1 3.0 9856588 2 Küng Fischer Anwendungsorientierte Josef Fatima 351047 VO 3.0 9856588 1 Wissensverarbeitung Küng Fischer

5.2.1 Lösungsalternative A: Wort-Index + Views + Datensatz-Ids

Lösungsalternative A ist eine beinahe unveränderte Übertragung der Funktions- weise einer WWW- bzw. IR-Suchmaschine auf das SAHSERD-Suchmodul. Teil- schritt 1 wird mit einem Wort-Index gelöst und liefert statt URLs (wie bei einer WWW-Suchmaschine) Datensatz-Ids. Im Teilschritt 2 werden dieses Ids auf (vor- handenen) Views übertragen und entsprechende SQL-Abfragen an die Datenbank generiert.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 67 Teilschritt 1: Lösung mittles Wort-Index

Analog zum "content index" einer WWW-Suchmaschine, einem Verzeichnis über die Wörter der indizierten HTML-Seiten und Verweise auf deren Fundstellen im Internet (als codierte URLs), bildet hier der Wort-Index als "Lexikon der Suchbeg- riffe", das zentrale Suchregister für das Suchmodul. Unabhängig von der internen Implementierung dieser Datenstruktur1, kann der Wort-Index als zweispaltige Tabelle veranschaulicht werden, deren linke Spal- te alle Suchbegriffe und deren rechte Spalte deren Vorkommen in der Datenbank enthält (siehe Abbildung 28). Zur Suche wird eine Funktion bzw. Methode benö- tigt, die zu einem gegebenen Wort alle Datensatz-Ids liefert. Spätestens bei der Implementierung ist hinsichtlich der Laufzeit der Suche mit Mustervergleich (LIKE-Suche) ebenfalls abzuwägen, ob auf der linken Tabel- lenseite ausschließlich vollständige Attributwerte stehen sollen, was einen kleine- rer Index bedeutet, da jeder Attributwert genau einen Eintrag im Index hat ("An- wendungsorientierte Wissensverarbeitung"). Stehen links jedoch ausschließlich einzelne Worte, erfordert dies einen größeren Index, da ein Attributwert auf mehr als einen Index-Eintrag verteilt sein kann ("Anwendungsorientierte", "Wissens- verarbeitung"), dafür verringert sich die Laufzeit von Index-Abfragen.

Schlüsselwort Datensatz-ID (Fortsetzung)

150 v_Studienrichtung:#150 Küng v_WissPersonal:#1100 175 v_Studienrichtung:#175 Küng v_InstMitglied:#829d27 881 v_Studienrichtung:#881 Küng v_LVALeiter:#898911 0055050 v_Student:#0055050 Küng v_LVALeiter:#989822 Küng v_LVAZeugnis:#719283 9856588 v_Student:#9856588 Küng v_LVAZeugnis:#a53842 9856588 v_Inskription:#a7f46b Küng v_LVAZeugnis:#30c9e2 9856588 v_Inskription:#a7f454 Küng v_LVAZeugnis:#b91e20 9856588 v_LVAZeugnis:#970c71 Küng v_LVAZeugnis:#3208a8 9856588 v_LVAZeugnis:#724667 9856588 v_LVAZeugnis:#b91e20 Wagner v_WissPersonal:#1202 9856588 v_LVAZeugnis:#3208a8 Wagner v_WissPersonal:#1203

1 Eine Datenstruktur, die ein assoziatives Array abbildet ist zur Lösung einer Reihe von Problemklas- sen nützlich und daher in vielen Klassen- und Funktions-Bibliotheken als „Map“, „Dictionary“ etc. implementiert, beispielsweise die Java-Klasse „java.utils.Map“. Die konkrete Implementierung er- folgt in der Praxis meist durch Varianten von „B-Bäumen“ (für numerische Werte) und „Hash- Tabellen“ (für Zeichenketten), die auf das erwartete Verhältnis der Lese-Zugriffe zur Datenände- rungsrate optimiert sind. Generell ist der Lese-Zugriff auf das Verzeichnis nur über die Schlüssel- wörter vorgesehen bzw. effizient implementiert.

68 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 9856588 v_LVAZeugnis:#0d3822 Wagner v_WissPersonal:#1204 9856588 v_LVAZeugnis:#9823bf Wagner v_WissPersonal:#1205

Abbildung 28: Wort-Index mit Datensatz-IDs

Unter der Voraussetzung dass ein entsprechender Wort-Index vorhanden ist, be- steht die Ablauflogik für Teilschritt 1 darin, den Wort-Index nach den Suchbegrif- fen auszulesen. Die dabei retournierten Datensatz-Ids, hier in der Form . bzw. ., werden an den zweiten Schritt weitergegeben. Besteht die Suchabfrage aus zwei oder mehreren Suchbeg- riffen, müssen aus den retournierten Datensatz-Ids diejenigen herausgefiltert werden, die ident sind. Die betroffenen Einträge des Wort-Index sind für Suchbeispiel 1: "Wagner" hellgrau und für Suchbeispiel 2: "Küng”, “9856588" dunkelgrau hervorgehoben.

Teilschritt 2: Lösung mittles Views

Unter einer View (Datensicht) versteht man eine virtuelle Tabelle, die auf dem Er- gebnis einer Abfrage basiert. Mittels dieser Technik werden in der Praxis (zumeist komplexe) Abfragen, die in der Regel mehrere Tabellen verknüpfen als virtuelle Tabelle erstellt, deren „Innenleben“ für den Anwender nicht sichtbar ist. In vielen Datenbanksystemen werden mittels Views Teile des Schemas für Endbenutzer- Abfragen denormalisiert. Der Anwender soll hierdurch auf alle Attribute eines Ob- jekts zugreifen können, unabhängig auf wie viele physische Tabellen die Attribute verteilt sind. Folgendes Beispiel zeigt ein typisches Anwendungsbeispiel aus der Testdatenbank UniLinz:

CREATE VIEW v_lvazeugnis AS SELECT * FROM lvazeugnis as lz, student as st, wisspersonal as wp WHERE lz.matrikelnr = st.matrikelnr AND lz.pruefer = wp.persnr; SELECT * FROM v_lvazeugnis WHERE matrikelnr = 9956627; Dieser Lösungsansatz für den zweiten Teilschritt nutzt ausschließlich die vorhan- denen Views zur Generierung der SQL-Abfragen. Das bedeutet, dass die "FROM- Klausel" nur genau eine Tabelle bzw. View enthält und daher in der "WHERE- Klausel" des erstellten SELECT-Statements keine Abfragebedingungen für Joins enthalten sind. In Kombination mit der hier gewählten Umsetzung für Teilschritt 1 (Wort- Index) und deren Schnittstelle zu Teilschritt 2 (Datensatz-Ids) bedeutet dies, dass

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 69 die generierten SQL-Abfragen keinen Bezug zu den ursprünglichen Suchbegriffen beinhalten, wie an den WHERE-Klauseln folgender SELECT-Statements erkenn- bar ist:

SELECT * FROM v_WissPersonal WHERE PersNr IN (1202, 1203, 1204, 1205);

SELECT-Statement für Suchbeispiel 1: „Wagner“

SELECT * FROM v_LVAZeugnis WHERE ROWID IN (b91e20, 3208a8);

SELECT-Statement für Suchbeispiel 2: „Küng“, „9856588“

Wie oben bereits erwähnt, kann als Datensatz-Id sowohl die Row-Id als auch jeder eindeutige Schlüssel (beispielsweise der Primärschlüssel) verwendet werden. Im Algorithmus zur Erstellung der WHERE-Klausel muss darauf entsprechend Rück- sicht genommen werden.

Vorteile und Nachteile von Lösungsalternative A

Die Vor- und Nachteile dieser Lösungsalternative für das SAHSERD-Suchmodul setzen sich aus den Vor- und Nachteilen für die hier kombinierten Teillösungen: Wort-Index, Views und Datensatz-Ids zusammen.

Der Einsatz eines Wort-Index hat folgende Stärken und Schwächen2: + Geschwindigkeit: Der Wort-Index ermöglicht die schnelle Ermittlung der ge- suchten Datensatz-Ids ohne langsames, sequentielles Durchsuchen der Da- tenbank. Die Implementierung kann auch derart erfolgen, dass bei der Suche gar kein physischer Zugriff notwendig ist, dann nämlich, wenn der Index voll- ständig im Hauptspeicher gehalten wird. – Voraussetzung: Der Wort-Index muss vor der Beantwortung der Suchabfragen (für die zu durchsuchende Datenbank) angelegt werden. – Aktualität: Für die Index-basierte Suche gilt die Schlussfolgerung: wird der Suchbegriff (nicht) im Wort-Index gefunden, so ist er auch (nicht) in der Da-

2 Ziel ist einerseits die Größe des Index gering, und andererseits gleichzeitig den Index möglichst ak- tuell zu halten. Diese Problematik gilt in besonderem Maße für WWW-Suchmaschinen, wobei dort zusätzlich die rollierende Aktualisierung und der gleichzeitige, verteilte Einsatz der Such-Robots berücksichtigt werden müssen. Vgl. hierzu Abschnitt 2.2.2

70 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken tenbasis - hier Datenbank. Damit keine Diskrepanz zwischen Datenbasis und Index entsteht, bzw. diese Abweichung möglichst klein ist, sollte der Index oft genug aktualisiert werden, im Optimalfall nach jeder Änderung der Daten- bank. – Platzbedarf: Der Wort-Index benötigt selbst einen erheblichen Teil an zusätz- lichen Speicher-Ressourcen. Der maximale Platzbedarf lässt sich wie folgt be- rechnen: Anzahl der Index-Einträge = Anzahl der Attribute x Anzahl der Da- tensätze x Korrekturfaktor. Werden als Schlüsselwörter nicht vollständige Att- ributwerte sondern einzelne Wörter gespeichert (siehe oben), muss dieser Wert noch mit einem entsprechenden Faktor multipliziert werden. Dies kann im Extremfall dazu führen, dass der Wort-Index mehr Platz benötigt als die Datenbank selbst. – Redundanz: Derzeit unterstützen die gängigen DBMS lediglich die Indizie- rung eines Attributs oder einer Kombination aus mehreren Attributen einer Tabelle. Einige DBMS bieten darüber hinaus Erweiterungen für Volltext-Suche in Attributen vom SQL-Datentyp "TEXT" bzw. "CLOB" an3. Ein einheitlicher, zentraler Wort-Index über alle in der Datenbank gespeicherten Attributwerte bzw. über alle in den Attributwerten enthaltenen Wörter (siehe oben) wird von keinem DBMS unterstützt. Somit muss parallel eine zusätzliche Daten- struktur verwaltet werden, deren Inhalt sich großteils mit den ohnehin vor- handenen Tabellen-Indizes überdeckt, die zur Beschleunigung von häufigen SQL-Abfragen (vom Datenbankadministrator) angelegt wurden.

Datensatz-Ids als Schnittstelle haben folgende Vor- und Nachteile: + Direkter Verweis auf den entsprechenden Treffer in der Datenbank + Anzahl der Treffer im vornherein berechenbar – Kein Bezug zum Suchbegriff herstellbar – Row-Ids sind nicht Teil des SQL-Sprachstandards und werden daher nur von einigen DBMS (proprietär) unterstützt.

Die Verwendung von Views für Teilschritt 2 ergibt folgende Vor- und Nachteile:

3 Mit dieser Funktionalität kann ein DBMS relativ einfach als Index und/oder Datenspeicher einer Volltext-Suchmaschine eingesetzt werden. Siehe dazu beispielsweise [Mysq10b], [Orac10a] und [Ibm10].

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 71 + Die Bildung der SQL-Abfrage ist mit einem einfachen Algorithmus realisier- bar, da das SELECT-Statement ohne Joins auskommt. + Views ermöglichen übersichtlichere, lesbarere Suchergebnisse u.a. durch: a) Formatierung: Groß-/Kleinschreibung, Zahlenformate etc., b) Umrechnung: Währungen, Metriken, Datums-/Zeitwerte etc., c) Ausblendung: aus Gründen der Vertraulichkeit und Datensicherheit d) Zusammenfassung: z.B.: "Name := [Titel + ' ' +] Vorname + ' ' + Nachname" + Wenn dem Suchmodul bereits vorhandene Views zur Verfügung gestellt wer- den, sieht der Benutzer die Suchergebnisse in bereits vertrauten Tabellen(- layouts). – Abfragen deren Datensatz-IDs, die sich nicht in einer konkreten View über- schneiden, liefern kein Ergebnis. Der Benutzer muss dann zu der nicht wahr- heitsgemäßen Überzeugung kommen, dass zwischen den Suchbegriffen kein Zusammenhang besteht bzw. hergestellt werden kann. Beispielsweise passt in der Testdatenbank UniLinz zur Suchanfrage „Institut“, „Wirtschaftsinforma- tik“, „LVA“ keine vordefinierte View. Obwohl ein realer Zusammenhang zwi- schen diesen Begriffen in der Datenbank besteht.

5.2.2 Lösungsalternative B: Wort-Index + Views + Zugriffspfade

Die Schnittstelle zwischen Teilschritt 1 und Teilschritt 2 wird nicht mehr mittels Datensatz-Ids sondern über sogenannte Zugriffspfade realisiert. Lösungsalterna- tive B stellt damit insofern nur eine Variante von Lösungsalternative A dar. Wäh- rend Datensatz-Ids (als Row-Ids oder mit eindeutigen Schlüsseln) auf bestimmte Datensätze (Tabellenzeilen) verweisen, zeigen Zugriffspfade auf Attribute (Tabel- lenspalten).

Teilschritt 1: Lösung mittles Wort-Index

Der Wort-Index muss gegenüber Lösungsalternative A so adaptiert werden, dass auf der rechten Seite der Index-Tabelle statt Datensatz-Ids nun Zugriffspfade ge-

72 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken speichert werden. Abbildung 29 zeigt einen derartigen veränderten Wort-Index4. Die betroffenen Einträge für Suchbeispiel 1 und 2 sind wieder hellgrau respektive dunkelgrau hervorgehoben.

Schlüsselwort Zugriffspfad (Fortsetzung)

150 v_Studienrichtung.SKZ Küng v_WissPersonal.Nachname 175 v_Studienrichtung.SKZ Küng v_InstMitglied.Nachname 881 v_Studienrichtung.SKZ Küng v_LVALeiter.Nachname 0055050 v_Student.MatrikelNr Küng v_LVAZeugnis.Nachname

9856588 v_Student.MatrikelNr Wagner v_WissPersonal.Nachname 9856588 v_Inskription.MatrikelNr Wagner v_InstMitglied.Nachname 9856588 v_LVAZeugnis.MatrikelNr Wagner v_LVALeiter.Nachname 9856857 v_Student.MatrikelNr Wagner v_LVAZeugnis.Nachname

Abbildung 29: Wort-Index mit Zugriffspfaden

Zu beachten ist, dass hier pro Schlüsselwort nur genau ein Eintrag im Index ent- halten ist und der Wort-Index dadurch insgesamt kleiner als bei Lösungsalternati- ve A ist. Beispielsweise repräsentiert der (hellgrau gekennzeichnete) Eintrag "Wagnerov_WissPersonal.Nachname" alle Datensätze der Tabelle "v_WissPerso- nal", deren Attribut "Nachname" dem Wert "Wagner" entspricht. Um welche und wie viele konkrete Datensätze es sich dabei handelt, ist im Wort-Index nicht ver- merkt.5 Die Entwurfsentscheidung, ob als Schlüsselwörter vollständige Attribut- werte oder einzelne Wörter auf der linken Seite des Index stehen sollen, ist aber auch hier zu treffen. Die Ablauflogik von Teilschritt 1 besteht weiterhin aus dem Auslesen der Zugriffspfade des Wort-Index pro Suchbegriff.

Teilschritt 2: Lösung mittles Views

Analog zur Lösungsalternative A werden wieder Views zur Generierung der SQL- Abfragen eingesetzt. Der Algorithmus zur Erstellung des SELECT-Statements un- terscheidet sich gegenüber der Lösung mit Datensatz-Ids insofern, als hier aus

4 Ein Zugriffspfad ist zur Veranschaulichung in der Notation: „.“ angegeben. Bei der Implementierung könnten die Zugriffspfade stattdessen auch durch codierte Verweise (Zugriffspfad-Ids) ersetzt werden. 5 Der Wort-Index müsste dazu nur um eine Spalte erweitert werden, die einen Zähler beinhaltet, der diese Information enthält, also für wieviele konkrete Datensätze ein Index-Eintrag steht. Diese Er- weiterung wird hier aber nicht weiter verfolgt.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 73 den Zugriffspfaden und den Suchbegriffen Abfragebedingungen für die WHERE- Klausel gebildet werden:

SELECT * FROM v_WissPersonal WHERE v_WissPersonal.Nachname = 'Wagner';

SELECT-Statement für Suchbeispiel 1: „Wagner“

SELECT * FROM v_LVAZeugnis WHERE v_LVAZeugnis.PrüferNachname = 'Küng' AND v_LVAZeugnis.MatrikelNr = 9856588;

SELECT-Statement für Suchbeispiel 2: „Küng“+„9856588“

Aus den beiden oben angeführten SELECT-Statements für die Suchbeispiele ist ersichtlich, dass hier nicht von vornherein bekannt ist, wie viele Datensätze der Views die Abfragebedingung(en) erfüllen. Enthält die WHERE-Klausel nur eine Bedingung liefert das SELECT-Statement zumindest einen Datensatz, andernfalls entspricht der Eintrag im Wort-Index nicht mehr dem aktuellen Stand der Datenbank. Enthält die WHERE-Klausel zwei oder mehrere Bedingungen, kann das Abfrageergebnis auch leer sein. Beispiels- weise führt die Suchanfrage „Küng“, „0055050“ zum SELECT-Statement:

SELECT * FROM v_LVAZeugnis WHERE v_LVAZeugnis.PrüferNachname = 'Küng' AND v_LVAZeugnis.MatrikelNr = 0055050;

SELECT-Statement für Suchbeispiel: „Küng“+„ 0055050“

Obwohl für „Küng“ als auch für „0055050“ alleine, entsprechende Datensätze in der View v_LVAZeugnis vorhanden sind (siehe Einträge im Wort-Index) retourniert diese SQL-Abfrage eine leere Ergebnismenge6. Diese Tatsache ist beim Entwurf des Moduls zur Ergebnisanzeige zu berücksichtigen.

6 Ein Eintrag im Wort-Index garantiert nur, dass zumindestens ein Attributwert (in dem durch den Zugriffspfad angegebenen Attribut) mit dem Schlüsselwort übereinstimmt. Alle Abfrage- bedingungen werden durch den Algorithmus – zumindest vorerst (vgl. 5.4) – mit logischem Und verknüpft. Woraus folgt, dass nur Datensätze ins Abfrageergebnis kommen, die alle Teilbedingun- gen gleichzeitig erfüllen.

74 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Vorteile und Nachteile von Lösungsalternative B

Lösungsalternative B unterscheidet sich von Lösungsalternative A nur durch die Schnittstelle zwischen den beiden Teilschritten. Deshalb werde ich an dieser Stel- le nur diejenigen Vor- und Nachteile anführen, die sich aus der Verwendung der Zugriffspfade gegenüber den bereits angeführten Vor- und Nachteilen von Lö- sungsalternative A ändern bzw. neu hinzukommen.

Für den Wort-Index ergeben sich folgende Änderungen: ~ Die Aktualität des Wort-Index ist mit weniger Aufwand zu realisieren. Erstens sind weniger Einträge zu verwalten und zweitens erfordert nicht jede Ände- rung in der Datenbank eine Aktualisierung des Index. – Der Wort-Index benötigt nun wesentlich weniger Speicher-Ressourcen und berechnet sich (für eine View) hier mit: Anzahl der Index-Einträge = Anzahl der unterschiedlichen Suchbegriffe.

Zugriffspfade als Schnittstelle haben folgende Vor- und Nachteile: Die generierten SQL-Abfragen: + lassen einen Rückschluss auf die Suchbegriffe zu, + sind jedenfalls konform zum Sprachstandard SQL92 und + sind nicht an bestimmte, verpflichtende Tabelleneigenschaften (Schlüsselatt- ribute, Indexe etc.) gebunden. – Zugriffspfade stellen einen indirekten Verweis auf konkrete Datensätze dar. – Die Anzahl der getroffenen Datensätze pro View kann nicht ohne Ausführung der Abfrage berechnet werden.

Für die im Teilschritt 2 verwendeten Views ergeben sich gegenüber Lösungsvari- ante A keine Änderungen an den genannten Vor- und Nachteilen.

5.2.3 Lösungsalternative C: Ad-hoc Suche + Joins + Zugriffspfade

Lösungsalternative C setzt sowohl für Teilschritt 1 als auch für Teilschritt 2 auf bisher noch nicht vorgestellte Lösungsvarianten. Zunächst werden die Zugriffs- pfade ad-hoc ermittelt (1b) und die SQL-Abfragen basieren hier nicht auf vordefi- nierten Views, sondern werden durch entsprechende Joins der Basistabellen ge- bildet (2b).

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 75 Teilschritt 1: Lösung mittles ad-hoc-Suche

Die Ermittlung der Zugriffspfade erfolgt bei diesem Lösungsansatz durch unmit- telbare Suche der Suchbegriffe in den Relationen der Datenbank. Dazu werden al- le Attributwerte (in allen Relationen) der Datenbank mit den gesuchten Suchbeg- riffen verglichen. Der Algorithmus für Teilschritt 1 hat demnach folgende Struk- tur:

0 // SAHSERD.SearchModule.adHocSearch() // first draft

1 adHocSearch(psearchedPhrase) { 2 foundDBAccessPaths = {}; 3 colsInWhereClause = {}; 4 for(currTbl in connectionToDB().getMetadata().getTables()) { 5 // build sql-statement for currTbl 6 sqlStmt = "SELECT * FROM " + currTbl.name() + " WHERE "; 7 for(currCol in currTbl.getColumns()) { 8 colsInWhereClause.add(currCol); 9 if(currCol.colNo() > 1) 10 sqlStmt += " OR "; 11 sqlStmt += currCol.name() + " = \'" + searchedPhrase + "\' "; 12 } 13 sqlStmt += ";"; 14 qResultSet = connectionToDB().executeSQL(sqlStmt); 15 // check db-values until EOF is reached or all cols are marked as hit 16 while(! colsInWhereClause.isEmpty() && qResultSet.nextRow()) { 17 for(currCol in colsInWhereClause) { 18 if(qResultSet.getValue(currCol).equals(searchedPhrase)) { 19 foundDBAccessPaths.add(currCol); // matching db-value found 20 colsInWhereClause.remove(); // don't check a col marked as hit again 21 } 22 } 23 } 24 qResultSet.close(); 25 } 26 return foundDBAccessPaths; 27 }

Die oben angeführte Ablauflogik von Teilschritt 1 durchsucht die Relationen der Datenbank datensatz-orientiert. Das sequentielle Auslesen aller Datensätze stellt aber die langsamste Form des Lesezugriffs dar. Um die Performanz der Ad-hoc- Suche zu erhöhen werden in Abschnitt 5.4.1 einige Überlegungen vorgestellt. Für Suchbeispiel 1: „Wagner“ lautet der ermittelte Zugriffspfad „WissPerso- nal.Nachname“, für Suchbeispiel 2: „Küng“, „9856588“ lauten sie „WissPerso- nal.Nachname“ und „Student.MatrikelNr“.

76 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Teilschritt 2: Lösung mittles Joins

Aufgabe von Teilschritt 2 ist die Generierung einer SQL-Abfrage, die einerseits (wie zuvor in Lösungsalternative B) aus den Suchbegriffen und Zugriffspfaden Ab- fragebedingungen für die WHERE-Klausel ermittelt. Andererseits muss der Algo- rithmus hier aber auch die dafür nötigen Joins berechnen. Generell kann der dafür nötige Algorithmus in zwei Abschnitte unterteilt wer- den: Je nach Anzahl der betroffenen Tabellen wird im Folgenden ausgeführt, wie die SQL-Anfrage a) für eine Tabelle und b) für zwei oder mehrere Tabellen gene- riert wird. Der Algorithmus für Teilschritt 2 hat damit folgende Struktur:

0 // SAHSERD.SearchModule.buildSQL()

1 buildSQL(pfoundDBAccessPaths) { 2 distinctTbls = {}; 3 for(currDBAP in foundDBAccessPaths) { 4 if(! distinctTbls.contains(currDBAP.tableName())) 5 distinctTbls.add(currDBAP.tableName()); 6 } 7 if(distinctTbls.size() == 1) 8 return buildSQLSingleTable(foundDBAccessPaths); 9 Else 10 return buildSQLMultiTable(foundDBAccessPaths); 11 }

Da für eine betroffene Tabelle keine Joins nötig sind, ist der Algorithmus für buildSQLSingleTable() beinahe ident mit Teilschritt 2 von Lösungsvariante B, wie die generierte SQL-Abfrage zeigt:

SELECT * FROM WissPersonal WHERE WissPersonal.Nachname = 'Wagner';

SELECT-Statement für Suchbeispiel 1: "Wagner"

Im Folgenden wird daher nur die Ablauflogik der Methode buildSQLMultiTable() näher ausgeführt. Für Suchbeispiel 2 werden durch Teilschritt 1 die Zugriffspfade „WissPersonal.Nachname“ und „Student.MatrikelNr“ ermittelt. Daraus soll hier nun folgende SQL-Abfrage generiert werden:

SELECT LVAZeugnis.*, Student.*, WissPersonal.* FROM LVAZeugnis, Student, WissPersonal WHERE WissPersonal.Nachname = 'Küng' AND Student.MatrikelNr = 9856588 AND LVAZeugnis.Pruefer = WissPersonal.PersNr AND LVAZeugnis.MatrikelNr = Student.MatrikelNr;

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 77 SELECT-Statement für Suchbeispiel 2: "Küng", "9856588"

Die ersten vier Zeilen dieser Abfrage entsprechen wiederum (bis auf die FROM- Klausel) dem SELECT-Statement, dass auch Teilschritt 2 in Lösungsalternative B generiert. Die Herausforderung liegt hier nun darin, die beiden fehlenden Abfra- gebedingungen – die Joins – zu konstruieren, die oben durch eine Linie abge- trennt sind.7 Der Lösungsansatz der hier zum Einsatz kommt, verwendet ebenfalls die Fremdschlüsselabhängigkeiten der Tabellen, die als Kanten eines (gerichteten8) Graphen veranschaulicht werden, dessen Knoten die Tabellen sind. Der dabei entstehende Graph entspricht in etwa einem vereinfachten ER-Diagramm der Da- tenbank, in dem n:m-Beziehungen bereits aufgelöst wurden. Der Graph, der sich für die hier betrachtete Datenbank "UniLinz" ergibt, ist in folgender Abbildung dargestellt:

Abbildung 30: Vereinfachter ER-Graph für die Datenbank "UniLinz"

7 Zur Lösung dieser Problemstellung existieren in der Literatur bereits einige Ansätze, stellvertretend führe ich hier das Modell der "Universal-Relation" an, siehe [Maie84], [Vard88], [Brüg95]. 8 Streng genommen müssten die Fremdschlüssel-Abhängigkeiten als gerichtete Kanten dargestellt werden (wobei die Pfeilspitze zur Relation mit dem Primärschlüssel zeigt). Algorithmen, die sich auf einem gerichteten Graphen „bewegen“, müssen in Folge aber auch, auf die Ausrichtungen der Kanten Rücksicht nehmen. Damit wäre beispielsweise Tabelle Institut von InstMitglied erreichbar aber nicht umgekehrt. Für unsere Zwecke ist es aber gleichgültig ob eine Tabelle in Richtung der Kante oder in Gegenrichtung erreichbar ist (solange sie überhaupt erreichbar ist), da jedenfalls ein gültiger Join entsteht.

78 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Das Problem, die fehlenden Joins zu bestimmen, damit ein gültiges SELECT- Statement entsteht, kann nun mithilfe dieses ER-Graphen gelöst werden, indem versucht wird, die entsprechenden Knoten (Tabellen) zyklusfrei zu verbinden. Für zwei Tabellen kann dabei auf den Algorithmus zum Auffinden des kürzesten Wegs zwischen A und B zurückgegriffen werden ("shortest path"). Sind mehr als zwei Knoten (Tabellen) miteinander zu verbinden, so muss ein sogenannter Join- Baum („join tree“) ermittelt werden, der möglichst wenige Kanten (Joins) enthält. Diese Problemstellung ist eine Variante des als "Steiner tree Problem in Graphs (SPG)" bekannten Problems (siehe beispielsweise [Wade03]) in einem Graphen, den minimal spannenden Baum zu ermitteln9. Teilschritt 2 benötigt für die Ermittlung des Join-Baums mittels ER-Graph die Fremdschlüsselabhängigkeiten der zu durchsuchenden Datenbank. Sinnvoller- weise werden diese Datenbank-Metadaten nicht bei jedem Aufruf von erneut ausgelesen, sondern nur einmal - bei der Initialisierung der Suchmaschine. Zur Zwischenspeicherung dieser Informationen (als ER-Graph) werden entsprechen- de Klassen benötigt.

Exkurs: Algorithmen für ER-Graphen

Hier werden, am Beispiel des in Abbildung 31 dargestellten ER-Graphs, die Ab- lauflogik zur Ermittlung: a) der kürzesten Verbindung zwischen Knoten "A" und "H" und b) eines minimalen Join-Baums für die Knoten "B", "G" und "F" erläutert.

9 Algorithmen zur Ermittlung von minimal spannenden Bäumen (minimal spanning tree, MST) sind hier nicht zur Lösung verwendbar, da deren Ziel die kostenminimale Verbindung der ALLER Knoten in einem (gewichteten) Graph ist. Hier ist aber nur eine Verbindung bestimmter Knoten in einem Graph gesucht.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 79 Abbildung 31: Ein abstrakter ER-Graph zur Demonstration

In der Literatur (beispielsweise seien hier [Corm90], [Ottm96] und [Sedg88] ge- nannt) sind verschiedene Algorithmen zur Ermittlung des kürzesten Wegs in ei- nem ungerichteten Graph zu finden10. Der im Folgenden angegebene Algorith- mus zur Ermittlung der kürzesten Verbindung zwischen zwei Knoten basiert auf einer "breath-first-search (BFS)"-Suchstrategie11:

0 // SAHSERD.ERGraph.joinTree() // shortest path (breath-frist search)

1 joinTree(pfromTbl, ptoTbl) { 2 unfinishedPaths = {}; 3 unfinishedPaths.add(fromTbl); 4 while(! unfinishedPaths.isEmpty()) { 5 newUFPaths = {}; 6 for(ufPath in unfinishedPaths) { 7 ufpTail = ufPath.to(); 8 for(adjEdge in ufpTail.adjacentEdges()) { 9 // next if-statement prevents from building cycles 10 if(! ufPath.containsVertex(adjEdge.to())) { 11 ufPath.appendEdge(adjEdge); 12 if(ufPath.to() == toTbl) 13 return ufPath; // done 14 else 15 newUFPaths.add(ufPath); // requeue ufPath 16 } 17 } 18 } 19 unfinishedPaths = newUFPaths; 20 } 21 return {}; // no shortest Path found => graph is not connected! 22 } Der Aufruf von joinTree(["A","H"]) liefert folgenden Join-Baum12: "[A]–k01o[B]– k04o[E]–k10o[H]" der aus den drei Kanten (Joins): k01, k04, k10 besteht. In Abbildung 32 ist dieser Join-Baum schwarz eingezeichnet:

10 Die ausführliche Behandlung der Suchstrategien und der Vor- und Nachteile der verschiedenen Algorithmen würde den Rahmen dieses Exkurses sprengen. Ich verweise daher auf die angegebene Literatur. 11 Dieser Algorithmus erwartet, dass der ERGraph mit Adjazenzlisten implementiert wird. Diese Art der Repräsentation wird gegenüber der Speicherung in einer Adjazenzmatrix bevorzugt wenn der Graph spärlich (sparse) ist. Ein Graph gilt als spärlich wenn die Anzahl der Kanten die Anzahl der Knoten nur geringfügig übersteigt, also |E| ~= |V| gilt. Diese Voraussetzung trifft in der Regel auf ER- Diagramme zu. 12 Ein Pfad ist eine vereinfachte Variante eines Baumes. Die Baumwurzel bildet den Anfang des Pfa- des, der einzige Blatt-Knoten (das Pfadende).

80 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 32: Kürzeste Verbindung zwischen Knoten "A" und "H"

Der nachfolgende Algorithmus zur Ermittlung des minimalen Join-Baums zwi- schen n (n >= 2) Knoten in einem (ungerichteten) Graph basiert auf der Vereini- gung der kürzesten Verbindungen zwischen je zwei Knoten zu einem Join-Baum:

0 // SAHSERD.ERGraph.joinTree() // minimal jointree (draft)

1 joinTree(ptblsToJoin[]) { 2 jTree = {}; 3 for(tblIdx = 0; tblIdx < tblsToJoin.length; tblIdx++) { 4 fromTbl = tblsToJoin[tblIdx]; 5 toTbl = tblsToJoin[tblIdx + 1]; 6 fromToJoinTree = joinTree(fromTbl, toTbl); 7 // build union of jTree with fromToJoinTree (without duplicating edges) 8 jTree.unifyWith(fromToJoinTree); 9 } 10 return jTree; 11 }

Der Aufruf von joinTree(["B","G","F"]) bewirkt, dass zuerst die kürzeste Verbin- dung zwischen Knoten "B" und "G" ermittelt wird ("[B]–k04o[E]–k09o[G]"), dann diejenige zwischen "G" und "F" ("[G]–k09o[E]–k07o[D]–k08o[F]"). Aus deren Vereinigung entsteht schließlich der Join-Baum für "B-F-G": "[E]–k04o[B], [E]–k09o[G], [E]–k07o[D]–k08o[F]". Zur Verbindung der Knoten (Tabellen) "B", "G" und "F" sind also vier Kanten (Joins) nämlich: k04, k07, k08 und k09 nötig. Der oben angegebene Algorithmus findet lediglich einen Join-Baum, der die angegebenen Knoten verbindet. Abhängig von der Reihenfolge, in der die Knoten in tblsToJoin[] angeordnet sind, können dabei Join-Bäume unterschiedlicher Länge entstehen. Beispielsweise retournieren die Aufrufe von:

a) joinTree(["B","G","F"]): k04, k07, k08 und k09 (4 Kanten/Joins) ("[E]–k04o[B], [E]–k09o[G], [E]–k07o[D]–k08o[F]"),

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 81 b) joinTree(["F","B","G"]): k03, k04, k06 und k09 (4 Kanten/Joins) ("[F]–k06o[C]–k03o[B]–k04o[E]–k09o[G]") und c) joinTree(["B","F","G"]): k03, k06, k07, k08 und k09 (5 Kanten/Joins) ("[B]–k03o[C]–k06o[F]–k08o[D]–k07o[E]–k09o[G]"). Außerdem zeigt der Vergleich von a) und b), dass beide Join-Bäume mit 4 Joins auskommen und daher mehrere, gleichwertige Join-Bäume zur Verbindung der angegebene Knoten in Frage kommen. In Abbildung 33 ist die Variante a) hellgrau und Variante b) dunkelgrau eingezeichnet:

Abbildung 33: Minimale Join-Bäume zwischen den Knoten "B", "G", und "F"

Der vorgestellte Algorithmus ist aus diesen Gründen als Entwurf („draft“) gekenn- zeichnet, da er zur Ermittlung der minimalen Join-Bäume für n (n >= 2) Knoten nur bedingt geeignet ist. Verbesserte Versionen der beiden vorgestellten Algorith- men, die alle möglichen Join-Bäume ermitteln, werden in 5.4.2 vorgestellt13. Für die nachfolgende Besprechung der Vor- und Nachteile von Teilschritt 2 nehme ich vorweg an, dass die Methode joinTree() unabhängig von der Reihen- folge der angegebenen Kanten (Tabellen) einen minimalen Join-Baum liefert.

Vorteile und Nachteile von Lösungsalternative C

Die Ad-hoc-Suche hat folgende Vor- und Nachteile: + Aktualität: Teilschritt 1 durchsucht die Datenbasis bei jeder Suchanfrage im- mer aufs Neue. Dadurch kann zwischen den gefundenen DB-Objekten und dem tatsächlichen Inhalt der DB keine Diskrepanz entstehen. Außerdem ent- fällt die Initialisierung bzw. der Erstaufbau eines zentralen Wort-Index.

13 Außerdem sollen die verbesserten Algorithmen die (optionale) Angabe einer Obergrenze ermögli- chen, aus wievielen Kanten/Joins der Join-Baum maximal bestehen darf.

82 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken + Platzbedarf: Die Suchmaschine benötigt keinen zusätzliche Speicherresour- cen für einen Wort-Index. Bereits vorhandene Indizes können bei der Ad-hoc- Suche mit verwendet werden. – Geschwindigkeit: Die Ad-hoc-Suche kann seitens des DBMS das langsame sequentielle Auslesen einer oder mehrerer Tabellen erfordern („full table scans“). – Die Ad-hoc-Suche erstreckt sich nur auf Basisattribute und ist damit von be- rechneten bzw. abgeleiteten Attributen ausgeschlossen.

Für die Verwendung von Zugriffspfaden als Schnittstelle ergeben sich gegenüber den, bei Lösungsalternative B angeführten Vor- und Nachteilen, keine Änderun- gen.

Die Generierung der SQL-Abfragen mittels Joins hat folgende Vor- und Nachteile: + Grundsätzlich können zu allen Kombinationen von Zugriffspfaden entspre- chende Joins und damit SQL-Abfragen generiert werden. – Zur Bildung der WHERE-Klausel ist ein komplexer Algorithmus nötig. – Das generierte SELECT-Statement liefert ein Suchergebnis im Rohformat, d.h. genauso wie in der Datenbank gespeichert. Die Formatierung, Umrechnung etc. von Attributen, wie sie in Views oftmals angewendet wird (z.B. Name = ConcatWithSpace(Vorname, Nachname)), ist hier nicht möglich.

5.3 Entwurfsentscheidung

Ziel dieser Arbeit ist der Entwurf und die Implementierung eines Prototyps einer Suchmaschine für relationale Datenbanken, der zumindest die im Kapitel Spezifi- kation aufgelisteten Anforderungen erfüllt. Bisher wurde eine allgemeine System- architektur vorgestellt und acht verschiedene Alternativen aufgelistet die zur Lö- sung dieser Anforderungen in Frage kommen. Drei Lösungsalternativen wurden ausgewählt und näher beschrieben. Nun gilt es die Entscheidung zugunsten einer Lösungsalternative zu treffen. Zur Erleichterung meiner Wahl habe ich die in Abschnitt 5.2 angeführten Vor- und

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 83 Nachteile der Lösungsalternativen B und C zu folgender Tabelle zusammenge- fasst14:

Tabelle 1: Gegenüberstellung der Vor- und Nachteile der Lösungsalternativen

Lösungsalternative B: Lösungsalternative C: Wort-Index+Views+Zugriffpfade ad-hoc-Suche+Joins+Zugriffpfade Hohe Aktualität des Suchergebnisses Suchergebnis ist durch Zugriff auf den durch Ad-hoc Suche Wort-Index schnell verfügbar Geringer Platzbedarf für zusätzliche Da- Einfache SQL-Abfragen durch Zurück- Vorteile tenstrukturen greifen auf existierende Views Keine grundsätzliche Einschränkung bei Präsentation der Suchergebnisse in der Ermittlung der Joins zur relationa- „vertrauter“ Form len Verbindung der Treffer Wort-Index muss vorab aufgebaut und Ad-hoc-Suche ist langsam und belastet laufend aktualisiert werden das DBMS (zusätzlich) Platzbedarf für Wort-Index Erstellung von komplexen SQL- Nachteile Die möglichen Verbindungen der Tref- Abfragen (WHERE-Klausel) fer sind auf die bestehenden Views be- Unaufbereitete Präsentation der Such- schränkt. ergebnisse

Die Vor- und Nachteile der beiden Lösungsansätze betreffen vereinfacht gesagt die Performanz und die benötigten (Speicher-)Ressourcen. Durch die vorgegebe- nen Rahmenbedingungen mit SAHSERD einen einfachen Prototyp einer Suchma- schine für (kleine) Relationale Datenbanken zu entwerfen, können die angegebe- nen Nachteile von Lösungsvariante C vernachlässigt werden. Zudem existieren bereits einzelne Prototypen, deren Suchmodul durch Vari- anten von Lösungsalternative B realisiert wurde (siehe Abschnitt 3.2). Eine Um- setzung von Lösungsvariante C ist noch wenig erforscht und soll daher in Rah- men dieser Arbeit weiterverfolgt werden.

5.4 Problembereiche und Erweiterungen

Die in diesem Abschnitt angeführten Problembereiche betreffen grundsätzlich al- le in Abschnitt 5.2 vorgestellten Lösungsvarianten. Aus Platzgründen werden sie aber nur vor dem Hintergrund der (zuvor ausgewählten) Lösungsalternative C be- sprochen und entsprechende Lösungsansätze aufgezeigt. Zusätzlich werden Er- weiterungen gegenüber den Basisanforderungen eingearbeitet. Die Punkte sind nach den Komponenten der Suchmaschine gegliedert.

14 Da Lösungsalternative B eine verbesserte Variante von Lösungsalternative A ist, wurde letztere bei der Gegenüberstellung der Vor- und Nachteile nicht berücksichtigt.

84 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 5.4.1 ad Suchmodul: ad-hoc Suche

Für die Qualität und Quantität des Endergebnisses des Suchmoduls sind die Ar- beitsweise des ersten Teilschritts und dessen Ergebnis vorentscheidend. Die Ab- lauflogik von Teilschritt 1, die in Abschnitt 5.2.3 bereits skizziert wurde, wird hier schrittweise überarbeitet und erweitert, indem sie unter den Aspekten Suchort, Suchmethode und Suchschärfe näher betrachtet wird. Ziel der folgenden Überle- gungen ist schneller (Suchort, Suchmethode) zu einem besseren (Suchschärfe) Suchergebnis zu kommen, indem die Ablauflogik von Teilschritt 1 sowohl die konkreten Gegebenheiten des DBS, als auch die Art der Suchanfrage berücksich- tigt.

Mit Suchorten sind hier jene Datenstrukturen des Datenbanksystems gemeint, die bei der Ad-hoc-Suche durchsucht werden. Das sind: a) die Attributwerte der Datenbank, aber auch b) die vom DBMS verwalteten Metadaten über die Datenbank.

Die Suche in Attributwerten wiederum kann nach der Suchmethode in a) attribut-orientiert (spaltenweise) und b) datensatz-orientiert (zeilenweise) unterteilt werden. Zusätzlich kann hier unterschieden werden, ob Teilschritt 1 bei mehreren Suchbegriffen, das Datenbanksystem a) in mehreren Suchdurchgängen (n Suchbegriffe => n Suchdurchgänge), oder b) in einem einzigen Suchdurchgang auf Treffer durchsucht.

Unter Suchschärfe wird die Genauigkeit verstanden, die bei der Suche der Such- begriffe angewendet wird. Folgende Vergleichsoperatoren können zur Prüfung auf Übereinstimmung (für alphanumerische Suchbegriffe) eingesetzt werden: a) exakter Vergleich: "Linz".equals("Linz"); 4040==4040 b) Vergleich unabhängig von Groß-/Kleinschreibung: "Linz".equalsIgnoreCase("LINZ") c) "Ist enthalten in"-Vergleich: "Linz".isSubstringIn("4020 Linz a.d. Donau") d) Synonym-Vergleich: "Linz".isSynoymFor("LNZ") e) "SoundEx"-Vergleich: "Linz".equalsSoundEx("Liz") f) Unscharfer-Vergleich: "Linz".equalsFuzzy("Pasching"); 4020~=4040

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 85 Die Vergleichsoperatoren a), b) und c) werden von SQL direkt unterstützt; d) ,e) und f) erfordern hingegen nicht standardisierte DBMS-Erweiterungen bzw. ein zwischengeschaltetes Modul ("Wrapper"), welches derartige Abfragen in Stan- dard-SQL übersetzt. Das Wrapper-Modul greift dazu auf geeignete Datenstruktu- ren zurück, in den Synonyme bzw. der Ähnlichkeiten verwaltet werden. Bezüglich der Suchschärfe von Teilschritt 1 werden nur die Varianten a), b), c) und einge- schränkt auch d) weiter betrachtet.15 Außerdem ist unter dem Aspekt der Suchschärfe zu untersuchen, ob bei der Suche in Attributwerten beispielsweise der Suchbegriff "4040" nur in numeri- schen Attributen oder auch als Zeichenkette gesucht werden soll und wenn ja, unter welchen Umständen diese typenübergreifende Suche sinnvoll ist16.

Ad-hoc Suche in den Attributwerten

Der in 5.2.3 vorgestellte Algorithmus überprüft (zeilenweise) alle Attributwerte al- ler Relationen auf Übereinstimmung mit einem angegebenen Suchbegriff. Hier wird dieser Algorithmus nun schrittweise verbessert, mit dem Ziel möglichst prägnante SQL-Abfragen zu generieren und (damit) die Laufzeit der ad-hoc Suche zu verbessern. Zur Veranschaulichung sollen die Relationen "Student (ST)", "Inskription (IK)", "Studienrichtung (SR)" und "Institut (I)" aus der Test-Datenbank "UniLinz" dienen, die durch folgende SQL "Create Table"-Statements erstellt wurden17: CREATE TABLE UniLinz.Student ( MatrikelNr INT(7) UNSIGNED ZEROFILL NOT NULL, Nachname VARCHAR(40) NOT NULL, Vorname VARCHAR(25) NOT NULL, GebDat DATE NOT NULL, Geschlecht ENUM('M', 'W') NOT NULL, Adresse VARCHAR(40) NOT NULL, PRIMARY KEY (MatrikelNr), INDEX Name (Nachname, Vorname) );

15 Die Integration von phonetischer/SoundEx- und Unscharfer/Fuzzy-Suche (in SQL-Abfragen) wür- de den Umfang dieser Arbeit sprengen. In der Literatur sind zu diesen Themen bereits einige Lö- sungsansätze zu finden, beispielsweise in [Motr90], [Bosc05] bzw. [Post69]. (Siehe auch 3.1) 16 Bei Volltextsuchmaschinen, wie beispielsweise einer WWW-Suchmaschine, stellt sich diese Proble- matik nicht. Die Datenbasis (zb HTML-Seiten) besteht ausschließlich aus einem Datentyp, nämlich (Hyper-)Text. Der Begriff „4040“ wird dort nicht anders als „Küng“ behandelt – als Zeichenkette mit der Länge 4. 17 Die angeführten „Create Table“-Statements beinhalten nur jene Konstrukte, die zur Veranschauli- chung der Überlegungen nötig sind. Der SQL-Code zur Erzeugung des gesamten Datenbanksche- mas ist im Anhang angeführt.

86 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken CREATE TABLE UniLinz.Inskription ( MatrikelNr INT(7) UNSIGNED ZEROFILL NOT NULL, SKZ INT(3) UNSIGNED NOT NULL, INDEX MatrikelNr (MatrikelNr), INDEX SKZ (SKZ), FOREIGN KEY (MatrikelNr) REFERENCES Student(MatrikelNr), FOREIGN KEY (SKZ) REFERENCES Studienrichtung(SKZ) ); CREATE TABLE UniLinz.Studienrichtung ( SKZ INT(3) UNSIGNED NOT NULL, Bezeichnung VARCHAR(60) NOT NULL, PRIMARY KEY (SKZ), UNIQUE INDEX StudRBez (Bezeichnung) ); CREATE TABLE UniLinz.Institut ( InstNr INT(5) UNSIGNED NOT NULL, Name VARCHAR(80) NOT NULL, Adresse VARCHAR(80) NOT NULL, PRIMARY KEY (InstNr), UNIQUE INDEX InstName (Name) ); Daraus ergibt sich folgende Liste der zu überprüfenden Attribute:

Student Inskription Studienrichtung Institut ST.MatrikelNr ST.Vorname IK.SKZ SR.SKZ I.InstNr ST.Nachname ST.GebDat IK.MatrikelNr SR.Bezeichnung I.Name ST.Geschlecht ST.Adresse I.Adresse

Ad Suchort: Genereller Ausschluss bestimmter Attribute Generell von der Suche in den Attributwerten ausgeschlossen werden einerseits von SAHSERD nicht unterstützte SQL-Datentypen und andererseits Fremd- schlüssel-Attribute. SAHSERD unterstützt nur SQL-Datentypen vom Typ Zeichenkette (CHAR, VARCHAR, TEXT) oder Ganzzahl (INT)18. Attribute mit anderen SQL-Datentypen (FLOAT, DATE, ENUM etc.) können daher nicht in die Suche einbezogen werden. Fremdschlüsselattribute können ebenfalls generell von der Suche ausge- schlossen werden, da deren Attributwerte per Definition eine Teilmenge der Attri- butwerte des referenzierten (Primärschlüssel-)Attributes sind. Die ad-hoc Suche in Fremdschlüsselattributen liefert somit niemals neue Attributwerte und kann daher generell ausbleiben19.

18 Siehe Anforderung a8 in Abschnitt 4.1 19 Gegenüber dem generellen Ausschluss von nicht unterstützten SQL-Datentypen, ist der Ausschluss von Fremdschlüsselattribute nicht zwingend. Unterbleibt er, verschlechtert sich die Laufzeit der ad-hoc Suche in den Attributwerten. Jedenfalls muss bei der Weiterverarbeitung der getroffenen Attribute (in Teilschritt 2) darauf Rücksicht genommen werden, ob das Ergebnis der ad-hoc Suche Fußnoten werden auf der nächsten Seite fortgesetzt

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 87 Bezogen auf den oben gewählten Ausschnitt der Datenbank UniLinz müssen somit die Attribute ST.GebDat und ST.Geschlecht (nicht unterstützter SQL-Daten- typ) sowie IK.SKZ und IK.MatrikelNr (Fremdschlüssel) generell von der Suche aus- geschlossen werden.

Weiters sollte (dem Datenbankadministrator) die Möglichkeit eingeräumt wer- den, bestimmte Attribute aus Gründen der Vertraulichkeit der darin gespeicher- ten Daten (z.B.: Gehälter, Passwörter etc.) oder aus Gründen der mangelnden Ver- trautheit der Anwender (z.B.: Surrogat-Attribute20 etc.) von der Suche generell auszuschließen. Die dabei vorgenommenen Beschränkungen sind jeweils vor dem konkreten Einsatzzweck der Suchmaschine und zudem vor dem Wissen der Anwender um das Datenbanksystem zu treffen. Für die hier ausgewählten Tabellen habe ich zu Zwecken der Demonstration das Surrogat-Attribut I.InstNr von der Suche ausgeschlossen.

Nach der Berücksichtigung von a) nicht unterstützten SQL-Datentypen, b) Fremdschlüssel, c) Vertraulichkeit und d) Vertrautheit ergibt sich folgende Liste der grundsätzlich zu durchsuchenden Attribute:

Student Inskription Studienrichtung Institut ST.MatrikelNr ST.Vorname IK.SKZ SR.SKZ I.InstNr ST.Nachname ST.GebDat IK.MatrikelNr SR.Bezeichnung I.Name ST.Geschlecht ST.Adresse I.Adresse

Es ist evident, dass die Ermittlung der getroffenen Attributwerte für diese verblei- benden neun Attribute schneller erfolgt, als für die Ausgangsbasis. Aus der Auf- stellung ist ebenfalls ersichtlich, dass die Tabelle Inskription nun überhaupt nicht mehr durchsucht werden muss.

Fremdschlüsselattribute beinhalten darf oder nicht. Hinsichtlich des endgültigen Suchergebnisses macht es sehr wohl einen Unterschied, ob beispielsweise der Suchbegriff „9856588“ im (Primär- schlüssel-)Attribut Student.MatrikelNr oder (auch) im Fremdschlüsselattribut Inskripti- on.MatrikelNr gefunden wird. Diese Thematik wird in Abschnitt 5.4.2 näher behandelt. 20 Sogenannte Surrogat-Attribute sind künstliche Attribute, die bei der Implementierung des logischen Datenbank-Modells als physische Datenbank aus Gründen der Performanz angelegt werden, aber keiner realen Eigenschaft der abgebildeten Entitäten entsprechen. Im gewählten Datenbankausschnitt dient das Attribut I.InstNr lediglich als eindeutiges, numerisches Schlüsselattribut.

88 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Ad Suchort: Ausschluss bestimmter Attribute in Abhängigkeit vom Typ des Suchbegriffs Durch Typ-Vergleich von Suchbegriff und den zu durchsuchenden Attributen können bestimmte Überprüfungen im Abfrageteil des SQL-Statements als aus- sichtslos erkannt und entfernt bzw. erst gar nicht generiert werden. Dadurch ent- stehen in der Regel kürzere SQL-Abfragen, was die Laufzeit der ad-hoc Suche wei- ter verbessert, weil das DMBS weniger Bedingungen prüfen muss. Folgende Bei- spiele sollen dies verdeutlichen: a) Bei der Suche nach dem Begriff "Küng" generiert adHocSearch() für die Relati- on "Student" folgende SQL-Abfrage21: SELECT MatrikelNr, Vorname, Nachname, Adresse FROM Student WHERE MatrikelNr = 'Küng' OR Vorname = 'Küng' OR Nachname = 'Küng' OR Adresse = 'Küng'; b) für den Suchbegriff "9856588" generiert adHocSearch()folgende SQL-Abfrage: SELECT MatrikelNr, Vorname, Nachname, Adresse FROM Student WHERE MatrikelNr = '9856588' OR Vorname = '9856588' OR Nachname = '9856588' OR Adresse = '9856588'; Durch Einsicht in die Tabellen-Definitionen der Relation Student kann beispiels- weise der Abfrageteil MatrikelNr = 'Küng' in Beispiel a) weggelassen werden, da hier der Wertebereich des Attributs numerisch, der Suchbegriff aber vom Typ Zei- chenkette ist. Diese Bedingung wird immer den Wahrheitswert falsch liefern. Wei- ters ist die Suche von numerischen Suchbegriffen in Attributen vom SQL-Typ Zei- chenkette nur bedingt sinnvoll, wie u.a. der Abfrageteil Vorname = '9856588' zeigt22. Teilschritt 1 sollte daher generell nur solche Abfrage-Bedingungen in die WHERE-Klausel aufnehmen, wo der Typ des Attributs zum Typ der angegebenen Suchphrase passt. Der mögliche Wertebereich für Attribute mit numerischem Typ ist durch die kleinste (=Untergrenze) und größte (=Obergrenze) Zahl, die darin gespeichert werden kann, festgelegt. Beispielsweise braucht ein Attribut, das in der Daten- bank als "SMALLINT UNSIGNED" definiert wurde, nach dem Wert "9856588" gar nicht durchsucht werden, da der Wertebereich dieses SQL-Datentyps per Defini- tion auf das Intervall [0, 65535] beschränkt ist.

21 Die Attribute GebDat und Geschlecht wurden generell von der Suche ausgeschlossen – siehe oben. 22 Die Typ-Übergreifende Suche wird weiter unter in diesem Abschnitt behandelt.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 89 Für Attribute vom Typ Zeichenkette bildet deren maximal mögliche Länge die Obergrenze. So kann die Suche nach einem Suchbegriff der Länge l in Attribu- ten, die beispielsweise als VARCHAR(n) definiert wurden, für alle l > n entfallen. Die dabei entstehende Abfragebedingung im SQL-Statement der Such-Funktion hat immer den Wahrheitswert falsch.

Berücksichtigt man diese Überlegungen, dann erstellt Teilschritt 1 für Suchbegrif- fe vom Typ Zeichenkette, beispielsweise "Küng" folgende SQL-Abfragen:

SELECT Vorname, Nachname, Adresse FROM Student WHERE Vorname = 'Küng' OR Nachname = 'Küng' OR Adresse = 'Küng'; SELECT Bezeichnung FROM Studienrichtung WHERE Bezeichnung = 'Küng'; SELECT Name, Adresse FROM Institut WHERE Name = 'Küng' OR Adresse = 'Küng'; Für numerische Suchbegriffe wie beispielsweise „9856588“ ergibt sich folgende SQL-Abfrage23:

SELECT MatrikelNr FROM Student WHERE MatrikelNr = 9856588; Generell wird die Liste der zu durchsuchenden Attributwerte (Suchorte) also auf jene Attribute weiter eingeschränkt, a) deren Typ mit dem Typ des Suchbegriffs übereinstimmt und b) deren Wertebereich (Domäne) den gesuchten Suchbegriff grundsätzlich beinhalten kann.

Ad Suchmethode: Gleichzeitige Suche nach allen Suchbegriffen Der in 5.2.3 skizzierte Algorithmus adHocSearch() für die ad-hoc Suche in den Att- ributwerten ist für die Suche nach einem einzigen Suchbegriff ausgelegt. Eine Suchanfrage die aus n Suchbegriffen besteht, erfordert demnach genau n Aufrufe von adHocSearch(). Dabei werden alle (jeweils in Frage kommenden) Attribute je- des Mal erneut durchsucht. Schließlich müssen die einzelnen Rückgabewerte (d.s. die getroffenen Attribute) noch zu einem Gesamtergebnis zusammengefasst wer- den.

23 Für die Relation Studienrichtung kann zu dem gegebenen Suchbegriff „9856588“ keine sinnvolle SQL-Abfrage erzeugt werden. Das Attribut SKZ ist als INT(3) UNSIGNED definiert und kann deshalb nur Attributwerte aus dem Intervall [0, 999] beinhalten. Relation Institut enthält hingegen kein nu- merisches Attribut.

90 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Eine wesentliche Verbesserung der Laufzeit der ad-hoc Suche kann erreicht werden, wenn die Überprüfung aller Suchbegriffe in einem einzigen Suchdurch- gang pro Relation erfolgt. Das bedeutet, dass pro Relation nur eine SQL-Abfrage mit einer entsprechend erweiterten WHERE-Klausel generiert wird. Zur Veran- schaulichung sollen folgende Beispiele dienen24: a) Die Suche nach „Küng“, „Wöß“ ergibt folgende SQL-Abfragen: SELECT Vorname, Nachname, Adresse FROM Student WHERE Vorname IN ('Küng', 'Wöß') OR Nachname IN ('Küng', 'Wöß') OR Adresse IN ('Küng', 'Wöß'); SELECT Bezeichnung FROM Studienrichtung WHERE Bezeichnung IN ('Küng', 'Wöß'); SELECT Name, Adresse FROM Institut WHERE Name IN ('Küng', 'Wöß') OR Adresse IN ('Küng', 'Wöß'); b) Die Suche nach „9956627“, „0055880“ ergibt folgende SQL-Abfrage: SELECT MatrikelNr FROM Student WHERE MatrikelNr IN (9956627, 0055880); c) Die Suche nach „Küng“, „881“ ergibt folgende SQL-Abfragen: SELECT MatrikelNr, Vorname, Nachname, Adresse FROM Student WHERE MatrikelNr = 881 OR Vorname = 'Küng' OR Nachname = 'Küng' OR Adresse = 'Küng'; SELECT SKZ, Bezeichnung FROM Studienrichtung WHERE SKZ = 881 OR Bezeichnung = 'Küng'; SELECT Name, Adresse FROM Institut WHERE Name = 'Küng' OR Adresse = 'Küng';

Ad Suchmethode: Attribut- oder Datensatz-orientierte Suche Vorausgesetzt, dass die Suchmaschine auch auf Informationen des Data- Dictionarys25 der Datenbank zugreifen kann – hier ist im Speziellen von Interesse, welche Attribute indiziert sind und welche nicht – kann der Suchalgorithmus wei- ter verbessert werden. Unterscheidet man a) in Relationen, die ausschließlich in- dizierte Attribute aufweisen und b) in solche die mindestens ein nicht indiziertes Attribut beinhalten, so kann der Suchalgorithmus für erstere optimiert werden indem man derartige Relationen Attribut für Attribut und nicht (wie bisher) Da-

24 Durch die Verwendung des SQL-Konstrukts „ IN (, , ...)“, anstatt der Verknüpfung mit logischem Oder („ = OR = OR ...“) entste- hen prägnatere SQL-Abfragen. 25 Siehe Abschnitt 5.4.5

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 91 tensatz für Datensatz durchsucht. Zur Attribut-orientierten Suche in indizierten Attributen benötigt das DBMS in der Regel sehr wenige Lesezugriffe auf den ver- gleichsweise langsamen Sekundärspeicher (Festplatte). Die Datensatz-orientierte Suche in einer Relation erfordert hingegen das se- quentielle Auslesen des Sekundärspeichers. Dazu müssen im schlechtesten Fall, d.h. die Relation enthält keine Übereinstimmungen mit dem Suchbegriff, alle Da- tensätze vom Sekundärspeicher eingelesen und geprüft werden. Die Laufzeit der ad-hoc Suche in den Attributwerten für Relationen vom Typ b) wächst somit pro- portional zur Anzahl der Datensätze bzw. zur Größe der Tabelle im Sekundärspei- cher. Zur Optimierung der Laufzeit kann der Datenbank-Administrator zusätzli- che Indizes anlegen oder nicht-indizierte Attribute manuell von der Suche aus- schließen (siehe oben)26. Für die Suche nach „Küng“, „881“, „175“ ergeben sich folgende SQL-Abfragen: SELECT MatrikelNr, Vorname, Nachname, Adresse FROM Student WHERE MatrikelNr IN (881, 175) OR Vorname = 'Küng' OR Nachname = 'Küng' OR Adresse = 'Küng'; SELECT SKZ FROM Studienrichtung WHERE SKZ = 881 LIMIT 1; SELECT SKZ FROM Studienrichtung WHERE SKZ = 175 LIMIT 1; SELECT Bezeichnung FROM Studienrichtung WHERE Bezeichnung = 'Küng' LIMIT 1; SELECT Name, Adresse FROM Institut WHERE Name = 'Küng' OR Adresse = 'Küng'; Für die ausschließlich aus indizierten Attributen bestehende Relation Studien- richtung wird nun pro Suchbegriff eine eigene SQL-Abfrage erstellt. Für das Ergebnis von Teilschritt 1 ist unerheblich, wie viele Übereinstimmun- gen existieren bzw. welche Datensätze getroffen wurden. Das DBMS wird daher immer dann mit dem Zusatz „LIMIT 1“ angewiesen, maximal einen Datensatz als Abfrageergebnis zu retournieren, wenn die WHERE-Klausel nur aus genau einer Abfragebedingung besteht27. Der Teil im Algorithmus von Teilschritt 1, der für die

26 Wenn der Benutzer eine Suche mit „ist enthalten in“ als Vergleichoperator, statt exaktem Vergleich (unabhängig von Groß-/Kleinschreibung), wünscht, benötigt auch die Attribut-orientierte Suche in der Regel (je nach Index-Typ) mehr als einen Lesezugriff zur Ermittlung eines Treffers. Die Suche mit „unscharfem Vergleich“ wird weiter unten ausführlich behandelt. 27 Die Klausel zur Einschränkung der Ergebnismenge auf die ersten n Datensätze, ist zwar nicht Teil des Sprachstandards ANSI SQL, der Großteil der verfügbaren DBMS bieten jedoch eine solche Er- Fußnoten werden auf der nächsten Seite fortgesetzt

92 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Auswertung der retournierten Datensätze zuständig ist, kann somit auf ein einzi- ges IF-Statement reduziert werden.

Ad Suchschärfe: Exakte Übereinstimmung Bei der Konstruktion der SQL-Abfrage in Methode adHocSearch(), wird als Ver- gleichsoperator das Ist-Gleich-Zeichen „=“ verwendet, um exakte Übereinstim- mungen mit einem Suchbegriff zu finden. Dabei gehe ich davon aus, dass das DBMS den Vergleich von Zeichenketten unabhängig von deren Groß- /Kleinschreibung vornimmt. Die Abfragebedingung „WHERE dbname = 'MySQL'“ muss damit für die Attributwerte „'mysql'“, „'MYSQL'“ und „'MySQL'“ jeweils den Wahrheitswert wahr ergeben28. Gleiches gilt auch für die Verwendung von „IN“ in der Abfragebedingung. Somit unterstützt SAHSERD standardmäßig als schärfste Einstellung der Suchschärfe den Vergleich unabhängig von Groß-/Kleinschreibung.

Ad Suchschärfe: Typ-Übergreifende Suche Zur Bildung einer Abfragebedingung in der WHERE-Klausel ist die Übereinstim- mung vom Typ des Suchbegriff mit dem Typ des Attributs erforderlich (siehe oben). Unter dem Aspekt der Suchschärfe ist dies aber in vielen Fällen nicht ziel- führend, vor allem dann nicht, wenn dem Benutzer die SQL-Typdefinitionen der Attribute nicht bekannt sind29. Bisher führte die Suche nach numerischen Suchbegriffen, beispielsweise „4020“, nur in Attributen mit numerischen SQL-Typ (beispielsweise „INT“) zu Treffern. Mit dem gesuchten Begriff „4020“ könnte der Benutzer eine Postleitzahl (Linz-Stadt) meinen. Angenommen die Relation Student würde statt dem Attribut

weiterung. Das in Rahmen dieser Arbeit verwendete MySQL stellt hierfür die Klausel „LIMIT n“ zur Verfügung. Kennt das DBMS keine derartige Klausel, so ändert dies zunächst nichts am Ergebnis der Abfrage, es ist jedoch damit zu rechnen, dass sich deren Laufzeit verschlechtert. 28 Das in dieser Arbeit verwendete DBMS: MySQL verhält sich gemäß dieser Annahme. Daneben lässt sich der Vergleich von Zeichenketten unabhängig von der Groß-/Kleinschreibung dadurch erzielen, indem beide Seiten zuvor beispielsweise in Kleinschreibung umgewandelt werden: „WHERE lower(dbname) = lower('MySQL')“. Letzteres funktioniert mit jedem DBMS, das konform zum SQL- Standard ist. 29 Der Großteil der Benutzer eines Datenbanksystems hat in der Regel wenig bzw. unvollständiges Wissen über das konkrete Schema der Datenbank. Das Fehlen dieses Spezialwissens stellt daher bei der Formulierung von (SQL-)Abfragen oftmals eine große Hürde dar. Moderne, benutzerfreundli- che Abfragewerkzeuge für (relationale) Datenbanken sollten solche Hürden maskieren. Für eine er- folgreiche Suche mit SAHSERD soll grundsätzlich so wenig (Schema-)Vorwissen wie möglich nötig sein.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 93 Adresse das Attribut Postleitzahl beinhalten, welches vom SQL-Typ VARCHAR(10) ist und u.a. folgende Attributwerte beinhaltet: „4020“, „1010“, „D-80123“. Die Suche nach „4020“ würde, mangels Typ-Übereinstimmung von Suchbegriff und Attribut, im Attribut Postleitzahl keine Treffer ergeben. Dieser Zustand ist im Hinblick auf die Benutzerfreundlichkeit von SAHSERD nicht haltbar. Der Algorithmus zur Bil- dung der SQL-Abfrage wird somit dahingehend verändert, dass künftig auch Ab- fragebedingungen für numerische Suchbegriffe und Attribute vom Typ Zeichen- kette gebildet werden. Andererseits sollte diese Typ-Umwandlung nur für geeig- nete Attribute erfolgen, andernfalls wird folgende SQL-Abfrage generiert:

SELECT MatrikelNr, Vorname, Nachname, Postleitzahl FROM StudentV2 WHERE MatrikelNr = 4020 OR Vorname = '4020' OR Nachname = '4020' OR Postleitzahl = '4020'; Die Suche nach „4020“ macht in Attributen, die beispielsweise (Personen-)Namen beinhalten, jedoch keinen Sinn. Welche Attribute für die Typen-übergreifende Su- che konkret geeignet sind, kann nicht mit einem Algorithmus ermittelt werden, da dazu semantisches Wissen benötigt wird, das in der Regel nicht im Datenbank- system enthalten ist. Die dafür nötigen Informationen muss der Datenbankadmi- nistrator SAHSERD in geeigneter Form zur Verfügung stellen.30 In Abbildung 34 sind die Regeln zur Bildung sinnvoller Abfragebedingung in Abhängigkeit vom Typ des Suchbegriffs und dem Typ des Attributes als Entschei- dungstabelle zusammengefasst:

Attribut Numerisch Zeichenkette z.B. INT z.B. CHAR, VARCHAR Suchbegriff

Abfragebedingung nur für “geeig- Numerisch Überprüfung des Suchbegriffs mit nete“ Attribute bilden, deren max. 4040, 175, 9856588 dem Wertebereich des Attributes Länge <= Länge des Suchbegriffs

Überprüfung der Länge des Such- Zeichenkette keine Abfragebedingung bilden begriffs mit der maximal möglichen "Wagner", "Linz" Länge des Attributes

Abbildung 34: Entscheidungstabelle zur Bildung einer Abfragebedingung

Unter der Voraussetzung, dass die numerische Suche nur für die Attribute Post- leitzahl bzw. Adresse freigegeben ist, generiert der Algorithmus für die Relation

30 Siehe Abschnitt 5.4.5

94 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Student und den (numerischen) Suchbegriffen „4020“, „985688“ folgende SQL- Abfragen: SELECT MatrikelNr, Postleitzahl FROM StudentV2 WHERE MatrikelNr IN (4020, 9856588) OR Postleitzahl IN ('4020', '9856588'); SELECT MatrikelNr, Adresse FROM Student WHERE MatrikelNr IN (4020, 9856588) OR Adresse IN ('4020', '9856588'); Während die Abfragebedingung „Postleitzahl IN ('4020', '9856588')“ in Relati- on StudentV2 zu Treffern führen wird, wird die Bedingung „Adresse IN ('4020', '9856588')“ in Relation Student von keinem Attributwert erfüllt. Die Attributwerte in Student.Adresse enthalten nämlich vollständige Adressen, beispielsweise „4020 Linz, Museumstraße 76“. Sollen solche Attributwerte, die „4020“ lediglich beinhal- ten, ebenfalls als Treffer erkannt werden, muss die Suchschärfe von „Exakte Über- einstimmung“ auf „Ist enthalten in“ herabgestuft werden.

Ad Suchschärfe: „Ist Enthalten In“-Suche Wie Eingangs dieses Abschnitts erwähnt, unterstützt SAHSERD bezüglich der Suchschärfe der ad-hoc Suche auf Wunsch31 auch eingeschränkt die unscharfe Suche in Form der „Ist Enthalten In“-Suche in den Attributwerten. Damit werden bei der Suche nach "System" beispielsweise auch Attributwerte wie „Systemtheo- rie“, „Informationssysteme“ oder „Sicherheitssystem“ getroffen. Die „Ist Enthalten In“-Suche, wird in SQL durch den „LIKE“-Operator unter- stützt, der gemäß dem SQL-92 Standard ausschließlich auf Attribute vom Typ Zei- chenkette anwendbar ist32. Die Abfragebedingungen in den WHERE-Klauseln der SQL-Abfragen müssen dazu von „ = “ auf „ LIKE '%%'“ geändert werden33. Ebenso wie beim exakten Vergleich mit dem Operator „=“ unterscheidet auch der „LIKE“-Operator nicht zwischen Groß- und Kleinschreibung. Mit aktivierter Suchschärfe „Ist enthalten In“, generiert die ad-hoc Suche nach „Küng“, „881“ folgende SQL-Abfragen:

31 Die Suchschärfe kann vom Suchmaschinenbenutzer pro Suchvorgang gewählt werden. 32 Proprietäre Erweiterungen in manchen DBMS (wie beispielsweise „MySQL“) ermöglichen den Ver- gleich mit den „LIKE“-Operator auch bei numerischen Attributtypen. 33 Der "LIKE"-Vergleichsoperator verwendet die Zeichen „_“ und „%“ zur Bildung des Such-Musters. Daraus ergibt sich, dass der Parser der Suchmaschine in Hinkunft Suchbegriffe, die diese besonde- ren Zeichen enthalten entsprechend maskieren muss.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 95 SELECT MatrikelNr, Vorname, Nachname, Adresse FROM Student WHERE MatrikelNr = 881 OR OR Vorname LIKE '%Küng%' OR Nachname LIKE '%Küng%' OR Adresse LIKE '%881%' OR Adresse LIKE '%Küng%'; SELECT SKZ, Bezeichnung FROM Studienrichtung WHERE SKZ = 881 OR Bezeichnung LIKE '%Küng%'; SELECT Name, Adresse FROM Institut WHERE Name LIKE '%Küng%' OR Adresse LIKE '%881%' OR Adresse LIKE '%Küng%'; Aus dem obigen Beispiel ist ersichtlich, dass mehrere Abfragebedingungen für dasselbe Attribut nicht mittels „ IN (LIKE '%%', LIKE '%%', ...)“ zusammengefasst werden können, da dieses Sprachkonstrukt in SQL nicht definiert ist.

Als Folge der Änderungen bei der Bildung der SQL-Abfrage, muss auch das Code- Stück zur Auswertung der getroffenen Datensätze angepasst werden. Einerseits sollen weiterhin exakte Übereinstimmungen als solche erkannt werden, anderer- seits aber auch Übereinstimmungen vom Typ „Ist enthalten In“. Beispielsweise ergibt die Suche nach „Informatik“ in der Relation Studienrichtung mit der SQL- Abfrage:

SELECT Bezeichnung FROM Studienrichtung WHERE Bezeichnung LIKE '%Informatik%'; eine exakte Übereinstimmung mit dem Attributwert „Informatik“ als auch eine unscharfe Übereinstimmung vom Typ „Ist enthalt in“ mit dem Attributwert „Wirt- schaftsinformatik“.34

Ad-hoc Suche in den Metadaten

Neben den Attributwerten kommen als Suchort der Ad-hoc-Suche auch noch die Metadaten der Datenbank infrage, im Speziellen die Bezeichnungen der Relatio- nen und Attribute. Der Algorithmus zur ad-hoc Suche adHocSearch() muss dem- nach in zwei Schritte aufgeteilt werden:

0 // SAHSERD.SearchModule.adHocSearch()

1 adHocSearch(psearchedPhrases) {

34 Die Auswirkungen dieser „gemischten“ Treffermenge werden im Abschnitt „Rangreihung im Such- ergebnis“ behandelt.

96 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 2 foundDBAccessPaths = {}; 3 foundDBAccessPaths.add(searchValues(searchedPhrases)); 4 foundDBAccessPaths.add(searchMetadata(searchedPhrases)); 5 return foundDBAccessPaths; 6 }

Die Methode searchValues() erledigt fortan die Suche in den Attributwerten und searchMetadata() liefert die Treffer in den Metadaten des Datenbanksystems. Die Teilergebnisse werden anschließend zum Gesamtergebnis foundDBAccessPaths vereinigt.

Ad Suchort: ad-hoc Suche im Data-Dictionary des DBS Die Metadaten über eine Datenbank werden vom DBMS in einem sogenannten Data-Dictionary verwaltet. In dieser internen Datenstruktur des DBMS sind unter anderem Informationen über Relationen, Attribute, Wertebereiche, Schlüsselatt- ribute und deren Abhängigkeiten, Indizes, Zugriffsrechte uvm. gespeichert. Ver- fügt man über die entsprechenden Zugriffsrechte, können die Metadaten einer Datenbank über DBMS-spezifische Schnittstellen ausgelesen (und teilweise auch direkt verändert) werden. Für die ad-hoc Suche in den Metadaten eines DBS sind jedoch nur die Bezeichnungen der Relationen und der Attribute von Interesse.

Für die folgenden Ausführungen zur Suchmethode und zur Suchschärfe gilt die Annahme, dass die Namen der Relationen und Attribute, im Zuge der Initialisie- rung von SAHSERD, in eine entsprechende Datenstruktur – die fortan als „Such- maschinen-internes Data-Dictionary“35 bezeichnet wird – eingelesen werden. Weiters wird die Existenz von einfachen Methoden zum Auslesen dieser Daten- struktur angenommen.

Ad Suchmethode: Suche im internen Data-Dictionary Unter den oben angeführten Voraussetzungen hat der Algorithmus zur ad-hoc Suche in den Metadaten searchMetadata() folgende einfache Struktur:

0 // SAHSERD.SearchModule.searchMetadata() // draft

1 searchMetadata(psearchedPhrases) { 2 foundDBAccessPaths = {}; 3 // 1) search in names of tables 4 for(currTbl in internalDataDictionary().getTables()) { 5 for(sPhrase in searchedPhrases) { 6 if(! isNumeric(sPhrase) && currTbl.name().equalsIgnoreCase(sPhrase))

35 Das Suchmaschinen-interne Data-Dictionary wird im Abschnitt 5.4.5 ausführlich behandelt.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 97 7 foundDBAccessPaths.add(currTbl); // found matching table 8 } 9 } 10 // 2) search in names of columns 11 for(currCol in internalDataDictionary().getColumns()) { 12 for(sPhrase in searchedPhrases) { 13 if(! isNumeric(sPhrase) && currCol.name().equalsIgnoreCase(sPhrase)) 14 foundDBAccessPaths.add(currCol); // found matching column 15 } 16 } 17 return foundDBAccessPaths; 18 }

Die Suche von numerischen Suchbegriffen in den Metadaten kann generell un- terbleiben (siehe Zeilen 6 und 13), da SQL als Bezeichnung für eine Relation bzw. ein Attribut nur alphanumerische Zeichenketten die nicht mit einer Ziffer begin- nen erlaubt, wie beispielsweise „L4020“.

Ad Suchschärfe: Exakte Übereinstimmung Damit eine für alle Suchorte, d.h. sowohl für Attributwerte als auch für Metada- ten, einheitliche Suchschärfe gewährleistet ist, hat die Methode searchMetadata() dafür Sorge zu tragen, dass der Vergleich der Metadaten mit den Suchbegriffen unabhängig von der Groß-/Kleinschreibung erfolgt – siehe Zeilen 6 und 13 im Pseudocode.

Ad Suchschärfe: Unscharfe Suche mittels Synonymen Analog zur ad-hoc Suche in den Attributwerten soll die unscharfe Suche auch in den Metadaten der Datenbank möglich sein. Die unscharfe Suche mit „Ist enthal- ten in“ macht für Metadaten aber wenig Sinn, weil die Relationen und Attribute aus verschiedenen Gründen im Zuge des physischen DB-Entwurfs oftmals künst- liche Namen erhalten36. Stattdessen soll dem Benutzer das Auffinden von Meta- daten durch Synonyme erleichtert werden. Bisher bleibt die Suche nach den Begriffen „Studentin“, „students“ oder „Hö- rer“ mit der Suchschärfe „exakte Übereinstimmung“ ohne Erfolg, da keine Relati- on bzw. kein Attribut auf diese Bezeichnungen lautet. Der Suchbegriff „Student“ hingegen, stimmt mit der Bezeichnung einer Relation in der Datenbank UniLinz überein. Für den Großteil der Suchmaschinenbenutzer sind diese Unterschiede im Suchergebnis, bei fast gleichlautenden Suchbegriffen, aber schwer nachzuvoll-

36 Der DB-Administrator könnte die Relation Student beispielsweise als Tabelle "TAB_STUDENT", "ST" oder "UL_VERW_STUDENT" anlegen.

98 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken ziehen und führen zu Verwirrung. Eine zentrale Anforderung an SAHSERD ist je- doch, dass vom Benutzer, für einfache Suchanfragen, keine detaillierten Kennt- nisse über das Datenbankschema und die Bezeichnung von Relationen und Attri- buten verlangt werden. Die Definition von entsprechenden Synonymen (durch den Datenbankadministrator) für Metadaten-Bezeichner kann hier Abhilfe schaf- fen.

Synonyme lassen sich in folgende, hier relevante Untergruppen einteilen: a) Abkürzungen, b) Wortformen und c) Synonyme im eigentlichen Sinn

Die Gruppe Abkürzungen umfasst (geläufige) Kurzformen von Begriffen, bei- spielsweise „LVA“o„Lehrveranstaltung“ oder „VO“o„Vorlesung“ etc. Unter Wortformen werden die Variationen eines Wortstammes (Student) ver- standen, die durch Beugung (Students), Bildung des Plurals (Studenten) oder der weiblichen Form (Studentin) gebildet werden können. Mit Synonymen im eigentlichen Sinn sind schließlich wirkliche sinnver- wandte Begriffe gemeint, das sind solche mit einem anderen Wortstamm, bei- spielsweise "Hörer"o"Student" oder "Schein"o"LVA-Zeugnis".

Zur Realisierung der unscharfen ad-hoc Suche in den Metadaten mittels Synony- men benötigt die Suchmaschine ein Verzeichnis zum Nachschlagen, ob ein gege- bener (Such-)Begriff ein Synonym für einen Metadaten-Bezeichner ist, und wenn dies der Fall ist, um welchen es sich dabei handelt. Die Datenstruktur zur Verwal- tung der Metadaten-Aliase, das sogenannte „Alias-Verzeichnis“ wird in Abschnitt „5.4.5 Interne Datenstrukturen“ ausführlich behandelt. Unter der Annahme, dass ein entsprechendes Alias-Verzeichnis angelegt wurde, muss die Suchmethode searchMetadata() nun noch um die Suche in der Synonymtabelle erweitert werden. Der Vergleich auf Übereinstimmung erfolgt wie bisher ohne Rücksichtnahme auf die Groß-/Kleinschreibung:

0 // SAHSERD.SearchModule.searchMetadata() // version 0.2

1 searchMetadata(psearchedPhrases) { : /* ... */ 17 // 3) check table of metadata-aliases 18 for(sPhrase in searchedPhrases) { 19 if(! isNumeric(sPhrase) && metadataAliases().containsIgnoreCase(sPhrase))

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 99 20 // found matching alias(es) 21 foundDBAccessPaths.addAll(metadataAliases().dbIdentifiersFor(sPhrase)); 22 } 23 return foundDBAccessPaths; 24 }

Die ad-hoc Suche in den Metadaten erfolgt, im Unterschied zur ad-hoc Suche in den Attributwerten, unabhängig von der (vom Benutzer) gewählten Suchschärfe in jedem Fall unscharf, d.h. unter Einbeziehung des Alias-Verzeichnisses. Damit soll gewährleistet werden, dass die ad-hoc Suche jedenfalls die entsprechenden Metadaten-Bezeichner findet, unabhängig davon, ob die Schreibweise der Such- begriffe mit den tatsächlichen Bezeichnungen übereinstimmt. Außerdem wirkt sich diese Erweiterung kaum auf die Performanz von Suchphase 1 aus37.

Ergebnis der ad-hoc Suche

Für die in dieser Arbeit verwendeten Suchbegriffe (insbesondere den Testfällen, siehe Abschnitt 4.4.2) ergeben sich durch den Aufruf von adHocSearch() je nach eingestellter Suchschärfe folgende Ergebnisse:

Ergebnis der ad-hoc Suche Ergebnis der ad-hoc Suche Suchbegriff mit exaktem Vergleich mit unscharfem Vergleich = VAL:Studienrichtung.SKZ 175 = VAL:Studienrichtung.SKZ ~ VAL:Student.Adresse = VAL:Studienrichtung.SKZ 881 = VAL:Studienrichtung.SKZ ~ VAL:InstMitglied.TelefonNr 0055880 = VAL:Student.MatrikelNr = VAL:Student.MatrikelNr 0056410 = VAL:Student.MatrikelNr = VAL:Student.MatrikelNr 9856588 = VAL:Student.MatrikelNr = VAL:Student.MatrikelNr 9956627 = VAL:Student.MatrikelNr = VAL:Student.MatrikelNr = COL:Institut.Adresse = COL:Institut.Adresse Adresse = COL:Student.Adresse = COL:Student.Adresse = VAL:Student.Nachname = VAL:Student.Nachname Bauer = VAL:WissPersonal.Nachname = VAL:WissPersonal.Nachname ~ VAL:WissPersonal.Nachname ~ VAL:Student.Nachname Berger (kein Treffer) ~ VAL:WissPersonal.Nachname Durchwahl ~ COL:InstMitglied.TelefonNr ~ COL:InstMitglied.TelefonNr Ederl = VAL:Student.Nachname = VAL:Student.Nachname = VAL:Student.Nachname = VAL:Student.Nachname Fischer = VAL:WissPersonal.Nachname = VAL:WissPersonal.Nachname

37 Die Laufzeit einer Suchabfrage ist hauptsächlich von der ad-hoc Suche in den Attributwerten ab- hängig, durch die Anzahl der Lesevorgänge vom Sekundärspeicher (Festplatte), die beim Ausführen der SQL-Abfragen seitens des DBMS entstehen. Die ad-hoc Suche in den Metadaten inklusive Zugriff auf aus Alias-Verzeichnis wirkt sich nur marginal auf die Gesamtlaufzeit aus. Hierfür sind keine Zugriffe auf den Sekundärspeicher notwendig.

100 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken = VAL:Student.Vorname = VAL:Student.Vorname Heinrich = VAL:WissPersonal.Nachname = VAL:WissPersonal.Nachname = VAL:WissPersonal.Vorname = VAL:WissPersonal.Vorname Holzer = VAL:Student.Nachname = VAL:Student.Nachname = VAL:Studienrichtung.Bezeichnung Informatik = VAL:Studienrichtung.Bezeichnung ~ VAL:Studienrichtung.Bezeichnung = VAL:LVA.Titel Informationssysteme = VAL:LVA.Titel ~ VAL:LVA.Titel = TAB:Institut Institut = TAB:Institut ~ VAL:Institut.Name Küng = VAL:WissPersonal.Nachname = VAL:WissPersonal.Nachname Lehrveranstaltungen ~ TAB:LVA ~ TAB:LVA ~ VAL:Institut.Adresse Linz (kein Treffer) ~ VAL:Student.Adresse LVAs ~ TAB:LVA ~ TAB:LVA Matrikel# ~ COL:Student.MatrikelNr ~ COL:Student.MatrikelNr = COL:Institut.Name = COL:Institut.Name ~ COL:Student.Nachname Name ~ COL:Student.Nachname ~ COL:WissPersonal.Nachname ~ COL:WissPersonal.Nachname ~ VAL:Student.Nachname Soziologie (kein Treffer) ~ VAL:Institut.Name = TAB:Student = TAB:Student Student = VAL:Student.Nachname = VAL:Student.Nachname Studenten ~ TAB:Student ~ TAB:Student Telefon ~ COL:InstMitglied.TelefonNr ~ COL:InstMitglied.TelefonNr Wagner = VAL:WissPersonal.Nachname = VAL:WissPersonal.Nachname Wöß = VAL:WissPersonal.Nachname = VAL:WissPersonal.Nachname Zeugnisse ~ TAB:LVAZeugnis ~ TAB:LVAZeugnis

Abbildung 35: Ergebnisse der ad-hoc Suche je nach Suchschärfe

Jedem Suchbegriff sind die getroffenen Zugriffspfade zugeordnet. Ergibt die ad- hoc Suche für einen Suchbegriff weder in den Attributwerten noch in den Meta- daten eine Übereinstimmung, so retourniert adHocSearch() eine leere Liste. Ein getroffener Zugriffspfad besteht aus dem Typ des Zugriffspfades („TAB“, „COL“ oder „VAL“), Adresse des Zugriffspfads ([.Attribut]) und Art der Übereinstimmung („=“ oder „~“). Wurden bei der ad-hoc Suche mehrere Überein- stimmungen gefunden dann sind die getroffenen Zugriffspfade nach dem Rang in der Begriffshierarchie geordnet. An erster Stelle kommen Übereinstimmungen mit Relationen (TAB), dann Treffer bei Attributen (COL) und schließlich Überein- stimmungen bei Attributwerten (VAL). Innerhalb dieser drei Gruppen sind exakte Treffer („=“) wiederum vor unscharfen Treffern („~“) gereiht. In Abbildung 35 sind die Ergebnisse für Anfragen mit einem einzigen Such- begriff dargestellt. Das Ergebnis für Suchanfragen die mehr als einen Begriff um- fassen, setzt sich einfach aus den Einzelergebnissen zusammen, das sind hier die entsprechenden Zeilen. Der Rückgabewert von adHocSearch() ist somit eine Liste

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 101 mit n Einträgen (n = Anzahl der Suchbegriffe), wobei jeder Listeneintrag aus einer Zuordnung der getroffenen Zugriffspfaden zu dem Suchbegriff besteht. Diese Lis- te stellt nun den Eingangsparameter für die zweite Suchphase dar, die Bildung der SQL-Anfragen.

5.4.2 ad Suchmodul: Bildung der SQL-Anfragen

Die zweite Phase zur Beantwortung einer Suchanfrage hat die Aufgabe, aus den Ergebnissen der ad-hoc Suche (Phase 1) das (End-)Ergebnis zu bilden. Unter dem Endergebnis werden hier jene SQL-Abfragen verstanden, deren Ausführung das eigentliche Suchergebnis ergibt, damit sind die der Suchanfrage entsprechenden Ausschnitte der Datenbank (Relationen, Attribute, Datensätze) gemeint. Bei- spielsweise soll aus dem Ergebnis der ad-hoc Suche (angegeben als Liste von Suchbegriffen und getroffenen Zugriffspfaden – siehe oben):

"Küng" = VAL:WissPersonal.Nachname "9856588" = VAL:Student.MatrikelNr folgende SQL-Abfrage generiert werden,

SELECT LZ.*, S.*, WP.* FROM LVAZeugnis as LZ, Student as S, WissPersonal as WP WHERE S.MatrikelNr = 9856588 AND WP.Nachname = 'Küng' AND LZ.Pruefer = WP.PersNr AND S.MatrikelNr = LZ.MatrikelNr; die schließlich zu folgendem Endergebnis38 führt:

LZ. LZ. LZ. S. S. S. WP. WP. LVANr Note Pruefer MatrikelNr Nachname Vorname Nachname Vorname 351002 3 1100 9856588 Fischer Fritz Küng Josef 351003 2 1100 9856588 Fischer Fritz Küng Josef

Der Lösungsansatz zur Bildung der SQL-Abfragen wurde bereits in Abschnitt 5.2.3 skizziert. In buildSQL() wird, abhängig von der Anzahl der verschiedenen Relatio- nen, die die Liste der getroffenen Zugriffspfade enthält, grundsätzlich in: a) Ergebnisse die eine einzige Relation betreffen (SingleTableResults) und b) Ergebnisse die mehrere Relationen betreffen (MultiTableResults)

38 Aus Platzgründen enthält die Ergebnistabelle nicht alle Attribute der Relationen LVAZeugnis, Stu- dent und WissPersonal, wie in der Select-Klausel gefordert.

102 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken unterschieden39. Die Bildung der SQL-Abfragen wird entsprechend an buildSQLSingleTable() bzw. buildSQLMultiTable() delegiert. Im Folgenden werden die Algorithmen für diese beiden Methoden präzisiert. Ein zweites, wichtiges Unterscheidungsmerkmal für die Liste der getroffenen Zugriffspfade (innerhalb dieser beiden Ergebnistypen) ist der Treffer-Typ. Enthält die Liste der Zugriffspfade mindestens einen Eintrag vom Typ Attributwert-Treffer (VAL) so ist die gesamte Liste vom Typ Attributwert-Treffer. Beinhaltet die Liste der Zugriffspfade jedoch keinen Eintrag vom Typ Attributwert-Treffer, dafür aber Relationen-Treffer (TAB) und/oder Attribut-Treffer (COL), so ist die gesamte Liste vom Typ Metadaten-Treffer. Vorerst widme ich mich den Ergebnissen die zumin- dest einen Attributwert-Treffer beinhalten. Die Behandlung einer Liste von Zugriffspfaden, die ausschließlich Metadaten-Treffer beinhaltet erfolgt am Ende dieses Abschnitts.

Der Algorithmus zur Bildung der SQL-Anfragen kann somit wie folgt formuliert werden:

0 // SAHSERD.SearchModule.buildSQL() // draft

1 buildSQL(phitDBAccessPaths) { 2 // check if hitDBAccessPaths contains nothing but metadata-hits 3 if(hitDBAccessPaths.isMetadataResult()) 4 return metadataResult(hitDBAccessPaths); 5 6 if(hitDBAccessPaths.isSingleTableResult()) 7 return sqlQueryForSingleTableResult(hitDBAccessPaths); 8 else 9 return sqlQueryForMultiTableResult(hitDBAccessPaths); 10 }

Bildung der SQL-Anfragen für SingleTableResults

Eine SQL-Abfrage setzt sich zumindest aus einer Select-Klausel und einer From- Klausel zusammen, wodurch die anzuzeigenden Relation(en) und Attribute fest- gelegt werden. Aus Gründen der Einfachheit verwendet SAHSERD immer alle Att- ribute aller betroffenen Relationen zur Anzeige des Endergebnisses. Dies hat den

39 Diese Einteilung erscheint vorerst zweckmäßig, da für SingleTableResults keine Joins nötig sind und daher nur einfache SQL-Abfragen gebildet werden müssen. Die Bildung der SQL-Abfragen für Mul- tiTableResults ist dagegen etwas komplizierter.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 103 Nebeneffekt, das Einträge in der Liste der getroffenen Zugriffspfade vom Typ Me- tadaten-Treffer nicht mehr gesondert berücksichtigt werden müssen, da die ge- troffenen Relationen (TAB) und/oder Attribute (COL) jedenfalls im Ergebnis ent- halten sind. Zur Beschränkung des Abfrageergebnisses auf eine bestimmte Menge an Datensätzen, muss die SQL-Abfrage um eine WHERE-Klausel erweitert wer- den, in der die entsprechenden Bedingungen zur Selektion definiert werden. Da- zu werden hier die Einträge in der Liste der getroffenen Zugriffspfade vom Typ Attributwert-Treffer (VAL) herangezogen. Der Algorithmus zur Bildung der SQL- Anfragen für SingleTableResults stellt sich damit wie folgt dar:

0 // SAHSERD.SearchModule.sqlQueryForSingleTableResults() // draft

1 sqlQueryForSingleTableResults(phitDBAccessPaths) { 2 tblName = hitDBAccessPaths.get(0).tableName(); 3 selectClause = tblName + ".*"; 4 fromClause = tblName; 5 whereClause = ""; 6 for(hdbap in hitDBAccessPaths) { 7 if(hdbap.isValueHit()) { 8 if(whereClause == "") 9 whereClause += " WHERE "; 10 else 11 whereClause += " AND "; 12 whereClause += hdbap.asWhereClauseString(); 13 } 14 } 15 return new SQLSelectStatement(selectClause, fromClause, whereClause); 16 }

Die gebildete SQL-Abfrage für SingleTableResults hängt demnach ausschließlich von der WHERE-Klausel und damit von den Attributwert-Treffern (VAL) in hitDBAccessPaths ab. Das bedeutet, dass für folgende Listen von getroffenen Zugriffspfaden jeweils dieselbe SQL-Abfrage generiert wird: (a) ["9856588" = VAL:Student.MatrikelNr] (b) ["Studenten" ~ TAB:Student, "9856588" = VAL:Student.MatrikelNr] (c) ["MatrikelNr" = COL:Student.MatrikelNr, "9856588" = VAL:Student.MatrikelNr] (d) ["Student" = TAB:Student, "Matrikel#" = COL:Student.MatrikelNr, "9856588" = VAL:Student.MatrikelNr]

Die Angabe von (vermeintlich) präzisierenden Relationen-/Attribut-Bezeich- nungen bei der Formulierung einer Suchanfrage (Beispiele b-d) bleibt demnach

104 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken ohne Einfluss auf das Abfrageergebnis, wenn zumindest ein Suchbegriff (hier „9856588“) mit einem Attributwert übereinstimmt und alle Zugriffspfade der Liste auf dieselbe Relation verweisen.

Die Methode asWhereClauseString() hat dafür Sorge zu tragen, dass bei der Um- wandlung eines Attributwert-Treffers in eine Abfragebedingung für eine WHERE- Klausel, sowohl der richtige Vergleichsoperator als auch der Typ des getroffenen Attributs berücksichtigt werden. Folgende Beispiele sollen dies verdeutlichen:

Zugriffspfad Abfragebedingung für WHERE-Klausel

„9856588“ = VAL:Student.MatrikelNr MatrikelNr = 9856588 „175“ ~ VAL:Student.Adresse Adresse LIKE '%175%' „Datenmodellierung“ = VAL:LVA.Titel Titel = 'Datenmodellierung' „Bauer“ ~ VAL:WissPersonal.Nachname Nachname LIKE '%Bauer%'

Logische Verknüpfung der Abfragebedingungen Mehrere Abfragebedingungen werden grundsätzlich mit logischem Und ver- knüpft (siehe Codezeile 11). Dadurch wird jene SQL-Abfrage generiert, die gleich- zeitig alle geforderten (Abfrage-)Bedingungen erfüllt. In der Regel wird dadurch auch der Ausschnitt aus der Datenbank als Endergebnis angezeigt, welcher der Suchanfrage entspricht40. Beispielsweise ergibt die Suchanfrage „9856588“, „Bau- er“ u.a. folgende getroffene Zugriffspfade:

"Bauer" = VAL:Student.Nachname "9856588" = VAL:Student.MatrikelNr woraus folgende SQL-Abfrage generiert wird:

SELECT Student.* FROM Student WHERE Student.MatrikelNr = 9856588 AND Student.Nachname = 'Bauer'; Die besondere Struktur der zu durchsuchenden Datenmenge (Relationen einer Datenbank) im Vergleich zu flachem Text bzw. HTML-Seiten bei klassischen Suchmaschinen, erfordert für bestimmte Sonderfälle jedoch eine Ausnahme bei der Verknüpfung der Abfragebedingungen. Enthält die Liste der getroffenen Zugriffspfade mehrere Einträge vom Typ Attributwert-Treffer, die auf dasselbe Att- ribut verweisen (identer Zugriffspfad), beispielsweise:

40 In der Regel werden Suchanfragen an WWW-Suchmaschinen, die mehrere Suchbegriffe umfassen, ebenso interpretiert.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 105 "Bauer" = VAL:Student.Nachname "Heinrich" = VAL:Student.Vorname "Holzer" = VAL:Student.Nachname entsteht mit dem angegebenen Algorithmus folgende SQL-Abfrage:

SELECT Student.* FROM Student WHERE Student.Nachname = 'Bauer' AND Student.Nachname = 'Holzer' AND Student.Vorname = 'Heinrich'; SQL-Abfragen, die in der WHERE-Klausel eine Bedingung der Form „ = AND ... AND = “ enthalten, ergeben jedoch jedenfalls eine leere Ergebnismenge, da sich solche Bedingungen gegenseitig ausschließen. Da- mit trotzdem eine sinnvolle SQL-Abfrage generiert wird, die alle angegebenen Bedingungen enthält, müssen diese mit logischem Oder verknüpft und gegebe- nenfalls in Klammern eingeschlossen werden:

SELECT Student.* FROM Student WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Holzer') AND Student.Vorname = 'Heinrich'; Weiterhin werden alle Abfragebedingungen der WHERE-Klausel grundsätzlich mit logischem Und verknüpft. Bedingungen, die dasselbe Attribut betreffen werden mit logischem Oder verknüpft und in Klammern eingeschlossen zu Gruppen zu- sammengefasst. Diese „Oder-Gruppen“ werden (wie alle anderen Abfragebedin- gungen) wiederum mit logischem Und verknüpft. Dadurch entstehen schließlich WHERE-Klauseln der allgemeinen Form:

b1 AND b2 AND (b3 OR b4) AND (b5 OR b6 OR .. OR bm) AND ... AND bn; Enthält die Liste der getroffenen Zugriffspfade auch unscharfe Attributwert- Treffer (vom Typ „ist enthalten in“), sollte diese Bildungsregel nochmals erweitert werden. Unter gewissen Umständen können Abfragebedingungen vom Typ „ist enthalten in“, die dasselbe Attribute betreffen, doch mit logischem Und statt mit logischem Oder verknüpft werden. Beispielsweise können für die folgende Liste getroffener Zugriffspfade:

"175" ~ VAL:Student.Adresse "Linz" ~ VAL:Student.Adresse entweder wie bisher SQL-Anfrage (a) oder aber Variante (b) generiert werden:

(a) SELECT Student.* FROM Student WHERE (Student.Adresse LIKE '%175%' OR Student.Adresse LIKE '%Linz%');

106 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken (b) SELECT Student.* FROM Student WHERE Student.Adresse LIKE '%175%' AND Student.Adresse LIKE '%Linz%'; Generell kann man nicht von vornherein ausschließen, dass zu einer SQL- Abfrage, mit einer WHERE-Klausel der Form „ LIKE '%%' AND ... AND LIKE '<%val2%>'“, kein Datensatz existiert, der alle diese Bedingungen er- füllt. Unter der Annahme, dass das Attribut Adresse der Relation Student den Att- ributwert „4040 Linz, Freistädterstr. 175“ enthält, liefert die SQL-Abfrage (b) nur genau für diesen Datensatz einen Treffer. Das Ergebnis von Variante (a) enthält zusätzlich aber auch noch jene Datensätze, die nur eine der beiden Bedingungen erfüllen. Die Verknüpfung mit logischem Und ist jedoch nur zulässig, wenn alle Einträ- ge in der Liste der getroffenen Zugriffspfade ausschließlich unscharfe Attribut- wert-Treffer vom Typ „ist enthalten in“ sind. Enthält die Liste der getroffenen Zugriffspfade sowohl exakte Übereinstimmung als auch unscharfe Übereinstim- mungen, dürfen alle Bedingungen nur mit logischem Oder verknüpft werden. Enthält die Liste getroffener Zugriffspfade beispielsweise:

"Datenmodellierung" = VAL:LVA.Titel "Informationssysteme" ~ VAL:LVA.Titel so lautet die entsprechende SQL-Abfrage:

SELECT LVA.* FROM LVA WHERE (LVA.Titel = 'Datenmodellierung' OR LVA.Titel LIKE '%Informationssysteme%'); Für den verbleibenden Teil dieses Kapitels gilt die Annahme, dass der Algorithmus sqlQueryForSingleTableResults() zur Bildung der SQL-Anfragen für SingleTable- Results entsprechend der eben ausgeführten Überlegungen arbeitet.

Bildung der SQL-Anfragen für MultiTableResults

Bei der Bildung der SQL-Abfragen für MultiTableResults kann nach dem bewähr- ten Prinzip „Aufgaben-Delegation und Ergebnis-Integration“ vorgegangen wer- den, indem mehrere SingleTableResults zusammen mit den nötigen Joins zu einer Lösung vereinigt werden. Die gewünschte Vorgehensweise soll zunächst an einem einfachen Beispiel gezeigt werden, das von folgender Liste der getroffenen Zugriffspfade ausgeht:

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 107 "Berger" ~ VAL:Student.Nachname "175" = VAL:Studienrichtung.SKZ Zunächst werden SingleTableResults für die Relationen Student und Studienrich- tung gebildet:

(1) SELECT Student.* FROM Student WHERE Student.Nachname LIKE '%Berger%'; (2) SELECT Studienrichtung.* FROM Studienrichtung WHERE Studienrichtung.SKZ = 175; Dann wird mittels joinTree()41 eine Verbindung (als Join-Baum) zwischen den be- troffenen Relationen, hier Student und Studienrichtung, generiert. Der kleinste Join-Baum lautet hier „Student – Inskription – Studienrichtung“, mittels der Joins „Student.MatrikelNr = Inskription.MatrikelNr“ und „Inskription.SKZ = Studien- richtung.SKZ“. Formuliert man diesen Join-Baum als vollständige SQL-Abfrage, erhält man:

(3) SELECT Student.*, Inskription.*, Studienrichtung.* FROM Student, Studienrichtung, Inskription WHERE Student.MatrikelNr = Inskription.MatrikelNr AND Inskription.SKZ = Studienrichtung.SKZ Die Vereinigung der SQL-Abfragen (1), (2) und (3) ergibt nun schließlich42:

SELECT Student.*, Inskription.*, Studienrichtung.* FROM Student, Studienrichtung, Inskription WHERE Student.Nachname LIKE '%Berger%' AND Studienrichtung.SKZ = 175 AND Student.MatrikelNr = Inskription.MatrikelNr AND Inskription.SKZ = Studienrichtung.SKZ Der Algorithmus zur Bildung der SQL-Abfrage für MultiTableResults hat somit fol- gende Form:

0 // SAHSERD.SearchModule.sqlQueryForMultiTableResults() // draft

1 sqlQueryForMultiTableResults(phitDBAccessPaths) { 2 // 1) group hitDBAccessPaths per table => hdapsPerTable 3 hdbapsPerTable = {}; 4 for(hdbap in hitDBAccessPaths) { 5 tblName = hdbap.tableName(); 6 hdbapList = hdbapsPerTable.get(tblName); 7 if(hdbapList == Null) 8 hdbapList = {};

41 Siehe Exkurs “Algorithmen für ER-Graphen“ in Abschnitt 5.2.3 42 Zur Vereinigung werden jeweils die Select-, die From- und die Where-Klauseln vereinigt, wobei mehrfach auftretende Abfrageteile nur einmal in das Ergebnis aufgenommen werden.

108 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 9 hdbapList.add(); 10 hdbapsPerTable.put(tblName, hdbapList); 11 } 12 13 // 2) get SingleTableResults for each table (in hdapsPerTable) 14 singleTblResWhereClause = ""; 15 for(tbl in hdbapsPerTable.keySet()) { 16 hdbapList = hdbapsPerTable.get(tblName); 17 singleTblResSQLQuery = sqlQueryForSingleTableResults(hdbapList); 18 singleTblResWhereClause += singleTblResSQLQuery.whereClause() + " AND "; 19 } 20 21 // 3) get joinTree for hit tables 22 jTree = joinTree(hdbapsPerTable.keySet()); 23 24 // 4) unify resulting sql-queries 25 sqlStmtJTree = jTree.asSQLSelectStatement(); 26 unifiedWhereClause = singleTblResWhereClause + sqlStmtJTree.whereClause(); 27 return new SQLSelectStatement(sqlStmtJTree.selectClause(), sqlStmtJTree.fromClause(), unifiedWhereClause); 28 }

Als Basis für die Konstruktion der resultierenden SQL-Abfrage dient die SQL- Abfrage, die dem ermittelten Join-Baum entspricht (sqlStmtJTree). Deren WHERE-Klausel wird um die Abfragebedingungen (singleTblResWhereClause) aus den SingleTableResults erweitert, wobei die Abfragebedingungen mit logischem Und vereinigt werden (siehe Zeile 18). Damit entsteht beispielsweise für folgende Liste der getroffenen Zugriffspfade:

"Bauer" = VAL:Student.Nachname "Holzer" = VAL:Student.Nachname "881" = VAL:Studienrichtung.SKZ eine SQL-Abfrage mit folgender WHERE-Klausel:

WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Holzer') AND Studienrichtung.SKZ = 881 AND Student.MatrikelNr = Inskription.MatrikelNr AND Inskription.SKZ = Studienrichtung.SKZ Die Bildung von SQL-Abfragen für MultiTableResults funktioniert demnach für al- le Listen von Zugriffspfaden die ausschließlich Attributwert-Treffer enthalten – vorausgesetzt ein Join-Baum zur Verbindung der getroffenen Relationen existiert.

Berücksichtigung von Metadaten-Treffern Zu Beginn dieses Abschnitts wurde nach dem Typ der Einträge in der Liste der Zugriffspfade grundsätzlich in Attributwert-Treffer und Metadaten-Treffer unter- schieden. Eine Liste vom Typ Attributwert-Treffer enthält per Definition mindes- tens einen Eintrag vom Typ Attributwert-Treffer (VAL).

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 109 Hier soll nun untersucht werden, inwieweit Einträge vom Typ Relationen- Treffer (TAB) oder vom Typ Attribut-Treffer (COL) in der Liste der getroffenen Zugriffspfade bei der Bildung der SQL-Abfragen berücksichtigt werden müssen. Zur Demonstration soll folgende Liste der getroffenen Zugriffspfade dienen:

"Lehrveranstaltungen" = TAB:LVA "Bauer" = VAL:Student.Nachname "Holzer" = VAL:Student.Nachname Zur Ermittlung des MultiTableResults werden zunächst die SingleTableResults für die Relationen Student (1) und LVA (2) ermittelt:

(1) SELECT Student.* FROM Student WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Holzer'); (2) SELECT LVA.* FROM LVA; Da die Liste der getroffenen Zugriffspfade für die Relation LVA keinen Attribut- wert-Treffer enthält, bleibt die WHERE-Klausel der generierten SQL-Abfrage leer. Schließlich fehlt noch ein Join-Baum zur Verbindung der Relationen LVA und Student. Er lautet „Student – LVAZeugnis – LVA“ und als vollständige SQL-Abfrage:

(3) SELECT LVA.*, LVAZeugnis.*, Student.* FROM LVA, LVAZeugnis, Student WHERE LVAZeugnis.MatrikelNr = Student.MatrikelNr AND LVA.LVANr = LVAZeugnis.LVANr Die Vereinigung der SQL-Abfragen (1), (2) und (3) ergibt schließlich:

SELECT LVA.*, LVAZeugnis.*, Student.* FROM LVA, LVAZeugnis, Student WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Holzer') AND LVAZeugnis.MatrikelNr = Student.MatrikelNr AND LVA.LVANr = LVAZeugnis.LVANr Damit wurde gezeigt, dass buildSQL() auch dann die gewünschte SQL-Abfrage generiert, wenn die Liste der Zugriffspfade Einträge vom Typ Metadaten-Treffer (TAB und/oder COL) enthält.

Zusammenführung der Algorithmen

Unter der Annahme, dass der Join-Baum für eine einzige Relation die Relation selbst ergibt, deren Darstellung als SQL-Abfrage die Form „SELECT .* FROM “ hat, liefert buildSQLMultiTable() für eine Liste von Zugriffspfaden, die nur eine Relation betreffen das gleiche Ergebnis wie buildSQLSingleTable(). Die Un-

110 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken terscheidung in SingleTableResults und MultiTableResults ist daher nicht mehr notwendig. Die Methode buildSQLMultiTable() wurde aus demselben Grund in sqlQueryForHDBAPs() umbenannt, wodurch sich folgende neue Form für buildSQL() ergibt:

0 // SAHSERD.SearchModule.buildSQL() // 0.2

1 buildSQL(phitDBAccessPaths) { 2 // check if hitDBAccessPaths contains nothing but metadata-hits 3 if(hitDBAccessPaths.isMetadataResult()) 4 return metadataResult(hitDBAccessPaths); 5 6 return sqlQueryForHDBAPs(hitDBAccessPaths); 7 }

Mit diesem Entwurf zur Bildung der SQL-Abfragen zu einer Liste von getroffenen Zugriffspfaden können nun grundsätzlich alle Suchanfragen beantwortet werden.

Alternative Lösung zur logischen Verknüpfung der Abfragebedingungen

Jede SQL-Abfrage, zu einer Liste von getroffenen Zugriffspfaden, die eine oder mehrere „Oder-Gruppen“ enthält und mindestens zwei Relationen betrifft, lässt sich in eine SQL-Abfrage überführen, in der alle Abfragebedingungen mit logi- schem Und verknüpft sind. Für die Transformation ist jedoch die mehrfache Ver- wendung von Joins aus dem Join-Baum nötig. Beispielsweise lässt sich die SQL- Abfrage:

(a) SELECT LVA.*, LVAZeugnis.*, Student.* FROM LVA, LVAZeugnis, Student WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Ederl' OR Student.Nachname = 'Holzer') AND LVAZeugnis.MatrikelNr = Student.MatrikelNr AND LVA.LVANr = LVAZeugnis.LVANr in folgende SQL-Abfrage transformieren:

(b) SELECT LVA.*, LZ1.*, ST1.*, ST2.*, ST3.* FROM LVA, LVAZeugnis as LZ1, LVAZeugnis as LZ2, LVAZeugnis as LZ3, Student as ST1, Student as ST2, Student as ST3 WHERE ST1.Nachname = 'Bauer' AND LZ1.MatrikelNr = ST1.MatrikelNr AND ST2.Nachname = 'Ederl' AND LZ2.MatrikelNr = ST2.MatrikelNr AND ST3.Nachname = 'Holzer' AND LZ3.MatrikelNr = ST3.MatrikelNr AND LZ1.LVANr = LZ2.LVANr AND LZ1.LVANr = LZ3.LVANr AND LZ1.LVANr = LVA.LVANr

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 111 Das Ergebnis von Variante (b) enthält nur jene Lehrveranstaltungszeugnisse, de- ren Lehrverstaltungen die Studenten mit den Nachnamen „Bauer“, „Ederl“ und „Holzer“ gemeinsam besucht haben. In der Datenbank UniLinz trifft dies auf kei- nen Datensatz zu. Das Suchergebnis zu Variante (b) lautet demnach:

KEINE Übereinstimmung(en) in 'UniLinz' gefunden! Im Vergleich dazu enthält das Ergebnis der SQL-Abfrage (a) alle Lehrveranstal- tungszeugnisse von Studenten mit den Nachnamen „Bauer“, „Ederl“ und „Hol- zer“:

10 Übereinstimmung(en) in 'UniLinz' gefunden: LZ. LZ. LVA. Student. Student. Student. LZ. LVANr LVATyp Titel MatrikelNr Vorname Nachname Note Datenbanksysteme und wis- 246309 VO 9856857 Eva-Marie Ederl 3 sensbasierte Systeme Datenbanksysteme und wis- 246309 VO 9955468 Heinrich Holzer 3 sensbasierte Systeme 246503 VO Vorlesung Algorithmen 9955468 Heinrich Holzer 1 Übung Algorithmen 2 246505 UE 9955468 Heinrich Holzer 2 (Gruppe 1) 246510 SE Diplomandenseminar WIN 9656873 Barbara Bauer 2 246510 SE Diplomandenseminar WIN 9856857 Eva-Marie Ederl 1 Informatik in Wirtschaft und 350000 VO 9856857 Eva-Marie Ederl 1 Verwaltung 351001 VO Informationssysteme 1 9656873 Barbara Bauer 1 351001 VO Informationssysteme 1 9955468 Heinrich Holzer 3 351004 UE Informationssysteme 1 9656873 Barbara Bauer 1

Nach Durchsicht der Treffer zeigt sich hier ebenso, dass es keine Lehrveranstal- tungszeugnisse/LVAs gibt, die alle drei Bedingungen erfüllen. Allerdings kann man hier im Gegensatz zu (a) feststellen, dass sowohl „Barbara Bauer“ und „Eva- Marie Ederl“ gemeinsam die LVA 246.510 absolviert haben. Ebenso gilt dies für „Bernd Bauer“-„Heinrich Holzer“ und die LVA 351.001, sowie für „Eva-Marie Ederl“-„Heinrich Holzer“ und die LVA 246.309.

Grundsätzlich sollte eine Suchmaschine alle Abfragebedingungen mittels logi- schem Und verknüpfen um die Dokumente – hier den kleinstmöglichen Aus- schnitt der Datenbank – als Suchergebnis zu liefern, bei dem alle Suchkriterien gleichzeitig zutreffen. Dieses „alles oder nichts“-Prinzip bei der Ergebnisermitt- lung wird hier zugunsten von Variante (a) aus folgenden Gründen verworfen:

¾ das Abfrageergebnis von Variante (b) beinhaltet nur vollständige Überein- stimmungen. Im Abfrageergebnis von Variante (a) scheinen zusätzlich noch jene Datensätze auf, bei denen zumindest eine Bedingung aus der Oder- Gruppe zutrifft. Trotzdem oder gerade deshalb, können derartige Suchergeb-

112 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken nisse für den Benutzer interessante Informationen enthalten. Allerdings muss er/sie die Zusammenhänge eigenständig aus dem Ergebnis herauslesen.

¾ das Abfrageergebnis von Variante (b) enthält pro Element der Oder-Gruppe jeweils alle Attribute der entsprechenden Relation und ist daher bereits bei wenigen Elementen unübersichtlich.

¾ die gebildete SQL-Abfrage von Variante (a) ist prägnanter und leichter zu ver- stehen. Im konkreten Fall können diese vermeintlichen Vorteile von Variante (a) gegen- über Variante (b) jedoch durch die vergleichsweise hohe Anzahl getroffener Da- tensätze egalisiert werden. Dies ist abhängig von der Anzahl der Elemente in der Oder-Gruppe und der Anzahl der Treffer pro Element. Dessen ungeachtet werden im Suchmodul von SAHSERD jedenfalls SQL- Abfragen der Variante (a), d.h. mit Oder-Gruppen generiert.

Beschränkung der Ergebnistiefe

Bisher bin ich bei der Bildung der SQL-Abfragen von der Annahme ausgegangen, dass joinTree() einen – den kürzesten – Join-Baum für eine Liste von Relationen ermittelt. Im Exkurs in Abschnitt 5.2.3 habe ich jedoch bereits aufgezeigt, dass zu einer gegebenen Liste von Relationen in der Regel mehrere, unterschiedlich lange Join-Bäume existieren, die jeweils alle angegebenen Relationen miteinander ver- binden. Unter Umständen gibt es sogar mehrere kürzeste Join-Bäume. Im Folgenden werden verschiedene Problemfälle rund um die Ermittlung ei- nes Join-Baums aufgezeigt und schließlich die Methode joinTree() entsprechend angepasst. Außerdem kann dabei die Ermittlung eines Join-Baums für eine einzi- ge Relation sinnvoll erweitert werden.

Zunächst soll gezeigt werden, dass der kleinste Join-Baum nicht immer das güns- tigste Abfrageergebnis liefert. Unter der vorübergehenden Annahme, dass im Da- tenmodell der Testdatenbank „UniLinz“ in der Tabelle Institut auch der Instituts- vorstand abgelegt wird, erweitert sich das ER-Diagramm um eine direkte Verbin- dung zwischen WissPersonal und Institut:

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 113 Abbildung 36: Um „Institutsvorstand“ erweiterter ER-Graph von UniLinz

Eine Abfrage nach „Stary“, „Wirtschaftsinformatik“ führt (nach wie vor) zur fol- genden List der getroffenen Zugriffspfade:

"Stary" = VAL:WissPersonal.Nachname "Wirtschaftsinformatik" ~ VAL:Institut.Name Der Join-Baum zur kürzesten Verbindung der Relationen WissPersonal und Insti- tut ist unter oben getroffener Annahme nunmehr: „WissPersonal – Institut“ und buildSQL() generiert somit folgende SQL-Abfrage: SELECT WissPersonal.*, Institut.* FROM WissPersonal, Institut WHERE WissPersonal.Nachname = 'Stary' AND Institut.Name LIKE '%Wirtschaftsinformatik%' AND WissPersonal.PersNr = Institut.VorstandPersNr Nachdem jedem Institut nur genau eine Person als Institutsvorstand zugeordnet ist, und im konkreten Fall Prof. Stary nicht Vorstand des Instituts für Wirtschafts- informatik ist, erfüllt kein Datensatz diese Abfragebedingung. Der Benutzer der Suchmaschine wird aus diesem leerem Ergebnis schließen, dass zwischen Prof. Stary und dem Institut für Wirtschaftsinformatik kein Zusammenhang gegeben ist, obwohl er tatsächlich Mitglied an diesem Institut ist. Hätte buildSQL() zur Verbindung der Relationen WissPersonal und Institut nämlich den (nächstgrößeren) Join-Baum: „WissPersonal – InstMitglied – Institut“ verwendet, entstünde die SQL-Abfrage:

114 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken SELECT WissPersonal.*, InstMitglied.*, Institut.* FROM WissPersonal, InstMitglied, Institut WHERE WissPersonal.Nachname = 'Stary' AND Institut.Name LIKE '%Wirtschaftsinformatik%' AND WissPersonal.PersNr = InstMitglied.PersNr AND InstMitglied.InstNr = Institut.InstNr mit dem „korrekten“ Ergebnis:

1 Übereinstimmung(en) in 'UniLinz' gefunden: WissPersonal. WissPersonal. WissPersonal. InstMitglied. Institut.Name Titel Vorname Nachname TelefonNr Institut für Dipl.Ing., Dr., Christian Stary 7101 Wirtschaftsinformatik o.Univ.Prof.

Hier erkennt der Benutzer der Suchmaschine nun, dass Prof. Stary Mitglied am Institut für Wirtschaftsinformatik ist. Der Algorithmus der Methode joinTree() sollte demnach derart abgeändert werden, dass nicht nur der kürzeste Join-Baum, sondern alle möglichen Join- Bäume gesucht werden (deren Länge einen festlegbaren Schwellwert nicht über- steigt).

Mit dem nächsten Beispiel soll demonstriert werden, dass grundsätzlich auch mehrere Join-Bäume als Ergebnis möglich sind. Zur Ermittlung der SQL-Abfrage für die getroffenen Zugriffspfade:

"Küng" = VAL:WissPersonal.Nachname "351001" = VAL:LVA.LVANr wird der Join-Baum zur Verbindung der Relationen WissPersonal und LVA benö- tigt. Als kürzeste Join-Bäume stehen dazu zwei gleich lange und damit gleichwer- tige Alternativen zur Auswahl: a) „WissPersonal – LVALeiter – LVA“ b) „WissPersonal – LVAZeugnis – LVA“ Die SQL-Abfrage, die auf Variante a) basiert zeigt alle LVAs, die von Prof. Küng (mit)geleitet werden. Variante b) hingegen liefert alle LVA-Zeugnisse zur LVA Nr. 351001, deren Prüfer Prof. Küng ist. Die Suchmaschine zeigt dem Benutzer in die- sem Fall die Ergebnisse für beide Varianten43:

43 Stehen mehrer, gleichwertige Alternative alsErgebnis von buildSQL() zur Auswahl, sollten diese Al- ternativen auch als Suchergebnis angezeigt werden, da offensichtlich mehrere Zusammenhänge zwischen den betroffenen Relationen bestehen.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 115 11 Übereinstimmung(en) in 'UniLinz' gefunden: LVA. LVA. LVA. LVA. LVA. WP. WP. LVANr Typ Titel Wochenstd ECTS Vorname Nach- name 351001 VO Informationssysteme 1 2 3 Josef Küng 351002 UE Informationssysteme 1 2 3 Josef Küng Projektstudium Informationssysteme 351031 PJ 6 9 Josef Küng WIN Anwendungsorientierte Wissensverar- 351047 VO 2 3 Josef Küng beitung Query Techniques for Information Sys- 351060 SE 3 4,5 Josef Küng tems

10 Übereinstimmung(en) in 'UniLinz' gefunden: LZ. LVA. WP. WP. ST. ST. ST. LZ. LVANr Titel Vorname Nachname MatrikelNr Vorname Nachname Note Informations- 351001 Josef Küng 9955468 Heinrich Holzer 3 systeme 1 Informations- 351001 Josef Küng 0055498 Norbert Namesnik 2 systeme 1 Informations- 351001 Josef Küng 0055735 Karin Kainz 1 systeme 1 Informations- Lehner- 351001 Josef Küng 0056665 Ludwig 3 systeme 1 Hartl Informations- 351001 Josef Küng 0156086 Paul Puchegger 1 systeme 1

Technische Umsetzung durch Erweiterung von joinTree() Zur Adaptierung der Methode joinTree() wird der zusätzliche Parameter maxJoinLevel eingeführt, der angibt, wie viele Joins/Kanten ein Join-Baum maxi- mal haben soll. Außerdem wird der Rückgabewert von einem einzigen Join-Baum auf eine (Ergebnis-)Liste von Join-Bäumen umgestellt. Zur Demonstration soll wieder ein vereinfachtes ER-Diagramm dienen, dass die Relationen (Knoten) und ihre Fremdschlüssel-Abhängigkeiten (Kanten) einer fiktiven relationalen Datenbank als gerichteten Graph zeigen:

Abbildung 37: Vereinfachtes ER-Diagramm

116 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Der Algorithmus von joinTree() zur Verbindung einer Menge von Knoten in ei- nem Graphen ermittelt zuerst die kürzeste Verbindung zwischen den ersten bei- den Knoten der Liste. Dann wird dieser Join-Baum sukzessive um Verbindungen zu den restlichen Knoten erweitert, bis alle angegebenen Knoten verbunden sind.

Alle Verbindungen zwischen zwei Knoten Bisher retourniert joinTree(k1, k2) die kürzeste Verbindung zwischen Knoten k1 und k2. Genauer gesagt bricht der Algorithmus die „breath-first“-Suche ab, sobald eine Verbindung von k1 nach k2 gefunden ist. Die erste gefundene Verbindung ist die bzw. eine der kürzest möglichen Verbindungen von k1 und k2. Durch eine An- passung am Abbruchkriterium werden in Hinkunft auch alle weiteren (zyklusfrei- en) Verbindungen von k1 nach k2 gesucht. Beispielsweise retourniert die sol- chermaßen erweiterte Methode joinTrees() für die Knoten „A“ und „E“ im in Abbildung 37 dargestellten Graphen folgende Liste von Join-Bäumen:

[A]–k01o[B]ko[E] Länge: 2 [A]k02o[C]k03o[B]k04o[E] Länge: 3 [A]k02o[C]k05o[D]k07o[E] Länge: 3 [A]k02o[C]k06o[F]k08o[D]k07o[E] Länge: 4 [A]k01o[B]k03o[C]k05o[D]k07o[E] Länge: 4 [A]k01o[B]k03o[C]k06o[F]k08o[D]k07o[E] Länge: 5 Die gefundenen Verbindungen zwischen den beiden angegebenen Knoten im Graph, sind nach deren Länge (= Anzahl der benötigten Kanten) aufsteigend sor- tiert. Der Algorithmus, der zu joinTrees(k1, k2, maxJoinLevel) erweiterte Metho- de, wobei der Parameter maxJoinLevel angibt, wie viele Kanten maximal zur Ver- bindung herangezogen werden dürfen, stellt sich schließlich wie folgt dar:

0 // SAHSERD.ERGraph.joinTrees() // all point-to-point connections with length <= threshold

1 joinTrees(pfromTbl, ptoTbl, pmaxJoinLevel) { 2 if(fromTbl == toTbl) return {}; 3 lFoundJPaths = {}; 4 unfinishedPaths = {}; 5 unfinishedPaths.add(fromTbl); 6 while(! unfinishedPaths.isEmpty()) { 7 newUFPaths = {}; 8 for(ufPath in unfinishedPaths) { 9 ufpTail = ufPath.to(); 10 for(adjEdge in ufpTail.adjacentEdges()) { 11 // next if-statement prevents from building cycles 12 if(! ufPath.containsVertex(adjEdge.to())) { 13 ufPath.appendEdge(adjEdge);

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 117 14 if(ufPath.to() == toTbl) 15 lFoundJPaths.add(ufPath); // connection found 16 else if(ufPath.length() < maxJoinLevel) 17 // requeue ufPath only if length < threshold 18 newUFPaths.add(ufPath); 19 } 20 } 21 } 22 unfinishedPaths = newUFPaths; 23 } 24 return lFoundJPaths; 25 }

Alle Verbindungen zwischen mehr als zwei Knoten Die Weiterführung dieser Änderungen auf die Methode joinTree(tblsToJoin[]) zu joinTrees(tblsToJoin[], maxJoinLevel) erfordert hier folgende Anpassungen:

0 // SAHSERD.ERGraph.joinTrees() // all multi-point connections with length <= threshold

1 joinTrees(ptblsToJoin[], pmaxJoinLevel) { 2 if(tblsToJoin.length < 2) return {}; 3 4 // init list of jTrees with connections for first two elements of tblsToJoin 5 jTrees = joinTree(tblsToJoin[0], tblsToJoin[1], maxJoinLevel); 6 7 for(tblIdx = 1; tblIdx < tblsToJoin.length - 1; tblIdx++) { 8 fromTbl = tblsToJoin[tblIdx]; 9 toTbl = tblsToJoin[tblIdx + 1]; 10 fromToJoinTrees = joinTree(fromTbl, toTbl, maxJoinLevel); 11 // build candList = jTrees x fromToJoinTrees 12 candList = {}; 13 for(jtA in jTrees) { 14 for(jtB in fromToJoinTrees) { 15 // build union of jtA with jtB (without duplicating edges) 16 jtA.unifyWith(jtB); 17 // skip candidate if it is no valid tree or already in candList 18 if(jtA.isTree() && ! candList.contains(jtA)) 19 candList.add(jtA); 20 } 21 } 22 jTrees = candList; 23 } 24 25 // sort list of resulting jTrees by length of jointrees ascending 26 jTrees.sortByLengthOfJTrees(ASC); 27 28 // return jointrees with length <= threshold 29 result = {}; 30 for(jT in jTrees) 31 if(jt.length() <= maxJoinLevel) 32 result.add(jt); 33 34 return result; 35 }

118 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Beim schrittweisen Bilden der Join-Bäume wird zunächst jeweils das Kreuzpro- dukt aus allen bisherigen Join-Bäumen (jTrees) mit den neuen Verbindungen (fromToJoinTrees) ermittelt, wodurch eine Liste von Kandidaten (candList) für das Zwischenergebnis entsteht (siehe Zeilen 12 bis 21). Alle Join-Bäume des Zwi- schenergebnisses, müssen nun darauf überprüft werden, ob sie einen gültigen (Join-) Baum darstellen – dies geschieht mit der Methode isTree(). In einem gül- tigen Baum ist jeder Knoten von jedem anderen Knoten aus erreichbar (Konnek- tivität) und der Baum darf zudem keine Zyklen enthalten. Außerdem müssen Dubletten aus der Kandidaten-Liste entfernt werden (siehe Zeile 18). Diese Schrit- te werden solange durchgeführt, bis alle zu verbindenden Knoten abgearbeitet sind. Das Zwischenergebnis (= verbleibende Liste der Kandidaten) aus der letzten Erweiterungsrunde, ist zugleich bereits das vorläufige Endergebnis. Zuletzt wer- den aus diesem jene Join-Bäume herausgefiltert, deren Länge kleiner-gleich maxJoinLevel ist (siehe Zeilen 25 bis 32).

Am Beispiel joinTrees(["A", "D", "E"], 4) wird die Arbeitsweise des neuen Algo- rithmus nun exemplarisch demonstriert: jT_AD = joinTrees("A", "D", 4) ergibt zunächst folgende Liste von Join-Bäumen: jT_AD[01] = "[A]-k02-[C]–k05-[D]" Länge: 2 jT_AD[02] = "[A]-k02-[C]-k06-[F]-k08-[D]" Länge: 3 jT_AD[03] = "[A]-k01-[B]-k03-[C]-k05-[D]" Länge: 3 jT_AD[04] = "[A]-k01-[B]-k04-[E]-k07-[D]" Länge: 3 jT_AD[05] = "[A]-k02-[C]-k03-[B]-k04-[E]-k07-[D]" Länge: 4 jT_AD[06] = "[A]-k01-[B]-k03-[C]-k06-[F]-k08-[D]" Länge: 4 jT_DE = joinTrees("D", "E", 4) ergibt: jT_DE[01] = "[D]-k07-[E]" Länge: 1 jT_DE[02] = "[D]-k05-[C]-k03-[B]-k04-[E]" Länge: 3 jT_DE[03] = "[D]-k08-[F]-k06-[C]-k03-[B]-k04-[E]" Länge: 4 jT_DE[04] = "[D]-k05-[C]-k02-[A]-k01-[B]-k04-[E]" Länge: 4 Das Kreuzprodukt jT_ADE = jT_AD x jT_DE ergibt folgende 24 Kandidaten, wobei hier aus Platzgründen jeweils nur die Bezeichnungen der Kanten angegeben sind: jT_ADE[01] = jT_AD[01]+jT_DE[01] = "k02, k05, k07" Länge: 3 jT_ADE[02] = jT_AD[01]+jT_DE[02] = "k02, k03, k04, k05" Länge: 4 jT_ADE[03] = jT_AD[01]+jT_DE[03] = "k02, k03, k04, k05, k06, k08" Länge: 6 jT_ADE[04] = jT_AD[01]+jT_DE[04] = "k01, k02, k04, k05" Länge: 4 jT_ADE[05] = jT_AD[02]+jT_DE[01] = "k02, k06, k07, k08" Länge: 4 jT_ADE[06] = jT_AD[02]+jT_DE[02] = "k02, k03, k04, k05, k06, k08" Länge: 6 jT_ADE[07] = jT_AD[02]+jT_DE[03] = "k02, k03, k04, k06, k08" Länge: 5 jT_ADE[08] = jT_AD[02]+jT_DE[04] = "k01, k02, k04, k05, k06, k08" Länge: 6

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 119 jT_ADE[09] = jT_AD[03]+jT_DE[01] = "k01, k03, k05, k07" Länge: 4 jT_ADE[10] = jT_AD[03]+jT_DE[02] = "k01, k03, k04, k05" Länge: 4 jT_ADE[11] = jT_AD[03]+jT_DE[03] = "k01, k03, k04, k05, k06, k08" Länge: 6 jT_ADE[12] = jT_AD[03]+jT_DE[04] = "k01, k02, k03, k04, k05" Länge: 5 jT_ADE[13] = jT_AD[04]+jT_DE[01] = "k01, k04, k07" Länge: 3 jT_ADE[14] = jT_AD[04]+jT_DE[02] = "k01, k03, k04, k05, k07" Länge: 5 jT_ADE[15] = jT_AD[04]+jT_DE[03] = "k01, k03, k04, k06, k07, k08" Länge: 6 jT_ADE[16] = jT_AD[04]+jT_DE[04] = "k01, k02, k04, k05, k07" Länge: 5 jT_ADE[17] = jT_AD[05]+jT_DE[01] = "k02, k03, k04, k07" Länge: 4 jT_ADE[18] = jT_AD[05]+jT_DE[02] = "k02, k03, k04, k05, k07" Länge: 5 jT_ADE[19] = jT_AD[05]+jT_DE[03] = "k02, k03, k04, k06, k07, k08" Länge: 6 jT_ADE[20] = jT_AD[05]+jT_DE[04] = "k01, k02, k03, k04, k05, k07" Länge: 6 jT_ADE[21] = jT_AD[06]+jT_DE[01] = "k01, k03, k06, k07, k08" Länge: 5 jT_ADE[22] = jT_AD[06]+jT_DE[02] = "k01, k03, k04, k05, k06, k08" Länge: 6 jT_ADE[23] = jT_AD[06]+jT_DE[03] = "k01, k03, k04, k06, k08" Länge: 5 jT_ADE[24] = jT_AD[06]+jT_DE[04] = "k01, k02, k03, k04, k05, k06, k08" Länge: 7 Die als einfach durchgestrichenen gekennzeichneten Kandidaten in jT_ADE[] ent- halten einen oder mehrere Zyklen, sind also keine Bäume und müssen verworfen werden. Nach der Sortierung der verbleibenden Liste der Join-Bäume gemäß ihrer Länge, werden schließlich auch noch die Einträge mit den Indizes 7, 21 und 23 ausgefiltert, da ihre Länge den angegebenen Schwellwert 4 übersteigt. Es verblei- ben als Endergebnis von joinTrees() somit folgende Join-Bäume: jT_ADE[13] = "k01, k04, k07" Länge: 3 jT_ADE[01] = "k02, k05, k07" Länge: 3 jT_ADE[04] = "k01, k02, k04, k05" Länge: 4 jT_ADE[10] = "k01, k03, k04, k05" Länge: 4 jT_ADE[09] = "k01, k03, k05, k07" Länge: 4 jT_ADE[02] = "k02, k03, k04, k05" Länge: 4 jT_ADE[17] = "k02, k03, k04, k07" Länge: 4 jT_ADE[05] = "k02, k06, k07, k08" Länge: 4

Sonderfall: Join-Baum für eine einzige Relation Für den Fall, dass die Liste der zu verbindenden Relationen lediglich einen Ein- trag einhält, liefert joinTrees() derzeit einen Join-Baum, der nur aus einem Kno- ten, der Relation selbst, besteht. Beispielsweise retourniert buildSQL() zur folgen- den Liste der getroffenen Zugriffspfade:

"Bauer" = VAL:Student.Nachname "Holzer" = VAL:Student.Nachname die SQL-Abfrage (a):

120 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken (a) SELECT Student.* FROM Student WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Holzer') Der Benutzer erhält damit alle Informationen zu den Studenten „Bauer“ und „Holzer“, die in der Relation Student gespeichert sind. In konkreten Fall sind das die Matrikelnummern und weitere Angaben zur Person (Name, Geburtsdatum, Adresse). Für den Benutzer der Suchmaschine könnte auch von Interesse sein, ob diese beiden Studenten noch weitere Gemeinsamkeiten haben, beispielsweise welche Studienrichtungen sie (gemeinsam) belegen, oder welche Lehrveranstal- tungen sie (gemeinsam) absolviert haben. Betrachtet man das Datenmodell von UniLinz so kann man anhand der Fremdschlüsselabhängigkeiten leicht erkennen, dass die Relation Student mit den Relationen Inskription und LVAZeugnis direkt verbunden ist. Grundsätzlich könn- te buildSQL() somit auch die SQL-Abfragen (b) und (c) generieren: (b) SELECT Inskription.*, Student.*, Studienrichtung.* FROM Inskription, Student, Studienrichtung WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Holzer') AND Inskription.MatrikelNr = Student.MatrikelNr AND Inskription.SKZ = Studienrichtung.SKZ (c) SELECT LVA.*, LVAZeugnis.*, Student.*, WissPersonal.* FROM LVA, LVAZeugnis, Student , WissPersonal WHERE (Student.Nachname = 'Bauer' OR Student.Nachname = 'Holzer') AND LVAZeugnis.MatrikelNr = Student.MatrikelNr AND LVAZeugnis.LVANr = LVA.LVANr AND LVAZeugnis.Pruefer = WissPersonal.PersNr Für die SQL-Abfragen (b) sind zwei, für (c) drei Joins nötig, (a) hingegen kommt ohne einen Join aus. Fortan soll der Parameter maxJoinLevel im Sonderfall, dass der Join-Baum für eine einzige Relation gesucht wird, dazu benutzt werden, das Ergebnis um solche Nachbar-Relationen zu erweitern. Dazu kommen alle Nachbarn, das sind die di- rekt erreichbaren Knoten im ER-Graph, in Frage, die selbst maximal maxJoinLevel Nachbarn haben. Wie im ER-Diagramm der Testdatenbank UniLinz ersichtlich ist (siehe Abbildung), sind die Nachbar-Relationen von Student: Inskription und LVAZeugnis. Inskription selbst hat zwei Nachbarn: Studienrichtung und Student, die Relation LVAZeugnis hat drei Nachbarn: LVA, WissPersonal und Student.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 121 Zur Berücksichtigung dieser Erweiterung im Algorithmus von joinTrees() müssen Zeile 2-3 wie folgt abgeändert werden:

0 // SAHSERD.ERGraph.joinTrees() // all multi-point connections with length <= threshold // final version

1 joinTrees(ptblsToJoin[], pmaxJoinLevel) { 2 if(tblsToJoin.length == 0) return {}; 3 if(tblsToJoin.length == 1) return joinTrees(tblsToJoin[0], maxJoinLevel); 4 // init list of jTrees with connections for first two elements of tblsToJoin 5 jTrees = joinTree(tblsToJoin[0], tblsToJoin[1], maxJoinLevel); 6 7 for(tblIdx = 1; tblIdx < tblsToJoin.length - 1; tblIdx++) {

Die in Zeile 3 aufgerufene Methode joinTrees(tbl, maxJoinLevel) übernimmt die Bildung der Join-Bäume für alle Nachbar-Relationen:

0 // SAHSERD.ERGraph.joinTrees() // joinTrees for dependent tables (with length <= threshold)

1 joinTrees(ptbl, pmaxJoinLevel) { 2 result = {}; 3 4 // add tbl itself 5 result.add(tbl.asJoinTree()); 6 7 // add joinTrees for dependent tables 8 for(depTbl in foreignKeysFromTbl(tbl)) { 9 noOfNeighbours = foreignKeysToTbl(depTbl); 10 if(noOfNeighbours <= maxJoinLevel) { 11 // build joinTree for depTbl and all its neighbours 12 tblList = {}; 13 tblList.add(depTbl); 14 tblList.addAll(foreignKeysToTbl(depTbl)); 15 result.add(joinTrees(tblList, noOfNeighbours)); 16 } 17 } 18 19 return result; 20 }

Die Erweiterungen von joinTree() zu joinTrees() erfordert entsprechende Ände- rungen in den aufrufenden Methoden sqlQueryForHDBAPs() und schließlich auch in buildSQL(). Dort muss nämlich fortan eine Liste von Join-Bäumen bzw. SQL- Abfragen statt Einzelergebnissen verarbeitet werden.

5.4.3 ad Suchmodul: Schnittstelle

Im Normalfall findet die Ad-hoc-Suche zu einem Suchbegriff genau einen Zugriffspfad. Die Sonderfälle, dass entweder a) kein passender Zugriffspfad ge-

122 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken funden wurde, oder b) mehrere verschiedene Zugriffspfade in Frage kommen, werden hier betrachtet.

Behandlung von nicht getroffenen Suchbegriffen

Findet adHocSearch() zu einem einzelnen Suchbegriff keinen Zugriffspfad, bedeu- tet dies, dass der gesuchte Begriff nicht in der Datenbank gespeichert ist, weder als Name einer Relation, eines Attributs noch als Attributwert (gemäß der Suchor- te)44. Beispielsweise gibt es zur Suchanfrage „Sahserd“, wie in Abbildung 35 er- sichtlich ist keine Übereinstimmungen in UniLinz. Die Suchmaschine soll in die- sem Fall dem Benutzer eine Meldung wie „Keine Übereinstimmung(en) in 'Uni- Linz' gefunden!“ anzeigen. Besteht eine Suchanfrage nun aus mehreren Suchbegriffen und liefert die Ad- hoc-Suche nicht zu allen Suchbegriffen getroffene Zugriffspfade, muss von der Suchmaschine entschieden werden, ob a) der Suchvorgang abgebrochen wird o- der b) die Suchanfrage unter Auslassung der nicht getroffenen Suchbegriffe fort- gesetzt wird. Die Suchabfrage „Sahserd“, „Küng“ liefert beispielsweise nur für den Suchbegriff „Küng“ einen Treffer ("Küng" = VAL:WissPersonal.Nachname). Damit bliebe das Ergebnis für Variante a) leer (siehe oben). Das Ergebnis für Variante b) hingegen ist ident mit dem der Suchabfrage „Küng“. Jedenfalls sollte hier das Er- gebnis eine Meldung enthalten, die den Benutzer darauf hinweist, dass eine Ver- kürzung der Suchabfrage vorgenommen wurde.

Behandlung von mehrdeutigen Suchbegriffen

Wie im letzten Abschnitt bereits angesprochen, können zu einem Suchbegriff auch mehrere Zugriffspfade gefunden werden. So kann "175" beispielsweise die Studienkennzahl für Wirtschaftsinformatik, die Telefon-Durchwahl eines Insti- tutsmitglieds aber auch die Hausnummer der Heimatadresse eines Studenten be- deuten. Generell gesprochen kann ein Suchbegriff45: a) mit mehreren Attributwerten verschiedener Attribute übereinstimmen. Bei- spielsweise ergibt die Adhoc-Suche für „Heinrich“ folgende Attributwert-

44 Dabei ist die vom Benutzer gewählte Suchschärfe zu beachten, da adHocSearch() mit einer schwä- cheren Einstellung (z.B. „Ist-enthalten-In“-Vergleich statt exaktem Vergleich) ohne weiteres zu ei- nem Treffer führen kann. Siehe dazu beispielsweise die Treffer zu „Linz“ in Abbildung 35. 45 Siehe die entsprechenden Einträge zu "Heinrich", "Adresse", "Student" in Abbildung 35

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 123 Treffer: =VAL:Student.Nachname, =VAL:WissPersonal.Nachname und =VAL:Wiss- Personal.Vorname. b) mit mehreren Metadatenbezeichnern übereinstimmen. Beispielsweise ergibt adHocSearch() für „Adresse“ folgende Metadaten-Treffer: =COL:Institut.Adresse und =COL:Student.Adresse. c) sowohl mit Attributwerten als auch mit Metadatenbezeichnern übereinstim- men. Beispielsweise ergibt die Adhoc-Suche nach „Student“ folgende getrof- fene Zugriffspfade: =TAB:Student und =VAL:Student.Nachname. Zur Behandlung solcher mehrdeutigen Suchbegriffe kann die Suchmaschine a) dem Benutzer die gefundenen Zugriffspfade anzeigen und die Auswahl eines Tref- fers einfordern, oder b) die Suchergebnisse zu allen gefundenen Interpretationen anzeigen. Beim Entwurf des Prototypen SAHSERD habe ich mich dazu entschie- den, Variante b) zu folgen. Das bedeutet, dass im Ergebnis zur Suchabfrage "Hein- rich" sowohl Datensätze aus der Tabelle Student, als auch aus der Tabelle WissPer- sonal angezeigt werden sollen:

1 Übereinstimmung(en) in 'UniLinz' gefunden: Student. Student. Student. Student. Student. Student. MatrikelNr Vorname Nachname GebDat Geschlecht Adresse 9955468 Heinrich Holzer 1978-03-19 M 4320 Perg, Jahnstrasse 2 2 Übereinstimmung(en) in 'UniLinz' gefunden: WissPersonal. WissPersonal. WissPersonal. WissPersonal. WissPersonal. PersNr Titel Vorname Nachname Geschlecht 1066 Dipl.Ing., Dr., o.Univ.Prof. Lutz J. Heinrich M 1154 Dipl.Ing., Dr., a.Univ.Prof. Heinrich Rolletschek M

Legt man Variante b) auf Suchanfragen um, die aus mehreren Suchbegriffen be- stehen, so müssen alle möglichen Kombinationen der getroffenen Zugriffspfade weiterverfolgt werden. Beispielsweise ergibt die Suchanfrage "175", "Heinrich", für die Suchschärfe „Ist-Enthalten-In“:46

"175" =VAL:Studienrichtung.SKZ, ~VAL:Student.Adresse "Heinrich" =VAL:ST.Nachname, =VAL:WP.Nachname, =VAL:WP.Vorname An buildSQL() werden daher folgende sechs Kombinationen zur Bildung der ent- sprechenden SQL-Abfragen weitergegeben:

1) ["175"=VAL:Studienrichtung.SKZ, "Heinrich"=VAL:Student.Nachname] 2) ["175"=VAL:Studienrichtung.SKZ, "Heinrich"=VAL:WissPersonal.Nachname]

46 Die Namen der Relationen wurden aus Platzgründen teilweise abgekürzt.

124 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 3) ["175"=VAL:Studienrichtung.SKZ, "Heinrich"=VAL:WissPersonal.Vorname] 4) ["175"~VAL:Student.Adresse, "Heinrich"=VAL:Student.Nachname] 5) ["175"~VAL:Student.Adresse, "Heinrich"=VAL:WissPersonal.Nachname] 6) ["175"~VAL:Student.Adresse, "Heinrich"=VAL:WissPersonal.Vorname] Zur Umsetzung der eben ausgeführten Behandlung von mehrdeutigen Suchbeg- riffen muss die Arbeitsweise der Suchmaschine so adaptiert werden, dass buildSQL() für jede Kombination aufgerufen wird, die sich aus den Ergebnissen von adHocSearch() bilden lässt.

5.4.4 ad Ergebnispräsentation

Das Modul zur Ergebnispräsentation erhält als Input die von buildSQL() generier- ten SQL-Abfragen und soll dem Benutzer die Suchergebnisse als Tabellen (in HTML) anzeigen. Eine zusätzliche Anforderung lautet jedoch, dass SAHSERD die Möglichkeit bietet, bei der Ausgabe des Suchergebnisses auch die Zwischener- gebnisse anzuzeigen47. Um dieser Anforderung gerecht zu werden, müssen diese fortan auch in das Suchergebnis aufgenommen werden.

Bildung mehrstufiger Suchergebnisse

Das Suchergebnis wird zunächst nach den bereits erledigten Teilschritten in so- genannte „ResultLevel“ eingeteilt, die jeweils eine Stufe von der Suchanfrage bis zu den Ergebnistabellen darstellen. Über einen Steuerungsparameter der Such- maschine kann der Benutzer nun einfach angeben, welches Zwischenergebnis – welcher ResultLevel angezeigt werden soll. Jede Suchanfrage wird in ein fünfstufiges Suchergebnis überführt. Beispiels- weise ergibt die Suchanfrage „Küng“, „Fischer“ (mit exaktem Vergleich und maxi- mal drei Joins)48:

Resultlevel 0: Getroffene Zugriffspfade pro Suchbegriff Resultlevel 0 entspricht dem Ergebnis der Ad-hoc-Suche pro Suchbegriff:

"Küng" = VAL:WissPersonal.Nachname "Fischer" = VAL:Student.Nachname, = VAL:WissPersonal.Nachname

47 Vgl Anforderung a12 in Abschnitt 4.2 48 Die in diesem Bespiel dargestellten Zwischergebnisse der einzelnen Resultlevel werden für die tat- sächliche Anzeige noch ansprechender aufbereitet/formatiert.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 125 Der Benutzer kann damit ersehen, dass es zu "Fischer" sowohl Treffer in der Rela- tion Student als auch in der Relation WissPersonal gibt.

Resultlevel 1: Kombinationen aus den getroffenen Zugriffspfaden Im nächsten Resultlevel werden alle Kombinationsmöglichkeiten aus den Ergeb- nissen von Resultlevel 0 gebildet. Weiters wird zu jedem Element der Liste ange- geben, welche Relationen die Ausgangspunkte für die ResultViews (siehe unten) bilden und wie viele Joins der Join-Baum zur Verbindung dieser Relationen benö- tigt: ["Küng"=VAL:WissPersonal.Nachname, "Fischer"=VAL:Student.Nachname] ResultView01: Student+WissPersonal (2 joins)

["Küng"=VAL:WissPersonal.Nachname, "Fischer"=VAL:WissPersonal.Nachname] ResultView02: WissPersonal (0 joins) ResultView03: Institut+InstMitglied+WissPersonal (2 joins) ResultView04: LVALeiter+LVA+WissPersonal (2 joins) ResultView05: LVAZeugnis+LVA+Student+WissPersonal (3 joins) Die ResultViews für eine Kombination von Zugriffspfaden sind nach der Länge der Join-Bäume aufsteigend angeordnet.

Resultlevel 2: ResultViews (vereinfachte SQL-Abfragen) Resultlevel 2 zeigt sogenannte „ResultViews“, also diejenigen Ausschnitte (Views) der Datenbank die das Suchergebnis enthalten. In dieser Ergebnisstufe werden die ResultViews als vereinfachte SQL-Abfragen angegeben. Vereinfacht bedeutet hier einerseits, dass die Select-Klausel immer mit „*“ gebildet wird. Andererseits werden hier noch keine konkreten Joins zur Verbindung der betroffenen Tabellen angegeben. Nach der WHERE-Klausel der SQL-Abfrage wird durch die Klausel "JOINED BY" angegeben, welche Tabellen verjoint werden. Beispielsweise erkennt man im Suchergebnis (Resultlevel 2) für die Anfrage "Küng”, “Fischer", dass in ResultView01 zur Verbindung der getroffenen Tabellen WissPersonal und Student die Tabellen LVAZeugnis, Student und WissPersonal ge- joint werden: ResultView02: WissPersonal (0 joins): SELECT * FROM WissPersonal as WP_ WHERE ( (WP_.Nachname = 'Küng' OR WP_.Nachname = 'Fischer') )

ResultView01: Student+WissPersonal (2 joins): SELECT * FROM LVAZeugnis as LV_, Student as S_, WissPersonal as WP_ WHERE ( (S_.Nachname = 'Fischer') AND (WP_.Nachname = 'Küng') ) (JOINED BY: LVAZeugnis, Student, WissPersonal)

126 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken ResultView03: Institut+InstMitglied+WissPersonal (2 joins): SELECT * FROM InstMitglied as IM_, Institut as I_, WissPersonal as WP_ WHERE ( (WP_.Nachname = 'Küng' OR WP_.Nachname = 'Fischer') ) (JOINED BY: InstMitglied, Institut, WissPersonal) ResultView04: LVALeiter+LVA+WissPersonal (2 joins): SELECT * FROM LVALeiter as LV_, LVA as LV0_, WissPersonal as WP_ WHERE ( (WP_.Nachname = 'Küng' OR WP_.Nachname = 'Fischer') ) (JOINED BY: LVALeiter, LVA, WissPersonal)

ResultView05: LVAZeugnis+LVA+Student+WissPersonal (3 joins): SELECT * FROM LVAZeugnis as LV_, LVA as LV0_, Student as S_, WissPersonal as WP_ WHERE ( (WP_.Nachname = 'Küng' OR WP_.Nachname = 'Fischer') ) (JOINED BY: LVAZeugnis, LVA, Student, WissPersonal) Die Ergebnisliste in ResultLevel 2 ist nach der Anzahl der benötigten Joins aufstei- gend gereiht.

Resultlevel 3: Konsoliderte ResultViews (vollständige SQL-Abfragen) Gegenüber Resultlevel 2 unterscheidet sich Resultlevel 3 dadurch, dass die Liste der ResultViews konsolidiert wird so weit dies möglich ist. Die Konsolidierung der ResultViews geschieht durch Zusammenfassung derjenigen ResultViews, die den- selben Join-Baum (= JOINED BY-Klausel in Level 2) verwenden. Zudem sind die SQL-Abfragen hier vollständig ausformuliert. Das bedeutet, einerseits dass die WHERE-Klausel um die Join-Bäume erweitert werden. Ande- rerseits wird die Select-Klausel von "*" in konkrete Spalten überführt, wobei be- rücksichtigt wird, ob eine bestimmte Tabellenspalte zur Suche freigegeben ist49. Beispielsweise werden in ResultView02 die Spalten PersNr und Geschlecht der Ta- belle WissPersonal nicht selektiert. Das Suchergebnis für die Anfrage "Küng”, “Fischer" für Resultlevel 3 ist hier aus Platzgründen verkürzt dargestellt: ResultView02: WissPersonal (0 joins): SELECT WP_.Titel as 'WP_Titel', WP_.Nachname as 'WP_Nachname', WP_.Vorname as 'WP_Vorname' FROM WissPersonal as WP_ WHERE ( (WP_.Nachname = 'Küng' OR WP_.Nachname = 'Fischer') ) ResultView01: Student+WissPersonal (2 joins): SELECT LV_.Pruefer as 'LV_Pruefer', LV_.Note as 'LV_Note', S_.MatrikelNr as 'S_MatrikelNr', S_.Nachname as 'S_Nachname', S_.Vorname as 'S_Vorname', S_.Adresse as 'S_Adresse', WP_.Titel as 'WP_Titel', WP_.Nachname as 'WP_Nachname', WP_.Vorname as 'WP_Vorname' FROM LVAZeugnis as LV_, Student as S_, WissPersonal as WP_ WHERE ( (S_.Nachname = 'Fischer') AND (WP_.Nachname = 'Küng') ) AND ( LV_.Pruefer = WP_.PersNr and S_.MatrikelNr = LV_.MatrikelNr )

49 Siehe Abschnitt 5.4.5

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 127 ResultView03: Institut+InstMitglied+WissPersonal (2 joins): SELECT IM_.TelefonNr as 'IM_TelefonNr', I_.Name as 'I_Name', I_.Adresse as 'I_Adresse', WP_.Titel as 'WP_Titel', WP_.Nachname as 'WP_Nachname', WP_.Vorname as 'WP_Vorname' FROM InstMitglied as IM_, Institut as I_, WissPersonal as WP_ WHERE ( (WP_.Nachname = 'Küng' OR WP_.Nachname = 'Fischer') ) AND ( IM_.InstNr = I_.InstNr and IM_.PersNr = WP_.PersNr ) ResultView04: LVALeiter+LVA+WissPersonal (2 joins): : ResultView05: LVAZeugnis+LVA+Student+WissPersonal (3 joins): : Die Liste der ResultViews ist wie im vorhergehenden Resultlevel nach der Anzahl der benötigten Joins aufsteigend sortiert.

Resultlevel 4: Ergebnistabellen Im letzten Resultlevel werden die Ergebnisse der SQL-Abfragen aus Resultlevel 3 in Tabellenform angezeigt. Das Endergebnis zur Suchanfrage "Küng”, “Fischer" (für maximal 3 Joins) lautet: ResultView02: WissPersonal: WP_Titel WP_Nachname WP_Vorname Mag., Prof. Fischer Roland Dipl.Ing., Dr., a.Univ.Prof. Küng Josef

ResultView01: Student+WissPersonal: LV_ LV_ S_ S_ S_ S_ WP_ WP_ WP_ Prue- Note Matrikel- Nach- Vor- Adresse Titel Nach- Vor- fer Nr name name name name 1100 1 9856588 Fischer Fritz 4061 Pasching, Dipl.Ing., Küng Josef Schulstrasse 8 Dr., [...] 1100 2 9856588 Fischer Fritz 4061 Pasching, Dipl.Ing., Küng Josef Schulstrasse 8 Dr., [...]

ResultView03: Institut+InstMitglied+WissPersonal: IM_ I_ I_ WP_ WP_ WP_ TelefonNr Name Adresse Titel Nachname Vorname 9591 Inst. für Fachspra- Management- Mag., Prof. Fischer Roland chen Zentrum, Stiege B, 1. Stock 8890 Inst. für Anwen- TNF-Turm, 7. Dipl.Ing., Dr., Küng Josef dungsorientierte Stock a.Univ.Prof. Wissensverarbeitung

ResultView04: LVALeiter+LVA+WissPersonal:

ResultView05: LVAZeugnis+LVA+Student+WissPersonal: Zu Resultlevel 4, dem Endergebnis einer Suchanfrage ist hier nochmals zu bemer- ken, dass es durchaus möglich ist, dass die SQL-Abfrage einer ResultView keine Datensätze retourniert.

128 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Behandlung von Metadaten-Ergebnissen

Besteht das Ergebnis der Ad-hoc-Suche aus Metadaten-Treffern, können wie bis- her innerhalb von buildSQL() passende Join-Bäume für die getroffenen Metada- ten-Bezeichner gebildet werden. Beispielsweise ermittelt buildSQL(["Studenten" ~ TAB:Student], 2) die Join-Bäume a) "Student" (0 Joins) und b) "Student – Inskrip- tion – Studienrichtung" (2 Joins)50 und retourniert somit die folgenden SQL- Abfragen:

(1) SELECT Student.* FROM Student; (2) SELECT Student.*, Inskription.*, Studienrichtung.* FROM Student, Studienrichtung, Inskription WHERE Student.MatrikelNr = Inskription.MatrikelNr AND Inskription.SKZ = Studienrichtung.SKZ; Es gilt die Annahme, dass der Benutzer mit der Abfrage „Studenten“ wohl eher ei- nen Einblick in die Testdatenbank „UniLinz“ gewinnen will, im Sinne von „Was ist zu/über Studenten in UniLinz gespeichert?“. Die oben dargestellten SQL- Abfragen retournieren aber alle Datensätze, d.h. die Stammdaten zu allen Studen- ten (1) und die Daten zu allen Inskriptionen (2). Abhilfe schafft hier die Verwendung der Klausel "LIMIT n", mit der die Anzahl der retournierten Datensätze seitens des DBMS auf n Zeilen beschränkt werden kann. In Hinkunft werden SQL-Abfragen die buildSQL() für Metadaten-Ergebnisse erstellt deshalb um „LIMIT 10“ ergänzt. Der Benutzer wird durch die Meldung „Metadaten-Ergebnis: Anzeige von 10 Beispiel-Datensätzen“ darauf hingewiesen und kann aus sich aus diesen Beispiel-Datensätzen rasch einen Überblick über den Aufbau und Inhalt einer Relation bzw. eines Attributes verschaffen. Zudem bleibt das Suchergebnis als Ganzes überschaubar groß.

5.4.5 Interne Datenstrukturen

Die Suchmaschine, im speziellen deren Suchmodul benötigt zur Überführung der Suchanfragen in SQL-Abfragen einerseits Informationen über die zu durchsu- chende Datenbank: ein internes Data-Dictionary und andererseits ein Verzeichnis zum Nachschlagen von Synonymen für Metadaten-Bezeichner: das Alias- Verzeichnis.

50 Siehe Abschnitt „Sonderfall: Join-Baum für eine einzige Relation“

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 129 Internes Datadictionary

Die meisten aktuell erhältlichen DBMS verfügen über ein sogenanntes Data- Dictionary, das Meta-Informationen über die verwaltete(n) Datenbank(en) ent- hält51. In dieser internen Datenstruktur des DBMS sind unter anderem charakte- ristische Informationen über Relationen, Attribute, Wertebereiche, Schlüsselattri- bute und deren Abhängigkeiten, Indizes uvm. gespeichert. Es ist sinnvoll, bestimmte, oft benötigte Informationen aus diesem Data- Dictionary in einer eigenen, Suchmaschinen-internen Datenstruktur zu verwal- ten um schnellen Zugriff (Cache) auf die Datenbank-Metadaten zu haben. Fol- gende Eigenschaften der Attribute müssen im Suchmaschinen-internen Data- Dictionary verwalten werden: a) Zugriffspfad des Attributs Setzt sich aus '.' zusammen. b) Suche generell erlaubt "Ja/Nein-Feld", das anzeigt ob das Attribut generell von der Suche ausge- schlossen wurde (='Nein'). c) Attributtyp und maximale Attributbreite bzw. -länge (in Zeichen) d) Numerische Suche erlaubt "Ja/Nein-Feld", das nur Attribute vom Typ Zeichenketten Bedeutung hat. Zeigt an, ob dieses Attribut gegebenenfalls nach numerischen Suchbegriffen durchsucht werden darf (='Ja'). e) Indiziert "Ja/Nein-Feld", das anzeigt ob das Attribut indiziert ist (=’Ja’).

Das interne Data-Dictionary für die Datenbank "UniLinz" kann somit wie folgt als Tabelle dargestellt werden52:

Suche gen. Numerische Zugriffspfad Typ Länge Indiziert erlaubt Suche erl. institut.InstNr Nein INT 5 Ja institut.Name Ja VARCHAR 80 Nein institut.Adresse Ja VARCHAR 80 Ja lva.LVANr Ja INT 6 Ja

51 Bei entsprechenden Zugriffsrechten kann es mittels Methoden aus dem Package „java.sql“ auch Ausgelesen werden. Die Existenz dieser Schnittstelle zum Data-Dictionary der Datenbank ist, wie in Abschnitt 3.2 erläutert, eine wesentliche Voraussetzung für eine Suchmaschine für relationale Da- tenbanken. 52 Das vollständige interne Data-Dictionary für "UniLinz" ist in Anhang B angegeben.

130 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken lva.Titel Ja VARCHAR 120 Ja lva.StdAnzahl Ja FLOAT 5,2 lva.ECTSCredits Ja FLOAT 5,2 Nein lva.LVATyp Nein CHAR 2 Nein Nein

student.MatrikelNr Ja INT 9 Ja student.Nachname Ja VARCHAR 40 Nein Ja student.Vorname Ja VARCHAR 25 Nein Ja student.GebDat Nein DATE 10 Nein student.Geschlecht Nein CHAR 2 Nein Nein student.Adresse Ja VARCHAR 40 Ja Nein

Abbildung 38: Ausschnitt aus dem Suchmaschinen-internen Data-Dictionary

Aus Zeile 1 in oben stehender Abbildung geht beispielsweise hervor, dass die Su- che im Attribut "InstNr" generell unterbunden wurde. Mit dieser Einstellung wur- de (beispielsweise durch den Datenbank-Administrator) gezielt verhindert, dass SAHSERD Suchbegriffe mit Attributwerten vergleicht, die für den Benutzer der Suchmaschinen keinen Informationsgehalt haben, weil sie beispielsweise künstli- che Schlüssel enthalten53. Die Attribute "Geschlecht", "GebDat" und "LVATyp" wurden ebenso von der Suche ausgeschlossen, da deren SQL-Datentypen: "DATE" bzw. "ENUM" nicht unterstützt werden, siehe Kapitel Spezifikation54. Weiters ist aus dem dargestellten Ausschnitt des Data-Dictionarys für UniLinz er- sichtlich, dass Attribute, die Bestandteile des Namens einer Person beinhalten, von der Suche nach numerischen Suchbegriffen ausgeschlossen wurde (siehe Zei- len für student.Vor-/Nachname).

Alias-Verzeichnis

Das Verzeichnis zur Verwaltung der Synonyme für Metadaten, das „Alias- Verzeichnis“, ist ein einfaches assoziatives Array. Auf der linken Seite enthält es die Synonyme/Aliase als Schlüssel, auf der rechten Seite stehen die tatsächlichen

53 Dies wurde zum Zwecke der Demonstration für meine Testdatenbank „UniLinz“ angenommen, die nur einen Teilbereich der Universitätsverwaltung abbildet. (Siehe Seite 59 f.) 54 Enumerations-Typen sind im ANSI/ISO SQL92-Standard nicht enthalten. Die JDBC-Methode re- tourniert den MySQL-Datentyp „ENUM“, der für die Attribute „Geschlecht“ und „LVATyp“ verwen- det wurde, als „CHAR(2)“. Datentypen, die von SAHSERD nicht unterstützt werden, können im Zu- ge der Initialisierung des internen Data-Dictionary automatisch von der Suche ausgeschlossen wer- den. Vgl. Anforderung a8 in Abschnitt4.2.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 131 Metadatenbezeichner (DB-Begriff) und ihre jeweiligen Zugriffspfade. Als Tabelle stellt sich das Alias-Verzeichnis für die Testdatenbank UniLinz wie folgt dar55:

Alias DB-Begriff Zugriffspfad

Beurteilung Note LVAZeugnis.Note Durchwahl TelefonNr InstMitglied.TelefonNr Geburtsdatum GebDat Student.GebDat Institute Institut Institut Matrikelnummer MatrikelNr Student.MatrikelNr

Scheine LVAZeugnis LVAZeugnis Studenten Student Student Studentin Student Student Studienrichtungen Studienrichtung Studienrichtung Studium Studienrichtung Studienrichtung Telefon TelefonNr InstMitglied.TelefonNr Zeugnis LVAZeugnis LVAZeugnis

Abbildung 39: Ausschnitt aus dem Suchmaschinen-internen Alias-Verzeichnis

Einerseits soll das Verzeichnis zu einem DB-Begriff mehrere Synonyme erlauben, siehe beispielsweise die fünf Einträge, für den Zugriffspfad InstMitglied.Tele- fonNr. Andererseits müssen aber auch mehrdeutige Aliase wie beispielsweise „Na- me“ damit verwalten werden können56. Die Beziehung zwischen Aliasen und DB- Begriffen ist demnach vom Verhältnis n:m. Zum Erstellen eines Alias-Verzeichnisses, ist einerseits Fachwissen über den Verwendungszweck der Datenbank gefragt, andererseits müssen die Vorkenntnis- se und der Sprachgebrauch (z.B.: gerne gebrauchte Abkürzungen) der potentiel- len Benutzer der Suchmaschine berücksichtigt werden. Welche und wie viele Syn- onyme konkret angelegt werden sollen, kann daher nicht allgemein beantwortet werden. Generell empfehle ich hier, zumindest den Plural aller Metadatenbe- zeichner ins Verzeichnis aufzunehmen – bzw. den Singular, falls die Bezeichnun- gen der Relationen/Attribute im Plural sind.

55 Das vollständige Alias-Verzeichnis für UniLinz ist in Anhang C angegeben. 56 Die Behandlung von mehrdeutigen Suchabfragen ist in Abschnitt 5.4.3 dargestellt.

132 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken KAPITEL 6

6 Implementierung

In diesem Kapitel wird die tatsächlich realisierte Systemarchitektur des Prototy- pen SAHSERD und dessen Hauptkomponenten im Überblick dargestellt.

6.1 Systemarchitektur

Erweitert man die in 5.3 gewählte Lösungsalternative um die im vorhergehenden Abschnitt besprochenen Problembereiche und Erweiterungen, ergibt sich folgen- de schematische Systemarchitektur:

Abbildung 40: Erweiterte schematische Architektur des Prototyps

Die tatsächlichen implementierten Komponenten (Java-Klassen) sind als Klas- sendiagramm in der folgenden Abbildung dargestellt:

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 133 Abbildung 41: Vereinfachtes Klassendiagramm für SAHSERD

6.2 Hauptkomponenten

6.2.1 Benutzerschnittstelle

Web-basierte Benutzerschnittstelle

Die die web-basierte Benutzerschnittstelle von SAHSERD setzt sich aus einem HTML-Formular zur Eingabe der Suchbegriffe und Suchoptionen (1) und einen Ergebnisbereich (2) zusammen:

134 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 42: Web-basierte Benutzerschnittstelle von SAHSERD

Das HTML-Formular-Submit-Ereignis, das sendet die Suchanfrage, d.h. die For- mularfelder, als URL-Encoded-Parameter an das SahserdServlet. Das Ergebnis der Suchanfrage wird im Ergebnisbereich dargestellt. Beispielsweise wird zu den in Abbildung 42 dargestellten Suchbegriffen und -optionen folgender URL aufgeru- fen:

/sahserd/search?query=Fischer Wagner&c=~&v=e&j=3&r=a Neben dem Textfeld zur Eingabe der Suchbegriffe stehen folgende Optionen zur Steuerung des Suchvorgangs zur Verfügung1:

¾ „Comparemode“: exact | matches

¾ „Resultlevel“: all | 0 … 4

¾ „View Limitation“: either or | both | generated only | predefined only

¾ „Joinlevel“: minimal needed | 0 (no joins) | 1 … 5

1 vlg. Anforderungen a2 und a11 in Abschnitt 4.1

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 135 SahserdServlet

Die Klasse SahserdServlet bildet die zusammen mit den HTML-Seiten die Präsen- tationsschicht der Suchmaschine. Suchanfragen (Requests) des Benutzers werden hier unter Zuhilfenahme der eigentlichen Suchmaschine in Ergebnisse (Respon- se) transformiert: // SahserdServlet.java // simplified java-code

1 public class SahserdServlet extends HttpServlet { 2 private SearchEngine se; 3 4 public void init(ServletConfig config) throws ServletException { 5 super.init(config); 6 // 1: Create instance of a SearchEngine 7 se = new SearchEngine(); 8 // 2: Get configuration-parameters for DB-connection 9 dbConfigParams = getDbConfigParams(config); 10 // 3: Open SEs connection to DB 11 se.connectToDB(dbConfigParams); 12 } 13 14 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 15 // 1: Check for empty query (and display info for user) 16 // ... 17 // 2: Parse request and set options of SearchEngine 18 se.setCompareMode(request.getParam(PARAM_COMPAREMODE)); 19 // ... 20 // 3: Get SearchResult from SearchEngine 21 SearchResult sResult = se.search(request.getParam(PARAM_QUERY)); 22 // 4: Render SearchResult as HTML for requested ResultLevel 23 response = sResult.print(request.getParam(PARAM_RESULTLEVEL)); 24 } 25 } // SahserdServlet

Kommandozeilen Benutzerschnittstelle

Vor allem zu Testzwecken habe ich die Möglichkeit geschaffen, SAHSERD ohne Web-Browser, d.h. von der Kommandozeile aus zu starten. Beispielsweise kann dieselbe Suchanfrage wie in Abbildung 42 angeführt, mittels Kommandozeile wie folgt ausgeführt werden:

> sahserd -j 3 -m ~ -ra -ve Fischer Wagner Vollständig aufgelistet stellt sich die Syntax der Sahserd-Kommandozeilen- parameter wie folgt dar:

usage: sahserd -c -d [-j ] [-m ] [-p ] [-r0 | -r1 | -r2 | -r3 | -r4 | -ra] -u [-va | -vb | -vg | -vp] -c,--dbclassforname full qualified classname of jdbc-driver. e.g.:

136 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken com.mysql.jdbc.Driver -d,--dburl url for db-connection, e.g.: jdbc:mysql://localhost/UniLinz -j,--joinlimit maximal number of joins to use { 'm(inmal)' | 0-20 } (default: m) -m,--comparemode comparemode { 'equals' (default) | 'matches' } -p,--dbpassword password for db-connection (optional) -r0 resultlevel 0: 'DB-Objects for each phrase' -r1 resultlevel 1: 'DB-Objects for all phrases' (default) -r2 resultlevel 2: 'ResultViews' -r3 resultlevel 3: 'SQL-Statements' -r4 resultlevel 4: 'DB-Data' -ra resultlevel all: Show resultlevels 0-4 -u,--dbuser username for db-connection, e.g.: sahserd -vb,--rv-both both: predefined and generated ResultViews -ve,--rv-eitheror either predefined or generated (default) -vg,--rv-generated generated: generated ResultViews only -vp,--rv-predefined predefined: only ResultViews only

Abbildung 43: Kommandozeilen-basierte Benutzerschnittstelle von SAHSERD

Die Klasse Sahserd erledigt hier analog zum SahserdServlet die „Übersetzung“ der Suchoptionen mittels der Apache-Commons-Bibliothek „CLI“ [Apac10a]: // Sahserd.java // simplified java-code

1 public class Sahserd { 2 static final PrintWriter resOut = new PrintWriter(System.out, true); 3 4 public static void main(String[] args) throws Exception { 5 // .1: Create SearchEngine-instance (with default options) 6 AdHocDBSearchEngine se = new AdHocDBSearchEngine(); 7 // .2: Parse options from cmd-line-args (using apache.commons.cli) 8 // and set corresponding se-options, options for db-connection 9 // : 10 // .3: get sPhrases[] from cmd-line-args 11 String[] sPhrases = cliCommandLine.getArgs(); 12 // .4: Connect SearchEngine-instance to DB 13 boolean connEstablished = se.connectToDB(dbConnectionInfo); 14 // .5: Search for passed phrase(s) (using maxJoinLvl) 15 SearchResult sResult = se.search(sPhrases); 16 // .6: Print Results (using resultLvl, to resOut) 17 sResult.setPrintWriter(resOut); 18 sResult.setOutputMode(SearchResultOutputMode.PLAINTEXT); 19 resOut.print("Results for: "); 20 sResult.printSearchedPhrases(); 21 resOut.print("\n using options: "); 22 sResult.printSearchEngineOptions(); 23 resOut.print("\n\n"); 24 if((resultLvl & SearchResult.RESULTLEVEL_HDBAP_ONEPHRASE) ==

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 137 SearchResult.RESULTLEVEL_HDBAP_ONEPHRASE) { 25 sResult.print(SearchResult.RESULTLEVEL_HDBAP_ONEPHRASE); 26 resOut.println(); 27 } 28 // : (check for result levels RESULTLEVEL_HDBAP_ALLPHRASES, RESULTLEVEL_RVIEW, RESULTLEVEL_SQLSTMT and print them) 29 if((resultLvl & SearchResult.RESULTLEVEL_DBDATA) == SearchResult.RESULTLEVEL_DBDATA) { 30 sResult.print(SearchResult.RESULTLEVEL_DBDATA); resOut.println(); 31 } 32 } 33 } // Sahserd

6.2.2 AdHocDBSearchEngine

AdHocDBSearchEngine stellt einerseits die eigentliche Suchfunktion zur Verfü- gung. Als zentrale Komponente von SAHSERD verwaltet und steuert sie anderer- seits auch die anderen Komponenten der Suchmaschine wie das DataDictionary, den ViewBuilder und die Verbindung zur Datenbank. Gemäß dem MVC- Paradigma stellt die Komponente SearchEngine das Model dar. Zur Suche stellt SearchEngine die Methode search() bzw. searchValues() und searchMetadata() zur Verfügung, die wie die im Entwurf skizzierte Methode adHocSearch() arbeiten (siehe Abschnitt 5.4.1). Zum Setzen und Abfragen der Suchoptionen gibt es die Methoden: get|setMaxNoOfSearchedPhrases(), get|setCompareMode(), get|setMaxJoinLevelForGeneratedRVs() und get|setResult- ViewsLimitation().

6.2.3 DataDictionary

Die Komponenten Suchmodul und QueryEngine beziehen die Metainformatio- nen der zu durchsuchenden Datenbank von der Komponente DataDictionary. Das DataDictionary hält eine Reihe von internen Datenstrukturen in denen diese Metainformationen verwaltet werden. Zur Initialisierung des DataDictionary steht die Methode init() zur Verfügung, mit welcher die Datenstrukturen mit den Einträgen aus den Hilfstabellen sahserd_datadic und sahserd_aliases befüllt wer- den. Diese Hilfstabellen müssen vorab in der zu durchsuchenden Datenbank (vom DB-Administrator) angelegt und entsprechend befüllt werden. Aus den Da- tensätzen in sahserd_datadic wird beispielsweise das eigentliche DataDictionary im Sinne von Abschnitt 5.4.5 erstellt und aus den angegebenen Foreign-Key- Abhängigkeiten ein interner ER-Graph (siehe unten) konstruiert.

138 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Für das Suchmodul stellt das DataDictionary nach der Initialisierung u.a. fol- gende Methoden zur Verfügung: containsTable(), containsColumn(), columnsFor- Table(), aliases(), hitDBAPsForTable(). Für die Komponente QueryEngine bietet das DataDictionary u.a. die Metho- den: fKeysToTable(), fKeysFromTable(), joinTrees().

6.2.4 ViewBuilder

Die Komponente ViewBuilder stellt im Wesentlichen die Methode resultViews() zur Verfügung, die ihrerseits wiederum auf predefinedResultViews() und/oder generatedResultViews() zurückgreift - je nach Konfiguration der Suchoptionen. Die bereits in der Datenbank vorliegenden und zur Ausgabe der Suchergebnisse geeigneten Views (=predefined ResultViews) werden intern in einer Liste gespei- chert. Mittels der Methode init() wird diese mit den Einträgen der Hilfstabelle sahserd_predefinedresultviews befüllt. Die Methode generatedResultViews() liefert in Zusammenarbeit mit dem Da- ta-Dictionary und dessen Methode joinTrees() für die übergebene Liste der HitD- BAccessPaths passende ResultViews.

6.3 Hilfsklassen

6.3.1 DBAccessPath

DBAccessPath ist eine einfache Java-Klasse, die einen strukturierten „Zugriffs- pfad“ auf ein DB-Objekt beinhaltet, ähnlich einem URL: tableName [’.’columnName] Die Methode compareTo() sortiert DBAccessPath zunächst nach dem Objekt- typ (Table > Column) und anschließend lexikalisch nach Tablename und Co- lumnname.

6.3.2 HitDBAccessPath

HitDBAccessPath erweitert die Klasse DBAccessPath um die Felder: cmpMode (EXACT oder MATCHES) und searchedPhrase. Die natürliche Sortierung von HitDBAccessPath-Objekten mit compareTo() erfolgt zuerst nach dem DBObjectTy-

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 139 pe (Table > Column > Value), dann nach dem ComparisonType (EXACT > MATCHES), dann der Super-Klasse DBAccessPath und schließlich lexikalisch nach searchedPhrase.

6.3.3 SearchResult

Ein Objekt der Klasse SearchResult wird bei jedem Suchvorgang aus einer Instanz von SearchResultDataLvl0 erstellt. SearchResultDataLvl0 ist ein Bean, in dem searchedPhrase, die Liste (als HitDBAccessPath) der Metadaten-Treffer (searchRe- sultMetadata) und der Value-Treffer (searchResultValues) zusammengefasst sind. Die Klasse SearchResult dient letztlich zur formatierten Ausgabe des Suchergeb- nisses und aller Zwischenergebnisse auf dem Wege zu dessen Erstellung. Die For- matierung kann mit setSearchResultOutputMode(PLAINTEXT | HTML) festgelegt wer- den. Die Ausgabe erfolgt mit der Methode print(ResultLevel). Das Suchergebnis wird dabei stufenweise (on demand) aus dem SearchResultDataLvl0 bis zum ge- wünschten ResultLevel erstellt. Für die höchsten ResultLevel werden dabei Re- sultView-Instanzen angelegt und die Ergebnisse der erstellten SQL-Abfragen aus- gegeben. (Konzept der ResultLevel siehe Abschnitt 5.4.4)

6.3.4 DBResultView

DBResultView stellt die abstrahierte Sicht eines Join-Baums, oder anders ausge- drückt einer SQL-View dar. Die Tabellen und die Joins zur Verknüpfung derselben werden gespeichert. Mittels gekapselter Rückfrage beim DataDictionary kann ei- ne DBResultView einerseits mit containedHitDBAPs() alle Treffermöglichkeiten (als Liste von HitDBAccessPaths) zurückgeben und andererseits mit containsAll- HDBAPs(List) feststellen ob eine angegebene Menge von HitD- BAccessPaths in einer konkreten DBResultView inkludiert sind. Letztere Methode wird verwendet um zu überprüfen, ob eine DBResultView für die Anzeige eines Suchergebnisses in Frage kommt. Zum Erstellen eines SQL SELECT-Statements oder bestimmten Teilen davon stehen die Methoden: selectStmt(List), selectClause(), fromClause(), joinClause() und whereClause(List) zur Verfü- gung. Bei der Bildung der WHERE-Klausel für eine Menge von Treffern, werden diese grundsätzlich mit logischem Und verknüpft. Mehrfachen Treffern auf Attri-

140 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken butwert-Ebene - sogenannte Value-Hits – für dasselbe Attribut werden hingegen mit logischem Oder verknüpft.

6.3.5 ERGraph

ERGraph ist die Hauptklasse im Package sahserd.ergraph und stellt Datenstruktu- ren und Methoden zur Verfügung, die zur Verarbeitung von Entitiy-Relationship- Graphen dienen, vor allem im Hinblick auf die Bildung von Joins und Join- Bäumen. Tabellen stellen die Knoten im ERGraphen dar und die Kanten Fremd- schlüssel-Beziehungen. Die Verknüpfung zweier oder mehrerer Tabellen mittels Joins kann so auf die Berechnung von (minimal) spannenden Bäumen aus der Graphen-Theorie übertragen werden. Zur Bildung dieser Join-Bäume kommen die Methoden joinTrees(listOfTblNames) bzw. joinTrees(listOfTblNames, maxNoOfEdges) zum Einsatz (siehe Abschnitt 5.4.2). Die Methode isTree(anERGraph) überprüft, ob der übergebene ERGraph ein Baum ist, d.h. alle Knoten müssen verbunden sein und der Graph darf keinen Zyklus enthalten. Diese Methode wird bei der Bildung von Join-Bäumen einge- setzt um „falsche“ Join-Bäume, vor allem solche mit Zyklen, auszuscheiden. Das Package sahserd.ergraph selbst enthält noch die zuarbeitenden Klassen ERGraphVertex, ERGraphEdge, ERGraphJoinPath und ERGraphJoinTree die hier aber nicht näher besprochen werden.

6.3.6 ListUtils

ListUtils ist eine Helper-Klasse die folgende (statische) Methoden zur Verfügung stellt: hasEqualContent(listA, listB) und combine(listA, listB). Die Methode combine() erstellt das Kreuzprodukt von zwei oder mehreren Lis- ten und wird für die Kombination der Suchergebnisse pro Suchphrase eingesetzt. Folgende Beispiele sollen die Funktionsweise erläutern: combine((a1), (b1, b2)) = ((a1, b1), (a1, b2)) combine((a1, a2), (b1, b2)) = ((a1, b1), (a1, b2), (a2, b1), (a2, b2)) combine(((a1, x1), (a2, x1)), (b1, b2)) = ((a1, x1, b1), (a1, x1, b2), (a2, x1, b1), (a2, x1, b2)) Erhält die Methode combine() als Eingabeparameter jedoch nur eine einzige Liste, oder ist eine der zu kombinierenden Liste leer, dann erhält man folgende Ergeb- nisse:

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 141 combine((g1, g2, g3)) = ((g1), (g2), (g3)) combine((a1, a2), ()) = ((a1), (a2)) combine((), (b1, b2)) = ((b1), (b2)) Dieses Verhalten wird benötigt, wenn zu einer Suchphrase keine Treffer gefunden werden. Dann sollen zumindest für die verbleibenden restlichen Treffer die Er- gebnisse weiterverarbeitet werden.

6.4 Entwicklungsumgebung

Als Arbeits- bzw. Entwicklungsumgebung habe ich folgende frei verfügbare Tools verwendet: Programmiersprache: Java 5.0 [Orac10b] Integr. Dev. Environment (IDE): Eclipse 3.3 [Ecli10] DBMS: MySQL 5.1 [Mysq10a] DBMS-Java-Connector: MySQL Connector Java 5.1 [Mysq10c] Web-Application-Container: Apache Tomcat 5.0 [Apac10b] Web-Browser: Firefox 40.0 [Mozi15] Texteditor: EditPad Lite 6.3 [Edit10]

142 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken KAPITEL 7

7 Proof-of-Concept

In diesem Kapitel wird anhand einiger Testfälle aus 4.4.2 die Funktionsweise des Prototyps SAHSERD demonstriert.

7.1 Start von SAHSERD

Voraussetzungen für den Einsatz von SAHSERD sind:

¾ Testdatenbank (hier UniLinz) ist erreichbar und enthält Daten

¾ DB-Benutzer (mit entsprechenden Berechtigungen) existiert und Zugangsda- ten sind bekannt

¾ SAHSERD-Hilfstabellen: sahserd_datadic, sahserd_aliases und sahserd_pre- definedresultviews sind in der Testdatenbank angelegt und entsprechend be- füllt (siehe Anhang B)

¾ WebApp SAHSERD ist in einem WebApp-Kontainer installiert und konfigu- riert und der WebApp-Kontainer-Server (hier Apache Tomcat) läuft Um die Suchmaschine zu starten muss dann lediglich das Suchformular in einem Web-Browser geöffnet werden (hier: http://localhost:8082/sahserd/)

7.2 Testfälle

Im Folgenden werden die Suchergebnisse zu ausgewählten Suchanfragen aus 4.4.2 dargestellt und erläutert.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 143 7.2.1 Einfache Anfragen mit einem Suchbegriff

Suchanfrage a1: „0056410“

Mit den Standard Suchoptionen, d.h. Comparemode: EQUALS, Minimal benötig- ter Joinlevel und View-Generierung: Entweder/Oder liefert SASHERD zu dieser Suchanfrage als Suchergebnis:

Abbildung 44: Ergebnis der Suchanfrage „0056410“

Zur Anzeige des konkreten Suchergebnisses (Resultlevel 4) wird die View „v_Student“ herangezogen und dazu sind 0 Joins nötig. Es werden Stammdaten des Students mit der Matrikelnummer „0056410“ angezeigt. Erhöht man den Join- level auf beispielsweise 3, dann erweitert sich das Suchergebnis auf:

Abbildung 45: Ergebnis der Suchanfrage „0056410“ mit erweiterten Suchoptionen

144 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Zu dem Datensatz aus v_Student kommen noch die Ergebnisse aus den Views „v_Inskription“ (2 joins) und „v_LVAZeugnis“ (3 joins), also die Studienrichtungen die Hr. McGregor belegt hat und die LVA-Zeugnisse die für ihn ausgestellt wurden.

Suchanfrage a3: „Informationssysteme“

Mit den Standard Suchoptionen liefert SAHSERD alle LVAs mit dem Titel „Infor- mationssysteme“:

Abbildung 46: Ergebnis der Suchanfrage „Informationssysteme“

Die gleiche Anfrage mit den veränderten Suchoptionen: Comparemode: MATCHES (also „unscharfe“ Suche) und dem Joinlevel 3, liefert zudem noch LVAs und LVA-Zeugnisse für LVAs die „Informationssysteme“ (an irgendeiner Stelle) im Titel haben:

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 145 Abbildung 47: Ergebnis der Suchanfrage „Informationssysteme“ mit erw. Suchoptionen

7.2.2 Einfache Abfragen mit mehreren Suchbegriffen

Suchanfrage b1: „Durchwahl“, „Wagner“

„Durchwahl“ ist ein Alias für das Attribut „TelefonNr“ in Tabelle „InstMitglied“ (Durchwahl~Col:'InstMitglied.TelefonNr'). Mit den Standard-Suchoptionen (siehe oben) erhält somit man, jene Datensätze aus der View „v_InstMitglied“, für Perso- nen mit dem Familiennamen „Wagner“:

Abbildung 48: Ergebnis der Suchanfrage „Durchwahl“, „Wagner“

Eine Erhöhung des maximalen Joinlevels für die View-Generierung/-Suche bringt hier keine weiteren Treffer, weil die View „v_InstMitglied“ den einzigen Zusam- menhang zwischen „TelefonNr“ und „Wagner“ darstellt.

146 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Suchanfrage b3: „Küng“, „9856588“

Die Suche nach den Suchbegriffen „Küng“ und „9856588“ mit den Standard- Suchoptionen ergibt:

Abbildung 49: Ergebnis der Suchanfrage „Küng“, „9856588“

Der Viewbuilder kann den Zusammenhang zwischen den beiden Value-Treffern Küng=Val:'WissPersonal.Nachname' und 9856588=Val:'Student.MatrikelNr' mit der vordefinierten View „V_LVAZeugnis“ herstellen, wobei 3 Joins benötigt werden. Eine Erweiterung der Suchoptionen hinsichtlich Comparemode oder des maxi- malen Joinlevel bringt keine weiteren Ergebnisse.

Suchanfrage b5: „9856588“, „9956627“, „0055880“

Das Ergebnis der Suche nach drei Matrikelnummern liefert mit Standard- Suchoptionen die Stammdaten der betreffenden Student(inn)en:

Abbildung 50: Ergebnis der Suchanfrage „9856588“, „9956627“, „0055880“

Setzt man den maximalen Joinlevel nun von minimal auf 3, erhält man zusätzlich Inskriptionen (v_Inskription: 2 joins) und LVA-Zeugnisse (v_LVAZeugnis: 3 joins):

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 147 Abbildung 51: Ergebnis der Suchanfrage „9856588“, „9956627“, „0055880“ mit erweiterten Suchoptionen

7.2.3 Komplexe Abfragen

Suchanfrage c2: „Informatik“

SAHSERD findet zum Suchbegriff „Informatik“ bei Standard-Suchoptionen den Value-Treffer: Informatik=Val:'Studienrichtung.Bezeichnung' und damit folgen- des Ergebnis:

148 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 52: Ergebnis der Suchanfrage „Informatik“

Mit erhöhtem maximalen Joinlevels werden zusätzlich die Datensätze aus der View v_Inskription angezeigt:

Abbildung 53: Ergebnis der Suchanfrage „Informatik“ mit erw. Suchoptionen

Bei Änderung des Comparemode von exakter Suche („EQUALS“) auf unscharfe Suche („MATCHES“) findet SASHERD Treffer in den drei Views „v_Studien- richtung“ (0 joins), „v_Institut“ (0 joins) und „v_LVA“ (2 joins):

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 149 Abbildung 54: Ergebnis der Suchanfrage „Informatik“ bei unscharfer Suche

Erhöht man bei aktivierter unscharfer Suche auch noch den maximalen Joinlevel auf 3 beinhaltet das Suchergebnis zusätzlich noch Treffer aus den Views „v_Inskription“ (2 joins), „v_InstMitglied“ (2 joins) und „v_LVAZeugnis“ (3 joins):

150 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 55: Ergebnis der Suchanfrage „Informatik“ bei unscharfer Suche und erweiterten Suchoptionen

Suchanfrage c4: „LVAs“, „Heinrich“

Zunächst wird der Suchbegriff „LVAs“ als Alias für die Tabelle „LVA“ erkannt. Be- trachtet man die Suchergebnisse für „Heinrich“ (Resultlevel 1), so sieht man, dass der Suchbegriff sowohl Übereinstimmungen mit Vor- und Nachnamen in der Ta- belle „WissPersonal“, als auch mit Vorname in der Tabelle „Student“ ergibt. Tat- sächlich enthält die View v_LVA aber keinen Treffer, bei dem der Vorname gleich „Heinrich“ ist. Dies lässt sich einfach dadurch erklären, dass zwar zumindest ei-

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 151 nen Eintrag in WissPersonal gibt, bei dem der Vorname mit dem Suchbegriff über- einstimmt (Prof. Heinrich Rolletschek), zu diesem aber keine LVAs gespeichert sind:

Abbildung 56: Ergebnis der Suchanfrage „LVAs“, „Heinrich“

Erst mit einem maximalen Joinlevel von 3 erhält man zusätzlich die Einträge aus v_LVAZeugnis bei beiden Vor- oder Nachname des Prüfers „Heinrich“ ist. Dies er- gibt sich aus der Tatsache, dass die View v_LVA nur 2 Joins benötigt (um zwischen LVA und WissPersonal.Vorname bzw. WissPersonal.Nachname einen Join-Baum zu spannen), v_LVAZeugnis aber bereits 3 Joins erfordert. Daher liefert die Suche mit der Standard Suchoption „minimaler Joinlevel“ nur Treffer aus v_LVA (siehe oben):

152 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Abbildung 57: Ergebnis der Suchanfrage „LVAs“, „Heinrich“ mit erw. Suchoptionen

Suchanfrage c5: „LVAs“, „Berger“

Mit den Standard-Suchoptionen findet SAHSERD lediglich eine Übereinstim- mung für „LVAs“ (siehe oben). „LVAs“ alleine ergibt ein Metadata-Result, d.h. es werden 10 Beispieldatensätze aus der entsprechenden View (v_LVA) angezeigt:

Abbildung 58: Ergebnis der Suchanfrage „LVAs“, „Berger“

Zum Suchbegriff „Berger“ gibt es erst Treffer, wenn die unscharfe Suche (MATCHES) aktiviert ist. Mit der Suchoption maximaler Joinlevel = 3 werden Stu- denten und LVA-Leiter und Prüfer gefunden:

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 153 Abbildung 59: Ergebnis der Suchanfrage „LVAs“, „Berger“ bei unscharfer Suche

154 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken KAPITEL 8

8 Schlussbetrachtung

Das Ende dieser Arbeit bilden eine kurze Zusammenfassung und ein Ausblick, der eine Reihe von Erweiterungsmöglichkeiten aufzeigt.

8.1 Zusammenfassung

Die wichtigsten Punkte dieser Arbeit, sind nach den beiden Teilen Untersu- chungsbereich und Prototyp „SAHSERD“ gegliedert.

8.1.1 Untersuchungsbereich

Im ersten Teil dieser Arbeit wurden zunächst die Problemstellung, die Ziele und Gliederung der Arbeit vorgestellt. Die begriffsbasierte Suche in relationalen Da- tenbanken ist im Schnittbereich der Informatik-Hauptbereiche: a) Relationale Datenbanken, b) Suchmaschinen und c) Human-Computer-Interaction angesie- delt. Die technischen Grundlagen zu den Bereichen: Relationale Datenbanken, SQL, sowie Suchmaschinen und ihre Vorläufer werden im gleichnamigen Kapitel kurz vorgestellt. Anschließend werden die Defizite von SQL als Benutzerschnitt- stelle für Gelegenheitsbenutzer dargelegt und alternative Ansätze zu SQL vorge- stellt. Neben der begriffsbasierte Suche wurden dort auch: Assistenten und For- mulierungshilfen, Abfragemasken, Systeme zur visuellen Datenabfrage, natürlich- sprachliche Benutzerschnittstellen und unscharfe Abfragen (jeweils samt Beispie- len) beschrieben. Auch zur begriffsbasierten Suche selbst gibt es verschiedene Ansätze die von Abfragemasken bis hin zur begriffsbasierte Suche im engeren Sinne reichen. Letztere zeichnen sich dadurch aus, dass

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 155 ¾ die Benutzerschnittstelle eingabeseitig aus einem einzigen Eingabefeld be- steht, in dem der/die Anwender(in) die Anfrage als mehr oder weniger lose Folge von Begriffen eingeben kann.

¾ das Backend-Modul der Suchmaschine, die SQL-Abfragen dynamisch gene- riert und dabei die Fremdschlüssel-Abhängigkeiten zur Verknüpfung der Ta- bellen verwendet.

¾ die Ausgabe der Suchergebnisse in tabellarischer Form erfolgt. Schließlich werden einige wichtige vorangegangene Forschungsarbeiten und Prototypen zur letztgenannten Gruppe vorgestellt und auf aktuelle Entwicklun- gen in diesem Bereich hingewiesen.

8.1.2 Prototyp SAHSERD

Hauptziel dieser Arbeit war, einen funktionierenden Prototyp für die begriffsba- sierte Suche in relationalen Datenbanken zu implementieren. Hierzu wurden die Rahmenbedingungen und Testfälle festgelegt. Auf Basis einer allgemeinen Archi- tektur die aus den Modulen Abfrageparser, Suchmodul und Ergebnisaufbereitung besteht wurden verschiedene Lösungsansätze für die Realisierung des Suchmo- duls vorgestellt. Einer der Ansätze, der eine ad-hoc Suche verwendet wurde aus- gewählt und die Entwurfsentscheidung begründet. Daraus wurde schließlich auch der Name des Prototyp: „SAHSERD“ abgeleitet: „a simple ad-hoc search en- gine for relational databases“. In Folge wurden Algorithmen und Datenstrukturen für die drei Hauptmodu- le der Suchmaschine erarbeitet, wobei detailliert auf die speziellen Herausforde- rungen eingegangen wurde, die sich durch den gewählten Lösungsansatz stellen. Anschließend wurde die konkrete Architektur von SAHSERD, die Benutzerschnitt- stelle(n) samt der Konfigurationsmöglichkeiten zur Suche und die Implementie- rung vorgestellt, wobei sich letztere auf die Ausführungen zu den Hauptkompo- nenten und einigen Hilfsklassen beschränken. Im Abschnitt Proof-of-Concept wurden konkrete Suchergebnisse gezeigt und erläutert, die der Prototyp zu einigen Testfällen liefert. Damit konnte schließlich demonstriert werden, dass das erstellte System SAHSERD und der gewählte Lö- sungsansatz (ad-hoc Suche) zur begriffsbasierte Suche in relationalen Datenban- ken geeignet ist.

156 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 8.2 Ausblick

Begriffsbasierte Suche in relationalen Datenbanken bleibt meiner Meinung nach ein interessanter Forschungsbereich im Spannungsfeld Datenbanktechnologie, HCI und Suchmaschinen. Einerseits gibt es hierzu noch vergleichsweise wenige Werkzeuge und kommerzielle Tools. Andererseits sind riesige Datenbestände in relationalen Datenbank gespeichert1 und nur via SQL-Abfragen zugänglich.

8.2.1 Erweiterungsmöglichkeiten für SAHSERD

Während der Entwicklungsarbeit am Prototypen SAHSERD sind mir einige Erwei- terungsmöglichkeiten in den Sinn gekommen, die jedoch aus Platz und Zeitgrün- den nicht (mehr) berücksichtigt wurden und teilweise weit über die Kernfunktio- nalität der begriffsbasierte Suche hinausgehen. Die Machbarkeit von einigen, der unten angeführten Punkte, wurde bereits in anderen Ansätzen aufgezeigt.

Allgemeine Erweiterungen

¾ Unterstützung der Suche in mehreren Datenbanksystemen

¾ Automatisches „schema grabbing“

¾ Unterstützung von arithmetische Operatoren (<, >, <=, >=) für Suchbegriffe

¾ Boolesche Operatoren und Klammernsetzung erlauben: AND, OR, NOT

Erweiterung der Mächtigkeit der ad-hoc Suche

¾ Unterstützung von Attributen mit Datentyp Datum, Zeit, Zeitstempel

¾ Unterstützung von speziellen DBMS-Features wie die Textsuche in Attributen vom Typ Text, CLOB oder ähnlichem mit der Funktion CONTAINS()

¾ Optionale Unterstützung von „Sound-Ex“-Suche

¾ Optionale Berücksichtigung von Groß-/Kleinschreibung

Verbesserte Unterstützung des Anwenders mittels GUI-Erweiterungen

¾ Visualisierung des Datenbank-Schemas als Graph inklusive Browsing- Funktionalität und Markierung der Suchergebnisse im Graph

1 Es wird davon ausgegangen, dass alleine das sogenannte Deep Web ca. zehnmal so groß ist als alle bisher von Suchmaschinen indizieren Webseiten. Wobei zum Deep Web nur jene Systeme zählen die ans WWW angebunden sind.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 157 ¾ Hinterlegung der Datenbankobjekte im Suchergebnis mit Hyperlinks zur Un- terstützung von Browsing

¾ Optionale Anzeige der Synonym-Tabelle

158 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken 0 Literaturverzeichnis

[Agra02] Agrawal, S.; Chaudhuri, S.; Das, G.: DBXplorer: enabling keyword search over re- lational databases. In: Proceedings of the 2002 ACM SIGMOD international confer- ence on Management of data. ACM, 2002. 627-627. [Andr00] Androutsopoulos I.; Ritchie, G. D.: Database Interfaces. In: Handbook of Natural Language Processing. Dale, R.; Moisl, H.; Somer, H. (eds.) CRC Press, 2000. [Andr94] Androutsopoulos I.; Ritchie, G. D.; Thanischa, P.: Natural language interfaces to databases – an introduction. In: Journal of Natural Language Engineering. Vol- ume 1, Issue 1, March 1995. 29-81. [Apac10a] Apache Software Foundation: Apache Commons CLI (Command Line Interface) http://commons.apache.org/cli/ (1. Feb. 2010) [Apac10b] Apache Software Foundation: Apache Tomcat http://tomcat.apache.org/ (1. Feb. 2010) [Aras01] Arasu, A.; Cho, J.; Garcia-Molina, H.; Paepcke, A.; Raghavan, S.: Searching the Web. In: ACM Transactions on Internet Technology. Volume 1, Issue 1, August 2001. 2-43. [Baez99] Baeza-Yates,R.; Ribeiro-Neto, B.: Modern Information Retrieval. ACM Press, Ad- dison-Wesley, New York 1999. [Bhal02] Bhalotia, G. et al.: Keyword searching and browsing in databases using BANKS. In: Data Engineering. Proceedings. 18th International Conference on. IEEE, 2002. 431-440. [Berg14] Bergamaschi, S.; Guerra, F.; Simonini, G.: Keyword search over relational data- bases: Issues, approaches and open challenges. In: Bridging Between Information Retrieval and Databases. Springer Berlin Heidelberg, 2014. 54-73. [Bern94] Berners-Lee, T.; Cailliau, R.; Luotonen, A.; Nielsen, H. F.; Secret, A.: The World- Wide-Web. In: Communications of the ACM. Vol. 37, No. 8, August 1994. 76-82. [Blun12] Blunschi, L. et al.: Soda: Generating sql for business users. In: Proceedings of the VLDB Endowment, 2012, 5. Jg., Nr. 10, 932-943. [Böhl99] Böhlen, M.; Bukauskas, L.; Dyreson, C.: The Jungle database search engine. In: ACM SIGMOD Record. ACM, 1999. 584-586. [Bosc05] Bosc, P.; Kraft, D.; Petry F.: Fuzzy sets in database and information systems: Status and opportunities. In: Fuzzy Sets and Systems archive. Volume 156, Issue 3, December 2005. Elsevier North-Holland, Amsterdam. 418-426. [Bowm95] Bowman, C. M.; Danzig, P. B.; Hardy, D. R.; Manber U; Schwartz M. F: The Har- vest information discovery and access system. In: Computer Networks and ISDN Systems. Volume 28, Issue 1-2, December 1995. 119-125. [Brin98] Brin, S.; Page, L.: The Anatomy of a Large-Scale-Hypertextual Web Search Engine Technical paper. Computer Systems Laboratory, Stanford University. 1998.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 159 [Brüg95] Brüggemann, H. H.; Teßmer B.: Implementing a Universal Relation Frontend for SQL. Technical Report, 1/95. Department of Computer Sciences, University Hildesheim. [Bush45] Bush, V.: As We May Think, Atlantic Monthly, Juli 1945, Band 176, Nr. 1, 101–108. [Cafa11] Cafarella, M.,J.; Halevy, A.; Madhavan, J.: Structured data on the web. In: Com- munications of the ACM. Vol. 54, No. 2, Feb. 2011. 72-79 [Cata97] Catarci, T.; Costabile, M. F.; Levialdi, S.; Batini, C.: Visual Query Systems for Data- bases: A Survey. In: Journal of Visual Languages & Computing. Volume 8, Issue 2, April 1997. 215–260 [Chen76] Chen, P. P.-S.: The Entity-Relationship Model - Toward a Unified View of Data. In: ACM Transactions on Database Systems, ACM Press, 1976, 9–36. [Codd70] Codd, E. F: A Relational Model of Data for Large Shared Data Banks. In: Commu- nications of the ACM. ACM Press, 1970, 377–387. [Cons92] Consens, M. P; Cruz, I. F.; Mendelzon, A. O.: Visualizing queries and querying visualizations. In: ACM SIGMOD Record. Volume 21, Issue 1, March 1992. 39-46. [Corm90] Cormen, T. H.; Leiserson, C. E.; Rivest, R. L.: Introduction to Algorithms. MIT Press. 1990. 462-578. [Cour95] Courtois, M.; Baer, W.; Stark., M.: Cool tools for searching the Web. In: Online. Vol. 19, Issue 6, 1995. 14-32. [Date98] Date, C. J; Darwen H.: SQL - Der Standard. SQL/92 mit den Erweiterungen CLI und PSM. Addison-Wesley, München, 1998. [Deut00] Deutsch, P.: Archie - a Darwinian development process. In: IEEE Internet Com- puting. Vol. 4, No. 1, Jan/Feb 2000. 69-71. [Dwiv14] Dwivedi, A. K.; Sharma, A. K.: A Framework For Processing Keyword-Based Que- ries in Relational Databases For Exact Record. In: International Journal of Com- puter Sciences and Engineering. Volume 2, Issue 8. 2014. 127-130. [Ecli10] Eclipse Foundation: Eclipse Java development tools (JDT) http://www.eclipse.org/jdt/overview.php (1. Feb. 2010) [Edit10] EditPadLite: EditPadLite, Text Editor for Windows http://www.editpadlite.com/ (1. Feb. 2010) [Elma11] Elmasri R. A.; Navathe, S. B.: Fundamentals of Database Systems. 6. Auflage, Pear- son Studium, 2011. [Emta92] Emtage, A.; Deutsch, P.: Archie: An electronic directory service for the Internet. In: Proceedings of the Winter 1992 Usenix Conference. January, 1992. 93-110. [Fost95] Foster, S.: Veronica FAQ http://www.ou.edu/research/electron/internet/veronica.htm (1. Jul. 2015) [Garc08] Garcia-Molina, H.; Ullman, J. D.; Widom, J.: Database Systems: The Complete Book. 2nd Edition, Prentice-Hall, 2008. [Gott09] Gottron, T.: Information Retrieval. Vorlesungsskript. Institut für Informatik der Uni Mainz, 2009. [Gray93] Gray, M.: WWW Wanderer. http://www.mit.edu/people/mkgray/net/background.html (3. Jän 2003)

160 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken [Haje96] Hajer, H.; Kolbeck; R.: Erfolgreiche Internetsuche. Informationen weltweit gezielt suchen und finden. Markt und Technik. München. 1996. [Heat11] Heath, T.; Bizer, C.: Linked Data: Evolving the Web into a Global Data Space. Syn- thesis Lectures on the Semantic Web: Theory and Technology. 1st Ed. Morgan & Claypool, 2011. [Hris02] Hristidis, V.; Papakonstantinou, Y.: Discover: Keyword search in relational data- bases. In: Proceedings of the 28th international conference on Very Large Data Bases. VLDB Endowment, 2002. 670-681. [Hris03] Hristidis, V.; Gravano, L.; Papakonstantinou, Y.: Efficient IR-style keyword search over relational databases. In: Proceedings of the 29th international conference on Very large data bases. VLDB Endowment, 2003. 850-861. [Ibm10] IBM Deutschland: Net Search Extender - Verwaltung und Benutzerhandbuch ftp://public.dhe.ibm.com/ps/products/db2/info/vr97/pdf/de_DE/DB2NetSearc hExtender-cteu9g972.pdf (29. Sep. 2010) [Ichi86] Ichikawa, T.; Hirakawa, M..: ARES: a relational database with the capability of performing flexible interpretation of queries. In: IEEE Transactions on Software Engineering, Volume 12, No. 5, 1986. 624-634. [ILSt15] Internet Live Stats: Statistics http://www.internetlivestats.com/google-search-statistics/#trend (11. Jun. 2015) [Jaya08] Jayapandian, M.; Jagadish, H. V.: Automated creation of a forms-based database query interface. In: Proceedings of the VLDB Endowment. Volume 1, issue 1, Au- gust 2008. 695-709. [Karg14] Kargar, M., et al.: MeanKS: meaningful keyword search in relational databases with complex schema. In: Proceedings of the 2014 ACM SIGMOD international conference on Management of data. ACM, 2014. 905-908. [Kelz98] Kelz, A.: Relationale Datenbanken, Eine Einführung. Kapitel 7: SQL und relationa- le Algebra. http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/chap7.htm (13. Aug. 2010) [Klei99] Kleinberg J.: Authoritative sources in a hyperlinked environment. In: Journal of the ACM. Volume 46, Issue 5, September 1999. 604-632. [Kost03] Koster, M.: The Web Robots Pages. http://www.robotstxt.org (5. Jän 2003) [Küng97] Küng, J.; Palkoska, J.: VQS – A Vague Query System Prototype. In: Proceedings of the eighth International Workshop on Database and Expert Systems Applications, IEEE, 1997. 614-618. [Liu06] Liu, F., et al.: Effective keyword search in relational databases. In: Proceedings of the 2006 ACM SIGMOD international conference on Management of data. ACM, 2006. 563-574. [Maie84] Maier D.; Ullman, J.D.; Vardi M.Y.: On the foundations of the universal relation model. In: ACM Transactions on Database Systems, Vol. 9, 1984, 283-308. [Mann09] Manning, C. D.; Raghavan, P.; Schütze, H.: An Introduction to Information Re- trieval. Cambridge University Press, Cambridge 2009.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 161 [Mase00a] Masermann, U.; Vossen G.: Design and implementation of a novel approach to keyword searching in relational databases. In: Current Issues in databases and in- formation systems. Springer Berlin Heidelberg, 2000. 171-184. [Mase00b] Masermann, U.; Vossen G.: SISQL: Schema-independent database querying (on and off the web). In: Database Engineering and Applications Symposium, 2000 In- ternational. IEEE, 2000. 55-64. [Maul97] Mauldin, M. L.: Lycos: Design choices in an Internet search service. In: IEEE Ex- pert. Volume 12, Issue 1, Jan/Feb 1997, 8-11. [Motr86] Motro A.: Constructing queries from tokens. ACM SIGMOD Record, 1986, 15. Jg., Nr. 2, 120-131. [Motr88] Motro A.: VAGUE: A user interface to relational databases that permits vague que- ries. In: ACM Transactions on Information Systems (TOIS), 1988, Volume 6, No. 3. 187-214. [Motr90] Motro A.: Accommodating imprecision in database systems: issues and solutions. In: ACM SIGMOD, Directions for future database research & development. Volume 19, Issue 4, December 1990. 69-74. [Mozi15] Mozilla Foundation: Mozilla Firefox http:// www.mozilla.org/de/firefox/ (10. Aug. 2015) [Mysq10a] MySQL: MySQL Server Community Edition http://dev.mysql.com (1. Feb. 2010) [Mysq10b] MySQL: MySQL-Volltextsuche http://dev.mysql.com/doc/refman/5.1/de/fulltext-search.html (29. Sep. 2010) [Mysq10c] MySQL: MySQL Connector/JDBC. Using MySQL with Java http://dev.mysql.com/usingmysql/java/ (1. Feb. 2010) [Orac10a] Oracle: Oracle Text Application Developer's Guide Release 9.2 http://download.oracle.com/docs/cd/B10500_01/text.920/a96517/cdefault.htm (29. Sep. 2010) [Orac10b] Oracle: Java Platform, Standard Edition (Java SE) http://www.oracle.com/technetwork/java/javase/overview/index.html (1. Feb. 2010) [Ottm96] Ottmann, P.; Widmeyer, P.: Algorithmen und Datenstrukturen. 3. Überarb. Aufla- ge. Spektrum Akademischer Verlag, Heidelberg, Berlin, Oxford, 1996. 535-585. [Ozso93] Ozsoyoglu, G.: Example-based graphical database query languages. In: Computer. Volume 26, Issue 5, Mai 1993. 25-38. [Page99] Page, L.; Brin, S.; Motwani, R.; Winograd, T.: The pagerank citation ranking: bringing order to the web. Technical paper. Computer Systems Laboratory, Stan- ford University. 1999. [Pfei95] Pfeifer, U.: HTTPs älterer Bruder. WAIS: Inhaltsorientierte Suche im Internet. In: iX. 2/1995. 120-126. [Post69] Postel, H. J.: Die Kölner Phonetik. Ein Verfahren zur Identifizierung von Perso- nennamen auf der Grundlage der Gestaltanalyse. In: IBM-Nachrichten, 19. Jg., 1969. 925-931.

162 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken [Qin09] Qin, L.; Yu, J., X.; Chang, L.: Keyword search in databases: the power of RDBMS. In: Proceedings of the 2009 ACM SIGMOD International Conference on Manage- ment of data. ACM, 2009. 681-694. [Rama03] Ramakrishnan, R.; Gehrke, J.: Database management systems. 3rd Edition. McGraw-Hill, New York 2003. [Salt83] Salton, G., McGill, M. J.: Introduction to modern information retrieval. McGraw- Hill, New York 1983. [SAS15] SAS 9.2 Documenation: SQL Query Window User's Guide – Performing simple queries http://support.sas.com/documentation/cdl/en/sqlug/59570/ HTML/default/viewer.htm#a002281590.htm (20. Jun 2015) [Schr01] Schraml, T.: Begriffbasierte Suche in relationalen Datenbanken – Konzepte und Prototyp. Diplomarbeit. Johannes Kepler Universität Linz. 2001. [Sear03] Search Tools Consulting: All About Search Indexing Robots and Spiders. http://www.searchtools.com/robots/ (5. Jän 2003) [Sedg88] Sedgewick, R.: Algorithms. 2nd Edition. Addison-Wesley, 1988. 415-484. [Squi15] Squirrel SQL: http://squirrel-sql.sourceforge.net/ (20. Jun 2015) [Stoc07] Stock, W. G.: Information Retrieval. Informationen suchen und finden. Olden- bourg Wissenschaftsverlag, München 2007. [Tata08] Tata, S.; Lohman, G. M.: SQAK: doing more with keywords. In: Proceedings of the 2008 ACM SIGMOD international conference on Management of data. ACM, 2008. 889-902. [Thom83] Thompson, B., H.; Thompson, F., B.: Introducing ASK, a simple knowledgeable system. In: Proceedings of the first conference on Applied natural language proc- essing. Association for Computational Linguistics, 1983. 17-24. [Ullm08] Ullman, J. D.; Widom, J.: A first course in database systems. 3rd Edition, Prentice- Hall, 2008. [Vard88] Vardi, M.Y.: The Universal-Relation Data Model for Logical Independence. In: IEEE Software. Volume 5, Issue 2, March 1988. 80-85. [Voss08] Vossen G.: Datenbankmodelle, Datenbanksprachen, Datenbankmanagement- Systeme, Oldenbourg, 2008 [Wade03] Wade, A.: Effective Local Search Techniques for the Steiner Tree Problem. Mathe- matical Algorithms Group. http://www.sys.uea.ac.uk/~asw/restricted/steiner.html (6. Jun. 2003) [Yu09] Yu, J., X.; Qin, L.; Chang, L.: Keyword search in databases. Synthesis Lectures on Data Management, 2009, 1. Jg., Nr. 1, 1-155. [Zabi95] Zabinski, T.: Surfing with Veronica. In: Electronic Learning. Vol. 15, No. 3, 1995. [Zeng14] Zeng, Z., et al.: Semantic path ranking scheme for relational keyword queries. In: Database and Expert Systems Applications. Springer International Publishing, 2014. 97-105. [Zloo77] Zloof, M. M.: Query-by-Example: A data base language. In: IBM Systems Journal, Volume 16, Issue 4, 1977. 324-343.

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 163 0 Anhang

Anhang A: Testdatenbank UniLinz

A.1 ER-Diagramm

164 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken A.2 Datenbank-Dump

Die Datensätze in den Tabellen Institute und WissPersonal wurden mit Stand 2005 aus dem elektronischen Lehrveranstaltungs-Verzeichnis der JKU Linz übernom- men und können sich in der Zwischenzeit geändert haben. Die Datensätz in den anderen Tabellen sind vom Autor generiert worden. Jede Übereinstimmung mit Personen und Objekten der realen Welt sind zufällig und nicht beabsichtigt.

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.Studienrichtung #

DROP TABLE IF EXISTS UniLinz.Studienrichtung;

CREATE TABLE UniLinz.Studienrichtung ( SKZ INT(3) UNSIGNED NOT NULL, Bezeichnung VARCHAR(60) NOT NULL,

PRIMARY KEY (SKZ), UNIQUE INDEX StudRBez (Bezeichnung) ) TYPE=InnoDB COMMENT='Studienrichtungen Studium';

# Daten

INSERT INTO UniLinz.Studienrichtung VALUES (84, 'Doktorratstudium der Sozial- und Wirtschaftswissenschaften'); INSERT INTO UniLinz.Studienrichtung VALUES (86, 'Doktorratstudium der Technischen Wissenschaften'); INSERT INTO UniLinz.Studienrichtung VALUES (130, 'Sozialwirtschaft'); INSERT INTO UniLinz.Studienrichtung VALUES (140, 'Volkswirtschaft'); INSERT INTO UniLinz.Studienrichtung VALUES (151, 'Betriebswirtschaft'); INSERT INTO UniLinz.Studienrichtung VALUES (160, 'Handelswissenschaft'); INSERT INTO UniLinz.Studienrichtung VALUES (170, 'Wirtschaftspädagogik'); INSERT INTO UniLinz.Studienrichtung VALUES (175, 'Wirtschaftsinformatik'); INSERT INTO UniLinz.Studienrichtung VALUES (726, 'Mechtronik'); INSERT INTO UniLinz.Studienrichtung VALUES (881, 'Informatik');

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.Student #

DROP TABLE IF EXISTS UniLinz.Student;

CREATE TABLE UniLinz.Student ( MatrikelNr INT(7) UNSIGNED ZEROFILL NOT NULL, Nachname VARCHAR(40) NOT NULL, Vorname VARCHAR(25) NOT NULL, GebDat DATE NOT NULL, Geschlecht ENUM('M', 'W') NOT NULL, Adresse VARCHAR(80) NOT NULL,

PRIMARY KEY (MatrikelNr), INDEX Name (Nachname, Vorname) ) TYPE=InnoDB COMMENT='Studenten Studentin';

# Daten

INSERT INTO UniLinz.Student VALUES (9655663, 'Altmann', 'Alfred', '1977-06-15', 'm', '4020 Linz, Fadingerstrasse 23'); INSERT INTO UniLinz.Student VALUES (9656522, 'Arnberger', 'Anna', '1975-12-16', 'w', '4040 Linz, Johann- Wilhelm-Klein-Str. 72 (WIST)'); INSERT INTO UniLinz.Student VALUES (9755612, 'Bankl-Trauner', 'Bruno', '1978-09-25', 'm', '4210 Gallneukirchen, Pfarrfeld 22'); INSERT INTO UniLinz.Student VALUES (9656873, 'Bauer', 'Barbara', '1977-03-03', 'w', '4190 Bad Leonfelden, Hintere Zeile 6');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 165 INSERT INTO UniLinz.Student VALUES (9755438, 'Castek', 'Claudia', '1978-12-04', 'w', '4100 Ottensheim, Mühlenweg 44'); INSERT INTO UniLinz.Student VALUES (9755904, 'Cermak', 'Clemens', '1978-04-01', 'm', '4040 Puchenau, Gartenstadtstrasse 25'); INSERT INTO UniLinz.Student VALUES (9756565, 'Danner', 'Daniel', '1979-07-18', 'm', '4221 Steyregg, Bergsiedlung 37'); INSERT INTO UniLinz.Student VALUES (9755666, 'Degenfeld', 'Dorothe', '1979-10-26', 'w', '4070 Eferding, Ledererstrasse 5'); INSERT INTO UniLinz.Student VALUES (9856857, 'Ederl', 'Eva-Marie', '1977-04-24', 'w', '4053 Ansfelden, Wasserwerkstrasse 28'); INSERT INTO UniLinz.Student VALUES (9856261, 'Elstner', 'Emil', '1979-04-19', 'm', '4470 Enns, Bahnhofstrasse 49'); INSERT INTO UniLinz.Student VALUES (9856588, 'Fischer', 'Fritz', '1977-08-14', 'm', '4061 Pasching, Schulstrasse 8'); INSERT INTO UniLinz.Student VALUES (9855804, 'Fürst', 'Freda', '1979-01-31', 'w', '4490 St. Florian, Am Seisberg 10'); INSERT INTO UniLinz.Student VALUES (9855280, 'Gebhart', 'Gabriele', '1978-08-12', 'w', '4050 Traun, Kremstalstrasse 150'); INSERT INTO UniLinz.Student VALUES (9956681, 'Goldmann', 'Georg', '1980-07-02', 'm', '4310 Mauthausen, Lerchenweg 29'); INSERT INTO UniLinz.Student VALUES (9956083, 'Hamberger', 'Helga', '1981-06-12', 'w', '4222 St. Georgen a. d. Gusen, Mauthausener Strasse 64'); INSERT INTO UniLinz.Student VALUES (9955468, 'Holzer', 'Heinrich', '1978-03-19', 'm', '4320 Perg, Jahnstrasse 2'); INSERT INTO UniLinz.Student VALUES (9956627, 'Igler', 'Ingo', '1980-06-02', 'm', '4201 Gramastetten, Hohe Strasse 123'); INSERT INTO UniLinz.Student VALUES (9956706, 'Ivanovic', 'Ingrid', '1980-06-19', 'w', '4040 Linz, Blütenstrasse 4'); INSERT INTO UniLinz.Student VALUES (9956175, 'Jelinek', 'Johann', '1981-03-13', 'm', '4050 Traun, Linzer Strasse 89'); INSERT INTO UniLinz.Student VALUES (9956352, 'Jürgens', 'Jana', '1977-03-28', 'w', '4020 Linz, Museumstrasse 76'); INSERT INTO UniLinz.Student VALUES (0055735, 'Kainz', 'Karin', '1979-12-24', 'w', '4600 Wels, Ingeborg- Bachmann-Strasse 22'); INSERT INTO UniLinz.Student VALUES (0055679, 'Kollhammer', 'Klaus', '1981-09-14', 'm', '4600 Wels, Traunsteinstrasse 52'); INSERT INTO UniLinz.Student VALUES (0055050, 'Lang-Sailer', 'Leopoldine', '1979-06-06', 'w', '4020 Linz, Lederergasse 14'); INSERT INTO UniLinz.Student VALUES (0056665, 'Lehner-Hartl', 'Ludwig', '1980-02-02', 'm', '4040 Linz, Aubergstrasse 24'); INSERT INTO UniLinz.Student VALUES (0056410, 'McGregor', 'Michael', '1979-08-18', 'm', '4400 Steyr, Arbeiterstrasse 38'); INSERT INTO UniLinz.Student VALUES (0055304, 'Mühlbach', 'Monika', '1979-10-14', 'w', '4020 Linz, Gruberstrasse 3'); INSERT INTO UniLinz.Student VALUES (0055498, 'Namesnik', 'Norbert', '1980-01-04', 'm', '4020 Linz, Langgasse 9'); INSERT INTO UniLinz.Student VALUES (0055407, 'Neubeck', 'Nina', '1980-02-25', 'w', '4040 Linz, Julius-Raab- Str. 1-3 (ESH)'); INSERT INTO UniLinz.Student VALUES (0056879, 'Obrowsky', 'Olga', '1981-04-03', 'w', '4020 Linz, Harrachstrasse 18'); INSERT INTO UniLinz.Student VALUES (0055880, 'Oswald', 'Otto', '1979-02-16', 'm', '4040 Linz, Ferihumerstrasse 42'); INSERT INTO UniLinz.Student VALUES (0155919, 'Paschinger', 'Petra', '1983-07-04', 'w', '4400 Steyr, Schubertstrasse 20'); INSERT INTO UniLinz.Student VALUES (0156086, 'Puchegger', 'Paul', '1980-12-09', 'm', '4070 Eferding, Gstöttenau 35'); INSERT INTO UniLinz.Student VALUES (0155902, 'Reisshofer', 'Rosa', '1981-06-11', 'w', '4600 Wels, Leharstrasse 31'); INSERT INTO UniLinz.Student VALUES (0155384, 'Rubenstein', 'Rudolf', '1981-08-25', 'm', '4040 Linz, Mengerstr 23 (KHG)'); INSERT INTO UniLinz.Student VALUES (0156178, 'Schön', 'Susanne', '1981-04-06', 'w', '4020 Linz, Steingasse 12'); INSERT INTO UniLinz.Student VALUES (0155304, 'Student', 'Stephan', '1980-12-31', 'm', '4470 Enns, Birkenstrasse 69'); INSERT INTO UniLinz.Student VALUES (0155035, 'Tomic', 'Theresa', '1980-08-08', 'w', '4040 Linz, Freistädterstr. 44'); INSERT INTO UniLinz.Student VALUES (0156278, 'Torado', 'Tino', '1981-09-22', 'm', '4040 Linz, Freistädterstr. 175'); INSERT INTO UniLinz.Student VALUES (0155891, 'Unger', 'Uwe', '1983-09-30', 'm', '4040 Linz, Julius-Raab-Str. 1-3 (ESH)'); INSERT INTO UniLinz.Student VALUES (0156580, 'Unterberger', 'Ulla', '1983-01-21', 'w', '4040 Linz, Rudolfstr. 33'); INSERT INTO UniLinz.Student VALUES (0256110, 'Vierlinger', 'Viktor', '1984-04-12', 'm', '4040 Linz, Julius- Raab-Str. 5-7 (JRH)'); INSERT INTO UniLinz.Student VALUES (0255121, 'Von Rosenheim', 'Valerie', '1982-06-16', 'w', '4040 Linz, Julius-Raab-Str. 5-7 (JRH)');

166 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.Student VALUES (0256241, 'Weber', 'Wolfgang', '1984-02-02', 'm', '4040 Linz, Julius-Raab- Str. 1-3 (ESH)'); INSERT INTO UniLinz.Student VALUES (0255360, 'Wittmann', 'Waltraud', '1983-08-05', 'w', '4040 Linz, Johann- Wilhelm-Klein-Str. 72 (WIST)'); INSERT INTO UniLinz.Student VALUES (0256814, 'Xandner', 'Xaver', '1982-03-17', 'm', '4040 Linz, Julius-Raab- Str. 5-7 (JRH)'); INSERT INTO UniLinz.Student VALUES (0255128, 'Xie', 'Xu Wie', '1982-02-17', 'w', '4040 Linz, Johann-Wilhelm- Klein-Str. 72 (WIST)'); INSERT INTO UniLinz.Student VALUES (0256994, 'Yilmaz', 'Yvonne', '1983-04-27', 'w', '4040 Linz, Mengerstr 23 (KHG)'); INSERT INTO UniLinz.Student VALUES (0255146, 'Yoo-Sang', 'Yong', '1982-08-15', 'm', '4040 Linz, Johann- Wilhelm-Klein-Str. 72 (WIST)'); INSERT INTO UniLinz.Student VALUES (0256591, 'Zainzinger', 'Zita', '1981-08-03', 'w', '4040 Linz, Mengerstr 23 (KHG)'); INSERT INTO UniLinz.Student VALUES (0255385, 'Zecevic', 'Zoran', '1981-10-09', 'm', '4040 Linz, Julius-Raab- Str. 5-7 (JRH)');

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.WissPersonal #

DROP TABLE IF EXISTS UniLinz.WissPersonal;

CREATE TABLE UniLinz.WissPersonal ( PersNr INT(4) UNSIGNED NOT NULL, Titel VARCHAR(50) NULL, Nachname VARCHAR(40) NOT NULL, Vorname VARCHAR(25) NOT NULL, Geschlecht ENUM('M', 'W') NOT NULL,

PRIMARY KEY (PersNr), INDEX Name (Nachname, Vorname) ) TYPE=InnoDB COMMENT='Personal Uni-Personal';

# Daten

INSERT INTO UniLinz.WissPersonal VALUES (1001, 'Dipl.Ing.', 'Affenzeller', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1002, 'Dipl.Ing., Dr.', 'Aichinger', 'Erhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1003, 'Dr.Univ.Prof.', 'Aiginger', 'Karl', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1004, 'Dr., o.Univ.Prof.', 'Altrichter', 'Herbert', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1005, 'Mag.', 'Andeßner', 'René', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1006, 'Dr., o.Univ.Prof.', 'Ardelt', 'Rudolf G.', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1007, 'Dr., a.Univ.Prof.', 'Auer-Rizzi', 'Werner', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1008, 'Mag.', 'Auinger', 'Andreas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1009, 'Mag.', 'Auinger', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1010, 'Mag., Dr.,a.Univ.Prof.', 'Bartel', 'Rainer', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1011, 'Dr.', 'Bauer', 'Robert', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1012, 'Dipl.Ing.', 'Beer', 'Wolfgang', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1013, 'Mag. Dr.', 'Beham-Rabanser', 'Martina', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1014, 'Dr., Univ.Prof.', 'Beran', 'Helmut', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1015, 'Dipl.Ing.', 'Bergmair', 'Marcus', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1016, 'Dr., Ass.Prof.', 'Bergmann', 'Christian', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1017, 'Mag.', 'Bernauer', 'Martin', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1018, 'Mag.', 'Bertl', 'Andreas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1019, 'Mag.', 'Birngruber', 'Dietrich', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1020, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Blaschek', 'Günther', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1021, 'Mag., Dr., o.Univ.Prof.', 'Böhnisch', 'Wolf', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1022, 'Mag.phil., Dr., a.Univ.Prof.', 'Born', 'Rainer', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1023, 'Dr.', 'Brandstätter', 'Eduard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1024, 'Mag.', 'Brenner', 'Julia', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1025, 'Dipl.Ing., DDr., o.Univ.Prof.', 'Brunner', 'Johann K.', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1026, 'Mag.', 'Brunner-Kranzmayr', 'Elisabeth', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1027, 'Dr., DDr.h.c., o.Univ.Prof.', 'Buchberger', 'Bruno', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1028, 'Mag., Dr., a.Univ.Prof.', 'Buchegger', 'Reiner', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1029, 'Mag.', 'Burgstaller', 'Johann', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1030, 'Dipl.Ing., Dr. M.Sc., o.Univ.Prof.', 'Chroust', 'Gerhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1031, 'Dkfm., Dr., Hon.Prof., Konsul h.c.', 'Czempirek', 'Klaus E.', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1032, 'Mag.', 'Dammerer', 'Gregor', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1033, 'Dipl.Kfm.', 'Dietrich', 'Ralph', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1034, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Diskus', 'Christian', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1035, 'Dipl.Ing., Dr.', 'Duller', 'Christine', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1036, 'Dr.,a.Univ.Prof.', 'Eder', 'Ferdinand', 'm');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 167 INSERT INTO UniLinz.WissPersonal VALUES (1037, 'Mag., Dr.', 'Edlinger', 'Herbert', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1038, 'Dipl.Ing.', 'Eggetsberger', 'Roland', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1039, 'Dipl.Kff.', 'Eierle', 'Brigitte', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1040, 'Mag., Dr., o.Univ.Prof.', 'Euler', 'Hanns Peter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1041, 'Mag., Dr., a.Univ.Prof.', 'Feldbauer-Durstmüller', 'Birgit', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1042, 'Dr., o.Univ.Prof.', 'Ferscha', 'Alois', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1043, 'Mag.', 'Filsecker', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1044, 'Mag., Prof.', 'Fischer', 'Roland', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1045, 'Mag., Dr.', 'Fischlmayr', 'Iris', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1046, 'Mag.', 'Freisler-Traub', 'Andrea', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1047, 'Dr., Ass.Prof.', 'Fröhlich', 'Gerhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1048, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Fuchs', 'Peter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1049, 'Dr., Univ.Prof.', 'Hauch', 'Gabriella', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1050, 'Dr., o.Univ.Prof.', 'Gadenne', 'Volker', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1051, 'Mag., Dr.', 'Gerich', 'Joachim', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1052, 'Dipl.Ing.', 'Ginzinger', 'Alice', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1053, 'Mag., Dr., Prof.', 'Glaser', 'Evelyne', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1054, 'MMag., Dr.', 'Gramlinger', 'Franz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1055, 'Mag., Dr.', 'Grausgruber', 'Alfred', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1056, 'Mag., Dr.', 'Grof', 'Erika', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1057, 'Mag., Dr.', 'Gross', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1058, 'Mag., Dr.', 'Grünbacher', 'Paul', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1059, 'Mag., Dr., a.Univ.Prof.', 'Gunz', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1060, 'Mag.,Dr.', 'Hackl', 'Franz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1061, 'Dipl.Ing., Dr., o.Univ.Prof.', 'Hafner', 'Robert', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1062, 'Mag.', 'Haider', 'Petra', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1063, 'Mag., Dr., o.Univ.Prof.', 'Håkanson', 'Lars', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1064, 'Mag., Dr., Univ.Prof.', 'Haller', 'Axel', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1065, 'Dr., a.Univ.Prof.', 'Hautmann', 'Hans', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1066, 'Dipl.Ing., Dr., o.Univ.Prof.', 'Heinrich', 'Lutz J.', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1067, 'Dipl.Ing.', 'Heinzlreiter', 'Paul', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1068, 'Dr.', 'Hellmuth', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1069, 'Mag., Dr.', 'Hemedinger', 'Fritz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1070, 'Mag.', 'Herndler', 'Andreas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1071, 'Mag., Dipl.Ing., Dr.', 'Hofer', 'Christian', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1072, 'DDr. a.Univ.Prof.', 'Höller', 'Johann', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1073, 'Mag., Dr.', 'Holley', 'Heinz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1074, 'Dr., o.Univ.Prof.', 'Holm', 'Kurt', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1075, 'Dipl.Ing.', 'Hoyer', 'Christoph', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1076, 'Dr.', 'Innreiter-Moser', 'Cäcilia', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1077, 'Mag.', 'Jauschnig', 'Harald', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1078, 'Dr.', 'Jebelean', 'Tudor', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1079, 'Dipl.Ing.', 'Jöbstl', 'Markus', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1080, 'Dr.', 'John', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1081, 'Dr. a.Univ.Prof.', 'Kannonier', 'Reinhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1082, 'Dipl.Ing., Mag., Dr., o.Univ.Prof.', 'Kappel', 'Gerti', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1083, 'Mag., Dr.', 'Kapsammer', 'Elisabeth', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1084, 'Mag.', 'Kathan', 'Markus', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1085, 'Dr.', 'Kerschbaumer', 'Monika', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1086, 'Dr., a.Univ.Prof.', 'Kette', 'Gerhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1087, 'Mag.', 'Kienberger', 'Alexandra', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1088, 'Dr., Univ.Prof.', 'Klement', 'Erich Peter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1089, 'Mag.', 'Kloimwieder', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1090, 'Mag.', 'Knoll', 'Günter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1091, 'Dr., o.Univ.Prof.', 'Kohler', 'Wilhelm', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1092, 'Mag.', 'Kolarik', 'Christian', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1093, 'Dipl.Ing.', 'Kolmhofer', 'Erich', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1094, 'Dipl.Ing.', 'Kramler', 'Gerhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1095, 'Dipl.Ing., Dr.', 'Kranzlmüller', 'Dieter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1096, 'Mag.', 'Krennhuber', 'Elisabeth', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1097, 'Mag.', 'Kronberger', 'Nicole', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1098, 'Dr., Univ.Prof.', 'Kropf', 'Rudolf', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1099, 'Mag.', 'Kuchinka', 'Petra', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1100, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Küng', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1101, 'Dipl.Ing.', 'Kurka', 'Gerhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1102, 'Dr., o.Univ.Prof.', 'Landesmann', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1103, 'Mag.', 'Langthaler', 'Silvia', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1104, 'Mag.', 'Lechner', 'Stephan', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1105, 'Dr., a.Univ.Prof.', 'Lehner', 'Johannes', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1106, 'Mag.', 'Lengauer', 'Efrem', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1107, 'MMag., Dr., Ass.Prof.', 'Lins', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1108, 'Mag.', 'Loidl-Keil', 'Rainer', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1109, 'Dr., o.Univ.Prof.', 'Malinsky', 'Adolf Heinz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1110, 'Mag., Dr.', 'Massimiani', 'Roberto', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1111, 'Mag., Dr.', 'Mayr', 'Albert', 'm');

168 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.WissPersonal VALUES (1112, 'Mag.', 'Mayr', 'Karin', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1113, 'Mag., Dr., a.Univ.Prof.', 'Mörth', 'Ingo', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1114, 'Dr., o.Univ.Prof.', 'Mössenböck', 'Hanspeter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1115, 'Dr., o.Univ.Prof.', 'Mühlbacher', 'Jörg R.', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1116, 'Dipl.Ing., Dr.', 'Narzt', 'Wolfgang', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1117, 'Mag., Dr., Ass.Prof.', 'Nemella', 'Joachim', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1118, 'Mag., Dr., a.Univ.Prof.', 'Neuweg', 'Georg', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1119, 'Mag., Dr., Ass.Prof.', 'Niedermair', 'Gerhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1120, 'Mag.', 'Nösslböck', 'Birgit', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1121, 'Dipl.Ing.', 'Novacek', 'Alfred', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1122, 'Mag.', 'Nowotny', 'Clemens', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1123, 'Mag.,Dr., a.Univ.Prof.', 'Ötsch', 'Walter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1124, 'Dipl.Ing.', 'Palkoska', 'Jürgen', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1125, 'DDr.', 'Pammer', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1126, 'Dr., a.Univ.Prof.', 'Paule', 'Peter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1127, 'Mag., Dr.', 'Pech', 'Susanne', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1128, 'Mag., Dr., o.Univ.Prof.', 'Pernsteiner', 'Helmut', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1129, 'Mag.', 'Pfeil', 'Gisela', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1130, 'Mag.', 'Pflüglmayer', 'Martin', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1131, 'Ing., Dr., o.Univ.Prof.', 'Pichler', 'Franz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1132, 'Dipl.Ing. (FH)', 'Pichler', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1133, 'Mag.', 'Piekarz', 'Bartosz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1134, 'Mag., Dr., Univ.Prof.', 'Pils', 'Manfred', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1135, 'Dr., o.Univ.Prof', 'Pilz', 'Günter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1136, 'Mag., Dr., Ass.Prof.', 'Plösch', 'Reinhold', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1137, 'Mag., Dr., a.Univ.Prof.', 'Pölz', 'Werner', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1138, 'Dipl.Ing., Dr., o.Univ.Prof.', 'Pomberger', 'Gustav', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1139, 'Dipl.Ing., Dr., Ass.Prof.', 'Prähofer', 'Herbert', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1140, 'Mag., Dr.', 'Prammer', 'Heinz Karl', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1141, 'Mag.,Dr.', 'Preimesberger', 'Christoph', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1142, 'Dipl.Ing., Dr.', 'Preuner', 'Günter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1143, 'Dr., Ass.Prof.', 'Priewasser', 'Reinhold', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1144, 'Dipl.Ing.', 'Pröll', 'Birgit', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1145, 'Mag., Dr., a.Univ.Prof.', 'Pruckner', 'Gerald', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1146, 'Mag., Dr.', 'Putz', 'Peter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1147, 'Dr.', 'Quatember', 'Andreas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1148, 'Mag., Dr.', 'Ranftl', 'Edeltraud', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1149, 'Dkfm., Dr., Dr. h.c.mult., MBA, o.Univ.Prof.', 'Reber', 'Gerhard', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1150, 'Dipl.Ing.', 'Reisinger', 'Susanne', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1151, 'Mag.', 'Reitbauer', 'Susanne', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1152, 'Mag., Dr.', 'Retschitzegger', 'Werner', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1153, 'Dr.,a.Univ.Prof.', 'Riese', 'Martin', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1154, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Rolletschek', 'Heinrich', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1155, 'Mag., Dr.', 'Romauer', 'Barbara', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1156, 'Mag., Dr., a.Univ.Prof.', 'Sageder', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1157, 'Dipl.Ing., Dr., a.Univ.Prof. ', 'Sametinger', 'Johannes', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1158, 'Mag.', 'Saminger', 'Susanne', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1159, 'Dr., Univ.Prof.', 'Sandgruber', 'Roman', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1160, 'Mag.', 'Schädle', 'Martin', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1161, 'Dr., Prof.', 'Schäffer', 'Christian', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1162, 'Dipl.Ing., Dr., a.Univ.Prof.;', 'Scharinger', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1163, 'Dipl.Ing.', 'Schaubschläger', 'Christian', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1164, 'Dkfm., Dr., o.Univ.Prof.,', 'Schauer', 'Reinbert', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1165, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Schicho', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1166, 'Dipl.Ing., Dr.', 'Schiefermayr', 'Klaus', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1167, 'Mag., Dr.', 'Schiller-Ripota', 'Christine', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1168, 'Mag.', 'Schmidt', 'Harald', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1169, 'Dr., o.Univ.Prof.', 'Schneider', 'Friedrich', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1170, 'Dipl.Ing., Dr.', 'Schneider', 'Walter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1171, 'Dipl.Ing., Dr., o.Univ.Prof.', 'Schrefl', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1172, 'Dipl.Ing., Dr.', 'Schreiner', 'Wolfgang', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1173, 'Mag., Dr., o.Univ.Prof.', 'Schurer', 'Bruno', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1174, 'o.Univ.Prof., Dr., B.COM.', 'Schuster', 'Helmut', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1175, 'Dr.', 'Schwärtzel', 'Heinz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1176, 'Dipl.Ing., Dr.', 'Seifert', 'Franz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1177, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Springer', 'Andreas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1178, 'Dr., Ass.Prof.', 'Stangl', 'Werner', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1179, 'Dipl.Ing., Dr., o.Univ.Prof.', 'Stary', 'Christian', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1180, 'Dr., a.Univ.Prof.', 'Steinbach-Gröbl', 'Evelyn', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1181, 'Dipl.Ing., Dr.', 'Stelzer', 'Andreas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1182, 'Ing., Mag., Dr., Univ.Prof.', 'Stiegler', 'Harald', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1183, 'Mag.', 'Stiglbauer', 'Alfred', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1184, 'Dipl.Ing.', 'Stoiber', 'Simone', 'w');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 169 INSERT INTO UniLinz.WissPersonal VALUES (1185, 'Mag., Dr., MBA, o.Univ.Prof.', 'Strehl', 'Franz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1186, 'Dipl.Ing., Dr., a.Univ.Prof.', 'Stritzinger', 'Alois', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1187, 'Mag.', 'Stummer', 'Harald', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1188, 'Dr., MBA', 'Szabo', 'Erna', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1189, 'Dr.', 'Tauber', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1190, 'Mag.', 'Thalhammer', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1191, 'Dipl.Ing., Dr., o.Univ.Prof.', 'Thim', 'Hartwig', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1192, 'Mag.', 'Thonabauer', 'Claudia', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1193, 'Dr.', 'Thumser', 'Regina', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1194, 'Mag.', 'Tischler', 'Astrid', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1195, 'Dr., o.Univ.Prof.', 'Tjoa', 'A Min', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1196, 'Mag.', 'Traugott', 'Gabriele', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1197, 'Dr., Univ.Prof.', 'Traunmüller', 'Roland', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1198, 'Mag., Dr.', 'Tschemer', 'Marlies', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1199, 'Dr., Univ.Prof.', 'Tumpel', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1200, 'Dipl.Ing.', 'Vogl', 'Simon', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1201, 'Dr., o.Univ.Prof.', 'Volkert', 'Jens', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1202, 'Mag., Dr. MA., Ph.D., Ass.Prof.', 'Wagner', 'Franz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1203, 'Mag., Dr.', 'Wagner', 'Helga', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1204, 'Dipl.Ing., Dr., Univ.Prof.', 'Wagner', 'Roland', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1205, 'Dr., a.Univ.Prof.', 'Wagner', 'Wolfgang', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1206, 'Mag., Dipl.Ing.', 'Wasner', 'Michael', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1207, 'Mag.', 'Weichbold', 'Josef', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1208, 'Mag.', 'Weichselbaumer', 'Doris', 'w'); INSERT INTO UniLinz.WissPersonal VALUES (1209, 'Dr.Ing., Dr.Ing.habil., o.Univ.Prof.', 'Weigel', 'Robert', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1210, 'Dipl.Ing., Dr., Ass.Prof.', 'Weinreich', 'Rainer', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1211, 'Dr., o.Univ.Prof.', 'Weiß', 'Peter', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1212, 'Ph.D.', 'Weisshaar', 'Andreas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1213, 'Mag., Dr.', 'Werani', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1214, 'Mag.', 'Windischbauer', 'Thomas', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1215, 'Dipl.Ing.', 'Windsteiger', 'Wolfgang', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1216, 'Dipl.Ing., Dr., o.Univ.Prof.', 'Winkler', 'Franz', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1217, 'Mag., Dr., a.Univ.Prof.', 'Winter-Ebmer', 'Rudolf', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1218, 'Dr.', 'Witschnig', 'Harald', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1219, 'Dipl.Ing.', 'Wöß', 'Albrecht', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1220, 'Dipl.Ing., Dr.', 'Wöß', 'Wolfram', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1221, 'Dkfm., Dr., o.Univ.Prof.', 'Wührer', 'Gerhard A.', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1222, 'Dr., o.Univ.Prof.', 'Zäpfel', 'Günther', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1223, 'Dr., o.Univ.Prof.', 'Zapotoczky', 'Klaus', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1224, 'Mag., Dr., a.Univ.Prof.', 'Ziegler', 'Meinrad', 'm'); INSERT INTO UniLinz.WissPersonal VALUES (1225, 'Mag., Dr.', 'Brunmayr', 'Hermann', 'm');

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.Institut #

DROP TABLE IF EXISTS UniLinz.Institut;

CREATE TABLE UniLinz.Institut ( InstNr INT(5) UNSIGNED NOT NULL, Name VARCHAR(80) NOT NULL, Adresse VARCHAR(80) NOT NULL,

PRIMARY KEY (InstNr), UNIQUE INDEX InstName (Name) ) TYPE=InnoDB COMMENT='Institute';

# Daten

INSERT INTO UniLinz.Institut VALUES (20100, 'Inst. für Soziologie', 'Keplergebäude, Stiege A, 1., 2. Stock; Stiege B, 2. Stock, Stiege C, 2.Stock'); INSERT INTO UniLinz.Institut VALUES (20200, 'Inst. für Pädagogik und Psychologie', 'Keplergebäude, Stiege B, 1. Stock; Stiege C, 2.Stock'); INSERT INTO UniLinz.Institut VALUES (20300, 'Inst. für Volkswirtschaftslehre', 'Keplergebäude, Stiege A, B, C, D, 1. Stock'); INSERT INTO UniLinz.Institut VALUES (20400, 'Inst. für Betriebliche und Regionale Umweltwirtschaft', 'TNF- Turm, 6. Stock'); INSERT INTO UniLinz.Institut VALUES (20500, 'Inst. für Angewandte Statistik (IFAS)', 'Keplergebäude, Stiege A, 2. Stock'); INSERT INTO UniLinz.Institut VALUES (20600, 'Inst. für Philosophie und Wissenschaftstheorie', 'Freistädterstraße 313, 2. Stock'); INSERT INTO UniLinz.Institut VALUES (20700, 'Inst. für Sozial- und Wirtschaftsgeschichte', 'Juridicum, Stiege B, 1. Stock');

170 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.Institut VALUES (20800, 'Inst. für Neuere Geschichte und Zeitgeschichte', 'Juridicum, Stiege B, 1. Stock'); INSERT INTO UniLinz.Institut VALUES (20900, 'Inst. für Handel, Absatz und Marketing', 'Management-Zentrum, Stiege A, 2. Stock'); INSERT INTO UniLinz.Institut VALUES (21000, 'Inst. für Industrie und Fertigungswirtschaft', 'Management- Zentrum, Stiege B, 4. Stock'); INSERT INTO UniLinz.Institut VALUES (21100, 'Inst. für Unternehmensführung', 'Kopfgebäude, 2. und 3. Stock'); INSERT INTO UniLinz.Institut VALUES (21200, 'Inst. für Betriebswirtschaftslehre der gemeinwirtschaftlichen Unternehmen', 'Management-Zentrum, Stiege A, 4. Stock'); INSERT INTO UniLinz.Institut VALUES (21300, 'Inst. für Revisions-, Treuhand- und Rechnungswesen', 'Management- Zentrum, Stiege A und B, 4. Stock'); INSERT INTO UniLinz.Institut VALUES (21400, 'Inst. für Betriebliche Finanzwirtschaft', 'Management-Zentrum, 2. Stock'); INSERT INTO UniLinz.Institut VALUES (21500, 'Inst. für Wirtschaftsinformatik', 'Management-Zentrum, Stiege A und B, 3. Stock; Freistädterstraße 315, 1. OG'); INSERT INTO UniLinz.Institut VALUES (21600, 'Inst. für Internationale Managementstudien', 'Kopfgebäude, 3. Stock'); INSERT INTO UniLinz.Institut VALUES (21700, 'Inst. für Datenverarbeitung in den Sozial- und Wirtschaftswissenschaften', 'Management-Zentrum, Stiege A, 1. und 2. Stock'); INSERT INTO UniLinz.Institut VALUES (21800, 'Inst. für Fachsprachen', 'Management-Zentrum, Stiege B, 1. Stock'); INSERT INTO UniLinz.Institut VALUES (30300, 'Inst. für Algebra, Stochastik und wissensbasierte mathematische Systeme', 'Kopfgebäude, 4. und 7. Stock'); INSERT INTO UniLinz.Institut VALUES (30400, 'Inst. für Symbolisches Rechnen', 'Schloß Hagenberg, A-4232 Hagenberg im Mühlkreis'); INSERT INTO UniLinz.Institut VALUES (31700, 'Inst. für Mikroelektronik', 'Mikroelektronikgebäude'); INSERT INTO UniLinz.Institut VALUES (31800, 'Inst. für Nachrichtentechnik/Informationstechnik', 'VÖEST- Gelände, BG 01, Hochofenstraße 1, 4020 Linz'); INSERT INTO UniLinz.Institut VALUES (31900, 'Inst. für Angewandte Informatik', 'TNF-Turm, 7. Stock'); INSERT INTO UniLinz.Institut VALUES (32000, 'Inst. für Praktische Informatik', 'Physikgebäude, 1. Stock; Freistädterstraße 315, 2. Stock'); INSERT INTO UniLinz.Institut VALUES (32100, 'Inst. für Anwendungsorientierte Wissensverarbeitung', 'TNF-Turm, 7. Stock; Softwarepark Hagenberg, A-4232 Hagenberg im Mühlkreis'); INSERT INTO UniLinz.Institut VALUES (32200, 'Inst. für Technische Informatik und Telematik', 'TNF-Turm, 6. und 9. Stock'); INSERT INTO UniLinz.Institut VALUES (32300, 'Inst. für Informationsverarbeitung und Mikroprozessortechnik (FIM)', 'TNF-Turm, 6. Stock'); INSERT INTO UniLinz.Institut VALUES (32400, 'Inst. für Systemwissenschaften', 'TNF-Turm, 6. und 7. Stock; Freistädterstraße 315, 2. Stock');

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.LVA #

DROP TABLE IF EXISTS UniLinz.LVA;

CREATE TABLE UniLinz.LVA ( LVANr INT(6) UNSIGNED NOT NULL, Titel VARCHAR(120) NOT NULL, StdAnzahl FLOAT(5,2) NOT NULL, ECTSCredits FLOAT(5,2) NOT NULL, LVATyp CHAR(2) NOT NULL,

PRIMARY KEY (LVANr), INDEX Titel (Titel) ) TYPE=InnoDB COMMENT='Lehrveranstaltung Lehrveranstaltungen LVAs';

# Daten

INSERT INTO UniLinz.LVA VALUES (228280, 'Kommunikation Englisch', 2.00, 3.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (228420, 'Kommunikation Englisch', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (228440, 'Kommunikation Englisch', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (228540, 'Sprache, Land, Leute Englisch', 2.00, 3.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (228560, 'Fallstudien Englisch', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (228570, 'Fallstudien Englisch', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (228660, 'Kurs zum Seminar Gastprofessor Englisch', 1.00, 2.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (239219, 'Diplomandenseminar', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (239223, 'Theorie demokratischer Wirtschaftspolitik', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (239247, 'Doktorandenseminar', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (241000, 'Angewandte Marketingforschung', 2.00, 3.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (241001, 'Strategisches Marketing-Management', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (241002, 'Grundlagen Beziehungsmarketing', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (241003, 'Vertiefung Beziehungsmarketing', 2.00, 3.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (241004, 'Diplomandenseminar Marketing', 2.00, 3.00, 'SE');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 171 INSERT INTO UniLinz.LVA VALUES (241005, 'Doktorandenseminar Marketing', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (241006, 'Forschungsseminar', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (241007, 'Projektseminar Angewandtes Marketing', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (241008, 'Intensivierungskurs Angewandte Marketingforschung', 2.00, 4.00, 'IK'); INSERT INTO UniLinz.LVA VALUES (242004, 'Strategisches Personalmanagement - Balanced Scorecard', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (242027, 'Grundlagen des operativen Personalmanagements - Einstiegskurs', 2.00, 3.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (242028, 'Diplomandenseminar Personalwirtschaft', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (242029, 'Dissertantenseminar Personalwirtschaft', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (242108, 'Managementsysteme Führung', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (242236, 'Dissertantenseminar Organisation', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (242244, 'Diplomandenseminar Organisation', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (242257, 'Individuum-Gruppe-Organisation', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (242258, 'Individuum-Gruppe-Organisation', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (242278, 'Organisationaler Wandel', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246001, 'Kommunikationssysteme', 3.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246004, 'Diplomandenseminar', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246009, 'Projektstudium', 6.00, 15.00, 'PJ'); INSERT INTO UniLinz.LVA VALUES (246013, 'Dissertantenseminar', 3.00, 5.00, 'DR'); INSERT INTO UniLinz.LVA VALUES (246024, 'Kommunikationssysteme', 2.00, 2.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246027, 'Ausgewählte Kapitel des Wissensmanagement', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246035, 'Praktikum aus Wissensmanagement', 4.00, 6.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (246100, 'Informationssysteme in Wirtschaft und Verwaltung 1', 2.00, 3.25, 'VO'); INSERT INTO UniLinz.LVA VALUES (246101, 'Management von Informatikprojekten', 2.00, 2.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246108, 'Informationsmanagement', 2.00, 2.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246115, 'Dissertantenseminar', 3.00, 5.00, 'DR'); INSERT INTO UniLinz.LVA VALUES (246123, 'Ausgewählte Gebiete des Information Engineering', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246126, 'Informationsmanagement (Service Level Agreements)', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246129, 'Informationsmanagement (EB-Strategien) Ausgewählte Gebiete des Informationsmanagement', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246154, 'Diplomandenseminar', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246273, 'Dissertantenseminar', 3.00, 5.00, 'DR'); INSERT INTO UniLinz.LVA VALUES (246274, 'Konversatorium Kommunikationssysteme', 3.00, 6.00, 'KO'); INSERT INTO UniLinz.LVA VALUES (246301, 'Datenmodellierung', 2.00, 3.50, 'VO'); INSERT INTO UniLinz.LVA VALUES (246303, 'Ausg. Kap. Datenbank- od. wissensbasierte Systeme', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246304, 'Diplomandenseminar für Wirtschaftsinformatiker und Informatiker', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246307, 'Datenbanksysteme oder wissensbasierte Systeme', 4.00, 6.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (246309, 'Datenbanksysteme und wissensbasierte Systeme', 2.00, 2.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246310, 'Datenbanksysteme und wissensbasierte Systeme', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246311, 'Datenbanksysteme und wissensbasierte Systeme', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246313, 'Dissertantenseminar für Wirtschaftsinformatiker und Informatiker', 3.00, 5.00, 'DR'); INSERT INTO UniLinz.LVA VALUES (246314, 'Datenmodellierung', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246315, 'Datenmodellierung', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246317, 'EC-Technology Datenbanksysteme und Wissensbasierte Systeme: XML und Datenbanken', 4.00, 6.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (246318, 'Datenmodellierung', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246321, 'Datenmodellierung', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246326, 'Datenmodellierung', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246328, 'Datenmodellierung', 2.00, 5.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246331, 'Data Warehousing & Mining', 4.00, 6.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (246332, 'Spez. Kap. aus Informationssys.: Data Mining', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246333, 'Spez. Kap. aus Informationssys.: Data Mining', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246334, 'Spez. Kap. aus Informationssys.: Data Warehousing', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246345, 'Projektstudium', 6.00, 15.00, 'PJ'); INSERT INTO UniLinz.LVA VALUES (246500, 'Grundlagen des Software Engineering', 2.00, 2.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (246501, 'Service Engineering', 2.00, 2.50, 'VU'); INSERT INTO UniLinz.LVA VALUES (246502, 'Ausgewählte Kapitel des Software Engineering', 2.00, 4.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246503, 'Vorlesung Algorithmen', 3.00, 4.50, 'VO'); INSERT INTO UniLinz.LVA VALUES (246504, 'Projektstudium aus ABWL (4h)', 4.00, 10.00, 'PJ'); INSERT INTO UniLinz.LVA VALUES (246505, 'Übung Algorithmen 2 (Gruppe 1)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246506, 'Übung Algorithmen 2 (Gruppe 2)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246507, 'Übung Algorithmen 2 (Gruppe 3)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246508, 'Übung Algorithmen 2 (Gruppe 4)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246509, 'Software Engineering (Gruppe 2)', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246510, 'Diplomandenseminar für Wirtschaftsinformatiker und Informatiker', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (246511, 'Software Engineering', 4.00, 6.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (246512, 'Software Engineering', 4.00, 6.00, 'PR');

172 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.LVA VALUES (246513, 'Software Engineering (Gruppe 1)', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246514, 'Projektstudium', 6.00, 15.00, 'PJ'); INSERT INTO UniLinz.LVA VALUES (246515, 'Übung Algorithmen 1', 2.00, 4.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246516, 'Übung Algorithmen 1', 2.00, 4.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246519, 'Software Engineering', 4.00, 6.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (246520, 'Übung Algorithmen 2 (Gruppe 5)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246521, 'Software Engineering', 4.00, 6.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (246522, 'Doktorandenseminar für Wirtschaftsinformatiker und Informatiker', 3.00, 6.00, 'DR'); INSERT INTO UniLinz.LVA VALUES (246525, 'Übung Algorithmen 1', 2.00, 4.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246526, 'Übung Algorithmen 1', 2.00, 4.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246527, 'Übung Algorithmen 1', 2.00, 4.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246528, 'Übung Algorithmen 1', 2.00, 4.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246531, 'Übung Algorithmen 2 (Gruppe 6)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246532, 'Übung Algorithmen 2 (Gruppe 7)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246534, 'Übung Algorithmen 2 (Gruppe 8)', 1.00, 2.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246543, 'Software Engineering (Gruppe 4)', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (246544, 'Software Engineering (Gruppe 3)', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (247004, 'Strategisches Management: Grundlagen', 2.00, 3.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (247007, 'Modelle des Strategischen Managements', 4.00, 8.00, 'IK'); INSERT INTO UniLinz.LVA VALUES (247017, 'Diplomandenseminar Strategisches Management', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (247025, 'Projektstudien: Strategieprozess', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (247100, 'Strategie und Marketing', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (247103, 'Strategie und Marketing', 2.00, 4.00, 'KS'); INSERT INTO UniLinz.LVA VALUES (247110, 'Strategie und Marketing', 1.00, 2.00, 'IK'); INSERT INTO UniLinz.LVA VALUES (247124, 'Strategie und Marketing', 1.00, 2.00, 'IK'); INSERT INTO UniLinz.LVA VALUES (311143, 'Praktikum Angewandte Statistik - Methoden des OR (Operation Research)', 2.00, 3.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (312514, 'Operations Research I', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (312516, 'Operations Research I (G2)', 1.00, 1.50, 'UE'); INSERT INTO UniLinz.LVA VALUES (312529, 'Operations Research I (G4)', 1.00, 1.50, 'UE'); INSERT INTO UniLinz.LVA VALUES (312530, 'Modellbildung und Simulation', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (312531, 'Modellbildung und Simulation', 1.00, 1.50, 'UE'); INSERT INTO UniLinz.LVA VALUES (338000, 'Softwareengineering 2', 2.00, 3.00, 'KV'); INSERT INTO UniLinz.LVA VALUES (338004, 'Algorithmen und Datenstrukturen 2', 3.00, 4.50, 'KV'); INSERT INTO UniLinz.LVA VALUES (338006, 'Embedded Systems', 2.00, 3.00, 'KV'); INSERT INTO UniLinz.LVA VALUES (338007, 'Dissertantenstunde für Informatiker', 3.00, 4.50, 'PV'); INSERT INTO UniLinz.LVA VALUES (338008, 'Telekooperation', 3.00, 4.50, 'KV'); INSERT INTO UniLinz.LVA VALUES (338009, 'Diplomandenseminar 1', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (338015, 'Projektpraktikum', 10.00, 15.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (338019, 'Diplomandenseminar 2', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (338131, 'Softwareentwicklung 1', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (338205, 'Einführung in die Informatik für Wirtschaftsinformatiker', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (338212, 'Dissertantenstunde für Informatiker', 3.00, 4.50, 'PV'); INSERT INTO UniLinz.LVA VALUES (338215, 'Praktische Informatik I - Algorithmen', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (338236, 'Mensch-Maschine-Kommunikation', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (338238, 'Prinzipien objektorientierter Programmiersprachen', 1.00, 1.50, 'VO'); INSERT INTO UniLinz.LVA VALUES (350000, 'Informatik in Wirtschaft und Verwaltung', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (350003, 'Dissertantenseminar', 3.00, 4.50, 'SE'); INSERT INTO UniLinz.LVA VALUES (350100, 'Projektpraktikum CSCW', 10.00, 15.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (350102, 'Informationssysteme 3', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (350106, 'Angewandte Informatik in Wirtschaft und Verwaltung', 2.00, 3.00, 'PV'); INSERT INTO UniLinz.LVA VALUES (350109, 'Projektpraktikum Informationssysteme CSCW', 10.00, 15.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (350117, 'Spezielle Kapitel aus Telekooperation CSCW', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (350119, 'Gestaltung von Benutzerschnittstellen', 2.00, 3.00, 'KV'); INSERT INTO UniLinz.LVA VALUES (350124, 'Seminar aus Informationssysteme', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (350131, 'Diplomandenseminar 1 aus Angewandter Informatik', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (350132, 'Diplomandenseminar 2', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (351001, 'Informationssysteme 1', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (351002, 'Informationssysteme 1', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (351003, 'Informationssysteme 1', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (351004, 'Informationssysteme 1', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (351005, 'Informationssysteme 1', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (351006, 'Diplomandenseminar 1 - Anwendungsorientierte Wissensverarbeitung', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (351007, 'Diplomandenseminar 2', 3.00, 5.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (351008, 'Dissertantenseminar 1', 3.00, 4.50, 'SE'); INSERT INTO UniLinz.LVA VALUES (351009, 'Dissertantenseminar 2', 3.00, 4.50, 'SE'); INSERT INTO UniLinz.LVA VALUES (351012, 'Informationssysteme', 5.00, 0.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (351013, 'Projektpraktikum Informationssysteme', 10.00, 15.00, 'PR'); INSERT INTO UniLinz.LVA VALUES (351014, 'Seminar: Informationssysteme', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (351015, 'Informationssysteme für WIN', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (351030, 'Seminar: Informationssysteme', 2.00, 3.00, 'SE');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 173 INSERT INTO UniLinz.LVA VALUES (351031, 'Projektstudium Informationssysteme WIN', 6.00, 9.00, 'PJ'); INSERT INTO UniLinz.LVA VALUES (351036, 'Web-Engineering', 2.00, 3.00, 'KV'); INSERT INTO UniLinz.LVA VALUES (351037, 'Spezielle Kapitel aus Informationssysteme E-Commerce', 1.00, 1.50, 'VO'); INSERT INTO UniLinz.LVA VALUES (351044, 'Informationssysteme 1', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (351047, 'Anwendungsorientierte Wissensverarbeitung', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (351048, 'Datenmodellierung', 4.00, 6.00, 'KV'); INSERT INTO UniLinz.LVA VALUES (351049, 'Spezielle Kapitel aus Wissensverarbeitung', 2.00, 3.00, 'SE'); INSERT INTO UniLinz.LVA VALUES (351050, 'Information Retrieval und Hypermediatechniken', 3.00, 4.50, 'KV'); INSERT INTO UniLinz.LVA VALUES (351052, 'Spezielle Kapitel aus Informationssysteme: E-Commerce', 2.00, 3.00, 'VO'); INSERT INTO UniLinz.LVA VALUES (351060, 'Query Techniques for Information Systems', 3.00, 4.50, 'SE'); INSERT INTO UniLinz.LVA VALUES (351061, 'Informationssysteme in E-Commerce Applikationen', 3.00, 4.50, 'SE'); INSERT INTO UniLinz.LVA VALUES (352174, 'Technische Informatik 1', 1.00, 1.50, 'UE'); INSERT INTO UniLinz.LVA VALUES (352186, 'Technische Informatik 3', 2.00, 3.00, 'UE'); INSERT INTO UniLinz.LVA VALUES (700000, 'Cultural Sensivity Training', 4.00, 2.00, 'UE');

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.LVALeiter #

DROP TABLE IF EXISTS UniLinz.LVALeiter;

CREATE TABLE UniLinz.LVALeiter ( LVANr INT(6) UNSIGNED NOT NULL, LVALeiter INT(4) UNSIGNED NOT NULL,

INDEX LVANr (LVANr), INDEX LVALeiter (LVALeiter), FOREIGN KEY (LVANr) REFERENCES LVA(LVANr), FOREIGN KEY (LVALeiter) REFERENCES WissPersonal(PersNr) ) TYPE=InnoDB;

# Daten

INSERT INTO UniLinz.LVALeiter VALUES (228280, 1044); INSERT INTO UniLinz.LVALeiter VALUES (228420, 1044); INSERT INTO UniLinz.LVALeiter VALUES (228440, 1044); INSERT INTO UniLinz.LVALeiter VALUES (228540, 1044); INSERT INTO UniLinz.LVALeiter VALUES (228560, 1044); INSERT INTO UniLinz.LVALeiter VALUES (228570, 1053); INSERT INTO UniLinz.LVALeiter VALUES (228660, 1053); INSERT INTO UniLinz.LVALeiter VALUES (239219, 1169); INSERT INTO UniLinz.LVALeiter VALUES (239223, 1169); INSERT INTO UniLinz.LVALeiter VALUES (239247, 1169); INSERT INTO UniLinz.LVALeiter VALUES (241000, 1221); INSERT INTO UniLinz.LVALeiter VALUES (241001, 1221); INSERT INTO UniLinz.LVALeiter VALUES (241002, 1213); INSERT INTO UniLinz.LVALeiter VALUES (241003, 1221); INSERT INTO UniLinz.LVALeiter VALUES (241004, 1221); INSERT INTO UniLinz.LVALeiter VALUES (241005, 1221); INSERT INTO UniLinz.LVALeiter VALUES (241006, 1221); INSERT INTO UniLinz.LVALeiter VALUES (241006, 1084); INSERT INTO UniLinz.LVALeiter VALUES (241007, 1221); INSERT INTO UniLinz.LVALeiter VALUES (241007, 1099); INSERT INTO UniLinz.LVALeiter VALUES (241008, 1213); INSERT INTO UniLinz.LVALeiter VALUES (242004, 1021); INSERT INTO UniLinz.LVALeiter VALUES (242027, 1021); INSERT INTO UniLinz.LVALeiter VALUES (242028, 1021); INSERT INTO UniLinz.LVALeiter VALUES (242029, 1021); INSERT INTO UniLinz.LVALeiter VALUES (242108, 1021); INSERT INTO UniLinz.LVALeiter VALUES (242236, 1149); INSERT INTO UniLinz.LVALeiter VALUES (242244, 1149); INSERT INTO UniLinz.LVALeiter VALUES (242257, 1149); INSERT INTO UniLinz.LVALeiter VALUES (242258, 1021); INSERT INTO UniLinz.LVALeiter VALUES (242258, 1149); INSERT INTO UniLinz.LVALeiter VALUES (242278, 1149); INSERT INTO UniLinz.LVALeiter VALUES (246001, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246004, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246009, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246013, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246024, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246027, 1022); INSERT INTO UniLinz.LVALeiter VALUES (246027, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246035, 1179);

174 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.LVALeiter VALUES (246100, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246101, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246108, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246115, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246123, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246126, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246129, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246154, 1066); INSERT INTO UniLinz.LVALeiter VALUES (246273, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246274, 1179); INSERT INTO UniLinz.LVALeiter VALUES (246301, 1171); INSERT INTO UniLinz.LVALeiter VALUES (246303, 1171); INSERT INTO UniLinz.LVALeiter VALUES (246304, 1171); INSERT INTO UniLinz.LVALeiter VALUES (246307, 1190); INSERT INTO UniLinz.LVALeiter VALUES (246309, 1171); INSERT INTO UniLinz.LVALeiter VALUES (246310, 1142); INSERT INTO UniLinz.LVALeiter VALUES (246311, 1142); INSERT INTO UniLinz.LVALeiter VALUES (246313, 1171); INSERT INTO UniLinz.LVALeiter VALUES (246314, 1142); INSERT INTO UniLinz.LVALeiter VALUES (246315, 1142); INSERT INTO UniLinz.LVALeiter VALUES (246317, 1017); INSERT INTO UniLinz.LVALeiter VALUES (246318, 1104); INSERT INTO UniLinz.LVALeiter VALUES (246321, 1104); INSERT INTO UniLinz.LVALeiter VALUES (246326, 1017); INSERT INTO UniLinz.LVALeiter VALUES (246328, 1017); INSERT INTO UniLinz.LVALeiter VALUES (246331, 1190); INSERT INTO UniLinz.LVALeiter VALUES (246332, 1142); INSERT INTO UniLinz.LVALeiter VALUES (246333, 1190); INSERT INTO UniLinz.LVALeiter VALUES (246334, 1142); INSERT INTO UniLinz.LVALeiter VALUES (246345, 1171); INSERT INTO UniLinz.LVALeiter VALUES (246500, 1138); INSERT INTO UniLinz.LVALeiter VALUES (246501, 1186); INSERT INTO UniLinz.LVALeiter VALUES (246502, 1138); INSERT INTO UniLinz.LVALeiter VALUES (246503, 1138); INSERT INTO UniLinz.LVALeiter VALUES (246504, 1138); INSERT INTO UniLinz.LVALeiter VALUES (246504, 1225); INSERT INTO UniLinz.LVALeiter VALUES (246505, 1052); INSERT INTO UniLinz.LVALeiter VALUES (246506, 1052); INSERT INTO UniLinz.LVALeiter VALUES (246507, 1052); INSERT INTO UniLinz.LVALeiter VALUES (246508, 1052); INSERT INTO UniLinz.LVALeiter VALUES (246509, 1136); INSERT INTO UniLinz.LVALeiter VALUES (246510, 1138); INSERT INTO UniLinz.LVALeiter VALUES (246511, 1157); INSERT INTO UniLinz.LVALeiter VALUES (246512, 1130); INSERT INTO UniLinz.LVALeiter VALUES (246513, 1136); INSERT INTO UniLinz.LVALeiter VALUES (246514, 1138); INSERT INTO UniLinz.LVALeiter VALUES (246515, 1132); INSERT INTO UniLinz.LVALeiter VALUES (246516, 1132); INSERT INTO UniLinz.LVALeiter VALUES (246519, 1210); INSERT INTO UniLinz.LVALeiter VALUES (246520, 1157); INSERT INTO UniLinz.LVALeiter VALUES (246521, 1136); INSERT INTO UniLinz.LVALeiter VALUES (246522, 1138); INSERT INTO UniLinz.LVALeiter VALUES (246525, 1186); INSERT INTO UniLinz.LVALeiter VALUES (246526, 1186); INSERT INTO UniLinz.LVALeiter VALUES (246527, 1052); INSERT INTO UniLinz.LVALeiter VALUES (246528, 1052); INSERT INTO UniLinz.LVALeiter VALUES (246531, 1157); INSERT INTO UniLinz.LVALeiter VALUES (246532, 1157); INSERT INTO UniLinz.LVALeiter VALUES (246534, 1157); INSERT INTO UniLinz.LVALeiter VALUES (246543, 1210); INSERT INTO UniLinz.LVALeiter VALUES (246544, 1210); INSERT INTO UniLinz.LVALeiter VALUES (247004, 1185); INSERT INTO UniLinz.LVALeiter VALUES (247007, 1185); INSERT INTO UniLinz.LVALeiter VALUES (247007, 1110); INSERT INTO UniLinz.LVALeiter VALUES (247017, 1185); INSERT INTO UniLinz.LVALeiter VALUES (247025, 1149); INSERT INTO UniLinz.LVALeiter VALUES (247100, 1185); INSERT INTO UniLinz.LVALeiter VALUES (247100, 1084); INSERT INTO UniLinz.LVALeiter VALUES (247103, 1185); INSERT INTO UniLinz.LVALeiter VALUES (247103, 1213); INSERT INTO UniLinz.LVALeiter VALUES (247110, 1185); INSERT INTO UniLinz.LVALeiter VALUES (247124, 1185); INSERT INTO UniLinz.LVALeiter VALUES (311143, 1170); INSERT INTO UniLinz.LVALeiter VALUES (312514, 1170); INSERT INTO UniLinz.LVALeiter VALUES (312516, 1170); INSERT INTO UniLinz.LVALeiter VALUES (312529, 1170);

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 175 INSERT INTO UniLinz.LVALeiter VALUES (312530, 1170); INSERT INTO UniLinz.LVALeiter VALUES (312531, 1170); INSERT INTO UniLinz.LVALeiter VALUES (338000, 1020); INSERT INTO UniLinz.LVALeiter VALUES (338000, 1116); INSERT INTO UniLinz.LVALeiter VALUES (338004, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338004, 1116); INSERT INTO UniLinz.LVALeiter VALUES (338006, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338006, 1200); INSERT INTO UniLinz.LVALeiter VALUES (338007, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338008, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338008, 1200); INSERT INTO UniLinz.LVALeiter VALUES (338009, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338009, 1020); INSERT INTO UniLinz.LVALeiter VALUES (338015, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338019, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338019, 1020); INSERT INTO UniLinz.LVALeiter VALUES (338131, 1042); INSERT INTO UniLinz.LVALeiter VALUES (338205, 1020); INSERT INTO UniLinz.LVALeiter VALUES (338212, 1020); INSERT INTO UniLinz.LVALeiter VALUES (338215, 1020); INSERT INTO UniLinz.LVALeiter VALUES (338236, 1020); INSERT INTO UniLinz.LVALeiter VALUES (338238, 1020); INSERT INTO UniLinz.LVALeiter VALUES (350000, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350003, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350100, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350102, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350106, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350109, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350117, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350119, 1189); INSERT INTO UniLinz.LVALeiter VALUES (350124, 1189); INSERT INTO UniLinz.LVALeiter VALUES (350131, 1197); INSERT INTO UniLinz.LVALeiter VALUES (350132, 1197); INSERT INTO UniLinz.LVALeiter VALUES (351001, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351002, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351003, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351004, 1220); INSERT INTO UniLinz.LVALeiter VALUES (351005, 1220); INSERT INTO UniLinz.LVALeiter VALUES (351006, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351006, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351006, 1220); INSERT INTO UniLinz.LVALeiter VALUES (351007, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351007, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351008, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351008, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351009, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351012, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351012, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351012, 1220); INSERT INTO UniLinz.LVALeiter VALUES (351013, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351014, 1220); INSERT INTO UniLinz.LVALeiter VALUES (351015, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351030, 1195); INSERT INTO UniLinz.LVALeiter VALUES (351031, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351031, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351036, 1144); INSERT INTO UniLinz.LVALeiter VALUES (351037, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351044, 1124); INSERT INTO UniLinz.LVALeiter VALUES (351047, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351048, 1220); INSERT INTO UniLinz.LVALeiter VALUES (351049, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351050, 1144); INSERT INTO UniLinz.LVALeiter VALUES (351050, 1124); INSERT INTO UniLinz.LVALeiter VALUES (351052, 1204); INSERT INTO UniLinz.LVALeiter VALUES (351060, 1100); INSERT INTO UniLinz.LVALeiter VALUES (351061, 1220); INSERT INTO UniLinz.LVALeiter VALUES (352174, 1170); INSERT INTO UniLinz.LVALeiter VALUES (352174, 1163); INSERT INTO UniLinz.LVALeiter VALUES (352186, 1170); INSERT INTO UniLinz.LVALeiter VALUES (352186, 1101); INSERT INTO UniLinz.LVALeiter VALUES (700000, 1053); INSERT INTO UniLinz.LVALeiter VALUES (700000, 1044); INSERT INTO UniLinz.LVALeiter VALUES (700000, 1045); INSERT INTO UniLinz.LVALeiter VALUES (700000, 1068);

176 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken # Definition und Testdaten-Inserts für Tabelle: # # UniLinz.InstMitglied #

DROP TABLE IF EXISTS UniLinz.InstMitglied;

CREATE TABLE UniLinz.InstMitglied ( PersNr INT(4) UNSIGNED NOT NULL, InstNr INT(5) UNSIGNED NOT NULL, Position ENUM('InstVorstand', 'InstMitglied') NOT NULL, TelefonNr VARCHAR(20) NULL,

INDEX PersNr (PersNr), INDEX InstNr (InstNr), FOREIGN KEY (PersNr) REFERENCES WissPersonal(PersNr), FOREIGN KEY (InstNr) REFERENCES Institut(InstNr) ) TYPE=InnoDB;

# Daten

INSERT INTO UniLinz.InstMitglied VALUES (1032, 20200, '2', '-'); INSERT INTO UniLinz.InstMitglied VALUES (1042, 32000, '1', '-'); INSERT INTO UniLinz.InstMitglied VALUES (1104, 21500, '2', '-'); INSERT INTO UniLinz.InstMitglied VALUES (1112, 20300, '2', '-'); INSERT INTO UniLinz.InstMitglied VALUES (1189, 31900, '2', '-'); INSERT INTO UniLinz.InstMitglied VALUES (1197, 32100, '2', '?'); INSERT INTO UniLinz.InstMitglied VALUES (1124, 32100, '2', '07236-3343-765'); INSERT INTO UniLinz.InstMitglied VALUES (1144, 32100, '2', '07236-3343-770'); INSERT INTO UniLinz.InstMitglied VALUES (1072, 21700, '2', '3214'); INSERT INTO UniLinz.InstMitglied VALUES (1006, 20800, '2', '3366'); INSERT INTO UniLinz.InstMitglied VALUES (1179, 21500, '2', '7101'); INSERT INTO UniLinz.InstMitglied VALUES (1008, 21500, '2', '7103'); INSERT INTO UniLinz.InstMitglied VALUES (1184, 21500, '2', '7103'); INSERT INTO UniLinz.InstMitglied VALUES (1114, 32000, '2', '7130'); INSERT INTO UniLinz.InstMitglied VALUES (1019, 32000, '2', '7133'); INSERT INTO UniLinz.InstMitglied VALUES (1185, 21600, '2', '7140'); INSERT INTO UniLinz.InstMitglied VALUES (1110, 21600, '2', '7142'); INSERT INTO UniLinz.InstMitglied VALUES (1180, 20600, '2', '7164'); INSERT INTO UniLinz.InstMitglied VALUES (1050, 20600, '1', '7190'); INSERT INTO UniLinz.InstMitglied VALUES (1047, 20600, '2', '7192'); INSERT INTO UniLinz.InstMitglied VALUES (1022, 20600, '2', '7193'); INSERT INTO UniLinz.InstMitglied VALUES (1169, 20300, '2', '8210'); INSERT INTO UniLinz.InstMitglied VALUES (1145, 20300, '2', '8213'); INSERT INTO UniLinz.InstMitglied VALUES (1183, 20300, '2', '8214'); INSERT INTO UniLinz.InstMitglied VALUES (1174, 20300, '2', '8215'); INSERT INTO UniLinz.InstMitglied VALUES (1010, 20300, '2', '8219'); INSERT INTO UniLinz.InstMitglied VALUES (1004, 20200, '1', '8221'); INSERT INTO UniLinz.InstMitglied VALUES (1036, 20200, '2', '8223'); INSERT INTO UniLinz.InstMitglied VALUES (1097, 20200, '2', '8224'); INSERT INTO UniLinz.InstMitglied VALUES (1125, 20700, '2', '8231'); INSERT INTO UniLinz.InstMitglied VALUES (1102, 20300, '2', '8233'); INSERT INTO UniLinz.InstMitglied VALUES (1217, 20300, '2', '8236'); INSERT INTO UniLinz.InstMitglied VALUES (1091, 20300, '1', '8239'); INSERT INTO UniLinz.InstMitglied VALUES (1208, 20300, '2', '8240'); INSERT INTO UniLinz.InstMitglied VALUES (1059, 20100, '2', '8242'); INSERT INTO UniLinz.InstMitglied VALUES (1025, 20300, '2', '8248'); INSERT INTO UniLinz.InstMitglied VALUES (1202, 20100, '2', '8249'); INSERT INTO UniLinz.InstMitglied VALUES (1224, 20100, '2', '8250'); INSERT INTO UniLinz.InstMitglied VALUES (1061, 20500, '1', '8280'); INSERT INTO UniLinz.InstMitglied VALUES (1203, 20500, '2', '8282'); INSERT INTO UniLinz.InstMitglied VALUES (1040, 20100, '2', '8286'); INSERT INTO UniLinz.InstMitglied VALUES (1148, 20100, '2', '8287'); INSERT INTO UniLinz.InstMitglied VALUES (1107, 20100, '2', '8288'); INSERT INTO UniLinz.InstMitglied VALUES (1074, 20100, '2', '8290'); INSERT INTO UniLinz.InstMitglied VALUES (1051, 20100, '2', '8292'); INSERT INTO UniLinz.InstMitglied VALUES (1147, 20500, '2', '8294'); INSERT INTO UniLinz.InstMitglied VALUES (1117, 20100, '2', '8296'); INSERT INTO UniLinz.InstMitglied VALUES (1108, 20100, '2', '8298'); INSERT INTO UniLinz.InstMitglied VALUES (1003, 20300, '2', '8332'); INSERT INTO UniLinz.InstMitglied VALUES (1060, 20300, '2', '8333'); INSERT INTO UniLinz.InstMitglied VALUES (1028, 20300, '2', '8360'); INSERT INTO UniLinz.InstMitglied VALUES (1113, 20100, '2', '8361'); INSERT INTO UniLinz.InstMitglied VALUES (1123, 20300, '2', '8364'); INSERT INTO UniLinz.InstMitglied VALUES (1079, 32300, '2', '8433'); INSERT INTO UniLinz.InstMitglied VALUES (1150, 32300, '2', '8437');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 177 INSERT INTO UniLinz.InstMitglied VALUES (1115, 32300, '1', '8440'); INSERT INTO UniLinz.InstMitglied VALUES (1038, 32300, '2', '8442'); INSERT INTO UniLinz.InstMitglied VALUES (1020, 32000, '2', '8521'); INSERT INTO UniLinz.InstMitglied VALUES (1116, 32000, '2', '8526'); INSERT INTO UniLinz.InstMitglied VALUES (1069, 20100, '2', '8572'); INSERT INTO UniLinz.InstMitglied VALUES (1055, 20100, '2', '8574'); INSERT INTO UniLinz.InstMitglied VALUES (1223, 20100, '1', '8575'); INSERT INTO UniLinz.InstMitglied VALUES (1205, 20200, '2', '8577'); INSERT INTO UniLinz.InstMitglied VALUES (1023, 20200, '2', '8578'); INSERT INTO UniLinz.InstMitglied VALUES (1156, 20200, '2', '8579'); INSERT INTO UniLinz.InstMitglied VALUES (1016, 20200, '2', '8580'); INSERT INTO UniLinz.InstMitglied VALUES (1178, 20200, '2', '8582'); INSERT INTO UniLinz.InstMitglied VALUES (1153, 20300, '2', '8584'); INSERT INTO UniLinz.InstMitglied VALUES (1073, 20100, '2', '8587'); INSERT INTO UniLinz.InstMitglied VALUES (1127, 20300, '2', '8593'); INSERT INTO UniLinz.InstMitglied VALUES (1086, 20200, '2', '8642'); INSERT INTO UniLinz.InstMitglied VALUES (1029, 20300, '2', '8706'); INSERT INTO UniLinz.InstMitglied VALUES (1204, 32100, '1', '8791'); INSERT INTO UniLinz.InstMitglied VALUES (1168, 21500, '2', '8803'); INSERT INTO UniLinz.InstMitglied VALUES (1119, 20200, '2', '8806'); INSERT INTO UniLinz.InstMitglied VALUES (1054, 20200, '2', '8807'); INSERT INTO UniLinz.InstMitglied VALUES (1090, 20200, '2', '8808'); INSERT INTO UniLinz.InstMitglied VALUES (1167, 20200, '2', '8828'); INSERT INTO UniLinz.InstMitglied VALUES (1118, 20200, '2', '8829'); INSERT INTO UniLinz.InstMitglied VALUES (1140, 20400, '2', '8830'); INSERT INTO UniLinz.InstMitglied VALUES (1062, 20400, '2', '8831'); INSERT INTO UniLinz.InstMitglied VALUES (1141, 20400, '2', '8831'); INSERT INTO UniLinz.InstMitglied VALUES (1109, 20400, '1', '8834'); INSERT INTO UniLinz.InstMitglied VALUES (1092, 20400, '2', '8835'); INSERT INTO UniLinz.InstMitglied VALUES (1143, 20400, '2', '8836'); INSERT INTO UniLinz.InstMitglied VALUES (1173, 20200, '2', '8837'); INSERT INTO UniLinz.InstMitglied VALUES (1065, 20800, '1', '8842'); INSERT INTO UniLinz.InstMitglied VALUES (1159, 20700, '1', '8844'); INSERT INTO UniLinz.InstMitglied VALUES (1098, 20700, '2', '8847'); INSERT INTO UniLinz.InstMitglied VALUES (1080, 20700, '2', '8848'); INSERT INTO UniLinz.InstMitglied VALUES (1014, 32400, '2', '8849'); INSERT INTO UniLinz.InstMitglied VALUES (1137, 32400, '2', '8851'); INSERT INTO UniLinz.InstMitglied VALUES (1081, 20800, '2', '8856'); INSERT INTO UniLinz.InstMitglied VALUES (1037, 20800, '2', '8859'); INSERT INTO UniLinz.InstMitglied VALUES (1030, 32400, '2', '8866'); INSERT INTO UniLinz.InstMitglied VALUES (1058, 32400, '2', '8867'); INSERT INTO UniLinz.InstMitglied VALUES (1071, 32400, '2', '8873'); INSERT INTO UniLinz.InstMitglied VALUES (1082, 31900, '2', '8879'); INSERT INTO UniLinz.InstMitglied VALUES (1197, 31900, '1', '8881'); INSERT INTO UniLinz.InstMitglied VALUES (1152, 31900, '2', '8883'); INSERT INTO UniLinz.InstMitglied VALUES (1201, 32200, '1', '8887'); INSERT INTO UniLinz.InstMitglied VALUES (1100, 32100, '2', '8890'); INSERT INTO UniLinz.InstMitglied VALUES (1139, 32400, '2', '8894'); INSERT INTO UniLinz.InstMitglied VALUES (1175, 32400, '2', '8895'); INSERT INTO UniLinz.InstMitglied VALUES (1131, 32400, '1', '8896'); INSERT INTO UniLinz.InstMitglied VALUES (1162, 32400, '2', '8898'); INSERT INTO UniLinz.InstMitglied VALUES (1096, 21100, '2', '9111'); INSERT INTO UniLinz.InstMitglied VALUES (1146, 21100, '2', '9111'); INSERT INTO UniLinz.InstMitglied VALUES (1077, 21100, '2', '9112'); INSERT INTO UniLinz.InstMitglied VALUES (1046, 21100, '2', '9113'); INSERT INTO UniLinz.InstMitglied VALUES (1089, 21100, '2', '9113'); INSERT INTO UniLinz.InstMitglied VALUES (1021, 21100, '1', '9115'); INSERT INTO UniLinz.InstMitglied VALUES (1045, 21100, '2', '9125'); INSERT INTO UniLinz.InstMitglied VALUES (1188, 21600, '2', '9126'); INSERT INTO UniLinz.InstMitglied VALUES (1105, 21100, '2', '9127'); INSERT INTO UniLinz.InstMitglied VALUES (1035, 20500, '2', '9128'); INSERT INTO UniLinz.InstMitglied VALUES (1007, 21600, '2', '9129'); INSERT INTO UniLinz.InstMitglied VALUES (1076, 21100, '2', '9130'); INSERT INTO UniLinz.InstMitglied VALUES (1011, 21100, '2', '9133'); INSERT INTO UniLinz.InstMitglied VALUES (1129, 21100, '2', '9135'); INSERT INTO UniLinz.InstMitglied VALUES (1187, 21100, '2', '9136'); INSERT INTO UniLinz.InstMitglied VALUES (1128, 21400, '1', '9137'); INSERT INTO UniLinz.InstMitglied VALUES (1166, 30300, '2', '9145'); INSERT INTO UniLinz.InstMitglied VALUES (1211, 30300, '1', '9150'); INSERT INTO UniLinz.InstMitglied VALUES (1088, 30300, '2', '9151'); INSERT INTO UniLinz.InstMitglied VALUES (1135, 30300, '2', '9152'); INSERT INTO UniLinz.InstMitglied VALUES (1002, 30300, '2', '9154'); INSERT INTO UniLinz.InstMitglied VALUES (1048, 30300, '2', '9155'); INSERT INTO UniLinz.InstMitglied VALUES (1158, 30300, '2', '9195'); INSERT INTO UniLinz.InstMitglied VALUES (1001, 32400, '2', '9200'); INSERT INTO UniLinz.InstMitglied VALUES (1101, 32200, '2', '9228');

178 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.InstMitglied VALUES (1170, 32200, '2', '9235'); INSERT INTO UniLinz.InstMitglied VALUES (1195, 32100, '2', '9294'); INSERT INTO UniLinz.InstMitglied VALUES (1191, 31700, '1', '9300'); INSERT INTO UniLinz.InstMitglied VALUES (1093, 31700, '2', '9303'); INSERT INTO UniLinz.InstMitglied VALUES (1034, 31700, '2', '9304'); INSERT INTO UniLinz.InstMitglied VALUES (1181, 31800, '2', '9304'); INSERT INTO UniLinz.InstMitglied VALUES (1015, 31700, '2', '9305'); INSERT INTO UniLinz.InstMitglied VALUES (1134, 21700, '1', '9346'); INSERT INTO UniLinz.InstMitglied VALUES (1043, 21700, '2', '9348'); INSERT INTO UniLinz.InstMitglied VALUES (1221, 20900, '1', '9401'); INSERT INTO UniLinz.InstMitglied VALUES (1031, 20900, '2', '9403'); INSERT INTO UniLinz.InstMitglied VALUES (1099, 20900, '2', '9407'); INSERT INTO UniLinz.InstMitglied VALUES (1084, 20900, '2', '9410'); INSERT INTO UniLinz.InstMitglied VALUES (1213, 20900, '2', '9411'); INSERT INTO UniLinz.InstMitglied VALUES (1018, 21400, '2', '9420'); INSERT INTO UniLinz.InstMitglied VALUES (1198, 20100, '2', '9428'); INSERT INTO UniLinz.InstMitglied VALUES (1138, 21500, '1', '9431'); INSERT INTO UniLinz.InstMitglied VALUES (1210, 21500, '2', '9434'); INSERT INTO UniLinz.InstMitglied VALUES (1157, 21500, '2', '9435'); INSERT INTO UniLinz.InstMitglied VALUES (1136, 21500, '2', '9436'); INSERT INTO UniLinz.InstMitglied VALUES (1186, 21500, '2', '9437'); INSERT INTO UniLinz.InstMitglied VALUES (1130, 21500, '2', '9439'); INSERT INTO UniLinz.InstMitglied VALUES (1052, 21500, '2', '9445'); INSERT INTO UniLinz.InstMitglied VALUES (1063, 21100, '2', '9447'); INSERT INTO UniLinz.InstMitglied VALUES (1192, 21500, '2', '9453'); INSERT INTO UniLinz.InstMitglied VALUES (1066, 21500, '2', '9455'); INSERT INTO UniLinz.InstMitglied VALUES (1164, 21200, '1', '9461'); INSERT INTO UniLinz.InstMitglied VALUES (1085, 21200, '2', '9462'); INSERT INTO UniLinz.InstMitglied VALUES (1196, 21000, '2', '9463'); INSERT INTO UniLinz.InstMitglied VALUES (1222, 21000, '1', '9464'); INSERT INTO UniLinz.InstMitglied VALUES (1106, 21000, '2', '9466'); INSERT INTO UniLinz.InstMitglied VALUES (1149, 21600, '1', '9469'); INSERT INTO UniLinz.InstMitglied VALUES (1190, 21500, '2', '9473'); INSERT INTO UniLinz.InstMitglied VALUES (1132, 21500, '2', '9474'); INSERT INTO UniLinz.InstMitglied VALUES (1171, 21500, '2', '9480'); INSERT INTO UniLinz.InstMitglied VALUES (1111, 21300, '2', '9481'); INSERT INTO UniLinz.InstMitglied VALUES (1041, 21300, '2', '9483'); INSERT INTO UniLinz.InstMitglied VALUES (1182, 21300, '1', '9486'); INSERT INTO UniLinz.InstMitglied VALUES (1064, 21300, '2', '9487'); INSERT INTO UniLinz.InstMitglied VALUES (1056, 21300, '2', '9490'); INSERT INTO UniLinz.InstMitglied VALUES (1122, 21300, '2', '9491'); INSERT INTO UniLinz.InstMitglied VALUES (1199, 21300, '2', '9494'); INSERT INTO UniLinz.InstMitglied VALUES (1095, 32200, '2', '9499'); INSERT INTO UniLinz.InstMitglied VALUES (1005, 21200, '2', '9506'); INSERT INTO UniLinz.InstMitglied VALUES (1103, 21200, '2', '9507'); INSERT INTO UniLinz.InstMitglied VALUES (1133, 21000, '2', '9516'); INSERT INTO UniLinz.InstMitglied VALUES (1142, 21500, '2', '9518'); INSERT INTO UniLinz.InstMitglied VALUES (1206, 21000, '2', '9519'); INSERT INTO UniLinz.InstMitglied VALUES (1151, 21300, '2', '9536'); INSERT INTO UniLinz.InstMitglied VALUES (1039, 21300, '2', '9537'); INSERT INTO UniLinz.InstMitglied VALUES (1094, 31900, '2', '9552'); INSERT INTO UniLinz.InstMitglied VALUES (1121, 21700, '2', '9560'); INSERT INTO UniLinz.InstMitglied VALUES (1053, 21800, '2', '9582'); INSERT INTO UniLinz.InstMitglied VALUES (1057, 31900, '2', '9586'); INSERT INTO UniLinz.InstMitglied VALUES (1220, 32100, '2', '9589'); INSERT INTO UniLinz.InstMitglied VALUES (1044, 21800, '2', '9591'); INSERT INTO UniLinz.InstMitglied VALUES (1209, 31800, '1', '9710'); INSERT INTO UniLinz.InstMitglied VALUES (1177, 31800, '2', '9725'); INSERT INTO UniLinz.InstMitglied VALUES (1083, 31900, '2', '9852'); INSERT INTO UniLinz.InstMitglied VALUES (1200, 32000, '2', '9888'); INSERT INTO UniLinz.InstMitglied VALUES (1215, 30400, '2', '9938'); INSERT INTO UniLinz.InstMitglied VALUES (1126, 30400, '2', '9940'); INSERT INTO UniLinz.InstMitglied VALUES (1027, 30400, '2', '9941'); INSERT INTO UniLinz.InstMitglied VALUES (1216, 30400, '1', '9943'); INSERT INTO UniLinz.InstMitglied VALUES (1078, 30400, '2', '9946'); INSERT INTO UniLinz.InstMitglied VALUES (1154, 30400, '2', '9947'); INSERT INTO UniLinz.InstMitglied VALUES (1165, 30400, '2', '9961'); INSERT INTO UniLinz.InstMitglied VALUES (1172, 30400, '2', '9966'); INSERT INTO UniLinz.InstMitglied VALUES (1067, 32200, '2', '9976'); INSERT INTO UniLinz.InstMitglied VALUES (1009, 21500, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1012, 32000, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1013, 20100, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1017, 21500, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1024, 21300, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1026, 21600, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1033, 21300, '2', null);

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 179 INSERT INTO UniLinz.InstMitglied VALUES (1049, 20800, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1068, 20800, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1070, 21300, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1075, 32400, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1087, 21200, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1120, 21300, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1155, 21300, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1160, 21400, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1161, 31800, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1163, 32200, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1176, 31800, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1193, 20800, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1194, 21400, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1207, 30300, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1212, 31800, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1214, 21000, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1218, 31800, '2', null); INSERT INTO UniLinz.InstMitglied VALUES (1219, 32000, '2', null);

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.Inskription #

DROP TABLE IF EXISTS UniLinz.Inskription;

CREATE TABLE UniLinz.Inskription ( MatrikelNr INT(7) UNSIGNED ZEROFILL NOT NULL, SKZ INT(3) UNSIGNED NOT NULL,

INDEX MatrikelNr (MatrikelNr), INDEX SKZ (SKZ), FOREIGN KEY (MatrikelNr) REFERENCES Student(MatrikelNr), FOREIGN KEY (SKZ) REFERENCES Studienrichtung(SKZ) ) TYPE=InnoDB;

# Daten

INSERT INTO UniLinz.Inskription VALUES (9656522, 84); INSERT INTO UniLinz.Inskription VALUES (9655663, 86); INSERT INTO UniLinz.Inskription VALUES (9756565, 130); INSERT INTO UniLinz.Inskription VALUES (9956706, 130); INSERT INTO UniLinz.Inskription VALUES (0056879, 130); INSERT INTO UniLinz.Inskription VALUES (0256110, 130); INSERT INTO UniLinz.Inskription VALUES (0056410, 140); INSERT INTO UniLinz.Inskription VALUES (0055880, 140); INSERT INTO UniLinz.Inskription VALUES (0256814, 140); INSERT INTO UniLinz.Inskription VALUES (9756565, 151); INSERT INTO UniLinz.Inskription VALUES (9855804, 151); INSERT INTO UniLinz.Inskription VALUES (0055050, 151); INSERT INTO UniLinz.Inskription VALUES (0055880, 151); INSERT INTO UniLinz.Inskription VALUES (0155919, 151); INSERT INTO UniLinz.Inskription VALUES (0155304, 151); INSERT INTO UniLinz.Inskription VALUES (0156278, 151); INSERT INTO UniLinz.Inskription VALUES (0255121, 151); INSERT INTO UniLinz.Inskription VALUES (0256110, 151); INSERT INTO UniLinz.Inskription VALUES (9755666, 160); INSERT INTO UniLinz.Inskription VALUES (9856261, 160); INSERT INTO UniLinz.Inskription VALUES (9956681, 160); INSERT INTO UniLinz.Inskription VALUES (9956175, 160); INSERT INTO UniLinz.Inskription VALUES (0055679, 160); INSERT INTO UniLinz.Inskription VALUES (0156178, 160); INSERT INTO UniLinz.Inskription VALUES (0255146, 160); INSERT INTO UniLinz.Inskription VALUES (0055304, 170); INSERT INTO UniLinz.Inskription VALUES (0155384, 170); INSERT INTO UniLinz.Inskription VALUES (0155035, 170); INSERT INTO UniLinz.Inskription VALUES (0156278, 170); INSERT INTO UniLinz.Inskription VALUES (9755612, 175); INSERT INTO UniLinz.Inskription VALUES (9856588, 175); INSERT INTO UniLinz.Inskription VALUES (9956083, 175); INSERT INTO UniLinz.Inskription VALUES (9956627, 175); INSERT INTO UniLinz.Inskription VALUES (9956352, 175); INSERT INTO UniLinz.Inskription VALUES (0055304, 175); INSERT INTO UniLinz.Inskription VALUES (0055407, 175); INSERT INTO UniLinz.Inskription VALUES (0155902, 175);

180 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.Inskription VALUES (0156178, 175); INSERT INTO UniLinz.Inskription VALUES (0156580, 175); INSERT INTO UniLinz.Inskription VALUES (0256110, 175); INSERT INTO UniLinz.Inskription VALUES (0255128, 175); INSERT INTO UniLinz.Inskription VALUES (0255385, 175); INSERT INTO UniLinz.Inskription VALUES (9755904, 726); INSERT INTO UniLinz.Inskription VALUES (9855280, 726); INSERT INTO UniLinz.Inskription VALUES (0156086, 726); INSERT INTO UniLinz.Inskription VALUES (0256994, 726); INSERT INTO UniLinz.Inskription VALUES (0256591, 726); INSERT INTO UniLinz.Inskription VALUES (0255385, 726); INSERT INTO UniLinz.Inskription VALUES (9656873, 881); INSERT INTO UniLinz.Inskription VALUES (9755438, 881); INSERT INTO UniLinz.Inskription VALUES (9856588, 881); INSERT INTO UniLinz.Inskription VALUES (9955468, 881); INSERT INTO UniLinz.Inskription VALUES (9856857, 881); INSERT INTO UniLinz.Inskription VALUES (0055735, 881); INSERT INTO UniLinz.Inskription VALUES (0056665, 881); INSERT INTO UniLinz.Inskription VALUES (0055498, 881); INSERT INTO UniLinz.Inskription VALUES (0156086, 881); INSERT INTO UniLinz.Inskription VALUES (0156580, 881); INSERT INTO UniLinz.Inskription VALUES (0155891, 881); INSERT INTO UniLinz.Inskription VALUES (0256591, 881);

# Definition und Testdaten-Inserts für Tabelle: # # UniLinz.LVAZeugnis #

DROP TABLE IF EXISTS UniLinz.LVAZeugnis;

CREATE TABLE UniLinz.LVAZeugnis ( LVANr INT(6) UNSIGNED NOT NULL, MatrikelNr INT(7) UNSIGNED ZEROFILL NOT NULL, Pruefer INT(4) UNSIGNED NOT NULL, Note ENUM('sehr gut', 'gut', 'befriedigend', 'genügend', 'nicht genügend') NOT NULL,

INDEX LVANr (LVANr), INDEX MatrikelNr (MatrikelNr), INDEX Pruefer (Pruefer), FOREIGN KEY (LVANr) REFERENCES LVA(LVANr), FOREIGN KEY (MatrikelNr) REFERENCES Student(MatrikelNr), FOREIGN KEY (Pruefer) REFERENCES WissPersonal(PersNr) ) TYPE=InnoDB COMMENT='Zeugnis Zeugnisse LVA-Zeugnis LVA-Zeugnisse Schein Scheine';

# Daten

INSERT INTO UniLinz.LVAZeugnis VALUES (228280, 0055407, 1044, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (228280, 0255128, 1044, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (228280, 0255146, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228280, 0256110, 1044, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (228280, 9756565, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228420, 0055880, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228420, 0056410, 1044, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (228420, 9755666, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228420, 9856588, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228420, 9956627, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228440, 0055407, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228440, 0056879, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228440, 0156178, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228440, 0256110, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228440, 9956175, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228540, 0155902, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228540, 0255146, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228540, 9956706, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228560, 0056879, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228560, 0156278, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228560, 0256110, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228560, 9956681, 1044, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (228560, 9956706, 1044, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228570, 0055407, 1053, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228570, 0056410, 1053, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (228570, 0155902, 1053, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (228570, 9755666, 1053, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (228570, 9856588, 1053, '2');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 181 INSERT INTO UniLinz.LVAZeugnis VALUES (228660, 0055304, 1053, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (239219, 0056410, 1169, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (239223, 0256814, 1169, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (241000, 0155304, 1221, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (241000, 9755612, 1221, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (241000, 9756565, 1221, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (241001, 0055050, 1221, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (241001, 0055679, 1221, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (241001, 0255385, 1221, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241001, 9856588, 1221, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241001, 9956681, 1221, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241002, 0055050, 1213, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (241002, 9755666, 1213, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241002, 9855804, 1213, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (241002, 9856261, 1213, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241002, 9956681, 1213, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (241003, 0055880, 1221, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241003, 0255121, 1221, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (241003, 9956352, 1221, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241004, 0055050, 1221, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (241005, 9656522, 1221, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (242257, 9755666, 1149, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (242257, 9956681, 1149, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (242258, 0155919, 1021, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (242258, 0255121, 1021, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246024, 0055407, 1179, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246024, 0156178, 1179, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246024, 0156580, 1179, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246024, 9856588, 1179, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246024, 9956083, 1179, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246100, 9856588, 1066, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246100, 0055735, 1066, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246100, 0255128, 1066, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246100, 0256110, 1066, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246100, 9956083, 1066, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246101, 0055304, 1066, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246101, 0055407, 1066, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246101, 0256110, 1066, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246101, 9856588, 1066, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246101, 9956083, 1066, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246108, 0055304, 1066, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246108, 0055735, 1066, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246108, 0155902, 1066, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246108, 9956083, 1066, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246108, 9956627, 1066, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246304, 0255385, 1171, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246307, 0055407, 1190, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246307, 0055735, 1190, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246309, 0055304, 1171, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246309, 0056665, 1171, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246309, 0256110, 1171, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246309, 9856857, 1171, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246309, 9955468, 1171, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246310, 0055304, 1142, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246310, 0055407, 1142, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246315, 0055304, 1142, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246315, 9956352, 1142, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246321, 0055304, 1104, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246321, 0055407, 1104, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246500, 9956627, 1138, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246500, 0055735, 1138, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246500, 0155902, 1138, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246500, 0255128, 1138, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246500, 9755612, 1138, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246502, 0156580, 1138, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246502, 9856588, 1138, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246502, 9956627, 1138, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246503, 0055304, 1138, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246503, 0155902, 1138, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246503, 0156580, 1138, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246503, 9955468, 1138, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246503, 9956083, 1138, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246505, 0156580, 1052, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246505, 9955468, 1052, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246506, 0156580, 1052, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246506, 9956083, 1052, '3');

182 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken INSERT INTO UniLinz.LVAZeugnis VALUES (246510, 0155891, 1138, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246510, 9656873, 1138, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246510, 9856857, 1138, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246510, 9956083, 1138, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246511, 0255128, 1157, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246511, 9856588, 1157, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (246515, 0055304, 1132, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246515, 0156580, 1132, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246515, 9956627, 1132, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246519, 0156086, 1210, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246519, 9956627, 1210, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246521, 0255128, 1136, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246521, 9755612, 1136, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246521, 9956083, 1136, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246531, 0256110, 1157, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (246531, 9956627, 1157, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (246543, 0055304, 1210, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (246543, 0055407, 1210, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (247004, 0055679, 1185, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (247004, 9856261, 1185, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (247004, 9956083, 1185, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (247017, 9856261, 1185, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (247100, 0156178, 1185, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (247100, 0156278, 1185, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (247100, 9956681, 1185, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (247103, 0156278, 1185, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (247103, 0255146, 1185, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (247103, 9956627, 1185, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (312514, 0056665, 1170, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (312514, 0155902, 1170, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (312514, 0256591, 1170, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (312530, 0055407, 1170, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (312530, 0156580, 1170, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (312530, 9956627, 1170, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (338131, 0256591, 1042, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (338131, 9856588, 1042, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (338236, 0055407, 1020, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (338236, 0056665, 1020, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (338236, 0155891, 1020, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (338236, 0156580, 1020, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350000, 0156086, 1197, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (350000, 9856857, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350000, 9956627, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350102, 0055498, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350102, 0155891, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350102, 0156580, 1197, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (350109, 0156086, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350109, 0255385, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350109, 0256591, 1197, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (350117, 0155891, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350117, 9956627, 1197, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (350119, 0055498, 1189, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (350119, 0256591, 1189, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (350119, 9956352, 1189, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 9955468, 1100, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 0055498, 1100, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 0055735, 1100, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 0056665, 1100, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 0156086, 1100, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 0156178, 1100, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 9656873, 1100, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 9755438, 1100, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 9856588, 1100, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351001, 9956627, 1100, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351002, 0055407, 1100, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351002, 0256591, 1100, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351002, 9956352, 1100, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351003, 0055407, 1100, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351003, 9755612, 1100, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351004, 0156178, 1220, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351004, 9656873, 1220, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351004, 9856588, 1220, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351005, 0155891, 1220, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351005, 0156086, 1220, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351006, 0055735, 1204, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351006, 0156086, 1204, '2');

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 183 INSERT INTO UniLinz.LVAZeugnis VALUES (351006, 0156580, 1204, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351008, 9655663, 1204, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351013, 0256110, 1204, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351013, 9755438, 1204, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351013, 9856588, 1204, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351014, 9856588, 1220, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351015, 0055407, 1204, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351015, 9856588, 1204, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351031, 0055304, 1204, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351031, 9956083, 1204, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351031, 9956627, 1204, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351047, 0155902, 1100, '4'); INSERT INTO UniLinz.LVAZeugnis VALUES (351047, 9856588, 1100, '3'); INSERT INTO UniLinz.LVAZeugnis VALUES (351048, 0055407, 1220, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (351048, 0156086, 1220, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351050, 0156086, 1144, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (351050, 9956352, 1144, '2'); INSERT INTO UniLinz.LVAZeugnis VALUES (700000, 0256110, 1053, '1'); INSERT INTO UniLinz.LVAZeugnis VALUES (700000, 9755666, 1053, '2');

184 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken Anhang B: SAHSERD Datenstrukturen

B.1 Datadictionary für UniLinz

Folgende Tabelle spiegelt den Inhalt der Tabelle sasherd_datadic wieder:

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 185 B.2 Alias-Verzeichnis für UniLinz

Folgende Tabelle spiegelt den Inhalt der Tabelle sasherd_aliases wieder:

Alias DB-Begriff Zugriffspfad

Beurteilung Note LVAZeugnis.Note Credits ECTSCredits LVA.ECTSCredits Durchwahl TelefonNr InstMitglied.TelefonNr ECTS ECTSCredits LVA.ECTSCredits Geburtsdatum GebDat Student.GebDat Institute Institut Institut Klappe TelefonNr InstMitglied.TelefonNr Lehrveranstaltung LVA LVA Lehrveranstaltungen LVA LVA LVA# LVANr LVA.LVANr LVA-Bezeichnung Titel LVA.Titel LVA-Leiter LVALeiter LVALeiter.LVALeiter LVA-Name Titel LVA.Titel LVA-Nummer LVANr LVA.LVANr LVA-Zeugnis LVAZeugnis LVAZeugnis LVA-Zeugnisse LVAZeugnis LVAZeugnis LVAs LVA LVA Matrikel# MatrikelNr Student.MatrikelNr Matrikelnummer MatrikelNr Student.MatrikelNr Name Nachname WissPersonal.Nachname Name Nachname Student.Nachname Noten Note LVAZeugnis.Note Personal WissPersonal WissPersonal Prüfer Pruefer LVAZeugnis.Pruefer Prüferin Pruefer LVAZeugnis.Pruefer Schein LVAZeugnis LVAZeugnis Scheine LVAZeugnis LVAZeugnis Studenten Student Student Studentin Student Student Studienrichtungen Studienrichtung Studienrichtung Studium Studienrichtung Studienrichtung Stunden StdAnzahl LVA.StdAnzahl StundenAnzahl StdAnzahl LVA.StdAnzahl Tel TelefonNr InstMitglied.TelefonNr Telefon TelefonNr InstMitglied.TelefonNr Telefon# TelefonNr InstMitglied.TelefonNr Uni-Personal WissPersonal WissPersonal Zeugnis LVAZeugnis LVAZeugnis Zeugnisse LVAZeugnis LVAZeugnis

186 SAHSERD: Eine einfache ad-hoc Suchmaschine für relationale Datenbanken B.3 (Vordefinierte) Views für UniLinz

Folgende Tabelle spiegelt den Inhalt der Tabelle sasherd_predefindedresultview wieder:

basetable join viewname joinclauselist selectclause aliaslist level ST_MatrikelNr as 'Matrikel-Nr', Inskription as IN_, CONCAT(ST_Vorname, ' ', IN_.MatrikelNr = Student as ST_, ST_Nachname) as 'Name', v_Inskription 2 ST_.MatrikelNr, Studienrichtung as ST_GebDat as 'Geburtsdatum', IN_.SKZ = SR_.SKZ SR_ SR_SKZ as 'SKZ', SR_Bezeichnung as 'Studienrichtung' v_Institut Institut as I_ 0 I_Name as 'Name' I_Name as 'Institut', InstMitglied as IM_, IM_.PersNr = CONCAT(IF(ISNULL(WP_Titel), '', Institut as I_, WP_.PersNr, CONCAT(WP_Titel, ' ')), v_InstMitglied 2 WissPersonal as IM_.InstNr = WP_Vorname, ' ', WP_Nachname) as WP_ I_.InstNr 'Name', IM_Position as 'Position', IM_TelefonNr as 'Telefon-Nr' LL_LVANr as 'LVA-Nr', L_LVATyp as LL_.LVANr = LVA as L_, LVALeiter 'LVA-Typ', L_Titel, L_StdAnzahl as L_.LVANr, v_LVA as LL_, WissPer- 2 Wochenstunden, L_ECTSCredits, LL_.LVALeiter = sonal as WP_ CONCAT(WP_Vorname, ' ', WP_.PersNr WP_Nachname) as 'LVA-Leiter' LZ_LVANr as 'LVA-Nr', L_LVATyp as 'LVA-Typ', L_Titel as 'LVA-Titel', CONCAT(WP_Vorname, ' ', LZ_.LVANr = WP_Nachname) as 'Pruefer', LVAZeugnis as LZ_, L_.LVANr, L_StdAnzahl as 'Wochenstunden', LVA as L_, Student LZ_.MatrikelNr = v_LVAZeugnis 3 L_ECTSCredits as 'ECTSCredits', as ST_, WissPer- ST_.MatrikelNr, LZ_MatrikelNr as 'Matrikel-Nr', sonal as WP_ LZ_.Pruefer = CONCAT(ST_Vorname, ' ', WP_.PersNr ST_Nachname) as 'Name', ST_GebDat as Geburtsdatum, LZ_Note as 'Note' ST_MatrikelNr as 'Matrikel-Nr', CONCAT(ST_Vorname, ' ', ST_Nachname) as 'Name', v_Student Student as ST_ 0 ST_GebDat as 'Geburtsdatum', ST_Geschlecht as 'Geschlecht', ST_Adresse as 'Adresse' v_Studien Studienrichtung as 0 SR_SKZ, SR_Bezeichnung richtung SR_ CONCAT(IF(ISNULL(WP_Titel), '', WissPersonal as CONCAT(WP_Titel, ' ')), v_WissPersonal 0 WP_ WP_Vorname, ' ', WP_Nachname) as 'Name'

SAHSERD: eine einfache ad-hoc Suchmaschine für relationale Datenbanken 187