Algorithmen und Datenstrukturen II

Überblick. Datenspeicherung in relationalen Datenbanken. Persistente Datenspeicherung in Java mit JDBC. ORM – Objekt-relationales Mapping. Datenspeich...

4 downloads 678 Views 578KB Size
Algorithmen und Datenstrukturen II Alexander Goesmann Bioinformatics Resource Facility Center for Biotechnology Universität Bielefeld Vorlesung Sommer 2010

Überblick   Datenspeicherung in relationalen Datenbanken

  Persistente Datenspeicherung in Java mit JDBC

  ORM – Objekt-relationales Mapping

  Datenspeicherung mit Hibernate

Datenspeicherung in relationalen Datenbanken Teil I

Relationale Datenbanken   Relationale Datenbank dient zur elektronischen Datenverwaltung in Computersystemen   Beruht auf relationalem Datenbankmodell von Edgar F. Codd aus dem Jahr 1970   Basiert auf Relationen und Operationen darauf (Vgl. relationale Algebra)   Verwaltung der gespeicherten Daten mit relationalem Datenbankmanagementsystem (RDBMS)   Abfrage und Manipulation der Daten mit Datenbanksprache SQL (Structured Query Language)

Grundlegende Konzepte   Relationale Datenbank ist Sammlung von Tabellen (Relationen) mit gespeicherten Daten   Jede Zeile (Tupel) in einer Tabelle ist ein Datensatz (record)   Tupel besteht aus Reihe von Attributwerten (Attribute = Eigenschaften), den Spalten der Tabelle   Relationenschema legt Anzahl und Typ der Attribute für eine Relation fest   Eindeutige Identifizierung von Datensätzen über Schlüssel (key)

Beispiel

Quelle: Wikipedia

Beziehungen zwischen Tabellen   Redundante Speicherung von Daten vermeiden   Verwendung eines eindeutigen Schlüssels pro Tabelle zur Identifizierung des Datensatzes (primary key)   Verweis aus anderen Tabellen auf Daten mit Hilfe dieses Schlüssels   Derartige Attribute werden als Fremdschlüssel (foreign key) bezeichnet   Tabellen ohne Fremdschlüssel heißen flache Tabellen

Tabelle anlegen Syntax: CREATE TABLE " " "

"Tabellen_Name" 
 "("Spalte 1" "Datentyp_für_Spalte_1",
 " "Spalte 2" "Datentyp_für_Spalte_2",
 " ... )"

