Hallo!
Vom 24. bis 25. Juni fand in Nowosibirsk die Konferenz Highload ++ Siberia 2019 statt. Unsere Mitarbeiter waren auch
beim Bericht „Oracle Container Bases (CDB / PDB) und ihre praktische Verwendung für die Softwareentwicklung“ dabei. Wir werden etwas später eine Textversion veröffentlichen. Es war cool, danke
olegbunin für die Organisation sowie allen, die gekommen sind.
In diesem Beitrag möchten wir Ihnen die Aufgaben an unserem Stand mitteilen, damit Sie Ihr Wissen in Oracle testen können. Beantworten Sie unter den 8 Aufgaben die Optionen und Erklärungen.
Was ist der Maximalwert der Sequenz, die wir als Ergebnis des folgenden Skripts sehen werden?
create sequence s start with 1; select s.currval, s.nextval, s.currval, s.nextval, s.currval from dual connect by level <= 5;
- 1
- 5
- 10
- 25
- Nein, es wird einen Fehler geben
Die AntwortGemäß Oracle-Dokumentation (zitiert aus 8.1.6):
Innerhalb einer einzelnen SQL-Anweisung erhöht Oracle die Sequenz nur einmal pro Zeile. Wenn eine Anweisung mehr als einen Verweis auf NEXTVAL für eine Sequenz enthält, erhöht Oracle die Sequenz einmal und gibt für alle Vorkommen von NEXTVAL denselben Wert zurück. Wenn eine Anweisung Verweise auf CURRVAL und NEXTVAL enthält, erhöht Oracle die Sequenz und gibt unabhängig von ihrer Reihenfolge innerhalb der Anweisung denselben Wert für CURRVAL und NEXTVAL zurück.
Somit entspricht der Maximalwert der Anzahl der Zeilen, d . H. 5 .
Wie viele Zeilen enthält das folgende Skript in der Tabelle?
create table t(i integer check (i < 5)); create procedure p(p_from integer, p_to integer) as begin for i in p_from .. p_to loop insert into t values (i); end loop; end; / exec p(1, 3); exec p(4, 6); exec p(7, 9);
Die AntwortLaut Oracle-Dokumentation (zitiert aus 11.2):
Vor dem Ausführen einer SQL-Anweisung markiert Oracle einen impliziten Sicherungspunkt (der Ihnen nicht zur Verfügung steht). Wenn die Anweisung fehlschlägt, setzt Oracle sie automatisch zurück und gibt den entsprechenden Fehlercode an SQLCODE in der SQLCA zurück. Wenn beispielsweise eine INSERT-Anweisung einen Fehler verursacht, indem versucht wird, einen doppelten Wert in einen eindeutigen Index einzufügen, wird die Anweisung zurückgesetzt.
Ein Anruf vom Kunden wird ebenfalls als einzelne Anweisung betrachtet und verarbeitet. Somit wird der erste Aufruf von HP erfolgreich abgeschlossen, indem drei Datensätze eingefügt werden. Der zweite Aufruf von HP endet mit einem Fehler und setzt den vierten Datensatz zurück, den ich einfügen konnte. Der dritte Aufruf schlägt fehl und drei Einträge werden in der Tabelle angezeigt .
Wie viele Zeilen enthält das folgende Skript in der Tabelle?
create table t(i integer, constraint i_ch check (i < 3)); begin insert into t values (1); insert into t values (null); insert into t values (2); insert into t values (null); insert into t values (3); insert into t values (null); insert into t values (4); insert into t values (null); insert into t values (5); exception when others then dbms_output.put_line('Oops!'); end; /
Die AntwortLaut Oracle-Dokumentation (zitiert aus 11.2):
Mit einer Prüfbedingung können Sie eine Bedingung angeben, die jede Zeile in der Tabelle erfüllen muss. Um die Einschränkung zu erfüllen, muss jede Zeile in der Tabelle die Bedingung entweder WAHR oder unbekannt machen (aufgrund einer Null). Wenn Oracle eine Prüfbedingung für eine bestimmte Zeile auswertet, beziehen sich alle Spaltennamen in der Bedingung auf die Spaltenwerte in dieser Zeile.
Somit besteht der Nullwert den Test und der anonyme Block wird erfolgreich ausgeführt, bis versucht wird, den Wert 3 einzufügen. Danach löst der Fehlerbehandlungsblock eine Ausnahme aus, es erfolgt kein Rollback, und die Tabelle enthält vier Zeilen mit den Werten 1, null, 2 und null.
Welche Wertepaare belegen den gleichen Platz im Block?
create table t ( a char(1 char), b char(10 char), c char(100 char), i number(4), j number(14), k number(24), x varchar2(1 char), y varchar2(10 char), z varchar2(100 char)); insert into t (a, b, i, j, x, y) values ('Y', '', 10, 10, '', '');
- A und X.
- B und Y.
- C und K.
- C und Z.
- K und Z.
- Ich und J.
- J und X.
- Alle aufgelistet
Die AntwortHier finden Sie Auszüge aus der Dokumentation (12.1.0.2) zum Speichern verschiedener Datentypen in Oracle.
Char Datentyp
Der Datentyp CHAR gibt eine Zeichenfolge fester Länge im Datenbankzeichensatz an. Sie geben den Datenbankzeichensatz an, wenn Sie Ihre Datenbank erstellen. Oracle stellt sicher, dass alle in einer CHAR-Spalte gespeicherten Werte die Länge haben, die in der ausgewählten Längensemantik durch die Größe angegeben ist. Wenn Sie einen Wert einfügen, der kürzer als die Spaltenlänge ist, füllt Oracle den Wert mit der Spaltenlänge auf.
Datentyp VARCHAR2
Der Datentyp VARCHAR2 gibt eine Zeichenfolge variabler Länge im Datenbankzeichensatz an. Sie geben den Datenbankzeichensatz an, wenn Sie Ihre Datenbank erstellen. Oracle speichert einen Zeichenwert in einer VARCHAR2-Spalte genau so, wie Sie ihn angegeben haben, ohne Leerzeichen, sofern der Wert die Länge der Spalte nicht überschreitet.
NUMBER Datentyp
Der Datentyp NUMBER speichert null sowie positive und negative feste Zahlen mit absoluten Werten von 1,0 x 10-130 bis 1,0 x 10126. Wenn Sie einen arithmetischen Ausdruck angeben, dessen Wert einen absoluten Wert größer oder gleich 1,0 x hat 10126, dann gibt Oracle einen Fehler zurück. Jeder NUMBER-Wert benötigt 1 bis 22 Bytes. Unter Berücksichtigung dessen kann die Spaltengröße in Bytes für einen bestimmten numerischen Datenwert NUMBER (p), wobei p die Genauigkeit eines gegebenen Werts ist, unter Verwendung der folgenden Formel berechnet werden: ROUND ((Länge (p) + s) / 2)) + 1 wobei s gleich Null ist, wenn die Zahl positiv ist, und s gleich 1 ist, wenn die Zahl negativ ist.
Außerdem nehmen wir einen Auszug aus der Dokumentation zum Speichern von Nullwerten.
Eine Null ist das Fehlen eines Wertes in einer Spalte. Nullen zeigen fehlende, unbekannte oder nicht anwendbare Daten an. Nullen werden in der Datenbank gespeichert, wenn sie zwischen Spalten mit Datenwerten liegen. In diesen Fällen benötigen sie 1 Byte, um die Länge der Spalte (Null) zu speichern. Nachgestellte Nullen in einer Zeile erfordern keinen Speicherplatz, da ein neuer Zeilenkopf signalisiert, dass die verbleibenden Spalten in der vorherigen Zeile null sind. Wenn beispielsweise die letzten drei Spalten einer Tabelle null sind, werden für diese Spalten keine Daten gespeichert.
Basierend auf diesen Daten bauen wir Argumente auf. Wir glauben, dass die Datenbank die Codierung AL32UTF8 verwendet. In dieser Codierung belegen russische Buchstaben 2 Bytes.
1) A und X, der Wert des Feldes a 'Y' ist 1 Byte, der Wert des Feldes x 'D' ist 2 Bytes
2) B und Y, 'Vasya' im b-Wert wird durch Leerzeichen mit bis zu 10 Zeichen ergänzt und belegt 14 Bytes, 'Vasya' in d - benötigt 8 Bytes.
3) C und K. Beide Felder sind NULL, danach gibt es signifikante Felder, sodass sie 1 Byte belegen.
4) C und Z. Beide Felder sind NULL, aber das Z-Feld ist das letzte in der Tabelle, sodass es keinen Speicherplatz belegt (0 Byte). Feld C nimmt 1 Byte ein.
5) K und Z. Ähnlich wie im vorherigen Fall. Der Wert im K-Feld beträgt 1 Byte in Z - 0.
6) I und J. Gemäß der Dokumentation benötigen beide Werte jeweils 2 Byte. Wir betrachten die Länge gemäß der Formel aus der Dokumentation: rund ((1 + 0) / 2) +1 = 1 + 1 = 2.
7) J und X. Der Wert im Feld J benötigt 2 Bytes, der Wert im Feld X 2 Bytes.
Insgesamt sind die richtigen Optionen: C und K, I und J, J und X.
Wie hoch wird der Clustering-Faktor des T_I-Index ungefähr sein?
create table t (i integer); insert into t select rownum from dual connect by level <= 10000; create index t_i on t(i);
- Über Dutzende
- Über Hunderte
- In der Größenordnung von Tausenden
- In der Größenordnung von Zehntausenden
Die AntwortLaut Oracle-Dokumentation (zitiert aus 12.1):
Bei einem B-Tree-Index misst der Index-Clustering-Faktor die physische Gruppierung von Zeilen in Bezug auf einen Indexwert.
Der Index-Clustering-Faktor hilft dem Optimierer bei der Entscheidung, ob ein Index-Scan oder ein vollständiger Tabellenscan für bestimmte Abfragen effizienter ist. Ein niedriger Clustering-Faktor zeigt einen effizienten Index-Scan an.
Ein Clustering-Faktor, der nahe an der Anzahl der Blöcke in einer Tabelle liegt, gibt an, dass die Zeilen in den Tabellenblöcken durch den Indexschlüssel physisch geordnet sind. Wenn die Datenbank einen vollständigen Tabellenscan durchführt, ruft die Datenbank die Zeilen ab, wenn sie auf der Festplatte gespeichert sind, sortiert nach dem Indexschlüssel. Ein Clustering-Faktor, der nahe an der Anzahl der Zeilen liegt, zeigt an, dass die Zeilen in Bezug auf den Indexschlüssel zufällig über die Datenbankblöcke verteilt sind. Wenn die Datenbank einen vollständigen Tabellenscan durchführt, ruft die Datenbank keine Zeilen in einer nach diesem Indexschlüssel sortierten Reihenfolge ab.
In diesem Fall sind die Daten ideal sortiert, sodass der Clustering-Faktor gleich oder nahe an der Anzahl der belegten Blöcke in der Tabelle liegt. Bei einer Standardblockgröße von 8 Kilobyte können Sie erwarten, dass ungefähr tausend enge Zahlenwerte in einen Block passen, sodass die Anzahl der Blöcke und damit der Clustering-Faktor in der Größenordnung von zehn liegt .
Bei welchen Werten von N wird das folgende Skript erfolgreich in einer regulären Datenbank mit Standardeinstellungen ausgeführt?
create table t ( a varchar2(N char), b varchar2(N char), c varchar2(N char), d varchar2(N char)); create index t_i on t (a, b, c, d);
Die AntwortLaut Oracle-Dokumentation (zitiert aus 11.2):
Logische Datenbankgrenzen
Daher sollte die Gesamtgröße der indizierten Spalten 6 KB nicht überschreiten. Ferner hängt es von der ausgewählten Codierungsbasis ab. Bei der AL32UTF8-Codierung kann ein Zeichen maximal 4 Byte belegen. Im schlimmsten Fall passen 6 Kilobyte auf etwa 1.500 Zeichen. Daher verbietet Oracle die Erstellung eines Index bei N = 400 (wenn die Schlüssellänge im schlimmsten Fall 1600 Zeichen * 4 Byte + Zeilen-ID-Länge beträgt), während die Erstellung des Index
bei N = 200 (oder weniger) problemlos funktioniert.
Die INSERT-Anweisung mit dem APPEND-Hinweis dient zum Laden von Daten im direkten Modus. Was passiert, wenn es auf die Tabelle angewendet wird, an der der Trigger hängt?
- Die Daten werden im Direktmodus geladen, der Trigger funktioniert wie es sollte
- Daten werden im direkten Modus geladen, aber der Trigger wird nicht ausgeführt
- Die Daten werden im herkömmlichen Modus geladen, der Trigger funktioniert wie gewünscht
- Daten werden im herkömmlichen Modus geladen, aber der Trigger wird nicht ausgeführt
- Daten werden nicht hochgeladen, Fehler behoben
Die AntwortIm Prinzip ist dies eher eine Frage der Logik. Um die richtige Antwort zu finden, würde ich das folgende Argumentationsmodell vorschlagen:
- Das Einfügen im Direktmodus erfolgt durch direkte Bildung eines Datenblocks hinter der SQL-Engine, wodurch eine hohe Geschwindigkeit sichergestellt wird. Daher ist es sehr schwierig, die Ausführung des Triggers sicherzustellen, wenn dies überhaupt möglich ist, und dies macht keinen Sinn, da dies das Einfügen ohnehin dramatisch verlangsamt.
- Wenn nicht ausgelöst wird, hängt der Status der gesamten Datenbank (anderer Tabellen) bei gleichen Daten in der Tabelle davon ab, in welchen Modus die Daten eingefügt werden. Dies wird offensichtlich die Datenintegrität zerstören und kann nicht als Lösung in der Produktion angewendet werden.
- Die Unfähigkeit, die angeforderte Operation auszuführen, wird im Allgemeinen als Fehler behandelt. Hierbei ist jedoch zu beachten, dass APPEND ein Hinweis ist und die allgemeine Logik von Hinweisen darin besteht, dass sie nach Möglichkeit berücksichtigt werden. Andernfalls wird der Operator ohne Berücksichtigung des Hinweises ausgeführt.
Die erwartete Antwort lautet daher, dass die
Daten im normalen (SQL) Modus geladen werden und der Trigger ausgelöst wird.Laut Oracle-Dokumentation (zitiert ab 8.04):
Verstöße gegen die Einschränkungen führen dazu, dass die Anweisung unter Verwendung des herkömmlichen Einfügepfads ohne Warnungen oder Fehlermeldungen seriell ausgeführt wird. Eine Ausnahme ist die Einschränkung, dass Anweisungen in einer Transaktion mehrmals auf dieselbe Tabelle zugreifen, was zu Fehlermeldungen führen kann.
Wenn beispielsweise Trigger oder referenzielle Integrität in der Tabelle vorhanden sind, wird der APPEND-Hinweis ignoriert, wenn Sie versuchen, INSERT (seriell oder parallel) direkt zu laden, sowie gegebenenfalls den PARALLEL-Hinweis oder die PARALLEL-Klausel.
Was passiert beim Ausführen des folgenden Skripts?
create table t(i integer not null primary key, j integer references t); create trigger t_a_i after insert on t for each row declare pragma autonomous_transaction; begin insert into t values (:new.i + 1, :new.i); commit; end; / insert into t values (1, null);
- Erfolgreiche Ausführung
- Syntaxfehler fehlgeschlagen
- Ungültiger Offline-Transaktionsfehler
- Fehler im Zusammenhang mit dem Überschreiten der maximalen Anrufverschachtelung
- Fehler bei der Verletzung von Fremdschlüsseln
- Sperrfehler
Die AntwortDie Tabelle und der Trigger werden korrekt erstellt und dieser Vorgang sollte nicht zu Problemen führen. Autonome Transaktionen im Trigger sind ebenfalls zulässig, andernfalls wäre beispielsweise eine Protokollierung nicht möglich.
Nach dem Einfügen der ersten Zeile würde die erfolgreiche Operation des Triggers zum Einfügen der zweiten Zeile führen, in Verbindung mit der der Trigger wieder funktionieren würde, die dritte Zeile einfügen usw., bis die Anweisung aufgrund des Überschreitens der maximalen Verschachtelung von Aufrufen abfällt. Ein weiterer subtiler Punkt wird jedoch ausgelöst. Zum Zeitpunkt der Ausführung des Triggers wird das Commit für den ersten eingefügten Datensatz noch nicht ausgeführt. Daher versucht ein Trigger, der in einer autonomen Transaktion arbeitet, eine Zeile in die Tabelle einzufügen, die durch einen Fremdschlüssel auf einen Datensatz verweist, der noch nicht festgeschrieben wurde. Dies führt zu einer Wartezeit (eine autonome Transaktion wartet darauf, dass das Haupt-Commit versteht, ob Daten eingefügt werden können), und gleichzeitig wartet die Haupttransaktion darauf, dass das autonome Commit nach dem Trigger weiter funktioniert. Ein Deadlock tritt auf und infolgedessen wird eine autonome Transaktion aus dem mit Sperren verbundenen Grund zurückgeschickt .