Datenbanken SoSe2019

Blatt 11

Download von H2: https://h2database.com/html/main.html (nehmt den Download "Download this database All Platforms (zip, 8 MB)").

Dann starten durch Ausführen der Datei "bin\h2.bat". Es öffnet sich ein Browserfenster. Wenn man sich in diesem anmelden will, gibt es aber eine Fehlermeldung.

In der Windows-Benachrichtigungsleiste (rechts unten neben der Uhr) befindet sich ein Symbol der Datenbank. Darauf einen Rechtsklick und "Create Database" aufrufen.


Man gibt bei "Database Path" einen Pfad und Datenbanknamen an sowie ein Passwort:

Im Beispiel ist der Pfad "./test". Das bedeutet: die Datenbank wird im Verzeichnis angelegt, in dem "h2" gestart wurde. D.h. die Datei "test.mv.db" entsteht jetzt in diesem Verzeichnis.
Man könnte hier auch einen absoluten Pfad angeben!

Die Beispiele auf der H2-Homepage erwähnen oft den Pfad "~/test": dies sucht die Datei im Benutzer-Homeverzeichnis. Man hätte beim Erzeugen der Datenbank auch "~/test" angeben können, um die Pfade wie z.B. in den Anleitungen zu verwenden.

Jetzt kann man sich im Browserfenster an der Datenbank anmelden:

Die URL beginnt mit "jdbc:h2:", danach folgt der Datenbankpfad - hier also "./test".

Im nächsten Schritt führt man das Script "eis.sql" im Abfragefenster aus. Hier kann man auch die Abfragen für die Lösung der Aufgabe zusammenbauen.

Im Eclipse-Javaprojekt muss man nur im BuildPath die Datei "h2-1.4.199.jar" hinzufügen:


Beispiel-Javacode:

package de.hsrm.cs.datenbanken.blatt11;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

public class Blatt11Test
{
  public static void main(String[] a) throws Exception
  {
    Connection conn = DriverManager.getConnection("jdbc:h2:c:\\temp\\h2\\bin\\test", "sa", "test");
    // add application code here

    //Testcode: alle Tabellen anzeigen.
    ResultSet result = conn.createStatement()
        .executeQuery("select * from INFORMATION_SCHEMA.TABLES order by table_name");
    while (result.next())
    {
      System.out.println(result.getString("TABLE_NAME"));
    }
    result.close();

    //Maximale Kalorienzahl der Tabelle "eis" ermitteln:
    ResultSet result2 = conn.createStatement().executeQuery("select max(kalorien) from eis");
    result2.next();
    System.out.println("Maximale Kalorienzahl: " + result2.getInt(1));

    conn.close();

    System.out.println("DONE");
  }
}
Wichtig ist hier die URL: Sie muss den absoluten Pfad zur Datenbank enthalten, mit "~/test" würde eine leere Datenbank im Verzeichnis des Eclipse-Projekt entstehen. Natürlich müssen Backslash im Windows-Umfeld gedoppelt/maskiert werden.


Kommt bei der Ausführung des Codes diese Exception, dann muss man erst ein Disconnect im Browserfenster ausführen:
Exception in thread "main" org.h2.jdbc.JdbcSQLNonTransientConnectionException: Datenbank wird wahrscheinlich bereits benutzt: null. Mögliche Lösungen: alle Verbindungen schliessen; Server Modus verwenden
Database may be already in use: null. Possible solutions: close all other connection(s); use the server mode [90020-199]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:617)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:427)
	at org.h2.message.DbException.get(DbException.java:194)
	...
	at java.sql.DriverManager.getConnection(DriverManager.java:247)
	at de.hsrm.cs.datenbanken.blatt11.Blatt11Test.main(Blatt11Test.java:12)
Caused by: java.lang.IllegalStateException: The file is locked: nio:C:/Temp/h2/bin/test.mv.db [1.4.199/7]
	at org.h2.mvstore.DataUtils.newIllegalStateException(DataUtils.java:883)
	at org.h2.mvstore.FileStore.open(FileStore.java:172)
	at org.h2.mvstore.MVStore.(MVStore.java:390)
	at org.h2.mvstore.MVStore$Builder.open(MVStore.java:3343)
	at org.h2.mvstore.db.MVTableEngine$Store.open(MVTableEngine.java:162)
	... 17 more