Beispiel: CREATE TABLE Nutzer (Nutzer-ID int, 
 " " "Vorname varchar(50), "
 "

"

"Nachname varchar(50))

"

Daten einfügen Syntax: INSERT INTO 
 " ( [, weitere Spaltennamen])
 VALUES ( [, weitere Werte])"

Beispiel: INSERT INTO Nutzer (Nutzer-ID, Vorname, Nachname) 
 " VALUES (13, 'Hans', 'Müller')"

Daten abfragen Syntax: SELECT ... FROM ... WHERE 
 " [ ]"

Beispiele: Select * FROM Nutzer" Select * FROM Nutzer WHERE Vorname = „Hans“" Select Autor, Titel FROM Bücher WHERE Verlagsjahr > 2000 
 "AND Verlag != „KVG“"

Daten aktualisieren Syntax: UPDATE SET = 
 [, weitere Spaltennamen = Ausdruck] WHERE "

Beispiele: UPDATE Bücher SET Datum = „20.07.2010“" UPDATE Bücher SET Datum = Datum + 2000 WHERE Datum < 20"

Daten löschen Syntax: DELETE FROM WHERE "

Beispiele: DELETE FROM Nutzer" DELETE FROM Entliehen WHERE Nutzer-ID = 12"

Weiterführende Themen   Zusammengesetzte Schlüssel   Indexierung   JOINs   Komplexe Abfragen und Unterabfragen   Normalisierung & Normalformen   Optimierung   Gespeicherte Funktionen und Prozeduren

Persistente Datenspeicherung in Java mit JDBC Teil II

JDBC   Java Database Connectivity   Einheitliche Datenbankschnittstelle zu DBMS verschiedener Hersteller Java Application JDBC

Client Machine

RDBMS proprietary protocol RDBMS

Database Server

JDBC Treiber   Für jedes DBMS ist ein JDBC-Treiber nötig   Typ 1 – bildet die JDBC API auf andere native API ab   Typ 2 – teilweise in Java, teilweise in nativem Code geschrieben   Typ 3 – vollständig in Java geschrieben, kommuniziert über einen middleware-server über ein datenbankunabhängiges Protokoll   Typ 4 – vollständig in Java geschrieben, implementiert das jeweilige Datenbank-Protokoll

Verbindung herstellen   Treiber laden   Class.forName(„com.mysql.jdbc.Driver “)   Treiber registriert sich beim Laden selbstständig beim DriverManager

  Verbindungs-URL   jdbc::[propertylist]   z.B. jdbc:mysql:testdb

  DriverManager vs. DataSource

DriverManager   Treiber registrieren sich beim DriverManager   Erhält Verbindungs-URL   Optional Benutzername, Passwort   Löst den Treiber über Namen in URL auf   Beispiele   Connection con = DriverManager.getConnection („jdbc:derby:COFFEES“)   DriverManager.getConnection („jdbc:derby:COFFEES“, „user“, „password“)

DataSource   Interface   Beschreibt eine Verbindung zur Datenbank   Wird häufig außerhalb der Anwendung definiert und z.B. über Java Naming and Directory Interface (JNDI) abgefragt (hängt vom verwendeten Framework ab)   Beispiel

InitialContext ic = new InitialContext(); DataSource ds = ic.lookup("java:comp/env/ jdbc/myDB"); Connection con = ds.getConnection();

Programmatische DataSource   Beispiel: ClientDataSource ds = new org.apache.derby.jdbc.ClientDataSource(); ds.setPort(1527); ds.setHost("localhost"); ds.setUser("APP") ds.setPassword("APP"); Connection con = ds.getConnection();

Beispieltabelle COFFEES COF_NAME Colombian

SUP_ID

PRICE

SALES

TOTAL

101

01.07.99

0

0

49

01.08.99

0

0

Espresso

150

01.09.99

0

0

Colombian_Decaf

101

01.08.99

0

0

49

01.09.99

0

0

French_Roast

French_Roast_Decaf

Connection   Connection stellt die Verbindung zur Datenbank dar   Kann über Statement-Objekte SQL Code ausführen   Ergebnisse der Statements werden durch ResultSets repräsentiert

Daten aus Tabelle lesen Statement stmt = con.createStatement(); ResultSet srs = stmt.executeQuery("SELECT COF_NAME, PRICE FROM COFFEES");   ResultSet repräsentiert zurückgegebene Tabelle   Methoden zum Auswählen der Zeile   Methoden zum Auslesen einer Zelle zur aktuellen Zeile   -> API

ResultSet Beispiel ResultSet srs = stmt.executeQuery( "SELECT COF_NAME, PRICE FROM COFFEES"); while (srs.next()) { String name = srs.getString("COF_NAME"); float price = srs.getFloat("PRICE"); System.out.println(name + " }

" + price);

Daten in der Tabelle ändern Statement stmt = conn.createStatement(); ResultSet srs = stmt.executeQuery("select COF_Name from COFFEES where price = 7.99"); srs.next(); srs.updateString("COF_NAME", "Foldgers"); srs.updateRow();

  Änderungen werden erst mit updateRow() geschrieben   Abbrechen mit cancelUpdates()

Weitere Features   Daten einfügen und löschen   INSERT/DELETE Statements

  Transaktionen   Es werden entweder alle Änderungen gemacht oder keine

  Stored Procedures   Werden in der Datenbank ausgeführt

Vor- und Nachteile   Vorteile:   Direkter und vollständiger Zugriff auf Daten   Ausführung von beliebigem (nativem) SQL-Code   Geringer Overhead

  Nachteile:          

Sehr aufwändig bei großen Datenbanken Duplikation von ähnlichen SQL-Statements Gefahr von Fehlern durch „copy & paste“ Kein direkter Bezug zu Objektmodell im Programm Kompatibilitätsprobleme bei Verwendung von RDBMS spezifischem Code

ORM – Objekt-Relationales Mapping Teil III

Persistente Datenspeicherung   Programme arbeiten oftmals auf großen Datenbeständen   Daten werden gelesen, geändert und gespeichert

Persistenz = Verwaltung und Speicherung von Daten über die Laufzeit eines Programms hinaus

Layerstruktur objektorientierter Applikationen

Objektorientierte Programmierung vs. Relationale Datenbanken   Objektorientierte Programmierung fordert Einheit von Code und Daten   Relationale Datenbank (RDB) beinhaltet nur Verwaltung von Daten und Aufrechterhaltung ihrer Konsistenz   Relationale Datenbanken sind nicht in der Lage komplette Objekte (als Summe ihrer Attribute und Methoden) zu verwalten   RDB eignet sich nur zur Speicherung der „Daten“ eines Objektes, also des Inhalts seiner Attribute   Ansatz: Mapping, also das Abbilden von Objekten und Attributen in Datenbank-Tabellen bzw. deren Spalten

Persistenz-Layer   Aufgabe: Bereitstellen von Methoden zum Erzeugen, Abfragen, Verändern und Löschen von Objekten einer Klassenhierarchie   CRUD: Create, Retrieve, Update, Delete   getter/setter-Methoden zur Abfrage und Veränderung einzelner Attribute   Schlüssel zur Flexibilität und Geschwindigkeit ist die Art und Weise, mit der die Struktur der Objekte auf die relationale Datenbank gemappt werden   Umfasst auch Information über Vererbungshierarchie

Identifizierung von Objekten in Datenbanken   Ein Objekt existiert laut dem Paradigma der ObjektOrientierten Programmierung (OOP) nur einmal   Jede Objekt-Orientierte Programmiersprache verwendet Referenzen auf Objekte, um diese zu verwalten:   Objekt wird erzeugt, eine Referenz verwaltet, weitere Referenzen angelegt, Methoden werden benutzt und das Objekt wird am Ende seiner Existenz zerstört   Gleichheit von Objekten wird durch Gleichheit der Referenz ausgedrückt   Inhaltliche Gleichheit durch Gleichheit der Werte von Attributen

Identifizierung von Objekten in Datenbanken   Beim Ablegen eines Objektes in einer relationalen Datenbank muss diese Form des „Selbst“ aufrecht erhalten werden   Objekt muss eindeutig von anderen Objekten unterscheidbar und identifizierbar sein   Persistenz-Layer weisen Objekten eindeutige Identifikationsnummern, genannt object ids (OID) zu   Anhand dieser Nummer kann das Objekt sich selbst, seine Daten und assoziierte Objekte identifizieren

Identifizierung von Objekten anhand einfacher Nummern   Fortlaufende Nummerierung der Objekte   Datenbank-Systeme liefern hierzu geeignete Hilfsmittel, z.B. SERIAL INTEGER in PostgreSQL oder AUTOINCREMENT in MySQL   Eigenhändige Lösung: Anlegen einer Datenbanktabelle für Metadaten zur Verwaltung der OIDs und anderer Daten   Vorteil: Gute Übertragbarkeit auf jedes Datenbank-System   Nachteil: Zusätzlicher Aufwand zur Verwaltung der Metadaten   Um Eindeutigkeit der OID zu gewährleisten, muss jeder Zugriff auf die Metadaten exklusiv erfolgen   Locking der Tabelle oder einzelner Spalten nicht zu umgehen   Ausbremsen des Systems durch Locking, wenn viele Clients in kurzer Folge neue OIDs anfordern

Identifizierung von Objekten mit zusammengesetzten Nummern   Um Performanz-Einbußen beim konkurrierenden Zugriff auf Metadaten zu verringern, wird OID aus zwei Komponenten zusammengesetzt (high-low-Ansatz)   Zwei Komponenten:   Sitzungszähler wird von Datenbank verwaltet und beim Starten der Applikation durch Datenbank initialisiert   Zweite Komponente wird durch Applikation selbst vergeben

  Beispiel: 32-bit-Integers (z.B. unterste 10 Bit aus internem Zähler, restliche Bits aus Sitzungszähler) gewährleistet Eindeutigkeit bei Verringerung der Zugriffe auf Metadaten um Faktor 210 = 1024   Nachteil: Verschwenderischer Umgang mit OIDs (Überlauf!)

Identifizierung von Objekten mit globalen OIDs   Einsatz (weltweit) verteilter Datenbanken erfordert andere Mittel   OID dient hier nicht nur dem Auffinden der Daten in der Datenbank, sondern muss es der Applikation auch ermöglichen, Datenbank als solche zu identifizieren   Ansatz: Text-OIDs, die Hostnamen des DatenbankServers, Namen der Datenbank, Namen der Tabelle und numerische OID enthalten   Andere Möglichkeiten: URIs und URNs

Mapping: Eine Tabelle pro Hierarchie   Alle Klassen einer Hierarchie sowie ihre Attribute werden in eine einzige Tabelle gemappt   Vorteile:        

Hohe Performanz (nur eine Tabelle pro Anfrage) Einfache Implementierung Einfache Abfrage der Daten Nachträgliches Verändern der Klassen sowie polymorphe Abfragen von Objekten ebenfalls einfach

  Nachteile:   Je nach verwendeter Klassenstruktur hoher Speicherverbrauch, da unnötig viele Spalten pro Klasse existieren   Viele leere Datenbankfelder

Mapping: Eine Tabelle pro konkreter Klasse   Pro Klasse eine Tabelle, die die kompletten Attribute dieser Klasse (inklusive der Attribute evtl. vorhandener abstrakter Oberklassen) enthält   Vorteile:   einfache Implementierung   Speicherbedarf hält sich in Grenzen

  Nachteile:   Polymorphe Abfragen von Objekten, besonders auf höherer Ebene der Klassenhierarchie, sind schwierig, da mehrere Tabellen nacheinander abgefragt werden müssen   Veränderung von Attributen (Hinzufügen, Löschen) ist um so aufwändiger, je höher die Klasse in der Hierarchie angesiedelt ist

Mapping: Eine Tabelle pro Klasse   Pro Klasse wird eine Tabelle erzeugt, die jedoch nur die in dieser Klasse definierten Attribute enthält, sowie die OID des Objektes   Verknüpfung von Tabellen mit Hilfe der OID um die Gesamtdaten der Attribute eines Objektes zu erhalten   Vorteile:   Beste Unterstützung für polymorphe Abfragen

  Nachteile:   Höchste Anforderungen an Implementierung   Performanz kann je nach verwendeter Datenbank geringer als bei anderen Methoden sein, da die Verknüpfung evtl. mehrerer Tabellen einen hohen Verarbeitungsaufwand erzeugt

Mapping: Ein einfaches Beispiel

Vor- und Nachteile der MappingVerfahren

Methode

Geschwindigkeit

Polymorphismus

Speicherbedarf

Hierarchie

+

-

-

Konkrete Klasse

+

-

+

Klasse

-

+

+

Datenspeicherung mit Hibernate Teil IV

Was ist Hibernate?  

 

Englisch für „Winterschlaf halten“ Persistenz- und Objekt-Relationales Mapping-Framework für Java (mittlerweile auch für .NET)  

 

Speicherung von Objekten mit Attributen und Methoden in relationalen Datenbanken Zugriff auf Daten mit eigener Abfragesprache (HQL) - 

Dadurch: Unabhängig von gewählter Datenbank (z.B. MySQL)

 

Kompatibel zur Java Persistence API (JPA)

 

Open-Source

Verbreitung und Verwendung  

Hibernate findet Verwendung in zehntausenden JavaProjekten weltweit

 

Etwa 25.000 angemeldete Entwickler in den Hibernate-Foren

 

Anzahl täglicher Download: ca. 3.000

(Quelle: Wikipedia 2010, Hibernate Framework)

POJO – Plain old Java Object = ein „ganz normales“ Objekt  

Beispiel – Die Klasse / das POJO „Region“:

public class Region() { private String name; private int start; private int stop; public int getStart () { return start; } public int getStop () { return stop; } public String getName () { return name; } }

Primärschlüssel  

 

Jedes Objekt benötigt zur eindeutigen Identifikation in der Datenbank einen eindeutigen Primärschlüssel Beispiel – Erweiterung der Klasse „Region“ um ein neues Attribut „_id“

public class Region() private Long _id;

{

public long get_id() { return _id; } }  

Alternativ hätte auch das Attribut „name“ verwendet werden können → Dann müsste Eindeutigkeit aber sichergestellt sein!

Datenbanktabelle  

Beispiel: Region

Feld

_id

name

start

stop

Typ

int(11)

char(255)

int(8)

int(8)

1

cg0025

1024

1258

2

cg0026

2080

1430

...

...

...

...

Objekt-Relationales Mapping  

 

Erlaubt Abbildung der Objekt/Klassenstruktur auf ein relationales Datenbankschema Grundgerüst des Mappings in Hibernate mittels XML:

...  

Alternativ möglich: Beschreibung des Mappings mit Hilfe von Annotationen

Objekt-Relationales Mapping  

Mapping für die Klasse Region auf die entsprechende Datenbanktabelle:

...

Objekt-Relationales Mapping  

Mapping für die Klasse Region auf die entsprechende Datenbanktabelle:



Objekt-Relationales Mapping  

Wichtig: Definition des Primärschlüssels mit der Anweisung diesen bei jedem neuen Objekt automatisch zu erhöhen



Erweiterung der Klasse Region  

Jede Region kann in einer Art „Eltern-Kind“-Relation zu einer anderen Region stehen:

public class Region() { ... private Region parentRegion; ... public Region getParentRegion () { return parentRegion; } }

Datenbanktabelle  

Beispiel: Region erweitert um „Eltern (Parent)“ Region  

Benötigt zusätzliche Spalte mit „Fremdschlüssel“

Feld

_id

name

start

stop

parent_region_id

Typ

int(11)

char(255)

int(8)

int(8)

int(11)

1

cg0025

1024

1258

2

2

cg0026

2080

1430

null

...

...

...

...

...

Objekt-Relationales Mapping  

Fremdschlüssel zeigt auf „Parent“-Region



Datenspeicherung und Abfrage Transaktionen  

 

Ausführung einer oder mehrerer Operationen (z.B. Holen und Änderung von Region-Objekten) innerhalb einer Transaktion ACID Eigenschaften von Transaktionen:   Atomarität: „Ganz oder gar nicht“   Konsistenz: konsistenter Datenzustand (z.B. Abbuchung von Konto und Einzahlung auf einem anderen)   Isolation: Keine gegenseitige Beeinflussung von Transaktionen (z.B. Reisebuchung – Sperrung eines Flugs während Auswahl des Hotels)   Dauerhaftigkeit: Änderungen einer erfolgreich abgeschlossenen Transaktion sind dauerhaft (persistent)

Datenspeicherung und Abfrage  

Komponenten/Architektur von Hibernate:  

 

Session - 

Repräsentiert „Konversation“ zwischen Anwender (Anwendung) und Datenbank

- 

Kapselt Verbindung zur Datenbank (JDBC-Connection)

SessionFactory - 

„Kennt“ alle Mappings für eine Datenbank

- 

Dient als Factory für Session-Objekte Optional: Zwischenspeicher für abgerufene Datenbankobjekte zur Steigerung der Performance (Caching)

- 

Hibernate Konfiguration  

XML-Konfiguration einer SessionFactory

com.mysql.jdbc.Driver org.hibernate.dialect.MySQLDialect ...

Beispiel: Ablauf einer Datenbankabfrage  

Erstellung der Verbindung zur Datenbank (Initialisierung der SessionFactory mit Hibernate Konfiguration)

 

Öffnen einer Session über die SessionFactory

 

Beginn einer Transaktion

 

Abfrage/Speicherung von Objekten

 

„Commit“ der Transaktion (Erst jetzt werden Änderung/ Objekte persistent!)

 

Schließen der Session

 

Später eventuell: Öffnen einer weiteren Session...

Beispiel: Holen aller „Regions“ // Initialisierung der SessionFactory (hier nicht gezeigt) private static SessionFacotory sessionFactory = ...

// Methode zum Holen aller Region-Objekte (Wo ist hier die Transaktion?) public List getRegions() { List regions = null; Session session = sessionFactory.openSession(); try { regions = session.createQuery( "select region from Region as region" ).list(); } catch (Exception ex) { // Fehlerbehandlung } finally { session.close(); } return regions; }

Beispiel: Speicherung einer Region // Methode zur Erstellung und Speicherung eines Region-Objekts public Region createNewRegion(String name, int start, int stop) { Region region = new Region(); region.setName(name); region.setStart(start); region.setStop(stop); Session session = sessionFactory.openSession(); Transaction tx = null; try { tx = session.beginTransaction(); session.save(region); tx.commit(); } catch (Exception ex) { tx.rollback(); // Rollback aller Änderungen! return null; // besser: Ausnahme werfen! } finally { session.close(); } return region; }

Literatur   C. J. Date und H. Darwen SQL - Der Standard. Addison-Wesley, 1997   S.W. Ambler The Design of a Robust Persistence Layer for Relational Databases.   S.W. Ambler Mapping Objects to Relational Databases.   S.W. Ambler Building Object Applications that work. Cambridge University Press, 1998   http://www.agiledata.org/essays/mappingObjects.html   http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/jdbc/basics/index.html   http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html   C. Bauer, G. King (2005) Hibernate in Action. Manning Publications Co.   Hibernate - JBoss Community (2010) www.hibernate.org

Vielen Dank für Eure Aufmerksamkeit