U tragovima Highload++ Siberia 2019 — 8 zadataka po Oracle

Pozdrav!

24. i 25. lipnja u Novosibirsku održana je konferencija Highload++ Siberia 2019. Naši dečki su također bili tamo izvještaj „Kontejnerske baze podataka Oracle (CDB/PDB) i njihova praktična upotreba za razvoj softvera“, tekstualnu verziju objavit ćemo malo kasnije. Bilo je sjajno, hvala olegbunin za organizaciju, kao i svima koji su došli.

U tragovima Highload++ Siberia 2019 — 8 zadataka po Oracle
U ovom postu željeli bismo podijeliti s vama zadatke koji su bili na našem štandu, kako biste mogli provjeriti svoje znanje o Oracleu. Ispod - 8 zadataka, varijante odgovora i objašnjenje.

Koja će biti maksimalna vrijednost sekvence rezultata izvršenja sljedećeg skripta?

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
  • Nijedna, dobit ćete grešku

OdgovorPrema dokumentaciji Oraclea (citirano iz 8.1.6):
Unutar jednog SQL izraza, Oracle će povećati sekvencu samo jednom po redu. Ako izraz sadrži više referenci na NEXTVAL za sekvencu, Oracle povećava sekvencu jednom i vraća istu vrijednost za sve pojave NEXTVAL-a. Ako izraz sadrži reference na CURRVAL i NEXTVAL, Oracle povećava sekvencu i vraća istu vrijednost za CURRVAL i NEXTVAL bez obzira na njihov redoslijed unutar izraza.

Dakle, maksimalna vrijednost će odgovarati broju redova, odnosno 5.

Koliko će redova biti u tablici kao rezultat izvođenja sljedećeg skripta?

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

OdgovorPrema dokumentaciji Oraclea (citirano iz 11.2):

Prije izvođenja bilo kojeg SQL izraza, Oracle označava implicitnu točku spremanja (koja nije dostupna vama). Tada, ako izraz ne uspije, Oracle ga automatski vraća i vraća odgovarajući kod greške u SQLCODE-u u SQLCA. Na primjer, ako INSERT izraz izazove grešku pokušavajući umetnuti dupliciranu vrijednost u jedinstveni indeks, izraz se vraća.

Poziv pohranjene procedure s klijenta također se smatra i obrađuje kao jedan izraz. Tako prvi poziv procedure uspješno završava umetajući tri zapisa; drugi poziv procedure završava greškom i vraća četvrti zapis koji je uspio umetnuti; treći poziv završava greškom, i u tablici ostaju tri zapisa.

Koliko će redova biti u tablici kao rezultat izvođenja sljedećeg skripta?

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

OdgovorPrema dokumentaciji Oraclea (citirano iz 11.2):

Ograničenje provjere omogućuje da odredite uvjet koji svaka redak u tablici mora zadovoljavati. Da bi se ispunilo ograničenje, svaki redak u tablici mora učiniti uvjet ili ISTINITIM ili nepoznatim (zbog niza). Kada Oracle procjenjuje uvjet ograničenja provjere za određeni redak, svi nazivi stupaca u uvjetu odnose se na vrijednosti stupaca u tom retku.

Tako će null vrijednost proći provjeru, a anonimna blok će se uspješno izvršiti do pokušaja umetanja vrijednosti 3. Nakon toga, blok obrade grešaka će ugasiti iznimku, neće doći do povrata i u tablici će ostati četiri retka s vrijednostima 1, null, 2 i ponovno null.

Koje parove vrijednosti će zauzeti jednake količine prostora u bloku?

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 i X
  • B i Y
  • C i K
  • C i Z
  • K i Z
  • I i J
  • J i X
  • Sve navedeno

OdgovorUzmimo izvatke iz dokumentacije (12.1.0.2) o pohrani različitih tipova podataka u Oracle.

CHAR Tip Podataka
CHAR tip podataka određuje fiksnu duljinu niza znakova u skupu znakova baze podataka. Određujete skup znakova baze podataka kada kreirate svoju bazu podataka. Oracle osigurava da sve vrijednosti pohranjene u CHAR stupcu imaju duljinu koju odredite prema veličini u odabranim semantici duljine. Ako umetnete vrijednost koja je kraća od duljine stupca, Oracle će popuniti vrijednost prazninama do duljine stupca.

VARCHAR2 Tip Podataka
VARCHAR2 tip podataka specificira niz znakova varijabilne duljine u skupu znakova baze podataka. Određujete skup znakova baze podataka kada kreirate svoju bazu podataka. Oracle pohranjuje vrijednost znaka u VARCHAR2 stupcu točno onako kako je navedete, bez praznina, pod uvjetom da vrijednost ne prelazi duljinu stupca.

