Hi!
24.-25.jÅ«nijÄ NovosibirskÄ notika konference Highload++ Siberia 2019. Tur bija arÄ« mÅ«su puiÅ”i.
Å ajÄ ierakstÄ mÄs vÄlamies dalÄ«ties ar jums problÄmÄm, kas radÄs mÅ«su stendÄ, lai jÅ«s varÄtu pÄrbaudÄ«t savas Oracle zinÄÅ”anas. Zem griezuma ir 8 problÄmas, atbilžu varianti un skaidrojums.
KÄda ir maksimÄlÄ secÄ«bas vÄrtÄ«ba, ko mÄs redzÄsim, izpildot Å”Ädu skriptu?
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
- NÄ, bÅ«s kļūda
atbildeSaskaÅÄ ar Oracle dokumentÄciju (citÄts no 8.1.6.):
Viena SQL priekÅ”raksta ietvaros Oracle palielinÄs secÄ«bu tikai vienu reizi rindÄ. Ja priekÅ”raksts satur vairÄkas atsauces uz NEXTVAL secÄ«bai, Oracle palielina secÄ«bu vienu reizi un atgriež vienu un to paÅ”u vÄrtÄ«bu visiem NEXTVAL gadÄ«jumiem. Ja priekÅ”rakstÄ ir atsauces gan uz CURRVAL, gan uz NEXTVAL, Oracle palielina secÄ«bu un atgriež vienu un to paÅ”u vÄrtÄ«bu gan CURRVAL, gan NEXTVAL neatkarÄ«gi no to secÄ«bas priekÅ”rakstÄ.
TÄtad, maksimÄlÄ vÄrtÄ«ba atbildÄ«s rindu skaitam, tas ir, 5.
Cik rindu bÅ«s tabulÄ, izpildot Å”Ädu skriptu?
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
atbildeSaskaÅÄ ar Oracle dokumentÄciju (citÄts no 11.2.):
Pirms jebkura SQL priekÅ”raksta izpildes Oracle atzÄ«mÄ netieÅ”u saglabÄÅ”anas punktu (jums nav pieejams). PÄc tam, ja priekÅ”raksts neizdodas, Oracle to automÄtiski atgriež un SQLCA atgriež piemÄrojamo kļūdas kodu SQLCODE. PiemÄram, ja INSERT priekÅ”raksts izraisa kļūdu, mÄÄ£inot ievietot dublikÄtu unikÄlÄ rÄdÄ«tÄjÄ, priekÅ”raksts tiek atcelts.
ArÄ« klienta zvanÄ«Å”ana HP tiek uzskatÄ«ta un apstrÄdÄta kÄ viens paziÅojums. TÄdÄjÄdi pirmais HP izsaukums tiek veiksmÄ«gi pabeigts, ievietojot trÄ«s ierakstus; otrais HP izsaukums beidzas ar kļūdu un atgriež ceturto ierakstu, ko izdevÄs ievietot; treÅ”ais zvans neizdodas, un tabulÄ ir trÄ«s ieraksti.
Cik rindu bÅ«s tabulÄ, izpildot Å”Ädu skriptu?
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
atbildeSaskaÅÄ ar Oracle dokumentÄciju (citÄts no 11.2.):
PÄrbaudes ierobežojums ļauj norÄdÄ«t nosacÄ«jumu, kas jÄatbilst katrai tabulas rindai. Lai izpildÄ«tu ierobežojumu, katrai tabulas rindai nosacÄ«jumam ir jÄbÅ«t TRUE vai nezinÄmam (nulles dÄļ). Kad Oracle novÄrtÄ pÄrbaudes ierobežojuma nosacÄ«jumu konkrÄtai rindai, visi nosacÄ«juma kolonnu nosaukumi attiecas uz kolonnu vÄrtÄ«bÄm Å”ajÄ rindÄ.
TÄdÄjÄdi vÄrtÄ«ba null izturÄs pÄrbaudi, un anonÄ«mais bloks tiks veiksmÄ«gi izpildÄ«ts lÄ«dz mÄÄ£inÄjumam ievietot vÄrtÄ«bu 3. PÄc tam kļūdu apstrÄdes bloks nodzÄsÄ«s izÅÄmumu, netiks veikta atcelÅ”ana un tabulÄ bÅ«s palikuÅ”as Äetras rindas ar vÄrtÄ«bÄm 1, null, 2 un vÄlreiz nulle.
Kuri vÄrtÄ«bu pÄri blokÄ aizÅems tikpat daudz vietas?
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 un X
- B un Y
- C un K
- C un Z
- K un Z
- Es un Dž
- J un X
- Visi uzskaitīti
atbildeÅ eit ir izvilkumi no dokumentÄcijas (12.1.0.2) par dažÄda veida datu glabÄÅ”anu Oracle.
CHAR datu tips
CHAR datu tips nosaka noteikta garuma rakstzÄ«mju virkni datu bÄzes rakstzÄ«mju kopÄ. Veidojot datu bÄzi, jÅ«s norÄdÄt datu bÄzes rakstzÄ«mju kopu. Oracle nodroÅ”ina, ka visÄm CHAR kolonnÄ saglabÄtajÄm vÄrtÄ«bÄm ir garums, kas norÄdÄ«ts pÄc izmÄra atlasÄ«tajÄ garuma semantikÄ. Ja ievietojat vÄrtÄ«bu, kas ir Ä«sÄka par kolonnas garumu, Oracle vÄrtÄ«bu pielÄgo kolonnas garumam.
VARCHAR2 datu tips
Datu tips VARCHAR2 nosaka mainÄ«ga garuma rakstzÄ«mju virkni datu bÄzes rakstzÄ«mju kopÄ. Veidojot datu bÄzi, jÅ«s norÄdÄt datu bÄzes rakstzÄ«mju kopu. Oracle saglabÄ rakstzÄ«mes vÄrtÄ«bu kolonnÄ VARCHAR2 tieÅ”i tÄ, kÄ to norÄdÄt, bez tukÅ”as aizpildÄ«Å”anas, ja vÄrtÄ«ba nepÄrsniedz kolonnas garumu.
NUMBER datu tips
Datu tips NUMBER saglabÄ nulles, kÄ arÄ« pozitÄ«vus un negatÄ«vus fiksÄtus skaitļus ar absolÅ«tajÄm vÄrtÄ«bÄm no 1.0 x 10-130 lÄ«dz 1.0 x 10126, bet neieskaitot. Ja norÄdÄt aritmÄtisko izteiksmi, kuras absolÅ«tÄ vÄrtÄ«ba ir lielÄka vai vienÄda ar 1.0 x 10126, tad Oracle atgriež kļūdu. Katrai NUMBER vÄrtÄ«bai ir nepiecieÅ”ami 1ā22 baiti. Å
emot to vÄrÄ, kolonnas lielumu baitos konkrÄtai skaitlisko datu vÄrtÄ«bai NUMBER(p), kur p ir dotÄs vÄrtÄ«bas precizitÄte, var aprÄÄ·inÄt, izmantojot Å”Ädu formulu: APKÄRTS((garums(p)+s)/2))+1 kur s ir vienÄds ar nulli, ja skaitlis ir pozitÄ«vs, un s ir vienÄds ar 1, ja skaitlis ir negatÄ«vs.
TurklÄt Åemsim fragmentu no dokumentÄcijas par Null vÄrtÄ«bu saglabÄÅ”anu.
Nulle ir vÄrtÄ«bas neesamÄ«ba kolonnÄ. Nulles norÄda trÅ«kstoÅ”us, nezinÄmus vai nepiemÄrojamus datus. Nulles tiek saglabÄtas datu bÄzÄ, ja tÄs atrodas starp kolonnÄm ar datu vÄrtÄ«bÄm. Å Ädos gadÄ«jumos kolonnas garuma (nulles) glabÄÅ”anai ir nepiecieÅ”ams 1 baits. Rindas beigu nullÄm nav nepiecieÅ”ama krÄtuve, jo jauna rindas galvene norÄda, ka pÄrÄjÄs kolonnas iepriekÅ”ÄjÄ rindÄ ir nulles. PiemÄram, ja tabulas pÄdÄjÄs trÄ«s kolonnas ir nulles, par Ŕīm kolonnÄm netiek glabÄti dati.
Pamatojoties uz Å”iem datiem, mÄs veidojam argumentÄciju. MÄs pieÅemam, ka datu bÄze izmanto AL32UTF8 kodÄjumu. Å ajÄ kodÄjumÄ krievu burti aizÅems 2 baitus.
1) A un X, lauka a vÄrtÄ«ba āYā aizÅem 1 baitu, lauka x vÄrtÄ«ba āDā aizÅem 2 baitus.
2) B un Y ā b vÄrtÄ«ba tiks papildinÄta ar atstarpÄm lÄ«dz 10 rakstzÄ«mÄm, un tÄ aizÅems 14 baitus, bet vÄrtÄ«ba āVasyaā laukÄ d aizÅems 8 baitus.
3) C un K. Abiem laukiem ir vÄrtÄ«ba NULL, aiz tiem ir nozÄ«mÄ«gi lauki, tÄpÄc tie aizÅem 1 baitu.
4) C un Z. Abiem laukiem ir vÄrtÄ«ba NULL, bet lauks Z ir pÄdÄjais tabulÄ, tÄpÄc tas neaizÅem vietu (0 baiti). Lauks C aizÅem 1 baitu.
5) K un Z. LÄ«dzÄ«gi kÄ iepriekÅ”ÄjÄ gadÄ«jumÄ. VÄrtÄ«ba laukÄ K aizÅem 1 baitu, laukÄ Z ā 0.
6) I un J. SaskaÅÄ ar dokumentÄciju abÄm vÄrtÄ«bÄm bÅ«s 2 baiti. MÄs aprÄÄ·inÄm garumu, izmantojot formulu, kas Åemta no dokumentÄcijas: apaļa( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J un X. VÄrtÄ«ba laukÄ J aizÅems 2 baitus, vÄrtÄ«ba laukÄ X aizÅems 2 baitus.
KopumÄ pareizÄs iespÄjas ir: C un K, I un J, J un X.
KÄds aptuveni bÅ«s T_I indeksa klasterizÄcijas faktors?
create table t (i integer);
insert into t select rownum from dual connect by level <= 10000;
create index t_i on t(i);
- ApmÄram desmitiem
- ApmÄram simtiem
- ApmÄram tÅ«kstoÅ”iem
- ApmÄram desmitiem tÅ«kstoÅ”u
atbildeSaskaÅÄ ar Oracle dokumentÄciju (citÄts no 12.1.):
B-koka indeksam indeksa klasterizÄcijas faktors mÄra rindu fizisko grupÄÅ”anu attiecÄ«bÄ pret indeksa vÄrtÄ«bu.
Indeksa klasterizÄcijas faktors palÄ«dz optimizÄtÄjam izlemt, vai indeksa skenÄÅ”ana vai pilnas tabulas skenÄÅ”ana ir efektÄ«vÄka noteiktiem vaicÄjumiem). Zems klasterizÄcijas koeficients norÄda uz efektÄ«vu indeksa skenÄÅ”anu.
KlasterizÄcijas faktors, kas ir tuvu bloku skaitam tabulÄ, norÄda, ka rindas tabulas blokos ir fiziski sakÄrtotas pÄc indeksa atslÄgas. Ja datu bÄze veic pilnu tabulas skenÄÅ”anu, datu bÄzei ir tendence izgÅ«t rindas, jo tÄs tiek glabÄtas diskÄ, sakÄrtotas pÄc indeksa atslÄgas. KlasterizÄcijas faktors, kas ir tuvu rindu skaitam, norÄda, ka rindas ir nejauÅ”i izkliedÄtas pa datu bÄzes blokiem saistÄ«bÄ ar indeksa atslÄgu. Ja datu bÄze veic pilnu tabulas skenÄÅ”anu, datu bÄze neizgÅ«s rindas nevienÄ sakÄrtotÄ secÄ«bÄ pÄc Ŕīs indeksa atslÄgas.
Å ajÄ gadÄ«jumÄ dati ir ideÄli sakÄrtoti, tÄpÄc klasterizÄcijas koeficients bÅ«s vienÄds ar aizÅemto bloku skaitu tabulÄ vai tuvu tam. Standarta bloka lielumam 8 kilobaiti var sagaidÄ«t, ka vienÄ blokÄ ietilps aptuveni tÅ«kstotis Å”auru skaitļu vÄrtÄ«bu, tÄpÄc bloku skaits un rezultÄtÄ klasterizÄcijas koeficients bÅ«s apmÄram desmitiem.
Ar kÄdÄm N vÄrtÄ«bÄm parastajÄ datu bÄzÄ ar standarta iestatÄ«jumiem tiks veiksmÄ«gi izpildÄ«ts Å”Äds skripts?
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
atbildeSaskaÅÄ ar Oracle dokumentÄciju (citÄts no 11.2.):
LoÄ£iskÄs datu bÄzes ierobežojumi
Punkts
Limita veids
RobežvÄrtÄ«ba
Indeksi
KopÄjais indeksÄtÄs kolonnas lielums
75% no datu bÄzes bloka lieluma, atskaitot dažas pieskaitÄmÄs izmaksas
TÄdÄjÄdi kopÄjais indeksÄto kolonnu lielums nedrÄ«kst pÄrsniegt 6 Kb. TÄlÄkais ir atkarÄ«gs no izvÄlÄtÄ bÄzes kodÄjuma. AL32UTF8 kodÄjumam viena rakstzÄ«me var aizÅemt ne vairÄk kÄ 4 baitus, tÄpÄc sliktÄkajÄ gadÄ«jumÄ aptuveni 6 rakstzÄ«mes ietilps 1500 kilobaitos. TÄpÄc Oracle neļaus indeksa izveidi pie N = 400 (ja sliktÄkÄ gadÄ«juma atslÄgas garums ir 1600 rakstzÄ«mes * 4 baiti + rindas garums), savukÄrt pie N = 200 (vai mazÄk) indeksa izveide darbosies bez problÄmÄm.
INSERT operators ar APPEND mÄjienu ir paredzÄts datu ielÄdei tieÅ”ajÄ režīmÄ. Kas notiek, ja tas tiek piemÄrots galdam, uz kura karÄjas sprÅ«da?
- Dati tiks ielÄdÄti tieÅ”ajÄ režīmÄ, trigeris darbosies kÄ paredzÄts
- Dati tiks ielÄdÄti tieÅ”ajÄ režīmÄ, bet trigeris netiks izpildÄ«ts
- Dati tiks ielÄdÄti parastajÄ režīmÄ, sprÅ«da darbosies kÄ nÄkas
- Dati tiks ielÄdÄti parastajÄ režīmÄ, bet trigeris netiks izpildÄ«ts
- Dati netiks ielÄdÄti, tiks ierakstÄ«ta kļūda
atbildeBÅ«tÄ«bÄ tas vairÄk ir loÄ£ikas jautÄjums. Lai atrastu pareizo atbildi, es ieteiktu Å”Ädu argumentÄcijas modeli:
- IevietoÅ”ana tieÅ”ajÄ režīmÄ tiek veikta, tieÅ”i veidojot datu bloku, apejot SQL dzinÄju, kas nodroÅ”ina lielu Ätrumu. TÄdÄjÄdi sprÅ«da izpildes nodroÅ”inÄÅ”ana ir ļoti sarežģīta, ja ne neiespÄjama, un tam nav jÄgas, jo tas joprojÄm radikÄli palÄninÄs ievietoÅ”anu.
- Ja netiek izpildÄ«ts trigeris, tad, ja dati tabulÄ ir vienÄdi, datu bÄzes stÄvoklis kopumÄ (citas tabulas) bÅ«s atkarÄ«gs no režīma, kurÄ Å”ie dati tika ievietoti. Tas acÄ«mredzami iznÄ«cinÄs datu integritÄti, un to nevar izmantot kÄ risinÄjumu ražoÅ”anÄ.
- NespÄja veikt pieprasÄ«to darbÄ«bu parasti tiek uzskatÄ«ta par kļūdu. Bet Å”eit jÄatceras, ka APPEND ir mÄjiens, un vispÄrÄ«gÄ mÄjienu loÄ£ika ir tÄda, ka, ja iespÄjams, tie tiek Åemti vÄrÄ, bet, ja nÄ, tad operators tiek izpildÄ«ts, neÅemot vÄrÄ mÄjienu.
TÄtad gaidÄmÄ atbilde ir dati tiks ielÄdÄti normÄlÄ (SQL) režīmÄ, trigeris tiks aktivizÄts.
SaskaÅÄ ar Oracle dokumentÄciju (citÄts no 8.04.):
Ierobežojumu pÄrkÄpumi izraisÄ«s priekÅ”raksta izpildi sÄrijveidÄ, izmantojot parasto ievietoÅ”anas ceļu, bez brÄ«dinÄjumiem vai kļūdu ziÅojumiem. IzÅÄmums ir aizliegums paziÅojumiem piekļūt vienai un tai paÅ”ai tabulai vairÄk nekÄ vienu reizi darÄ«juma laikÄ, kas var izraisÄ«t kļūdu ziÅojumus.
PiemÄram, ja tabulÄ ir trigeri vai atsauces integritÄte, tad APPEND padoms tiks ignorÄts, mÄÄ£inot izmantot tieÅ”Äs ielÄdes INSERT (seriÄlo vai paralÄlo), kÄ arÄ« PARALÄLU mÄjienu vai klauzulu, ja tÄds ir.
Kas notiks, kad tiks izpildÄ«ts Å”Äds 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);
- Veiksmīga pabeigŔana
- Kļūme sintakses kļūdas dÄļ
- Kļūda: autonomais darījums nav derīgs
- Kļūda, kas saistÄ«ta ar maksimÄlÄ zvanu ligzdoÅ”anas apjoma pÄrsniegÅ”anu
- ÄrÄjÄs atslÄgas pÄrkÄpuma kļūda
- Kļūda, kas saistÄ«ta ar slÄdzenÄm
atbildeTabula un sprÅ«da ir izveidoti diezgan pareizi, un Å”ai darbÄ«bai nevajadzÄtu radÄ«t problÄmas. Ir atļautas arÄ« autonomas transakcijas trigerÄ, pretÄjÄ gadÄ«jumÄ, piemÄram, reÄ£istrÄÅ”ana nebÅ«tu iespÄjama.
PÄc pirmÄs rindas ievietoÅ”anas veiksmÄ«ga aktivizÄtÄja aktivizÄÅ”ana izraisÄ«tu otrÄs rindas ievietoÅ”anu, izraisot aktivizÄtÄja atkÄrtotu aktivizÄÅ”anu, treÅ”Äs rindas ievietoÅ”anu un tÄ tÄlÄk, lÄ«dz paziÅojums neizdevÄs, jo tika pÄrsniegts maksimÄlais izsaukumu ligzdoÅ”anas skaits. TomÄr spÄlÄ vÄl viens smalks punkts. LaikÄ, kad tiek izpildÄ«ts trigeris, pirmÄ ievietotÄ ieraksta apÅemÅ”anÄs vÄl nav pabeigta. TÄpÄc trigeris, kas darbojas autonomÄ darÄ«jumÄ, mÄÄ£ina ievietot tabulÄ rindu, kas atsaucas uz ÄrÄjo atslÄgu uz ierakstu, kas vÄl nav veikts. TÄ rezultÄtÄ notiek gaidÄ«Å”ana (autonomais darÄ«jums gaida, lÄ«dz galvenais darÄ«jums uzÅemsies saistÄ«bas, lai redzÄtu, vai tas var ievietot datus), un tajÄ paÅ”Ä laikÄ galvenais darÄ«jums gaida, lÄ«dz autonomais darÄ«jums turpinÄs darboties pÄc trigera. Notiek strupceļŔ, kÄ rezultÄtÄ autonomais darÄ«jums tiek atcelts ar slÄdzenÄm saistÄ«tu iemeslu dÄļ.
AptaujÄ var piedalÄ«ties tikai reÄ£istrÄti lietotÄji.
Bija grūti?
-
KÄ ar diviem pirkstiem uzreiz visu izlÄmu pareizi.
-
Nav Ä«sti, es kļūdÄ«jos pÄris jautÄjumos.
-
Pusi no tÄ atrisinÄju pareizi.
-
Es divreiz uzminÄju atbildi!
-
RakstÄ«Å”u komentÄros
Nobalsoja 14 lietotÄji. 10 lietotÄji atturÄjÄs.
Avots: www.habr.com