Hallo!
Vom 24. bis 25. Juni fand in Nowosibirsk die Konferenz Highload++ Siberia 2019 statt. Unsere Leute waren auch dort. „Container-Datenbanken Oracle (CDB/PDB) und deren praktische Nutzung für die Softwareentwicklung“, wir werden später die Textversion veröffentlichen. Es war großartig, vielen Dank. für die Organisation sowie allen, die gekommen sind.

In diesem Beitrag möchten wir einige Aufgaben mit Ihnen teilen, die an unserem Stand waren, damit Sie Ihr Wissen in Oracle testen können. Nach dem Cut — 8 Aufgaben, Antwortmöglichkeiten und Erklärungen.
Welchen maximalen Sequenzwert sehen wir als Ergebnis der Ausführung des folgenden Skripts?
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
- Keinen, es wird ein Fehler auftreten.
AntwortLaut der Oracle-Dokumentation (zitiert aus 8.1.6):
Innerhalb einer einzelnen SQL-Anweisung wird Oracle die Sequenz nur einmal pro Zeile erhöhen. Wenn eine Anweisung mehr als einen Verweis auf NEXTVAL für eine Sequenz enthält, erhöht Oracle die Sequenz einmal und gibt denselben Wert für alle Vorkommen von NEXTVAL zurück. Wenn eine Anweisung sowohl Verweise auf CURRVAL als auch NEXTVAL enthält, erhöht Oracle die Sequenz und gibt denselben Wert für sowohl CURRVAL als auch NEXTVAL zurück, unabhängig von deren Reihenfolge in der Anweisung.
Daher wird der maximale Wert der Anzahl der Zeilen entsprechen, also 5..
Wie viele Zeilen erscheinen in der Tabelle nach Ausführung des folgenden Skripts?
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);- 0
- 3
- 4
- 5
- 6
- 9
AntwortLaut der Oracle-Dokumentation (zitiert aus 11.2):
Bevor Oracle eine SQL-Anweisung ausführt, markiert es einen impliziten Speicherpunkt (der für Sie nicht verfügbar ist). Wenn die Anweisung fehlschlägt, wird sie automatisch zurückgerollt, und der entsprechende Fehlercode wird im SQLCODE in der SQLCA zurückgegeben. Wenn beispielsweise eine INSERT-Anweisung einen Fehler verursacht, indem sie versucht, einen doppelten Wert in einen eindeutigen Index einzufügen, wird die Anweisung zurückgerollt.
Der Aufruf der PL/SQL-Prozedur von einem Client aus wird ebenfalls als einzelner Befehl betrachtet und verarbeitet. Daher wird der erste Aufruf der Prozedur erfolgreich abgeschlossen und fügt drei Einträge ein; der zweite Aufruf endet mit einem Fehler und rollt den vierten Eintrag zurück, den er bereits eingefügt hat; der dritte Aufruf endet mit einem Fehler, und es befinden sich drei Einträge in der Tabelle.
Wie viele Zeilen erscheinen in der Tabelle nach Ausführung des folgenden Skripts?
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;
/- 1
- 2
- 3
- 4
- 5
- 6
- 7
AntwortLaut der Oracle-Dokumentation (zitiert aus 11.2):
Eine Überprüfungsbedingung ermöglicht es Ihnen, eine Bedingung festzulegen, die jede Zeile in der Tabelle erfüllen muss. Um die Bedingung zu erfüllen, muss jede Zeile in der Tabelle die Bedingung entweder auf WAHR oder unbekannt (aufgrund eines Nullwerts) setzen. Wenn Oracle eine Überprüfungsbedingung für eine bestimmte Zeile bewertet, beziehen sich alle Spaltennamen in der Bedingung auf die Spaltenwerte in dieser Zeile.
Somit wird der Nullwert die Überprüfung bestehen, und der anonyme Block wird erfolgreich ausgeführt, bis versucht wird, den Wert 3 einzufügen. Danach löscht der Fehlerbehandlungsblock die Ausnahme, ein Rollback erfolgt nicht, und die Tabelle behält vier Zeilen mit den Werten 1, null, 2 und erneut null.
Welche Wertpaare 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', 'Vasya', 10, 10, 'D', 'Vasya');
- A und X
- B und Y
- C und K
- C und Z
- K und Z
- I und J
- J und X
- Alle aufgelisteten
AntwortHier sind Auszüge aus der Dokumentation (12.1.0.2) zur Speicherung verschiedener Datentypen in Oracle.
CHAR Datentyp
Der CHAR-Datentyp gibt eine Zeichenkette mit fester Länge im Zeichensatz der Datenbank an. Sie geben den Zeichensatz der Datenbank an, wenn Sie Ihre Datenbank erstellen. Oracle stellt sicher, dass alle in einer CHAR-Spalte gespeicherten Werte die durch die Größe in der gewählten Längensemantik angegebene Länge haben. Wenn Sie einen Wert einfügen, der kürzer als die Spaltenlänge ist, dann füllt Oracle den Wert mit Leerzeichen auf die Spaltenlänge auf.
VARCHAR2 Datentyp
Der VARCHAR2-Datentyp spezifiziert eine variabel lange Zeichenkette im Zeichensatz der Datenbank. Den Zeichensatz der Datenbank geben Sie bei der Erstellung Ihrer Datenbank an. Oracle speichert einen Zeichenwert in einer VARCHAR2-Spalte genau so, wie Sie ihn angeben, ohne Leerzeichen zuzufügen, solange der Wert die Länge der Spalte nicht überschreitet.
DATENTYP NUMBER
Der DATENTYP NUMBER speichert Null sowie positive und negative feste Zahlen mit absoluten Werten von 1,0 x 10-130 bis, aber nicht einschließlich 1,0 x 10^126. Wenn Sie einen arithmetischen Ausdruck angeben, dessen Wert einen absoluten Wert größer oder gleich 1,0 x 10^126 hat, gibt Oracle einen Fehler zurück. Jeder NUMBER-Wert benötigt zwischen 1 und 22 Byte. Unter Berücksichtigung dessen kann die Spaltengröße in Byte für einen bestimmten numerischen Datenwert NUMBER(p), wobei p die Präzision eines bestimmten Wertes ist, mit folgender Formel berechnet werden: ROUND((length(p)+s)/2))+1 wobei s null ist, wenn die Zahl positiv ist, und s gleich 1, wenn die Zahl negativ ist.
Außerdem nehmen wir einen Auszug aus der Dokumentation über die Speicherung von Nullwerten.
Ein Nullwert ist das Fehlen eines Wertes in einer Spalte. Nullwerte zeigen fehlende, unbekannte oder nicht anwendbare Daten an. Nullwerte werden in der Datenbank gespeichert, wenn sie zwischen Spalten mit Datenwerten liegen. In diesen Fällen benötigen sie 1 Byte zur Speicherung der Länge der Spalte (null). Anhängende Nullwerte in einer Zeile benötigen keinen Speicherplatz, da ein neuer Zeilenheader signalisiert, dass die verbleibenden Spalten in der vorherigen Zeile null sind. Wenn beispielsweise die letzten drei Spalten einer Tabelle null sind, wird für diese Spalten keine Daten gespeichert.
Ausgehend von diesen Daten führen wir Überlegungen an. Wir nehmen an, dass in der DB die Codierung AL32UTF8 verwendet wird. In dieser Codierung nehmen die russischen Buchstaben 2 Byte in Anspruch.
1) A und X, der Wert des Feldes a ‘Y’ benötigt 1 Byte, der Wert des Feldes x ‘Д’ benötigt 2 Bytes.
2) B und Y, ‘Вася’ im b-Wert wird mit Leerzeichen auf 10 Zeichen aufgefüllt und benötigt 14 Bytes, ‘Вася’ im d benötigt 8 Bytes.
3) C und K. Beide Felder haben den Wert NULL, davor sind bedeutende Felder, daher benötigen sie jeweils 1 Byte.
4) C und Z. Beide Felder haben den Wert NULL, aber Feld Z ist das letzte in der Tabelle, daher benötigt es keinen Platz (0 Bytes). Feld C benötigt 1 Byte.
5) K und Z. Ähnlich wie im vorherigen Fall. Der Wert im Feld K benötigt 1 Byte, im Z benötigt es 0.
6) I und J. Laut Dokumentation benötigen beide Werte jeweils 2 Bytes. Die Länge wird gemäß der in der Dokumentation angegebenen Formel berechnet: round((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 benötigt 2 Bytes.
Insgesamt sind die korrekten Kombinationen: C und K, I und J, J und X.
Wie hoch wird ungefähr der Clustering-Faktor des Index T_I sein?
create table t (i integer);
insert into t select rownum from dual connect by level <= 10000;
create index t_i on t(i);
- In der Größenordnung von Dutzenden
- In der Größenordnung von Hunderten
- In der Größenordnung von Tausenden
- In der Größenordnung von Zehntausenden
AntwortLaut Oracle Dokumentation (zitiert aus 12.1):
Für einen B-Baum-Index misst der Clustering-Faktor des Index die physische Gruppierung von Zeilen in Bezug auf einen Indexwert.
Der Clusterfaktor des Index hilft dem Optimierer zu entscheiden, ob ein Index-Scan oder ein vollständiger Tabellenscan für bestimmte Abfragen effizienter ist. Ein niedriger Clusterfaktor weist auf einen effizienten Index-Scan hin.
Ein Clusterfaktor, der nahe der Anzahl der Blöcke in einer Tabelle liegt, zeigt an, dass die Zeilen physisch in den Tabellenblöcken nach dem Indexschlüssel geordnet sind. Wenn die Datenbank einen vollständigen Tabellenscan durchführt, tendiert sie dazu, die Zeilen in der Reihenfolge abzurufen, in der sie auf der Festplatte nach dem Indexschlüssel gespeichert sind. Ein Clusterfaktor, der nahe der Anzahl der Zeilen liegt, weist darauf hin, dass die Zeilen zufällig über die Datenbankblöcke in Bezug auf den Indexschlüssel verteilt sind. Wenn die Datenbank einen vollständigen Tabellenscan durchführt, würde sie die Zeilen nicht in einer sortierten Reihenfolge gemäß diesem Indexschlüssel abrufen.
In diesem Fall sind die Daten perfekt sortiert, sodass der Clusterfaktor gleich oder nahe der Anzahl der belegten Blöcke in der Tabelle liegt. Bei einer Standardblockgröße von 8 Kilobyte kann man erwarten, dass etwa tausend schmale Zahlenwerte in einen Block passen, sodass die Anzahl der Blöcke und folglich der Clusterfaktor im Bereich von wenigen Dutzend liegt..
Bei welchen Werten von N wird das folgende Skript erfolgreich auf einer normalen Datenbank mit Standardkonfigurationen 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);
- 100
- 200
- 400
- 800
- 1600
- 3200
- 6400
AntwortLaut der Oracle-Dokumentation (zitiert aus 11.2):
Logische Datenbankgrenzen
Element
Art der Grenze
Grenzwert
Indizes
Gesamtgröße der indizierten Spalte
75% der Größe des Datenbankblocks abzüglich eines gewissen Overheads
Der Gesamtdatenumfang der indizierten Spalten sollte 6 KB nicht überschreiten. Alles Weitere hängt von der gewählten Datenbankkodierung ab. Bei der Kodierung AL32UTF8 kann ein Zeichen maximal 4 Bytes belegen, was bedeutet, dass in 6 Kilobyte im schlimmsten Fall etwa 1500 Zeichen Platz finden. Daher wird Oracle die Erstellung eines Indexes bei N = 400 verbieten (wenn die Schlüsselgröße im schlechtesten Fall 1600 Zeichen * 4 Byte + die Länge von rowid beträgt), während bei N = 200 (oder weniger) die Erstellung des Indexes problemlos funktioniert.
Der INSERT-Befehl mit dem HINT APPEND dient zum Laden von Daten im Direct-Modus. Was passiert, wenn er auf eine Tabelle angewendet wird, die einen Trigger hat?
- Die Daten werden im Direct-Modus geladen, der Trigger wird wie vorgesehen ausgelöst.
- Die Daten werden im Direct-Modus geladen, der Trigger wird jedoch nicht ausgeführt.
- Die Daten werden im Conventional-Modus geladen, der Trigger wird wie vorgesehen ausgelöst.
- Die Daten werden im Conventional-Modus geladen, der Trigger wird jedoch nicht ausgeführt.
- Die Daten werden nicht geladen, es tritt ein Fehler auf.
AntwortIm Grunde genommen ist dies eine Frage der Logik. Um die richtige Antwort zu finden, würde ich folgendes Denkmodell vorschlagen:
- Der Direktmodus der Datenübertragung erfolgt durch die direkte Bildung von Datenblöcken, ohne den SQL-Engine, was eine hohe Geschwindigkeit garantiert. Daher ist es sehr schwierig, einen Trigger auszuführen, wenn nicht sogar unmöglich, und es macht keinen Sinn, da er die Einfügung ohnehin stark verlangsamen würde.
- Das Nichterfüllen des Triggers führt dazu, dass der Zustand der Datenbank insgesamt (anderer Tabellen) bei identischen Daten in der Tabelle davon abhängt, in welchem spezifischen Modus diese Daten eingefügt wurden. Dies würde die Datenintegrität offensichtlich gefährden und kann nicht als Lösung im Produktionsumfeld verwendet werden.
- Die Unmöglichkeit, die angeforderte Operation auszuführen, wird allgemein als Fehler interpretiert. Hier sollte jedoch bedacht werden, dass APPEND ein Hinweis ist, und die allgemeine Logik von Hinweisen besteht darin, dass sie berücksichtigt werden, wenn dies möglich ist. Andernfalls wird der Operator ohne Berücksichtigung des Hinweises ausgeführt.
Somit lautet die erwartete Antwort – die Daten werden im normalen (SQL-) Modus geladen, der Trigger wird ausgelöst.
Laut der Oracle-Dokumentation (zitiert von 8.04):
Verstöße gegen die Beschränkungen führen dazu, dass die Anweisung seriell ausgeführt wird, wobei der konventionelle Einfügepfad ohne Warnungen oder Fehlermeldungen verwendet wird. Eine Ausnahme bildet die Beschränkung für Anweisungen, die in einer Transaktion mehr als einmal auf dasselbe Tabellenobjekt zugreifen, was Fehlermeldungen verursachen kann.
Wenn beispielsweise Trigger oder referentielle Integrität auf der Tabelle vorhanden sind, wird der APPEND-Hinweis ignoriert, wenn Sie versuchen, den direkten Lade-Einfüge-Befehl (seriell oder parallel) zu verwenden, ebenso wie den PARALLEL-Hinweis oder die Klausel, falls vorhanden.
Was passiert bei der Ausführung 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
- Fehler aufgrund eines Syntaxfehlers
- Fehler, der mit der Ungültigkeit der autonomen Transaktion verbunden ist
- Fehler, der mit der Überschreitung der maximalen Verschachtelungstiefe verbunden ist
- Fehler, der mit einer Verletzung des Fremdschlüssels verbunden ist
- Fehler, der mit Sperren verbunden ist
AntwortDie Tabelle und der Trigger werden korrekt erstellt, und diese Operation sollte keine Probleme verursachen. Autonome Transaktionen im Trigger sind ebenfalls erlaubt, da sonst beispielsweise ein Logging nicht möglich wäre.
Nach dem Einfügen der ersten Zeile würde das erfolgreiche Auslösen des Triggers zum Einfügen der zweiten Zeile führen, woraufhin der Trigger erneut ausgelöst würde, die dritte Zeile eingefügt würde und so weiter, bis die Anweisung aufgrund der maximalen Verschachtelung von Aufrufen fehlschlägt. Allerdings gibt es noch einen weiteren kniffligen Punkt. Zum Zeitpunkt der Ausführung des Triggers für den ersten eingefügten Datensatz war das Commit noch nicht durchgeführt. Daher versucht der Trigger, der in einer autonomen Transaktion arbeitet, eine Zeile in die Tabelle einzufügen, die über einen Fremdschlüssel auf einen noch nicht abgeschlossenen Datensatz verweist. Dies führt zu einer Wartesituation (die autonome Transaktion wartet auf das Commit der Haupttransaktion, um zu entscheiden, ob die Daten eingefügt werden können), während gleichzeitig die Haupttransaktion auf das Commit der autonomen Transaktion wartet, um nach dem Trigger fortzufahren. Es entsteht ein Deadlock, und als Folge wird die autonome Transaktion aufgrund von Blockierungen abgebrochen..
Nur registrierte Benutzer können an der Umfrage teilnehmen. Sind Sie an Contour interessiert?
War das schwierig?
Wie zwei Finger, habe sofort alles richtig entschieden.
Nicht besonders, habe mich bei ein paar Fragen vertan.
Habe die Hälfte richtig gelöst.
Ich habe zweimal die Antwort erraten!
Ich werde in den Kommentaren schreiben
Es haben 14 Nutzer abgestimmt. 10 Nutzer haben sich enthalten.
Quelle: habr.com