NUMBER Tip Podataka
NUMBER tip podataka pohranjuje nulu kao i pozitivne i negativne fiksne brojeve s apsolutnim vrijednostima od 1.0 x 10-130 do ali ne uključujući 1.0 x 10126. Ako odredite aritmetički izraz čija vrijednost ima apsolutnu vrijednost veću ili jednake 1.0 x 10126, Oracle će vratiti grešku. Svaka NUMBER vrijednost zahtijeva od 1 do 22 bajta. Uzimajući to u obzir, veličina stupca u bajtovima za određenu brojčanu vrijednost NUMBER(p), gdje je p preciznost dane vrijednosti, može se izračunati koristeći sljedeću formulu: ROUND((length(p)+s)\/2))+1 gdje s je jednako nula ako je broj pozitivan, a s je jednako 1 ako je broj negativan.

Osim toga, uzmimo izvadak iz dokumentacije o pohrani Null vrijednosti.

Null je odsustvo vrijednosti u stupcu. Nullovi ukazuju na nedostajuće, nepoznate ili neprimjenjive podatke. Nullovi se pohranjuju u bazi podataka ako se nalaze između stupaca s vrijednostima podataka. U tim slučajevima zahtijevaju 1 bajt za pohranu duljine stupca (nula). Nullovi na kraju reda ne zahtijevaju pohranu jer novi zaglavlje reda signalizira da su preostali stupci u prethodnom redu null. Na primjer, ako su posljednja tri stupca tablice null, tada se za te stupce ne pohranjuju podaci.

Na temelju tih podataka formiramo zaključke. Pretpostavljamo da u Bazi podataka koristi se kodiranje AL32UTF8. U ovom kodiranju ruska slova zauzimat će 2 bajta.

1) A i X, vrijednost polja a ‘Y’ zauzima 1 bajt, vrijednost polja x ‘D’ – 2 bajta
2) B i Y, ‘Vasja’ u b će se dopuniti razmacima do 10 znakova i zauzeti 14 bajtova, ‘Vasja’ u d – zauzet će 8 bajtova.
3) C i K. Oba polja imaju vrijednost NULL, nakon njih slijede značajna polja, zato zauzimaju po 1 bajt.
4) C i Z. Oba polja imaju vrijednost NULL, ali polje Z je posljednje u tablici, stoga ne zauzima mjesto (0 bajtova). Polje C zauzima 1 bajt.
5) K i Z. Slično prethodnom slučaju. Vrijednost u polju K zauzima 1 bajt, u Z – 0.
6) I i J. Prema dokumentaciji, obje vrijednosti zauzet će po 2 bajta. Duljinu računamo prema formuli preuzetoj iz dokumentacije: round( (1 + 0) / 2) + 1 = 1 + 1 = 2.
7) J i X. Vrijednost u polju J zauzet će 2 bajta, vrijednost u polju X zauzet će 2 bajta.

Dakle, ispravni varijante su: C i K, I i J, J i X.

Koliko će otprilike biti clustering factor indeksa T_I?

create table t (i integer);
 
insert into t select rownum from dual connect by level <= 10000;
 
create index t_i on t(i);

  • Otprilike desetci
  • Otprilike stotine
  • Otprilike tisuće
  • Otprilike desetci tisuća

OdgovorPrema dokumentaciji Oracle (citirano iz 12.1):

Za B-stablo indeks, indeks clustering factor mjeri fizičko grupiranje redaka u odnosu na vrijednost indeksa.

Indeks clustering factor pomaže optimizatoru da odluči hoće li indeks skenirati ili obaviti puni pregled tablice kao učinkovitiji za određene upite. Nizak clustering factor ukazuje na učinkovitije skeniranje indeksa.

Clustering factor koji je blizu broju blokova u tablici ukazuje da su redci fizički poredani u blokovima tablice prema indeksnom ključu. Ako baza podataka izvodi puni pregled tablice, tada će često dohvaćati redce kako su spremljeni na disku, sortirani prema indeksnom ključu. Clustering factor koji je blizu broju redaka ukazuje da su redci nasumično raspršeni preko blokova baze podataka u odnosu na indeks ključ. Ako baza podataka izvrši puni pregled tablice, tada neće dohvatiti redce u bilo kojem sortiranom redoslijedu prema ovom indeks ključu.

U ovom slučaju podaci su savršeno sortirani, stoga će clustering factor biti jednak ili blizak broju zauzetih blokova u tablici. Za standardnu veličinu bloka od 8 kilobajta može se očekivati da će u jedan blok stati otprilike tisuću uskih number vrijednosti, stoga će broj blokova, a time i clustering factor biti otprilike desetci.

Pod kojim vrijednostima N će sljedeći skript uspješno biti izvršen u običnoj bazi podataka sa standardnim postavkama?

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

OdgovorPrema dokumentaciji Oraclea (citirano iz 11.2):

Logička ograničenja baze podataka

Stavka
Tip ograničenja
Vrijednost ograničenja

Indeksi
Ukupna veličina indeksiranog stupca
75% veličine bloka baze podataka minus neki prekovremeni trošak

