CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = {user
| CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER }] VIEWview_name
[(column_list
)] ASselect_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
Diese Anweisung legt eine neue View an oder ersetzt eine
vorhandene, wenn die OR REPLACE
-Klausel
angegeben wurde. Das select_statement
ist eine SELECT
-Anweisung, welche die
Definition der View liefert. Diese
SELECT
-Anweisung kann sich auf Basistabellen
oder andere Views beziehen.
Diese Anweisung erfordert das CREATE VIEW
-Recht
für die View sowie Spaltenrechte für die in der
SELECT
-Anweisung referenzierten Spalten. Für
Spalten, die anderswo in der SELECT
-Anweisung
angesprochen werden, benötigen Sie das
SELECT
-Recht. Wenn die OR
REPLACE
-Klausel angegeben wurde, benötigen Sie
überdies das DROP
-Recht für die View.
Eine View gehört zu einer Datenbank. Nach Voreinstellung wird
eine neue View immer in der Standarddatenbank angelegt. Um sie
explizit in einer bestimmten Datenbank anzulegen, geben Sie bei
ihrer Erzeugung ihren Namen als
db_name.view_name
an.
mysql> CREATE VIEW test.v AS SELECT * FROM t;
Da Basistabellen und Views in einer Datenbank denselben Namensraum teilen, darf eine Datenbank nicht eine Basistabelle und eine View gleichen Namens enthalten.
Views müssen eindeutige Spaltennamen ohne Doppelnennungen haben,
genau wie Basistabellen. Nach Voreinstellung werden die Namen von
Spalten, die mit der SELECT
-Anweisung abgefragt
werden, auch als Spaltennamen für die View genutzt. Wenn Sie
explizite Namen für die View-Spalten einsetzen möchten, können
Sie optional eine column_list
-Klausel
mit einer Liste von kommagetrennten Bezeichnern angeben. Die
Anzahl der Namen in der column_list
muss gleich der Anzahl der von der
SELECT
-Anweisung abgefragten Spalten sein.
Die von der SELECT
-Anweisung abgefragten
Spalten können einfache Verweise auf Tabellenspalten sein, oder
auch Ausdrücke mit Funktionen, Konstantenwerten, Operatoren und
so weiter.
Wird der Name einer Tabelle oder View in einer
SELECT
-Anweisung nicht weiter qualifiziert,
wird davon ausgegangen, dass er sich auf die Standarddatenbank
bezieht. Eine View kann jedoch auch auf Tabellen oder Views in
anderen Datenbanken Bezug nehmen, wenn sie die Namen dieser
Tabellen oder Views mit dem Namen der betreffenden Datenbank
qualifiziert.
Eine View kann aus vielen Arten von
SELECT
-Anweisungen angelegt werden. Sie kann
Basistabellen oder andere Views verwenden, ebenso wie Joins,
UNION
und Unterabfragen. Die
SELECT
-Anweisung muss nicht unbedingt Tabellen
verwenden. Das folgende Beispiel definiert eine View, die zwei
Spalten aus einer anderen Tabelle und darüber hinaus einen aus
diesen beiden Spalten berechneten Ausdruck abfragt:
mysql>CREATE TABLE t (qty INT, price INT);
mysql>INSERT INTO t VALUES(3, 50);
mysql>CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;
mysql>SELECT * FROM v;
+------+-------+-------+ | qty | price | value | +------+-------+-------+ | 3 | 50 | 150 | +------+-------+-------+
Für die Definition einer View gelten folgende Beschränkungen:
Die SELECT
-Anweisung darf in der
FROM
-Klausel keine Unterabfrage enthalten.
Die SELECT
-Anweisung darf keine System-
oder Benutzervariablen verwenden.
Die SELECT
-Anweisung darf keine Parameter
enthalten, die vorbereitete Anweisungen sind.
Innerhalb einer gespeicherten Routine darf die Definition keine Routinenparameter oder lokalen Variablen referenzieren.
Eine Tabelle oder View, die in der Definition angegeben wird,
muss auch vorhanden sein. Nach der Erzeugung der View kann
allerdings eine Tabelle oder View, die in der Definition
angesprochen wird, gelöscht werden. Um eine View-Definition
auf derartige Probleme hin zu untersuchen, verwenden Sie die
CHECK TABLE
-Anweisung.
Die Definition darf weder eine
TEMPORARY
-Tabelle referenzieren noch eine
TEMPORARY
-View erzeugen.
Die in der View-Definition verwendeten Tabellen müssen vorhanden sein.
Sie dürfen mit einer View keinen Trigger verbinden.
Eine ORDER BY
-Klausel in einer View-Definition
ist zwar erlaubt, wird aber ignoriert, wenn Sie eine View mit
einer SELECT
-Anweisung abfragen, die eine
eigene ORDER BY
-Klausel hat.
Die sonstigen Optionen oder Klauseln in der Definition werden den
Optionen und Klauseln der Anweisung hinzugefügt, welche die View
referenziert, allerdings mit undefiniertem Ergebnis. Wenn
beispielsweise eine View-Definition eine
LIMIT
-Klausel enthält und Sie diese View mit
einer Anweisung abfragen, die ihre eigene
LIMIT
-Klausel hat, ist nicht definiert, welche
der beiden Klauseln gilt. Dasselbe gilt für Optionen wie
ALL
, DISTINCT
oder
SQL_SMALL_RESULT
, die auf das Schlüsselwort
SELECT
folgen, sowie für Klauseln wie
INTO
, FOR UPDATE
,
LOCK IN SHARE MODE
und
PROCEDURE
.
Wenn Sie eine View anlegen und dann die Verarbeitungsumgebung für Anfragen ändern, indem Sie Systemvariablen umstellen, kann sich dies auf die Ergebnisse der View auswirken:
mysql>CREATE VIEW v AS SELECT CHARSET(CHAR(65)), COLLATION(CHAR(65));
Query OK, 0 rows affected (0.00 sec) mysql>SET NAMES 'latin1';
Query OK, 0 rows affected (0.00 sec) mysql>SELECT * FROM v;
+-------------------+---------------------+ | CHARSET(CHAR(65)) | COLLATION(CHAR(65)) | +-------------------+---------------------+ | latin1 | latin1_swedish_ci | +-------------------+---------------------+ 1 row in set (0.00 sec) mysql>SET NAMES 'utf8';
Query OK, 0 rows affected (0.00 sec) mysql>SELECT * FROM v;
+-------------------+---------------------+ | CHARSET(CHAR(65)) | COLLATION(CHAR(65)) | +-------------------+---------------------+ | utf8 | utf8_general_ci | +-------------------+---------------------+ 1 row in set (0.00 sec)
Die DEFINER
- und die SQL
SECURITY
-Klausel geben an, in welchem Sicherheitskontext
die Zugriffsberechtigungen zum Zeitpunkt des Aufrufs der View
geprüft werden. Diese Klauseln kamen in MySQL 5.1.2 neu hinzu.
CURRENT_USER
kann auch als
CURRENT_USER()
angegeben werden.
In einer gespeicherten Routine, die mit dem Merkmal SQL
SECURITY DEFINER
definiert ist, gibt
CURRENT_USER
den Erzeuger der Routine zurück.
Dies wirkt sich auch auf eine innerhalb einer solchen Routine
definierte View aus, wenn in der View-Definition der
DEFINER
als CURRENT_USER
angegeben ist.
Nach Voreinstellung ist der DEFINER
der
Benutzer, der die CREATE VIEW
-Anweisung
ausführt. (Dies ist dasselbe wie DEFINER =
CURRENT_USER
.) Wird ein
user
-Wert angegeben, dann als
MySQL-Konto im Format
'
(dasselbe Format, das auch in der
user_name
'@'host_name
'GRANT
-Anweisung verwendet wird. Die Werte
user_name
und
host_name
sind beide erforderlich.
Wenn Sie die DEFINER
-Klausel angeben, können
Sie keinen anderen Benutzer als sich selbst einsetzen, sofern Sie
nicht über das SUPER
-Recht verfügen. Die
folgenden Regeln legen fest, welche Werte für
DEFINER
zulässig sind:
Wenn Sie nicht das SUPER
-Recht haben, ist
der einzig zulässige Wert für
user
Ihr eigenes Konto, das Sie
entweder wörtlich oder mit CURRENT_USER
angeben können. Auf ein anderes Konto dürfen Sie den
DEFINER
nicht einstellen.
Wenn Sie über das SUPER
-Recht verfügen,
dürfen Sie jeden Kontonamen angeben, wenn er nur syntaktisch
korrekt ist. Sollte das angegebene Konto nicht existieren,
wird eine Warnung ausgegeben.
Mit dem Merkmal SQL SECURITY
wird festgelegt,
welches MySQL-Konto zur Prüfung von Zugriffsberechtigungen für
die View herangezogen wird, wenn diese ausgeführt wird. Hier ist
das Merkmal DEFINER
oder
INVOKER
zulässig, um anzuzeigen, dass die View
von ihrem Erzeuger oder ihrem Aufrufer ausgeführt werden darf.
Der Standardwert für SQL SECURITY
ist
DEFINER
.
Seit MySQL 5.1.2 (der Version, in der die Klauseln
DEFINER
und SQL SECURITY
erstmals implementiert waren) werden die Berechtigungen für Views
folgendermaßen geprüft:
Zum Definitionszeitpunkt einer View benötigt ihr Erzeuger die Berechtigungen zum Zugriff auf die von seiner View benutzten Objekte der obersten Ebene. Wenn in der Definition einer View beispielsweise eine gespeicherte Funktion angesprochen wird, können nur die Berechtigungen zum Aufruf dieser Funktion geprüft werden. Die Berechtigungen, die erforderlich sind, wenn die Funktion läuft, können erst bei ihrer Ausführung geprüft werden: Für unterschiedliche Aufrufe der Funktion können unterschiedliche Ausführungspfade in ihr eingeschlagen werden.
Bei der Ausführung der View werden die Berechtigungen für
die von ihr benutzten Objekte mit den Berechtigungen ihres
Erzeugers oder Aufrufers verglichen, je nachdem, ob das
Merkmal SQL SECURITY
als
DEFINER
oder INVOKER
angegeben ist.
Wenn die Ausführung einer View die Ausführung einer
gespeicherten Funktion verursacht, werden die Berechtigungen
für Anweisungen im Rahmen dieser Funktion je nachdem
überprüft, ob die Funktion das SQL
SECURITY
-Merkmal DEFINER
oder
INVOKER
hat. Ist das Sicherheitsmerkmal
DEFINER
, läuft die Funktion mit den
Berechtigungen ihres Erzeugers; ist es
INVOKER
, läuft die Funktion mit den
Berechtigungen, die durch das SQL
SECURITY
-Merkmal der View vorgegeben sind.
Vor MySQL 5.1.2 (also vor der Implementierung der
DEFINER
- und der SQL
SECURITY
-Klausel) wurden die Berechtigungen für die in
einer View benutzten Objekte bei der Erzeugung dieser View
geprüft.
Beispiel: Eine View könnte von einer gespeicherten Funktion
abhängen, die ihrerseits andere gespeicherte Routinen aufruft. So
ruft zum Beispiel die folgende View eine gespeicherte Funktion
namens f()
auf:
CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);
Angenommen, f()
enthält eine Anweisung wie
diese:
IF name IS NULL then CALL p1(); ELSE CALL p2(); END IF;
Die Berechtigungen zur Ausführung von Anweisungen innerhalb von
f()
müssen geprüft werden, wenn
f()
ausgeführt wird. Dies könnte je nach dem
Ausführungspfad für f()
bedeuten, dass
entweder die Berechtigungen für p1()
oder die
für p2()
gebraucht werden. Diese
Berechtigungen müssen zur Laufzeit geprüft werden, und der
Benutzer, der sie besitzen muss, wird anhand des SQL
SECURITY
-Werts der Funktion f()
und
der View v
bestimmt.
Die DEFINER
- und die SQL
SECURITY
-Klausel für Views sind Erweiterungen des
SQL-Standards. Im Standard-SQL werden Views nach den Regel für
SQL SECURITY INVOKER
behandelt.
Wenn Sie eine View aufrufen, die vor MySQL 5.0.13/5.1.2 erzeugt
wurde, wird sie behandelt, als sei sie mit einer SQL
SECURITY INVOKER
-Klausel und Ihrem eigenen Konto als
DEFINER
angelegt worden. Da jedoch der
tatsächliche Erzeuger unbekannt ist, gibt MySQL eine Warnung aus.
Um die Warnung abzuschalten, genügt es, die View mit einer
DEFINER
-Klausel erneut zu definieren.
Die optionale ALGORITHM
-Klausel ist ebenfalls
eine MySQL-Erweiterung des Standard-SQL.
ALGORITHM
kann drei Werte annehmen:
MERGE
, TEMPTABLE
oder
UNDEFINED
. Wenn keine
ALGORITHM
-Klausel angegeben wurde, ist der
Standardalgorithmus UNDEFINED
. Der Algorithmus
nimmt Einfluss darauf, wie MySQL die View verarbeitet.
Ist MERGE
der Algorithmus, wird der Text der
Anweisung, in welcher die View benutzt wird, mit der
View-Definition verschmolzen, sodass Teile der View-Definition die
entsprechenden Teile der Anweisung ersetzen.
Wenn TEMPTABLE
als Algorithmus eingestellt
wurde, werden die Ergebnisse der View in eine temporäre Tabelle
geladen, die dann zur Ausführung der Anweisung genutzt wird.
Ist der Algorithmus UNDEFINED
, sucht sich MySQL
den passenden Algorithmus selbst aus. Wo immer es möglich ist,
wird MERGE
gegenüber
TEMPTABLE
bevorzugt, da
MERGE
normalerweise effizienter ist und eine
View bei Verwendung einer temporären Tabelle unveränderbar wird.
Ein Grund, explizit TEMPTABLE
zu verlangen,
wäre der, dass Sperren auf zugrunde liegenden Tabellen aufgehoben
werden können, nachdem die temporäre Tabelle angelegt wurde und
bevor sie benutzt wird, um die Verarbeitung der Anweisung
abzuschließen. So könnte eine schnellere Freigabe der Sperre als
mit dem MERGE
-Algorithmus erreicht werden, um
andere Clients, die die View benötigen, nicht so lange zu
blockieren.
Es gibt drei Gründe, als View-Algorithmus
UNDEFINED
einzustellen:
Keine ALGORITHM
-Klausel in der
CREATE VIEW
-Anweisung.
Die CREATE VIEW
-Anweisung enthält eine
explizite ALGORITHM = UNDEFINED
-Klausel.
Für eine View, die nur mit einer temporären Tabelle
verarbeitet werden kann, wurde ALGORITHM =
MERGE
angegeben. In diesem Fall generiert MySQL eine
Warnung und stellt den Algorithmus auf
UNDEFINED
ein.
Wie bereits gesagt, werden durch den
MERGE
-Algorithmus die entsprechenden Teile
einer View-Definition mit Teilen der die View referenzierenden
Anweisung zusammengeführt. Die folgenden Beispiele sollen die
Funktionsweise des MERGE
-Algorithmus kurz
verdeutlichen. Die Beispiele legen eine View namens
v_merge
zugrunde, die folgendermaßen definiert
ist:
CREATE ALGORITHM = MERGE VIEW v_merge (vc1, vc2) AS SELECT c1, c2 FROM t WHERE c3 > 100;
Beispiel 1: Angenommen, wir geben folgende Anweisung:
SELECT * FROM v_merge;
MySQL würde diese Anweisung wie folgt bearbeiten:
v_merge
wird t
*
wird vc1, vc2
, was
c1, c2
entspricht.
Die WHERE
-Klausel der View wird
hinzugefügt.
Im Ergebnis wird folgende Anweisung ausgeführt:
SELECT c1, c2 FROM t WHERE c3 > 100;
Beispiel 2: Dieses Mal ist unsere Anweisung wie folgt:
SELECT * FROM v_merge WHERE vc1 < 100;
Diese Anweisung wird ähnlich wie die vorherige behandelt, nur
dass hier vc1 < 100
zu c1 <
100
wird und die WHERE
-Klausel der
View der WHERE
-Klausel der Anweisung mit einem
AND
hinzugefügt wird (und runde Klammern
sicherstellen, dass die Teile der Klausel in der richtigen
Reihenfolge ausgeführt werden). Infolgedessen wird folgende
Anweisung ausgeführt:
SELECT c1, c2 FROM t WHERE (c3 > 100) AND (c1 < 100);
Letztlich hat die Anweisung eine WHERE
-Klausel
in der folgenden Form:
WHERE (select WHERE) AND (view WHERE)
Der MERGE
-Algorithmus erfordert eine
Eins-zu-eins-Beziehung zwischen den Zeilen der View und den Zeilen
der zugrunde liegenden Tabelle. Wenn diese Beziehung nicht gilt,
muss stattdessen eine temporäre Tabelle benutzt werden. Die
Eins-zu-eins-Beziehung fehlt, wenn die View eines der folgenden
Konstrukte enthält:
Aggregatfunktionen (SUM()
,
MIN()
, MAX()
,
COUNT()
usw.)
DISTINCT
GROUP BY
HAVING
UNION
oder UNION ALL
wenn die View nur Literalwerte verwendet (in diesem Fall gibt es gar keine zugrunde liegende Tabelle)
Manche Views sind veränderbar und können somit in Anweisungen
wie UPDATE
, DELETE
oder
INSERT
genutzt werden, um die Inhalte der
zugrunde liegenden Tabelle zu ändern. Damit eine View
veränderbar ist, muss eine Eins-zu-eins-Beziehung zwischen den
Zeilen der View und den Zeilen der zugrunde liegenden Tabelle
existieren. Es gibt also eine Reihe von Konstrukten, durch die
eine View nicht mehr veränderbar wird. Hierzu gehören folgende:
Aggregatfunktionen (SUM()
,
MIN()
, MAX()
,
COUNT()
usw.)
DISTINCT
GROUP BY
HAVING
UNION
oder UNION ALL
eine Unterabfrage in der Select-Liste
Join
eine unveränderbare View in der
FROM
-Klausel
eine Unterabfrage in der WHERE
-Klausel, die
eine Tabelle in der FROM
-Klausel
referenziert.
wenn die View nur Literalwerte verwendet (in diesem Fall gibt es gar keine zugrunde liegende Tabelle)
ALGORITHM = TEMPTABLE
(die Verwendung einer
temporären Tabelle macht eine View immer unveränderbar)
Was Einfügungen betrifft (also die Veränderbarkeit mit
INSERT
-Anweisungen), so ist eine veränderbare
View für Einfügungen nutzbar, wenn ihre Spalten zusätzlich
folgende Anforderungen erfüllen:
Ein Spaltenname darf nicht mehrfach auftreten.
Die View muss alle Spalten der Basistabelle enthalten, die keinen Standardwert haben.
Die View-Spalten müssen einfache Spaltenreferenzen und keine abgeleiteten Spalten sein. Eine abgeleitete Spalte ist eine Spalte, die nicht einfach benannt werden kann, sondern von einem Ausdruck abgeleitet wird, wie in den folgenden Beispielen:
3.14159
col1 + 3
UPPER(col2)
col3 / col4
(subquery
)
Eine View mit einer Mischung von einfachen Spaltenreferenzen und abgeleiteten Spalten ist nicht für Einfügungen geeignet, kann aber veränderbar sein, wenn nur diejenigen Spalten geändert werden, die nicht abgeleitet sind. Betrachten Sie folgende View:
CREATE VIEW v AS SELECT col1, 1 AS col2 FROM t;
Diese col2
ist von einem Ausdruck abgeleitet.
Sie ist jedoch veränderbar, wenn das Update nicht versucht,
col2
zu verändern. Das folgende Update ist
erlaubt:
UPDATE v SET col1 = 0;
Dagegen ist das nun folgende Update unzulässig, weil es versucht, eine abgeleitete Spalte zu ändern:
UPDATE v SET col2 = 0;
Manchmal kann eine View aus mehreren Tabellen veränderbar sein,
sofern sie mit dem MERGE
-Algorithmus
verarbeitet wird. Damit das funktioniert, muss die View einen
Inner Join verwenden (keinen Outer Join und keine
UNION
). Außerdem kann nur eine einzige Tabelle
in der View-Definition verändert werden, sodass die
SET
-Klausel nur Spalten aus dieser einen
Tabelle der View aufführen darf. Views, die UNION
ALL
verwenden, sind selbst dann nicht erlaubt, wenn sie
theoretisch veränderbar wären, da die Implementierung für ihre
Verarbeitung temporäre Tabellen einsetzt.
Bei einer veränderbaren View mit mehreren Tabellen kann auch
INSERT
funktionieren, sofern nur eine einzelne
der Tabellen angesprochen wird. DELETE
ist
jedoch nicht möglich.
Die WITH CHECK OPTION
-Klausel kann für eine
veränderbare View benutzt werden, um Einfügungen oder
Änderungen an Zeilen zu verhindern, für welche das
select_statement
in der
WHERE
-Klausel nicht gilt.
In einer WITH CHECK OPTION
-Klausel einer
veränderbaren View legen die Schlüsselwörter
LOCAL
und CASCADED
den
Rahmen der Überprüfungen fest, wenn die View auf Grundlage einer
anderen View definiert wurde. Das Schlüsselwort
LOCAL
schränkt die CHECK
OPTION
auf die View ein, die gerade definiert wird,
während CASCADED
dafür sorgt, dass sich die
Prüfungen auch auf die zugrunde liegenden Views erstrecken. Wenn
keines der beiden Schlüsselwörter angegeben ist, ist
CASCADED
der Standard. Betrachten Sie folgende
Definitionen für die nachfolgende Tabelle und die Views:
mysql>CREATE TABLE t1 (a INT);
mysql>CREATE VIEW v1 AS SELECT * FROM t1 WHERE a < 2
->WITH CHECK OPTION;
mysql>CREATE VIEW v2 AS SELECT * FROM v1 WHERE a > 0
->WITH LOCAL CHECK OPTION;
mysql>CREATE VIEW v3 AS SELECT * FROM v1 WHERE a > 0
->WITH CASCADED CHECK OPTION;
Hier werden die Views v2
und
v3
mit einer anderen View namens
v1
definiert. Da v2
die
Check-Option LOCAL
hat, werden Einfügungen nur
anhand der Vorgaben für v2
getestet, während
die View v3
mit ihrer Prüfoption
CASCADED
für Einfügungen hier nicht nur die
eigenen, sondern auch die Prüfoptionen der zugrunde liegenden
Views berücksichtigen muss. Die folgende Anweisung
veranschaulicht die Unterschiede:
mysql>INSERT INTO v2 VALUES (2);
Query OK, 1 row affected (0.00 sec) mysql>INSERT INTO v3 VALUES (2);
ERROR 1369 (HY000): CHECK OPTION failed 'test.v3'
Die Veränderbarkeit von Views wird durch die Systemvariable
updatable_views_with_limit
beeinflusst. Siehe
auch Abschnitt 5.2.2, „Server-Systemvariablen“.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.