i

Fachkonzept - Strukturen anlegen

Nach der Modellierung der Anforderungen (z.B. als E/R-Schema) wird ein konzeptionelles Modell in ein relationales Schema verwandelt; d.h. die notwendigen Tabellen werden definiert. Für einen Teil der Anforderungen der Fahrschul-Miniwelt könnte das z.B. so aussehen:

Teilschema für die Modellierung einer Fahrschule

Erkennbar sind die Attribute der Tabellen mit ihren Datentypen sowie die Beziehung zwischen der Fahrstunde-Tabelle und der Schueler-Tabelle.
Um diese Struktur in der SQL-Datenbank zu erzeugen, kann man Werkzeuge wie z.B. phpMyAdmin verwenden. Diese nutzen aber intern auch nur SQL-Befehle, die zur DDL - Data Definition Language gehören.

DDL als ein Teil von SQL

Mit dem Befehl CREATE TABLE können neue Tabellen in einer Datenbank angelegt werden.
Damit wird nur die Struktur einer Tabelle festgelegt - es werden noch keine Daten abgespeichert.
Entsprechend erlaubt der Befehl DROP TABLE das Löschen einer Tabelle (mit allen Daten darin).

Wie die Daten über Python angelegt werden können, unterscheidet sich leicht - je nachdem, ob MySQL oder SQLite verwendet werden soll.
Wähle also jetzt die richtige Version aus!

Der folgende Ausschnitt eines Python-Programms benutzt DDL-Befehle, um die oben gezeigten Tabellen zu erzeugen:

[...]
SQLBefehle = """
CREATE TABLE IF NOT EXISTS schueler (
  SNR     integer NOT NULL,
  Vorname varchar(30),
  Name    varchar(50) NOT NULL,
  PRIMARY KEY (SNR)
);
CREATE TABLE IF NOT EXISTS fahrstunde (
  SNR    integer,
  Datum  date,
  Zeit   time,
  PRIMARY KEY (SNR, Datum),
  FOREIGN KEY (SNR) 
        REFERENCES Schueler(SNR)
);
"""
cursor = con.cursor()

try:
  for einzelCursor in cursor.execute(SQLBefehle, multi=True):
    print(einzelCursor._executed.decode('UTF-8'))

   
except mysql.connector.Error as err:
  print("Fehler bei der SQL-Ausführung: %s" % (err))
[...]

Der Befehl CREATE TABLE ist dabei sehr einfach zu lesen und erschließt sich fast von selbst; ein paar Besonderheiten sollen aber am Beispiel erklärt werden:

Befehl Bedeutung
SNR integer NOT NULL definiert ein Attribut namens SNR vom Typ integer (also eine ganze Zahl). Dieses Attribut darf nicht leer bleiben (NOT NULL)
Vorname varchar(30) das Attribut Vorname ist ein string; varchar(30) steht für eine Zeichenkette (variable character), die maximal 30 Zeichen lang sein darf.
PRIMARY KEY (SNR) ist eine Bedingung (engl. Constraint) an die Tabelle: SNR ist der Primärschlüssel
FOREIGN KEY (SNR) REFERENCES schueler(SNR) ist eine weitere Bedingung: SNR ist ein Fremdschlüssel, der sich auf das Attribut SNR in der Tabelle schueler bezieht.

Leider ist SQL an vielen Stellen nicht ganz genormt - nur ein Teil ist in allen relationalen Datenbanksystemen gleich. So ist auch der Zusatz IF NOT EXISTS nicht im "Standard"-SQL vorhanden; er verhindert eine Fehlermeldung, falls die Tabelle schon existiert.

Auch die Datentypen unterscheiden sich stark zwischen den Datenbanksystemen. Nur einige gehören zum SQL-Standard, wie z.B. die oben verwendeten. Übersicht der standardisierten Datentypen:

Datentyp Namen in SQL
varchar(n) Ein string (text) mit der maximalen Länge n. Werden längere Texte eingefügt, so werden diese abgeschnitten.
integer Eine ganze Zahl. Welche maximale bzw. minimale Zahl wirklich gespeichert werden kann, ist vom Datenbanksystem abhängig.
real Speicherung einer Kommazahl - die Genauigkeit hängt wieder vom Datenbanksystem ab. Alternative ist float(n), wobei n für die Anzahl an Nachkommastellen steht.
date Speichert ein Datum (ohne Zeit). Die Darstellung ist in der Regel dem amerikanischen angelehnt (also '2016-06-30' für den 30. Juni 2016)
time Angabe einer Uhrzeit
blob(n) Ein "binäres" Objekt mit maximal n Bytes Länge. Wird z.B. für das Speichern von Bildern, etc. verwendet. Die Art der Speicherung differiert zwischen den verschiedenen Datenbanksystemen.

Exkurs - Verarbeiten von SQL-Skripten in Python

Im Gegensatz zu den letzten Kapiteln wird im Beispiel nicht nur ein SQL-Befehl abgearbeitet, sondern gleich eine Abfolge von Befehlen - ein sogenanntes SQL-Skript. Die einzelnen SQL-Befehle werden dort mit einem Strichpunkt voneinander getrennt.