Man könnte sie wohl alternativ auch im Server-Modus starten, aber das ist hier nicht nötig.


Blatt 8

Hinweis zu Aufgabe 1e: sucht im Internet mal nach "Multi table delete".


Und ein Nachtrag bzw. eine Korrektur zu Primary und Foreign Keys:
Primary Keys haben bei MySQL/MariaDB generell den Namen "primary". Ich habe heute im Praktikum behauptet, dass man dem einen Namen geben kann:
create table artikel 
( 
  anr int not null,
  name varchar(100),
  constraint artikel_pk primary key (anr)
);
Das wird aber von MySQL/MariaDB ignoriert - der Primary Key hat immer den Namen "primary". Im "create table" wird der Name wohl nur akzeptiert, um zu anderen Datenbanksystemen syntaxkompatibel zu sein.
Löschen kann man ihn so:
alter table artikel drop primary key;

Ein Löschen mit Namensangabe geht schief:
alter table artikel drop constraint  artikel_pk;


Foreign Keys können aber Namen haben. Im folgenden Beispiel wird gezeigt, wie man einen Foreign Key nachträglich erzeugen kann:
create table artikel 
( 
  anr int not null,
  name varchar(100),
  primary key (anr)
);

create table einkauf
(
  einkaufid int not null,
  anr int not null,
  datum date,
  primary key (einkaufid)
  
);
alter table einkauf add CONSTRAINT einkauf_fk1 foreign key (anr) references artikel(anr) on delete cascade;
Diesen Foreign Key kann man mit Angabe des Namens löschen:
alter table einkauf drop CONSTRAINT einkauf_fk1;
Mit folgendem Statement kann man sich das "create table"-Statement anzeigen lassen und sieht dort, dass der Foreign Key tatsächlich den gewünschten Namen hat:
SHOW CREATE TABLE einkauf;


Blatt 6

Einrichten von SquirrelSQL für den Zugriff auf die MariaDB-Hochschul-Datenbank:
Die Schritte sind die gleichen wie unten. Allerdings wird der MariaDB-JDBC-Treiber verwendet: https://downloads.mariadb.com/Connectors/java/connector-java-2.4.1/mariadb-java-client-2.4.1.jar (Einstieg zum Download: https://mariadb.com/kb/en/library/about-mariadb-connector-j/).
Hier muss keine Datei entpackt werden, da wir direkt die Treiber-JAR-Datei heruntergeladen haben.

Im SquirrelSQL links auf "Drivers" klicken, den "MariaDB Driver..." wählen, Rechtsklick und "Modify Driver" aufrufen:

Auf den Karteireiter "Extra Class Path" gehen. Auf "Add" klicken und die eben heruntergeladene JAR-Datei wählen. Dann "List Drivers" klicken. Jetzt in der Combobox unten "org.mariadb.jdbc.Driver" wählen.

Danach den Alias zufügen:
Dem Alias irgendeinen Namen geben. In der Combobox "Driver" den "MariaDB Driver..." wählen. Die URL ist:

jdbc:mysql://mariadb1.local.cs.hs-rm.de:3306/db19s0__
Der letzte Teil ist der Datenbankname, dies entspricht dem PraGA-Login. Die beiden Unterstriche sind die Gruppennummer.
Als "Username" wird ebenfalls der PraGA-Login verwendet, und das Passwort ist natürlich das PraGA-Passwort.

Blatt 5

Einrichten von SquirrelSQL für den Zugriff auf die Hochschul-Datenbank:
Download SquirrelSQL (benötigt Java): https://sourceforge.net/projects/squirrel-sql/files/1-stable/3.9.1-plainzip/ (nehmt "squirrelsql-3.9.1-standard.zip").
Entpacken und starten über "squirrel-sql.bat".

Nach dem Start muss der MySQL-JDBC-Treiber eingerichtet werden: die Datei https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.16.zip herunterladen.
Aus der Zip-Datei die Datei "mysql-connector-java-8.0.16.jar" extrahieren.

Im letzten Praktikum gab es noch ein Problem mit dem neuesten JDBC-Treiber, und wir mussten auf 5.1.47 zurückgehen. Dies ist mittlerweile korrigiert.


Im SquirrelSQL links auf "Drivers" klicken, den "MySQL Driver" wählen, Rechtsklick und "Modify Driver" aufrufen:

