llen einer Oracle-Datenbank

Transcription

llen einer Oracle-Datenbank
Das Erzeugen und Füllen einer
Oracle-Datenbank
Holger Jakobs – [email protected], [email protected]
2008-05-15
Inhaltsverzeichnis
1 Oracle vs. ANSI-SQL
1
2 Erzeugung einer Datenbank
2.1 Benutzer und Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2 Anlegen von Tabellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3
3
3 Anlegen der Sportvereins-Datenbank
3.1 Erzeugen der Tabellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2 Laden der Daten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3 Vergeben von Rechten . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
3
4
5
4 Sperrstrategie
6
5 Integritäten und ihre Überwachung
5.1 Primärschlüssel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 Fremdschlüssel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
6
6
6 Andere Integritäten
6.1 CHECK-Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 Prüfzeitpunkt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
8
9
Hinweis auf Online-Dokumentation zu Oracle auf den Unix-Rechnern im b.i.b. Bergisch
Gladbach: https://www.bg.bib.de/Bibliothek/oracle/index.htm
1 Oracle vs. ANSI-SQL
Grundsätzlich sollte die Handhabung von Datenbanken durch den SQL-Standard genormt
sein. Allerdings definiert der SQL-Standard nicht alle Kommandos – insbesondere nicht,
1
1 ORACLE VS. ANSI-SQL
wie eine neue Datenbank erzeugt wird. Die Erzeugung von Tabellen und deren Abfrage ist weitestgehend genormt. Die einzelnen Datenbanksysteme setzen aber alle nur eine
Teilmenge des Standards um.
Um sich von den Unterschieden ein Bild machen zu können, setzen wir neben Oracle auch
PostgreSQL1 ein, ein Open Source Datenbanksystem. Tatsächlich war es lange Zeit das einzige Open Source Datenbanksystem, das man als ein richtiges Datenbanksystem bezeichnen kann, weil es Fremdschlüssel und Transaktionen (und auch gespeicherte Prozeduren,
Trigger, Vererbung usw.) unterstützt. Alternativ könnte man auch Firebird2 verwenden.
Bei Oracle werden die Datenbanken nicht als Dateien im normalen Dateisystem unter
dem Homedirectory gespeichert (sowas tun nur ganz popelige Systeme), sondern in einem
besonders geschützten Bereich. Die Dateien gehören auch keinem normalen Benutzer. Das
ist überhaupt kein Problem, da man nur über die vom DBMS (Datenbank-ManagementSystem) definierten Kommandos auf die Daten zugreift und auch nur so zugreifen darf.
Der Sicherheit der Daten vor unbefugtem Zugriff wegen musste man diesen Weg wählen.
Ähnlich ist es auch bei allen anderen Datenbanksystemen.
Es besteht auch die Möglichkeit,
die Datenbank außerhalb des Dateisystems auf einem Raw Device“,
”
d. h. einer eigenen Partition ohne
Dateisystem anzulegen. Das macht
das Datenbanksystem zwar hardwareabhängiger und erschwert die Portierung auf andere Betriebssysteme,
aber diesen Aufwand kann man bei
Oracle durchaus treiben. Für die
Performance ist das auf jeden Fall
von Vorteil.
Für den Zugriff auf OracleDatenbanken benötigen Sie eine
Zugangskennung, die bei uns mit
dem Windows-/Unix-Login-Benutzernamen übereinstimmt. Das Kennwort dagegen ist eigenständig. An Ihr Oracle-Kennwort
kommen Sie durch Eingeben des Kommandos dabpasswd ora in einem Terminalfenster unter Linux. Nach der Ausführung gibt es in Ihrem HOME-Directory eine nur für Sie lesbare
Datei namens dabpw_oracle.sql mit nebenstehendem Inhalt:
Sie können Ihr Kennwort anschließend ändern mit SERVER
= dbserver2
dem Kommando ALTER USER. Durch erneutes Aufrufen USERNAME = bbXXXXXX
des o. g. Kommandos können Sie jederzeit wieder das PASSWORD = YYYYYYYY
Standard-Kennwort einstellen.
DATABASE = ORA10
SERVICE = ORA10.BG.BIB.DE
1) http://www.postgresql.org
2) http://www.firebirdsql.org/
2
3 ANLEGEN DER SPORTVEREINS-DATENBANK
2 Erzeugung einer Datenbank
2.1 Benutzer und Schemas
Wenn Sie sich bei Oracle mit Hilfe des Worksheet oder des Programms TOra anmelden,
haben Sie schon Ihren eigenen logischen Datenbereich (Schema), der von den Systembetreuern gemeinsam mit Ihrer Oracle-Benutzerkennung angelegt wurde. Sie können also gleich
mit dem Erzeugen von Tabellen loslegen. Da wir nur eine einzige, große Oracle-Datenbank
namens ORA10 haben, die für jeden Benutzer ein Schema enthält, besteht leider keine Möglichkeit, explizit weitere Schemas anzulegen, um den eigenen Bereich weiter zu unterteilen,
da es keine Subschemas (vergleichbar Unterverzeichnissen) gibt.
Jeder Benutzer hat immer ein gleichnamiges Schema, eigenständige Schemas ohne gleichnamigen Benutzer gibt es bei Oracle nicht. Zitat aus der Oracle-Dokumentation: A schema
”
is owned by a database user and has the same name as that user.“
Kurz gesagt: Das Erzeugen einer Datenbank oder eines Schemas fällt bei uns flach, weil
Sie keine eigene Datenbank haben und weil Sie keine weiteren Benutzer anlegen dürfen. Sie
legen also gleich mit dem Erzeugen von Tabellen los.
2.2 Anlegen von Tabellen
Erzeugen Sie Tabellen möglichst nicht interaktiv, sondern machen Sie vorher einen ordentlichen Entwurf und schreiben Sie die Erzeugungskommandos in eine Datei. Auf diese Weise
können Sie die Datenbank immer wieder auf dieselbe Art erzeugen, falls Sie sie einmal
löschen müssen oder Veränderungen zu Übungszwecken wiederholen möchten.
Sollte beim Erzeugen der Tabellen etwas schiefgehen, so kann man sie wieder löschen,
die Generatordatei modifizieren und erneut beginnen. Dies wiederholt man so lange, bis
die Datenbank mit ihren Tabellen den Wünschen entspricht. Darüber hinaus ist die Generatordatei auch ein sehr schönes Protokoll über die Datenbank. Aus manchen Datenbanken
kann man immer wieder eine Generatordatei extrahieren – für Oracle gilt dies leider nicht
ohne besondere Hilfsmittel (wie zum Beispiel TOra). Die extrahierte Version ist außerdem
meist nicht so schön und übersichtlich wie das von Hand Geschriebene und enthält es evtl.
nicht portable Syntax-Elemente.
3 Anlegen der Sportvereins-Datenbank
Die Generatordateien stehen im Datenbank-Portal zum Download zur Verfügung.
3.1 Erzeugen der Tabellen
-- Version fuer Oracle
-- http://www.bg.bib.de/portale/dab/Quelltexte/createspieler_ora.sql
CREATE TABLE spieler (
3
3.2 Laden der Daten
3 ANLEGEN DER SPORTVEREINS-DATENBANK
spielnr
integer primary key,
spielname character varying(15) NOT NULL,
vorname
varchar(15) NOT NULL,
titel
character(3),
gebjahr
integer NOT NULL,
geschl
character
constraint geschlecht
check (geschl='M' or geschl='W'),
eintritt integer NOT NULL,
plz
character(5) NOT NULL,
ort
character(20) NOT NULL,
verbnr
character(4),
constraint "nur_Lebende" check (eintritt >= gebjahr)
);
CREATE TABLE teams (
teamnr
integer primary key,
spielnr
integer NOT NULL references spieler,
liga
character(10) NOT NULL
);
CREATE TABLE wettkaempfe (
teamnr
integer references teams,
spielnr
integer references spieler,
gewonnen integer NOT NULL,
verloren integer NOT NULL,
primary key (teamnr, spielnr)
);
CREATE TABLE strafen (
zahlnr
integer primary key,
spielnr
integer NOT NULL references spieler,
datum
date default CURRENT_DATE NOT NULL,
betrag
numeric(10,2) NOT NULL check (betrag > 0.0)
);
Nach der Erzeugung sollte man sich davon überzeugen, dass alle Tabellen auch wirklich
angelegt worden sind. Eine Übersicht über die existierenden Tabellen bekommt man mit
dem Schema Browser, siehe auch Abbildung 1 auf der nächsten Seite.
3.2 Laden der Daten
4
3 ANLEGEN DER SPORTVEREINS-DATENBANK
3.3 Vergeben von Rechten
Abbildung 1: Schema Browser von Tora
Zum Importieren von Daten aus externen Dateien (ASCII-Dateien
mit fester oder variabler Satzlänge) verwendet man das Tool
SQL*Loader“, das im Handbuch Database Utitlities“ in der Oracle”
”
Dokumentation erläutert ist. Zum Daten-Im- und -Export gibt es auch
ein Kapitel im Datenbank-Portal unter Administration“.
”
Ohne Verwendung dieses Loaders kann man Daten mittels INSERT-Statements oder über
die Datenansicht im Schema-Browser von TOra eingeben, was allerdings nicht sonderlich
komfortabel ist. Darüber hinaus kann man sich auch ein kleines Programm oder Script
hierfür schreiben.
3.3 Vergeben von Rechten
Rechte können an einen einzelnen Benutzer vergeben werden, indem man das GRANT-Kommando verwendet. Es können einem Benutzer Rechte für die diversen Aktionen auf eine
Tabellen gegeben werden. Weggenommen werden diese Rechte mit REVOKE. Die Aktionen
sind SELECT (Lesen einer Tabelle), UPDATE (Verändern von Tabelleninhalten), INSERT (Einfügen von neuen Tupeln) und DELETE. Hier werden Fritz und Emma die Lese-, Änderungsund Einfügerechte an der Tabelle spieler gegeben. Anschließend werden Fritz alle Rechte
an den Tabellen teams und wettkaempfe entzogen.
grant select, update on spieler to fritz, emma;
revoke all on teams, wettkaempfe from fritz;
Natürlich kann man noch viel mehr Rechte vergeben, z. B. überhaupt das Recht, sich an
der Datenbank anzumelden, Rechte an einzelnen Spalten, an Sichten (Views) usw. Dies
kann in der Oracle-Dokumentation unter dem Stichwort GRANT nachgelesen werden.
Es gibt bei Oracle keine Benutzergruppen wie in einige anderen Datenbanken. Im ANSIStandard kommen sie auch nicht vor. Vielmehr gibt es bei Oracle ein Konzept namens
ROLE (Rolle). Dieses Rollenkonzept ist deutlich flexibler und leistungsfähiger als das recht
einfache Gruppenkonzept, aber auch komplexer in der Handhabung.
5
5 INTEGRITÄTEN UND IHRE ÜBERWACHUNG
4 Sperrstrategie
Bei Oracle werden keine Informationen bezüglich Sperrstrategien in der Datenbank gespeichert. Der Default-Isolation-Level ist read committed“ und kann mittels ALTER SES”
SION geändert weren. Im SQL-Standard gibt es READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ und SERIALIZABLE. Der Standard schreibt SERIALIZABLE als Default vor
(woran sich aber aus Performance-Gründen kaum ein Datenbank-System hält). Das Standardkommando zum Ändern des Isolation Levels ist SET TRANSACTION ISOLATION LEVEL
level.
5 Integritäten und ihre Überwachung
5.1 Primärschlüssel-Integrität
Die Primärschlüssel-Integrität legt fest, dass in einer Tabelle ein Primärschlüssel-Wert nur
ein einziges Mal vorkommen darf. Man kann also kein zweites Tupel mit demselben Primärschlüssel-Wert eintragen, es wird daher von der Datenbank abgelehnt.
Bei Oracle ist man nicht verpflichtet, einen Primärschlüssel festzulegen. Legt man keinen
fest, können auch doppelte Tupel vorkommen, was gegen das relationale Modell verstößt.
Daher sollte man unbedingt einen Primärschlüssel angeben.
5.2 Fremdschlüssel-Integrität
Die Fremdschlüssel-Integrität wird über FOREIGN-KEY-Klauseln der Datenbank bekannt
gemacht und von dieser überwacht. Intern werden dazu entsprechende Constraints (Beschränkungen) erzeugt.
Viele Beziehungsintegritäten können so über FOREIGN-KEY-Klauseln überwacht werden.
Komplexere Integritätsregeln sind nicht durch einfache Klauseln darstellbar und müssen auf
andere Weise überwacht werden, z. B. durch entsprechende SQL-Prozeduren und Trigger.
Grundsätzlich beziehen sich Fremdschlüssel auf den Primärschlüssel der referenzierten
Tabelle. In Ausnahmefällen können sie sich aber auch auf andere Spalten beziehen, für
die ein eindeutiger Index existiert (entweder durch CREATE INDEX explizit angelegt oder
durch eine UNIQUE-Klausel implizit erzeugt). Dann muss man bei der REFERENCES-Klausel
neben der referenzierten Tabelle angeben, auf welche Spalte(n) man sich bezieht, z. B. REFERENCES station (sname), wenn man sich auf die Spalte sname in der Tabelle station
bezieht.
Was passiert nun bei einem Verstoß gegen eine Integritätsbedingung? Grundsätzlich wird
die Aktion abgelehnt. Beim Löschen (und teilweise auch beim Aktualisieren) von Tupeln
dagegen kann man bei einigen SQL-Systemen, z. B. Oracle und PostgreSQL, aus einer Reihe
von Reaktionsweisen auswählen. Die Möglichkeiten sind in Tabelle 1 auf der nächsten Seite
dargestellt.
Auch beim Einfügen von Datensätzen haben die Restriktionen eine Auswirkung: Das Einfügen eines untergeordneten Tupels ist nur dann erlaubt, wenn das übergeordnete bereits
6
5 INTEGRITÄTEN UND IHRE ÜBERWACHUNG
(ohne Zusatz)
ON DELETE
CASCADE
ON DELETE
SET NULL
ON DELETE
SET DEFAULT
5.2 Fremdschlüssel
bewirkt, dass das Löschen eines übergeordneten Tupels bei Vorhandensein untergeordneter Tupel nicht erlaubt wird. Solange eine
Spielnummer also bei Wettkämpfen, Strafen oder woanders vorkommt, kann der zugehörige Spieler nicht gelöscht werden – es wird
ein Fehler gemeldet. Im ANSI-SQL-1992-Standard und bei manchen anderen Datenbanken kann man dies auch explizit setzen mit
ON DELETE NO ACTION oder (nahezu gleichbedeutend) ON DELETE
NO ACTION
bewirkt, dass beim Löschen eines übergeordneten Tupels die zugehörigen abhängigen Tupel mitgelöscht werden. Beispiel: Ein Spieler wird gelöscht. Als Folge werden alle Tupel in allen abhängigen
Tabellen mitgelöscht, d. h. seine Spielergebnisse in der WettkampfTabelle, seine Strafen in der Strafen-Tabelle und auch sein Team
in der Teams-Tabelle. Letzteres könnte in einer Art Domino-Effekt
auch alle Wettkampf-Ergebnisse dieses Teams löschen.
bewirkt, dass beim Löschen eines übergeordneten Tupels die Referenz im abhängigen Tupel auf NULL gesetzt wird. Beispiel: Ein Spieler wird gelöscht, der noch in der Tabelle Wettkämpfe vorhanden
ist. Als Folge wird in der Tabelle Wettkämpfe die Spielernummer
bei den betroffenen Tupeln auf NULL gesetzt. Dieses Attribut muss
hierfür natürlich NULL-Werte erlauben.
gibt es zwar im ANSI-SQL-1992-Standard, aber nicht bei Oracle.
Es bewirkt, dass beim Löschen eines übergeordneten Tupels die
Referenz im abhängigen Tupel auf den default-Wert gesetzt wird.
Sofern dieser nicht angegeben ist, ist er ohnehin NULL.
Tabelle 1: ON DELETE-Möglichkeiten
existiert. Man kann also keinen Spieler bestrafen, der nicht als Spieler selbst eingetragen
ist.
Bei Oracle gibt es – in Abweichung von ANSI-SQL-1992-Standard und im Unterschied
zu PostgreSQL – keine ON UPDATE-Klausel. Man kann hier argumentieren, dies sei bei den
bei Oracle üblichen großen Datenmengen auch nicht sinnvoll.
Beispiel einer Datenbank-Tabellen-Definition in ORACLE oder PostgreSQL:
CREATE TABLE TRAINER (
TRAINER_NR
SMALLINT
NOT NULL,
TRAINER_NAME
CHAR (20) NOT NULL,
PRIMARY KEY (TRAINER_NR));
CREATE TABLE MITARBEITER (
7
6 ANDERE INTEGRITÄTEN
MITARB_NR
SMALLINT
NOT NULL,
MITARB_NAME
CHAR (20) NOT NULL,
PRIMARY KEY (MITARB_NR));
CREATE TABLE KURS (
KURS_NR
SMALLINT
NOT NULL,
BEGINN_DATUM
DATE,
TRAINER_NR
SMALLINT,
PRIMARY KEY (KURS_NR),
FOREIGN KEY (TRAINER_NR) REFERENCES TRAINER
ON DELETE SET NULL);
CREATE TABLE KURSTEILNEHMER (
KURS_NR
SMALLINT
NOT NULL,
MITARB_NR
SMALLINT
NOT NULL,
BEURTEILUNG
SMALLINT,
PRIMARY KEY (KURS_NR, MITARB_NR),
FOREIGN KEY (MITARB_NR) REFERENCES MITARBEITER
ON DELETE CASCADE,
FOREIGN KEY (KURS_NR)
REFERENCES KURS
-- keine ON DELETE-Klausel => ON DELETE NO ACTION
);
Oracle erlaubt es nicht, explizit die Klausel ON DELETE NO ACTION anzugeben. Wenn man
nichts angibt, gilt dies sowieso als default-Wert.
6 Andere Integritätsbedingungen und ihre Überwachung
6.1 CHECK-Constraints
Es gibt noch weitere Möglichkeiten, Integritäten automatisch überprüfen zu lassen, ohne
gleich zu Prozeduren und Triggern zu greifen: die CHECK-Bedingungen. Sie werden beim
Erzeugen von Tabellen mitgegeben oder nachträglich eingebaut (über ALTER TABLE). Sie
können einfache Bedingungen enthalten, üblicherweise Vergleiche mit anderen Spaltenwerten aus demselben Tupel (dann als CHECK-Klausel auf Tabellen-, nicht auf Attribut-Ebene)
oder mit festen Werten, um den Wertebereich einzugrenzen. Ein Vergleich mit dem aktuellen Datum (CURRENT_DATE) oder anderen CURRENT-Werten ist bei Oracle leider nicht
möglich, sondern kann nur über Trigger erreicht werden. Der Standard verlangt dies allerdings auch nicht.
Immerhin lässt sich hiermit in der Sportlerdatenbank sicherstellen, dass niemand vor seiner Geburt in den Verein eintritt, dass keine Strafen mit negativen Beträgen eingetragen
werden oder dass bei Geschlecht etwas anderes eingegeben wird als ’M’ oder ’W’. CHECK-
8
6 ANDERE INTEGRITÄTEN
6.2 Prüfzeitpunkt
Bedingungen können bei der Definition eines Attributs angegeben werden oder als eigenständige Angaben für die Tabelle erfolgen – genau wie die Schlüssel und Referenzangaben
auch, Anwendung siehe Abschnitt 3 auf Seite 3.
Gemäß Standard lassen sich CHECK-Bedingungen auch nachträglich einfügen, indem man
die Tabelle ändert. Hätten wir die Prüfung, dass das Geburtsjahr kleiner oder gleich dem
Eintrittsjahr ist, nicht in der Tabellengenerierung drin, könnten wir das nachträglich einbauen mit:
ALTER TABLE spieler ADD CONSTRAINT "keine Ungeborenen"
CHECK (gebjahr <= eintritt);
Bei Oracle kann man Tabellen jederzeit umbenennen (ALTER TABLE Tabellenname RENAME
TO neuerTabellenname . Attribute kann man mittlerweile auch umbenennen mit ALTER
TABLE Tabellenname RENAME COLUMN Spaltenname TO neuer-Spaltenname , nicht nur
hinzufügen: ALTER TABLE Tabellenname ADD (Spaltenname Typ ). Diese Syntax weicht
etwas von der Syntax im Standard ab: ALTER TABLE Tabellenname ADD COLUMN Spaltenname Typ . Dafür ist es bei Oracle (über den Standard hinaus) auch möglich, vorhandene Attribute wieder zu löschen: (ALTER TABLE Tabellenname DROP (Spaltenname )
Beim Eintragen von Constraints werden auch bestehende Tupel auf die Einhaltung der
Bedingung geprüft. Sollten sie der Bedingung widersprechen, so können sie nicht eingetragen werden. Löschen kann man alle Arten von Constraints mit ALTER TABLE Tabellenname DROP CONSTRAINT constraintname . Hierzu muss man den Namen des Constraints
kennen, wozu es praktisch ist, diese in TOra leicht nachschauen zu können. Allerdings ist
es auch eine gute Idee, alle Contraints mit einem Namen zu versehen, weil dieser Name
beim Verletzten des Constraints in der Fehlermeldung erscheint und dem Anwender einen
Hinweis geben kann.
Probieren Sie die CHECK-Bedingungen aus, indem Sie in Ihre Datenbank(en) welche eingeben, sich die veränderte Anzeige in TOra anschauen und sowohl manuell als auch mit
Hilfe von Programmen (später, siehe Kapitel Embedded SQL“ und JDBC“) und über den
”
”
SQL-Loader Daten eingeben bzw. verändern.
Geben Sie Daten ein, die den Constraints nicht genügen und notieren Sie sich, wie die
Datenbank auf falsche“ Daten reagiert.
”
6.2 Prüfzeitpunkt von Constraints
Bei Constraints kann man wahlweise angeben, ob diese immer sofort, d. h. nach jedem
Kommando, oder aber erst am Ende der Transaktion geprüft werden. Dieses Verzögern bis
zum Transaktionsende kann man auch nachträglich für eine einzelne Transaktion einstellen,
sofern es nicht verboten wurde. Ohne Angaben werden Constraints nach jedem Kommando
geprüft, aber die Prüfung kann verzögert werden.
Man kann die Einstellungen verändern, indem man am Ende der Constraint-Klausel
zusätzlich eine oder beide der folgenden Klauseln angibt:
[ NOT ] DEFERRABLE
INITIALLY { IMMEDIATE | DEFERRED }
9
6.2 Prüfzeitpunkt
6 ANDERE INTEGRITÄTEN
Mit dem Verzögern von Constraints kann man erreichen, dass man voneinander wechselseitig abhängige Tupel überhaupt eintragen kann.
Anwendungsbeispiel: Schreibt man für ausnahmslos jeden Mitarbeiter einen von ihm
selbst verschiedenen Vertreter vor, wird man kein Tupel in die leere Tabelle eintragen
können, weil man vorher schon ein anderes Tupel benötigt, auf das man verweist – den
Vertreter. Mit Hilfe der Verzögerung des zugehörigen Constraints wird es möglich, Einträge
vorzunehmen. Es muss lediglich sichergestellt werden, dass vor Ende der Transaktion jedes
Tupel auf ein anderes verweist.
$Id: erzeugen_fuellen_ora.tex,v 1.5 2008-05-15 10:56:00 hj Exp $
10