Damit der Python-Connector nicht nur den ersten Befehl abarbeitet, sondern das gesamte Skript, muss die Verarbeitung des Cursors angepasst werden:

  for einzelCursor in cursor.execute(SQLBefehle, multi=True):
    print(einzelCursor._executed.decode('UTF-8'))

Die execute-Methode führt nacheinander alle SQL-Befehle aus und gibt jeweils einen "normalen" Cursor für diesen Befehl zurück. Bei DDL-Befehlen wird (anders als beim SELECT) keine Rückgabe erwartet, weshalb mit diesen Einzelcursor hier auch nicht weiter gearbeitet wird. Stattdessen wird mit print(...) nur der jeweilige SQL-Befehl ausgegeben.

Der folgende Ausschnitt eines Python-Programms benutzt DDL-Befehle, um die oben gezeigten Tabellen zu erzeugen:

[...]
SQLBefehle = """
CREATE TABLE IF NOT EXISTS schueler (
  SNR     integer NOT NULL,
  Vorname varchar(30),
  Name    varchar(50) NOT NULL,
  PRIMARY KEY (SNR)
);
CREATE TABLE IF NOT EXISTS fahrstunde (
  SNR    integer,
  Datum  date,
  Zeit   time,
  PRIMARY KEY (SNR, Datum),
  FOREIGN KEY (SNR) 
        REFERENCES Schueler(SNR)
);
"""
cursor = con.cursor()

try:
    cursor.executescript(SQLBefehle)
   
except sqlite3.Error as err:
  print("Fehler bei der SQL-Ausführung: %s" % (err))
  raise err # Fehler an übergeordnetes Programm weitergeben
[...]

Der Befehl CREATE TABLE ist dabei sehr einfach zu lesen und erschließt sich fast von selbst; ein paar Besonderheiten sollen aber am Beispiel erklärt werden:

Befehl Bedeutung
SNR integer NOT NULL definiert ein Attribut namens SNR vom Typ integer (also eine ganze Zahl). Dieses Attribut darf nicht leer bleiben (NOT NULL)
Vorname varchar(30) das Attribut Vorname ist ein string; varchar(30) steht für eine Zeichenkette (variable character), die maximal 30 Zeichen lang sein darf.
PRIMARY KEY (SNR) ist eine Bedingung (engl. Constraint) an die Tabelle: SNR ist der Primärschlüssel
FOREIGN KEY (SNR) REFERENCES schueler(SNR) ist eine weitere Bedingung: SNR ist ein Fremdschlüssel, der sich auf das Attribut SNR in der Tabelle schueler bezieht.

Leider ist SQL an vielen Stellen nicht ganz genormt - nur ein Teil ist in allen relationalen Datenbanksystemen gleich. So ist auch der Zusatz IF NOT EXISTS nicht im "Standard"-SQL vorhanden; er verhindert eine Fehlermeldung, falls die Tabelle schon existiert.

Auch die Datentypen unterscheiden sich stark zwischen den Datenbanksystemen. Nur einige gehören zum SQL-Standard, wie z.B. die oben verwendeten. Übersicht der standardisierten Datentypen:

Datentyp Namen in SQL
varchar(n) Ein string (text) mit der maximalen Länge n. Werden längere Texte eingefügt, so werden diese abgeschnitten.
integer Eine ganze Zahl. Welche maximale bzw. minimale Zahl wirklich gespeichert werden kann, ist vom Datenbanksystem abhängig.
real Speicherung einer Kommazahl - die Genauigkeit hängt wieder vom Datenbanksystem ab. Alternative ist float(n), wobei n für die Anzahl an Nachkommastellen steht.
date Speichert ein Datum (ohne Zeit). Die Darstellung ist in der Regel dem amerikanischen angelehnt (also '2016-06-30' für den 30. Juni 2016)
time Angabe einer Uhrzeit
blob(n) Ein "binäres" Objekt mit maximal n Bytes Länge. Wird z.B. für das Speichern von Bildern, etc. verwendet. Die Art der Speicherung differiert zwischen den verschiedenen Datenbanksystemen.

Exkurs - Verarbeiten von SQL-Skripten in Python

Im Gegensatz zu den letzten Kapiteln wird im Beispiel nicht nur ein SQL-Befehl abgearbeitet, sondern gleich eine Abfolge von Befehlen - ein sogenanntes SQL-Skript. Die einzelnen SQL-Befehle werden dort mit einem Strichpunkt voneinander getrennt.

Damit der Python-Connector dies kann, wird nun die Methode cursor.executescript(...) verwendet. Diese hat allerdings den Nachteil, dass Fehler in der Ausführung nur als Ganzes erkannt werden.

Suche

v
3.4.4.2
dev.inf-schule.de/datenbanksysteme/zugriff/ddl/konzept_ddl
dev.inf-schule.de/3.4.4.2
dev.inf-schule.de/@/page/P8FvcYHs7useRzIi

Rückmeldung geben