Auf den Karteireiter "Extra Class Path" gehen. Auf "Add" klicken und die eben entpackte JAR-Datei wählen. Dann "List Drivers" klicken. Jetzt in der Combobox unten "com.mysql.jdbc.Driver" wählen.

Jetzt auf den Karteireiter "Alias" gehen. Rechtsklick - "New Alias...":

Dem Alias irgendeinen Namen geben. In der Combobox "Driver" den "MySQL Driver" wählen (hat ein blaues Symbol, wenn ihr den Alias richtig angelegt habt). Die URL ist:

jdbc:mysql://mysql1.local.cs.hs-rm.de/db19s0__
Der letzte Teil ist der Datenbankname, dies entspricht dem PraGA-Login. Die beiden Unterstriche sind die Gruppennummer.
Als "Username" wird ebenfalls der PraGA-Login verwendet, und das Passwort ist natürlich das PraGA-Passwort.

Über "Test" kann die Verbindung getestet werden.

Nach dem Verbinden zur Datenbank öffnet sich ein Fenster, in dem ihr auf den Karteireiter "SQL" klickt.
Der markierte Button "Run SQL" führt die markierten SQL-Befehle aus.



Hinweise zu Blatt 5:
Aufgabe 2c: Lösung = "565". Beachtet die Tabellen "musikstueck" und "tontraeger_enthaelt_musikstueck".
Aufgabe 2d: Tabelle "angebot".
Aufgabe 2e: Lösung = "26,618".

Blatt 3

Aufgabe 3: die Kardinalitäten einiger Beispiel meiner Musterlösung stimmten nicht. Korrekt sind:
Ich habe die Bewertungen im PraGA nochmal aktualisiert.


Blatt 4

Beispieldaten für Aufgabe 2 - können in RelaX eingeladen werden: Blatt4Aufgabe2.txt

Beispieldaten für Aufgabe 3 - können in RelaX eingeladen werden: Blatt4Aufgabe3.txt
Hinweis: mit den Beispieldaten kommen folgende Ergebnismengen heraus:
a+b) ..das ist einfach...
c) vier Zeilen: Meier/Gruber Paris 2005, Meier/Huber Paris 2005, Gruber/Huber Paris 2005, Huber/Krämer - New York 2019
d) V_ID = 100


RelaX kann übrigens auch eine Art der Linearen Notation verarbeiten.
Beispiel: die Lösung von Blatt 3, Aufgabe 1.a sieht so aus:

pi did,name,hauptsuperkraft (sigma Drachen.art=Drachenkunde.aid (Drachen cross join Drachenkunde))
In der Linearen Notation ist dies:
A = Drachen cross join Drachenkunde
B = sigma Drachen.art=Drachenkunde.aid (A)
C = pi did,name,hauptsuperkraft (B)
C
In der letzten Zeile muss der Name der letzten Relation stehen.

Das entspricht aber nicht ganz der in der Aufgabenstellung geforderten Notation: statt "=" soll ":=" verwendet werden, und bei jeder links definierten Relation sollen die Spalten angegeben werden:
A(Drachen.did, Drachen.name, Drachen.vater, Drachen.mutter, Drachen.gj, Drachen.gs, Drachen.art, Drachenkunde.aid, Drachenkunde.art, Drachenkunde.beschreibung, Drachenkunde.hauptsuperkraft) := Drachen cross join Drachenkunde
B(Drachen.did, Drachen.name, Drachen.vater, Drachen.mutter, Drachen.gj, Drachen.gs, Drachen.art, Drachenkunde.aid, Drachenkunde.art, Drachenkunde.beschreibung, Drachenkunde.hauptsuperkraft) := sigma Drachen.art=Drachenkunde.aid (A)
C(Drachen.did, Drachen.name, Drachen.hauptsuperkraft) := pi did,name,hauptsuperkraft (B)
Answer := C



Stand 19.06.2019
Historie:
20.05.2019: Erstellt
23.05.2019: Korrektur der Musterlösung Blatt 3
29.05.2019: SquirrelSQL
02.06.2019: SquirrelSQL zur MariaDB, Verbindung zur MySQL geht jetzt auch mit dem neuesten JDBC-Treiber.
19.06.2019: Hinweis Blatt 8, Foreign Keys und Primary Keys