Dakle, ukupna veličina indeksiranih kolona ne smije prelaziti 6KB. Sve dalje zavisi od odabrane kodne stranice baze. Za kodnu stranicu AL32UTF8 jedan znak može zauzimati maksimalno 4 bajta, tako da u 6 kilobajta u najgorem slučaju može stati oko 1500 znakova. Stoga će Oracle zabraniti stvaranje indeksa pri N = 400 (kada je dužina ključa u najgorem slučaju 1600 znakova * 4 bajta + dužina rowid), dok pri N = 200 (i manje) stvaranje indeksa će proći bez problema.

INSERT operator sa hintom APPEND namijenjen je za učitavanje podataka u direktnom režimu. Što će se dogoditi ako se primijeni na tabelu na kojoj se nalazi okidač?

  • Podaci će se učitati u direktnom režimu, okidač će se aktivirati kao što treba
  • Podaci će se učitati u direktnom režimu, ali okidač neće biti aktiviran
  • Podaci će se učitati u konvencionalnom režimu, okidač će se aktivirati kao što treba
  • Podaci će se učitati u konvencionalnom režimu, ali okidač neće biti aktiviran
  • Podaci neće biti učitani, zabilježit će se greška

OdgovorU principu, ovo je više pitanje logike. Da bih pronašao ispravan odgovor, predložio bih sljedeći model razmišljanja:

  1. Umetanje u direktnom režimu se vrši direktnim generisanjem bloka podataka, mimo SQL engine-a, što omogućava veliku brzinu. Tako je veoma teško osigurati izvršenje okidača, ako je to uopšte moguće, i nema smisla, jer bi to i dalje značajno usporilo umetanje.
  2. Neizvršenje okidača će dovesti do toga da će stanje baze u celini (drugih tabela) zavisiti od toga u kojem režimu su podaci umetnuti. To će očito narušiti integritet podataka i ne može se primeniti kao rešenje u produkciji.
  3. Nemogućnost izvršenja zatražene operacije, općenito govoreći, smatra se greškom. Međutim, ovde se treba setiti da je APPEND hint, a opća logika hintova je da se uzimaju u obzir ako je to moguće, ako nije – operator se izvršava bez obzira na hint.

Dakle, očekivani odgovor je podaci će se učitati u običnom (SQL) režimu, okidač će se aktivirati.

Prema Oracle dokumentaciji (citirano iz 8.04):

Kršenja ograničenja uzrokovat će da se iskaz izvrši serijski, koristeći konvencionalni put umetanja, bez upozorenja ili poruka o grešci. Izuzetak je ograničenje na iskaze koji pristupaju istoj tabeli više od jednom u transakciji, što može izazvati poruke o grešci.
Na primjer, ako su na tablici prisutni okidači ili referentna cjelovitost, tada će se APPEND savjet zanemariti kada pokušate koristiti direktno učitavanje INSERT (serijski ili paralelno), kao i PARALLEL savjet ili klauzulu, ako ih ima.

Što će se dogoditi prilikom izvršavanja sljedećeg skripta?

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);

  • Uspješno izvršenje
  • Neuspjeh zbog sintaktičke pogreške
  • Pogreška vezana uz neprihvatljive autonomne transakcije
  • Pogreška vezana uz prekoračenje maksimalne ugniježdene dubine poziva
  • Pogreška vezana uz kršenje vanjskog ključa
  • Pogreška vezana uz zaključavanje

OdgovorTablica i okidač su ispravno kreirani i ova operacija ne bi trebala uzrokovati probleme. Autonomne transakcije u okidaču su također dozvoljene, inače logiranje ne bi bilo moguće.

Nakon umetanja prve vrste, uspješno aktiviranje okidača dovelo bi do umetanja druge vrste, zbog čega bi se opet aktivirao okidač, umetnuo treću vrstu i tako dalje, sve dok izjava ne padne zbog prekoračenja maksimalne ugniježdene dubine poziva. Međutim, postoji još jedna suptilna točka. Tijekom izvršenja okidača za prvi umetnuti zapis, još nije izvršen commit. Stoga okidač koji radi u autonomnoj transakciji pokušava umetnuti u tablicu redak koji se poziva vanjskim ključem na još ne potvrđeni zapis. To dovodi do očekivanja (autonomna transakcija čeka commit glavne, kako bi shvatila može li umetnuti podatke) i istovremeno glavna transakcija čeka commit autonomne, kako bi nastavila rad nakon okidača. Dolazi do deadlocka i kao posljedica - autonomna transakcija se prekida zbog problema vezanih uz zaključavanje.

Samo registrirani korisnici mogu sudjelovati u anketi. Prijavite se, molimo.

Je li bilo teško?

  • Kao dva prsta, odmah sam sve ispravno riješio.

  • Nije bilo posebno, pogriješio sam u nekoliko pitanja.

  • Riješio sam polovicu ispravno.

  • Dva puta sam pogodio odgovor!

  • Napisaću u komentarima

Glasalo je 14 korisnika. Suzdržalo se 10 korisnika.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster