Erhalten Sie Zugang zu diesem und mehr als 300000 Büchern ab EUR 5,99 monatlich.
Dies ist der zweite Teil meines Lehrbuches zum Thema "Relationale Datenbanken und SQL". Er beschreibt die Dinge, die vor allem für jene interessant sind, die praktisch mit Relationalen Datenbanken arbeiten oder das in absehbarer Zeit tun werden: In erster Linie sind es die Dinge, die Datenbank-Administratoren oder Programmierer wissen müssen. Im Einzelnen werden Tuning, Berechtigungsvergabe, die Programmierung von Clients, die Server-Programmierung, die Systemtabellen, Tricks zur Ersparung von Programmieraufwänden, die bei Datenbanken äußerst komplizierten Probleme der Internationalisierung und weitere - insbesondere praktische - Probleme behandelt.
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 163
Veröffentlichungsjahr: 2023
Das E-Book (TTS) können Sie hören im Abo „Legimi Premium” in Legimi-Apps auf:
Lachen und Lernen ein Leben lang:
Relationale Datenbanken und SQL
Teil 2
Harald Kellerwessel
Lachen und Lernen ein Leben lang:
Relationale Datenbanken und SQL
Teil 2
Harald Kellerwessel
Verlag:
epubli – ein Service der neopubli GmbH, Berlin
Texte: © Copyright by Harald Kellerwessel
Umschlaggestaltung:
© Copyright by Harald Kellerwessel
Verlag:
epubli – ein Service der neopubli GmbH, Berlin
Harald Kellerwessel
Sprendlinger Straße 50
55546 Pfaffen-Schwabenheim
E-Mail: harald.kellerwessel@web.de
Homepage: www.haraldk.de
Sehen wir es realistisch: Wer ein Schloss an der Türe, aber den Schlüssel noch nie benutzt hat, braucht dieses Kapitel nicht zu lesen.
Ich bin übrigens von meinen Eltern von klein auf darauf getrimmt worden, im Auto den Sicherheitsgurt anzulegen. Das war zwanzig Jahre lang überflüssig. Aber ohne Gurt hätte ich bereits vor 35 Jahren mein Leben auf der Autobahn von Aachen nach Köln ausgehaucht. Auch Datenschutz und Datensicherheit interessieren nur in ganz seltenen Fällen – aber wehe, wenn einer dieser Fälle mal eintritt, und man hat nicht vorgesorgt!
Sie werden hier lernen, wie man mit SQL ganz genau festlegen kann, wer was darf: Wer die Kundenadressen zu sehen kriegt und wer die Einkaufspreise der Artikel. Und wer Aufträge bis zu welcher Höhe und unter welchen Bedingungen erteilen darf, kann man auch im Einzelnen ganz genau bestimmen.
Wir werden hier aber auch noch etwas mehr machen: Es kommt nämlich nicht nur darauf an, dass man weiß, welche Mittel zur Verfügung stehen, um Anforderungen umzusetzen. Wie man den Bedarf auf den Gebieten Datenschutz und Datensicherheit für ein System bestimmt, wird in diesem Kapitel ebenso – zumindest im Groben – thematisiert werden. Das wird vom Schutz personenbezogener Daten über Methoden, um Hackern das Leben schwer zu machen, bis zum simplen Anfertigen von Sicherheitskopien einer ganzen Datenbank reichen.
Ein sechzehnjähriges Mädchen macht seine Tagebucheinträge ganz fortschrittlich auf dem Computer. Mit automatisch vergebenem Zeitstempel. Um das außerordentlich gute Vertrauensverhältnis zu den Eltern nicht zu untergraben, möchte sie Ihnen sogar Einblicke in ihr Tagebuch gewähren. Das machen schließlich auch alle ihre Klassenkameradinnen, wie ihr diese – natürlich nur unter dem Siegel äußerster Verschwiegenheit – anvertraut haben.
Jetzt gibt es (wirklich nur ganz ausnahmsweise) im Tagebuch auch Einträge, die ein sechzehnjähriges Mädchen seinen Eltern nicht unbedingt zeigen möchte: es könnte schließlich sein, dass die Ahnen noch nicht aufgeklärt sind – auch, wenn Vater und Mutter beide den Dr. med. haben und seit zwei Jahrzehnten gemeinsam erfolgreich eine gynäkologische Praxis führen. Ach ja, ab und zu arbeiten Mammi und Papi – natürlich immer nur ganz kurz zur Vertretung – auch in einer Praxis für Sexualtherapie.
Langer Rede, kurzer Sinn: unsere junge Dame macht also sicherheitshalber in der Tabelle mit den Tagebucheinträgen eine zusätzliche Spalte „freigegeben_fuer_die_elternBOOLEAN DEFAULT FALSE“ und legt eine VIEW an, die sie theatralisch „mein_tagebuch“ nennt – natürlich ohne „_view“, denn die Eltern sollen ja nichts merken:
Da kann sie Ihnen ruhig das Lesen erlauben.
Zunächst legt sie zwei Benutzer (Fachsprache: USER) an:
CREATE USER mutti ENCRYPTED PASSWORD 'FrauDr.1';
CREATE USER papa ENCRYPTED PASSWORD 'HerrDr.2'
Die Passwörter sind selbstverständlich verschlüsselt („ENCRYPTED“). Über vernünftige Kennwörter (Fachsprache: passwords) hat sie sich lange Gedanken gemacht. Kennwörter sollten – egal, ob bei Datenbanken oder irgendwo anders –schwer zu knacken und schwer für andere zu erraten sein. Aber der jeweilige Benutzer muss sie sich leicht merken können:
Da bei Datenbanken häufig viele Benutzer dieselben Berechtigungen benötigen, fast man sie zusammen zu GROUPs oder ROLEs:
CREATE ROLE eltern;
GRANT eltern TO mutti;
GRANT eltern TO papa;
GRANT SELECT ON mein_tagebuch TO eltern
Für Mutti und Papa sieht es jetzt z.B. So aus;
SELECT * FROM mein_tagebuch
datum | eintrags_text
------------+-------------------------
12. APR 22 | Dies ist 1 dritter Test
Unserem sechzehnjährigen Mädchen bietet sich da ein anderer Anblick:
SELECT
eintrags_datum,
eintrags_text,
freigegeben_fuer_die_eltern AS fe
FROM tagebucheintraege_tabl
Ergebnis:
eintrags_datum | eintrags_text | fe
----------------------------+-------------------------+---
2022-04-12 20:26:03.501131 | Dies ist 1 Test | f
2022-04-12 20:30:40.508178 | Dies ist 1 zweiter Test | f
2022-04-12 20:31:27.370511 | Dies ist 1 dritter Test | t
In der letzten Zeile am Ende sehen wir ein „t“ für TRUE, also „wahr“. Darüber steht zweimal ein „f“ für FALSE, also „falsch“. Also steht nur bei einem Datensatz das „freigegeben_fuer_die_eltern“ auf wahr, also ist auch nur die betreffende Zeile für Mutti und Papa zu sehen.
Ganz kurz noch mal, wie es im Prinzip geht:
Das Schöne dabei: Man kann passende Berechtigungen für jede in Frage kommende Art Datenbankobjekt und für jeden einzelnen Benutzer (bzw. praktischer: für jede Rolle, sprich: Gruppe) vergeben. Für uns interessant ist aber glücklicherweise nur ein Bruchteil der möglichen Berechtigungsarten („Privileges“):
Den Zusatz „TABLE“ braucht man weder bei physikalischen Tabellen, noch bei VIEWs. Ansonsten muss die Art des Datenbankobjektes immer angegeben werden. Wichtig ist noch, dass auch alle in Frage kommenden Berechtigungen auf einmal erteilt werden können: Dann heißt es nicht SELECT, EXECUTE oder INSERT, sondern einfach „ALL“.
Ein USER kann auch gleichzeitig mehrere Rollen zugeteilt bekommen. Dann kann er mit „SET ROLE“ diejenige davon auswählen, die er gerade benötigt (… sofern sein RDBMS diesen Befehl unterstützt).
(Die Anmeldung am Computer oder einem System wie Email oder Datenbank nennt man login.)
Ein Beispiel mit dem RDBMS „postgreSQL“:
postgres=> set role eltern;
SET
postgres=> select current_role, session_user;
current_role | session_user
--------------+--------------
eltern | postgres
Das Aufheben irgendwelcher Berechtigungen geschieht mit dem Befehl REVOKE. Eigentlich genau entsprechend zu dem ursprünglichen GRANT-Statement, aber mit einer wichtigen Ausnahme: Jetzt heißt es nicht „TO“, sondern „FROM“. (Das „ON“ bleibt stehen!) Beispiel:
REVOKE SELECT ON mein_tagebuch FROM eltern
Mit Hilfe des GRANT ON VIEWs kann man schon sehr genau steuern, wer worauf lesend zugreifen darf. Um aber auch ebenso präzise festlegen zu können, wer unter welchen Umständen und wie im Einzelnen ein INSERT, UPDATE oder DELETE auf eine oder mehrere Tabellen auszuführen berechtigt ist, gibt es einen sehr hilfreichen Zusatz beim Anlegen von FUNCTIONs bzw. PROCEDUREs.
Jetzt muss ich leider etwas vorgreifen: Also zum einen muss man wissen, dass FUNCTIONs und PROCEDUREs nicht nur SELECTs ermöglichen, sondern auch jede Art von schreibenden Zugriffen. Man kann dabei angeben, ob während der Ausführung die Berechtigungen
Wenn ich also eine Tabelle habe, und an den Daten darin nur ganz bestimmte Änderungen erlauben möchte, arbeite ich nicht mit
GRANT ALL ON mayne_tabelle TO jemand_anders
sondern erstelle mir eine oder mehrere Funktionen mit der zusätzlichen Klausel „SECURITY DEFINER“ anstelle des standardmäßigen „SECURITY INVOKER“. (So heißt es bei postgreSQL. Andere RDBMS bieten ähnliche Möglichkeiten unter Schlagworten wie „SQL SECURITY“, „AUTHID“ oder „EXECUTE_AS“.)
Mir gehört mayne_tabelle und ich habe auch mayne_funktion definiert. Wenn ich also jetzt eingebe:
GRANT EXECUTE ON mayne_funktion TO jemand_anders
kann dieser jemand anders mayne_funktion aufrufen und dabei alles mit mayne_tabelle anstellen, was die Funktion mayne_funktion zulässt. Der Standard ist SECURITY INVOKER (also „Aufrufender“): Jeder Versuch der Funktion mayne_funktion auf mayne_tabelle zuzugreifen, würde jetzt jemand_anders zugerechnet und zu der Fehlermeldung „keine Berechtigung für Tabelle mayne_tabelle“ (oder einer ähnlichen) führen.
(Für diejenigen unter den Lesern, die doch schon etwas Vorkenntnisse mitbringen: Das „SECURITY DEFINER“ entspricht ziemlich genau dem Setuid-Bit unter Unix.)
In postgreSQL – andere RDBMS bieten das nur eingeschränkt oder gar nicht – kann man als Rückgabewert einer Funktion eine Tabelle festlegen:
Das „LANGUAGE SQL“ ist eine Spezialität von postgreSQL: Dieses RDBMS lässt verschiedene prozedurale und sonstige Erweiterungen zu – und benötigt deswegen diese Angabe.
Das Ergebnis der „Funktion als Tabelle“ sieht schon ziemlich gut aus:
postgres=# SELECT * FROM tagebuch_select_func();
datum | eintrags_text
------------+-------------------------
12. APR 22 | Dies ist 1 dritter Test
Der Funktionsname einschließlich der Klammern kann wie ein Tabellenname verwendet werden. Die Klammern stören noch, denn den Eltern soll lieber nichts eigenartig vorkommen:
DROP VIEW mein_tagebuch;
CREATE VIEW mein_tagebuch AS
SELECT * FROM tagebuch_select_func()
Die Eltern sind jetzt schon ziemlich an der Nase herumgeführt:
postgres=# SELECT * FROM mein_tagebuch
datum | eintrags_text
------------+-------------------------
12. APR 22 | Dies ist 1 dritter Test
Aber jetzt möchten Sie sicherlich auch wissen, was das ganze sollte – denn bis jetzt ist doch gar kein Vorteil?!? Also weiter im Text:
Das sehen jetzt die Eltern – genau wie vorher:
SELECT * FROM mein_tagebuch
datum | eintrags_text
------------+-------------------------
12. APR 22 | Dies ist 1 dritter Test
Was sie aber wohl kaum ahnen, ist, dass ihr listenreiches Töchterlein jetzt genau sagen kann, wer wann ihr Tagebuch angeguckt hat:
SELECT wer, wann, welche_funktion FROM zugriffs_protokolle
wer | wann | welche_funktion
-----+----------------------------+---------------------
mutti| 2022-04-14 13:04:14.343566 | tagebuch_select_func()
Zumindest bei postgreSQL kann man in der gezeigten Weise heutzutage lesende Zugriffe protokollieren. Bei schreibenden Zugriffen war so etwas schon vor Jahrzehnten möglich. Ziemlich einfach ist die hier gezeigte Methode noch dazu – wie immer, wenn man den Trick (hier: mit einer Tabelle als Rückgabewert einer Funktion) kennt.
Allerdings muss ich hier auch warnen: Die Möglichkeit von postgreSQL, nahezu jede Art von SQL-Statement innerhalb einer Funktion auszuführen, lädt – insbesondere kombiniert mit dem Rückgabetyp „TABLE (…) “ – zum Missbrauch ein.
Zugriffe zu protokollieren, ist eine häufig verwendete Maßnahme, um unberechtigtem „Abzapfen von Informationen“ auf die Spur zu kommen. Aber auch wenn das Thema hier eigentlich die Datensicherheit ist, soll der andere Zweck des Protokollierens an dieser Stelle nicht verschwiegen bleiben: Man kann auf diese oder ganz ähnliche Art Informationen darüber sammeln, welche Daten wie häufig genutzt werden. Darauf aufbauend kann man dann sehr gezielte Maßnahmen zur Verkürzung von Antwortzeiten u.ä. ergreifen.
Es bleibt das leidige Hauptproblem der relationalen Datenbanken: Es fehlt die Sicht auf das Datenobjekt als Ganzes. Alles wird zerlegt in Zeilen von Tabellen, was in manch einer Hinsicht auch sehr praktisch ist. Aber Berechtigungen auf Tabellen passen eigentlich nur dann, wenn auch die Datenobjekte jeweils durch eine Zeile nur einer Tabelle repräsentiert werden können.
Schon bei ganz normalen Rechnungen wird das Problem deutlich: Es ist völlig unsinnig ein GRANT SELECT auf die Tabelle rechnungs_pos_tabl zu machen, ohne den gleichen Benutzern auch die entsprechenden Berechtigungen für die Rechnungskopfdaten zu erteilen. Anders herum mag es ja vielleicht noch Gründe geben, aber Rechnungspositionen ohne Rechnungsdatum oder beispielsweise kunden_nr wären schon sehr merkwürdig.
Bei den schreibenden Zugriffen können uns vielleicht noch die FUNCTIONs und PROCEDUREs helfen: denn denen könnte man möglicherweise noch irgendwie ein Datenobjekt als Ganzes übergeben, und sie müssten es dann nur richtig auf die verschiedenen Tabellen verteilen. GRANT EXECUTE würde es dann erlauben, die Einheit von Berechtigung und Datenobjekt zumindest für das Einfügen (INSERT) und wohl auch für UPDATE und DELETE herzustellen.
Tabellen sind und bleiben aber kein geeignetes Mittel, um Objekte darzustellen, die tiefer strukturiert sind. Bereits einfache Handwerker-Angebote sind eigentlich schon zu viel. Spätestens bei einem großen Projekt, das in Teilaufgaben zerfällt, die dann wiederum aufgeteilt werden können usw., wird die Darstellung in einer einzigen Tabelle vollends ungeeignet – und damit das Verteilen des Gesamt-Datenobjektes auf mehrere Tabellen unausweichlich.
Dann stößt selbst ein sogenanntes „objekt-rationales“ Datenbanksystem (ORDBMS) wie postgreSQL an seine Grenzen: Das Berechtigungskonzept orientiert sich an den Datenbankobjekten – und das sind bei Systemen, die SQL als Zugriffssprache haben, nun mal in erster Linie Tabellen. Auch Funktionen mit einem Rückgabetyp TABLE (…) helfen da logischerweise nicht weiter; elementare Datentypen wie z.B. Zahlen erst recht nicht.
Ein Konzept, um beim GRANT auch Teil-Objekte gleich mit zu berücksichtigen, fehlt in SQL: Eine Berechtigung auf rechnungen_tabl ist völlig unabhängig von der für die Rechnungspositionen; eine Beziehung für Genehmigungen so herzustellen, wie es z.B. für die Existenz von Werten von Schlüsselattributen über eine FOREIGN KEY-CONSTRAINT geht, ist in SQL nicht vorgesehen. Da kann ich Ihnen auch leider keine SQL-Befehle erklären – zumindest jetzt noch nicht.
Kundenadressen vor unbefugtem Zugriff zu schützen, ist höchstens ein Problem für den Unternehmer selbst – denn Derartiges sollte die Konkurrenz lieber nicht kriegen. Aber Patientendaten beim Arzt gehören schon nach Recht und Gesetz unter Verschluss: Theoretisch darf nicht einmal bekannt werden, zu welchem Arzt Sie gehen – es könnte ja beispielsweise ein Psychiater sein. (Ist natürlich dumm, wenn man dann zufällig einen Bekannten dort im Wartezimmer trifft …)
Es gibt insgesamt fünf mögliche Probleme, denen wir einen Riegel vorschieben möchten:
Den letzten Punkt werden wir noch in einem gesonderten Abschnitt behandeln. Jetzt erst einmal einige allgemeine Dinge vorab:
Alle diese Dinge haben zunächst einmal recht wenig mit dem GRANT-Befehl zu tun. Aber mit GRANT allein ist es auch nicht getan: eine Kette ist nun mal nur so stark wie ihr schwächstes Glied. Und das wissen vor allem die Hacker: Wenn das Scheunentor verriegelt und verrammelt ist, gehen die in aller Seelenruhe erst mal gucken, ob nicht jemand die Hintertür offen gelassen hat.
Die häufigsten Fehler am Computer sind zweifelsohne die Tippfehler.:
Tausende von E-Books und Hörbücher
Ihre Zahl wächst ständig und Sie haben eine Fixpreisgarantie.
Sie haben über uns geschrieben: