Kufuata nyayo za Highload++ Siberia 2019 - kazi 8 kwenye Oracle

Hi!

Mnamo Juni 24-25, mkutano wa Highload++ Siberia 2019 ulifanyika Novosibirsk. Vijana wetu walikuwepo pia ripoti "Hifadhi hifadhidata za vyombo vya Oracle (CDB/PDB) na matumizi yao ya vitendo kwa uundaji wa programu", tutachapisha toleo la maandishi baadaye kidogo. Ilikuwa poa, asante olegbunin kwa shirika, na pia kwa kila mtu aliyekuja.

Kufuata nyayo za Highload++ Siberia 2019 - kazi 8 kwenye Oracle
Katika chapisho hili, tungependa kushiriki nawe matatizo ambayo tulikuwa nayo kwenye kibanda chetu ili uweze kupima ujuzi wako wa Oracle. Chini ya kata kuna shida 8, chaguzi za jibu na maelezo.

Ni thamani gani ya juu ya mlolongo tutakayoona kama matokeo ya kutekeleza hati ifuatayo?

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
  • Hapana, kutakuwa na hitilafu

KujibuKulingana na hati za Oracle (zilizonukuliwa kutoka 8.1.6):
Ndani ya taarifa moja ya SQL, Oracle itaongeza mlolongo mara moja tu kwa kila safu. Ikiwa taarifa ina marejeleo zaidi ya moja ya NEXTVAL ya mfuatano, Oracle huongeza mfuatano mara moja na kurejesha thamani sawa kwa matukio yote ya NEXTVAL. Ikiwa taarifa ina marejeleo ya CURRVAL na NEXTVAL, Oracle huongeza mfuatano na kurejesha thamani sawa kwa CURRVAL na NEXTVAL bila kujali mpangilio wao ndani ya taarifa.

Hivyo, thamani ya juu italingana na idadi ya mistari, ambayo ni 5.

Je, ni safu ngapi zitakuwa kwenye jedwali kama matokeo ya kuendesha hati ifuatayo?

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

KujibuKulingana na hati za Oracle (zilizonukuliwa kutoka 11.2):

Kabla ya kutekeleza taarifa yoyote ya SQL, Oracle huweka alama ya hifadhi isiyo wazi (haipatikani kwako). Kisha, taarifa ikishindikana, Oracle huirudisha kiotomatiki na kurudisha msimbo wa hitilafu unaotumika kwa SQLCODE katika SQLCA. Kwa mfano, ikiwa taarifa ya INSERT inasababisha hitilafu kwa kujaribu kuingiza thamani iliyorudiwa katika faharasa ya kipekee, taarifa hiyo inarudishwa nyuma.

Kupigia HP kutoka kwa mteja pia kunazingatiwa na kuchakatwa kama taarifa moja. Kwa hivyo, simu ya kwanza ya HP inakamilisha kwa mafanikio, baada ya kuingiza rekodi tatu; simu ya pili ya HP inaisha na hitilafu na inarudisha rekodi ya nne ambayo imeweza kuingiza; simu ya tatu inashindwa, na kuna rekodi tatu kwenye jedwali.

Je, ni safu ngapi zitakuwa kwenye jedwali kama matokeo ya kuendesha hati ifuatayo?

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

KujibuKulingana na hati za Oracle (zilizonukuliwa kutoka 11.2):

Kizuizi cha kuangalia hukuruhusu kubainisha hali ambayo kila safu mlalo kwenye jedwali lazima ikidhi. Ili kukidhi kikwazo, kila safu katika jedwali lazima ifanye hali iwe TRUE au haijulikani (kutokana na ubatili). Wakati Oracle inapotathmini hali ya kizuizi cha kuangalia kwa safu mlalo fulani, majina yoyote ya safu wima katika hali hurejelea thamani za safu wima katika safu mlalo hiyo.

Kwa hivyo, null ya thamani itapita hundi, na kizuizi kisichojulikana kitatekelezwa kwa ufanisi hadi jaribio la kuingiza thamani 3. Baada ya hayo, kizuizi cha kushughulikia hitilafu kitafuta ubaguzi, hakuna kurudi nyuma kutatokea, na kutakuwa na safu nne zilizobaki kwenye jedwali na maadili 1, null, 2 na null tena.

Ni jozi gani za maadili zitachukua kiasi sawa cha nafasi kwenye 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 na X
  • B na Y
  • C na K
  • C na Z
  • K na Z
  • Mimi na J
  • J na X
  • Zote zimeorodheshwa

KujibuHapa kuna manukuu kutoka kwa hati (12.1.0.2) juu ya kuhifadhi aina mbalimbali za data katika Oracle.

Aina ya data ya CHAR
Aina ya data ya CHAR hubainisha mfuatano wa herufi za urefu usiobadilika katika seti ya vibambo vya hifadhidata. Unabainisha herufi ya hifadhidata iliyowekwa unapounda hifadhidata yako. Oracle huhakikisha kwamba thamani zote zilizohifadhiwa katika safu wima ya CHAR zina urefu uliobainishwa na saizi katika semantiki ya urefu iliyochaguliwa. Ukiingiza thamani ambayo ni fupi kuliko urefu wa safuwima, basi Oracle huweka wazi-pedi za thamani hadi urefu wa safu.

Aina ya Data ya VARCHAR2
Aina ya data ya VARCHAR2 inabainisha mfuatano wa herufi za urefu tofauti katika seti ya herufi ya hifadhidata. Unabainisha herufi ya hifadhidata iliyowekwa unapounda hifadhidata yako. Oracle huhifadhi thamani ya herufi katika safu wima ya VARCHAR2 jinsi unavyoibainisha, bila pedi-tupu yoyote, mradi thamani haizidi urefu wa safu.

Aina NUMBER ya Data
Aina ya data NUMBER huhifadhi nambari sifuri na vile vile nambari chanya na hasi zisizobadilika zenye thamani kamili kutoka 1.0 x 10-130 hadi lakini bila kujumuisha 1.0 x 10126. Ukibainisha usemi wa hesabu ambao thamani yake ina thamani kamili kuliko au sawa na 1.0 x 10126, kisha Oracle hurejesha hitilafu. Kila thamani NUMBER inahitaji kutoka baiti 1 hadi 22. Kwa kuzingatia hili, saizi ya safuwima katika baiti kwa thamani fulani ya data ya nambari NUMBER(p), ambapo p ni usahihi wa thamani fulani, inaweza kuhesabiwa kwa kutumia fomula ifuatayo: MZUNGUKO((urefu(p)+s)/2))+1 ambapo s ni sawa na sifuri ikiwa nambari ni chanya, na s ni sawa na 1 ikiwa nambari ni hasi.

Kwa kuongeza, hebu tuchukue dondoo kutoka kwa nyaraka kuhusu kuhifadhi maadili ya Null.

Batili ni kukosekana kwa thamani katika safu. Nulls zinaonyesha data inayokosekana, isiyojulikana, au isiyotumika. Nulls huhifadhiwa kwenye hifadhidata ikiwa zitaanguka kati ya safu wima zilizo na maadili ya data. Katika kesi hizi, zinahitaji 1 byte kuhifadhi urefu wa safu (sifuri). Nunu zinazofuata mfululizo hazihitaji hifadhi kwa sababu kichwa kipya cha safu mlalo huashiria kwamba safu wima zilizosalia katika safu mlalo iliyotangulia ni batili. Kwa mfano, ikiwa safu wima tatu za mwisho za jedwali ni batili, basi hakuna data iliyohifadhiwa kwa safuwima hizi.

Kulingana na data hizi, tunaunda hoja. Tunadhani kwamba hifadhidata hutumia usimbaji wa AL32UTF8. Katika usimbuaji huu, herufi za Kirusi zitachukua ka 2.

1) A na X, thamani ya uga 'Y' inachukua baiti 1, thamani ya uga x 'D' inachukua baiti 2.
2) B na Y, 'Vasya' katika b thamani itabandikwa kwa nafasi hadi herufi 10 na itachukua baiti 14, 'Vasya' katika d itachukua baiti 8.
3) C na K. Sehemu zote mbili zina thamani NULL, baada yao kuna sehemu muhimu, kwa hivyo zinachukua baiti 1.
4) C na Z. Sehemu zote mbili zina thamani NULL, lakini sehemu ya Z ndiyo ya mwisho kwenye jedwali, kwa hivyo haichukui nafasi (baiti 0). Uwanja C unachukua baiti 1.
5) K na Z. Sawa na kesi ya awali. Thamani katika sehemu ya K inachukua baiti 1, katika Z - 0.
6) Mimi na J. Kulingana na hati, maadili yote mawili yatachukua ka 2. Tunahesabu urefu kwa kutumia fomula iliyochukuliwa kutoka kwa nyaraka: pande zote ( (1 + 0) / 2) +1 = 1 + 1 = 2.
7) J na X. Thamani katika uwanja wa J itachukua ka 2, thamani katika uwanja wa X itachukua ka 2.

Kwa jumla, chaguzi sahihi ni: C na K, I na J, J na X.

Je, ni takriban gani itakuwa sababu ya nguzo ya faharasa ya 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);

  • Kuhusu makumi
  • Kuhusu mamia
  • Kuhusu maelfu
  • Kuhusu makumi ya maelfu

KujibuKulingana na hati za Oracle (zilizonukuliwa kutoka 12.1):

Kwa faharasa ya mti B, kigezo cha nguzo cha faharasa hupima upangaji wa safu mlalo kulingana na thamani ya faharasa.

Kipengele cha kuunganisha faharasa husaidia kiboreshaji kuamua kama uchanganuzi wa faharasa au uchanganuzi kamili wa jedwali ni bora zaidi kwa hoja fulani). Kipengele cha chini cha kuunganisha kinaonyesha uchanganuzi mzuri wa faharasa.

Kipengele cha kuunganisha ambacho kiko karibu na idadi ya vizuizi kwenye jedwali kinaonyesha kuwa safu mlalo zimepangwa kimaumbile kwenye vizuizi vya jedwali kwa ufunguo wa faharasa. Ikiwa hifadhidata itafanya uchanganuzi kamili wa jedwali, basi hifadhidata huelekea kupata safu mlalo jinsi zinavyohifadhiwa kwenye diski iliyopangwa kwa ufunguo wa faharasa. Kipengele cha kuunganisha ambacho kiko karibu na idadi ya safu mlalo kinaonyesha kuwa safu mlalo hutawanywa kwa nasibu kwenye vizuizi vya hifadhidata kuhusiana na ufunguo wa faharasa. Ikiwa hifadhidata itafanya uchanganuzi kamili wa jedwali, basi hifadhidata haingeweza kupata safu mlalo kwa mpangilio wowote uliopangwa kwa ufunguo huu wa faharasa.

Katika kesi hii, data imepangwa vizuri, kwa hivyo sababu ya nguzo itakuwa sawa au karibu na idadi ya vizuizi vilivyochukuliwa kwenye jedwali. Kwa saizi ya kawaida ya block ya kilobytes 8, unaweza kutarajia kuwa takriban elfu moja ya nambari nyembamba zitatoshea kwenye block moja, kwa hivyo idadi ya vizuizi, na kwa sababu hiyo, sababu ya nguzo itakuwa. kuhusu makumi.

Ni kwa maadili gani ya N hati ifuatayo itatekelezwa kwa mafanikio katika hifadhidata ya kawaida na mipangilio ya kawaida?

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

KujibuKulingana na hati za Oracle (zilizonukuliwa kutoka 11.2):

Mipaka ya Hifadhidata ya Kimantiki

Item
Aina ya Kikomo
Thamani ya Kikomo

Fahirisi
Jumla ya ukubwa wa safu wima iliyoonyeshwa kwenye faharasa
75% ya ukubwa wa hifadhidata ukiondoa sehemu ya juu

Kwa hivyo, saizi ya jumla ya safu wima zilizoonyeshwa haipaswi kuzidi 6Kb. Kinachotokea baadaye inategemea usimbaji msingi uliochaguliwa. Kwa usimbaji wa AL32UTF8, herufi moja inaweza kuchukua upeo wa baiti 4, kwa hivyo katika hali mbaya zaidi, takriban herufi 6 zitatoshea katika kilobaiti 1500. Kwa hivyo, Oracle haitaruhusu uundaji wa faharisi kwa N = 400 (wakati urefu wa ufunguo mbaya zaidi ni herufi 1600 * ka 4 + urefu wa safu), wakati kwa N = 200 (au chini) kuunda index itafanya kazi bila matatizo.

Opereta INSERT yenye kidokezo cha APPEND imeundwa kupakia data katika hali ya moja kwa moja. Nini kinatokea ikiwa inatumika kwenye meza ambayo trigger hutegemea?

  • Data itapakiwa katika hali ya moja kwa moja, kichochezi kitafanya kazi kama inavyotarajiwa
  • Data itapakiwa katika hali ya moja kwa moja, lakini kichochezi hakitatekelezwa
  • Data itapakiwa katika hali ya kawaida, kichochezi kitafanya kazi inavyopaswa
  • Data itapakiwa katika hali ya kawaida, lakini kichochezi hakitatekelezwa
  • Data haitapakiwa, hitilafu itarekodiwa

KujibuKimsingi, hii ni zaidi ya swali la mantiki. Ili kupata jibu sahihi, ningependekeza mfano ufuatao wa hoja:

  1. Uingizaji katika hali ya moja kwa moja unafanywa na malezi ya moja kwa moja ya kuzuia data, kupitisha injini ya SQL, ambayo inahakikisha kasi ya juu. Kwa hiyo, kuhakikisha utekelezaji wa trigger ni vigumu sana, ikiwa haiwezekani, na hakuna uhakika katika hili, kwani bado itapunguza kasi ya kuingizwa.
  2. Kushindwa kutekeleza trigger itasababisha ukweli kwamba, ikiwa data katika meza ni sawa, hali ya database kwa ujumla (meza nyingine) itategemea mode ambayo data hii iliingizwa. Hii bila shaka itaharibu uadilifu wa data na haiwezi kutumika kama suluhisho katika uzalishaji.
  3. Kutoweza kutekeleza utendakazi ulioombwa kwa ujumla huchukuliwa kama kosa. Lakini hapa tunapaswa kukumbuka kuwa APPEND ni kidokezo, na mantiki ya jumla ya vidokezo ni kwamba huzingatiwa ikiwa inawezekana, lakini ikiwa sio, operator hutekelezwa bila kuzingatia ladha.

Kwa hivyo jibu linalotarajiwa ni data itapakiwa katika hali ya kawaida (SQL), trigger itawaka moto.

Kulingana na hati za Oracle (zilizonukuliwa kutoka 8.04):

Ukiukaji wa vikwazo utasababisha taarifa kutekelezwa mfululizo, kwa kutumia njia ya kawaida ya kuingiza, bila maonyo au ujumbe wa hitilafu. Isipokuwa ni kizuizi cha taarifa kufikia jedwali moja zaidi ya mara moja katika shughuli ya malipo, ambayo inaweza kusababisha ujumbe wa hitilafu.
Kwa mfano, ikiwa vichochezi au uadilifu wa marejeleo upo kwenye jedwali, basi kidokezo cha APPEND kitapuuzwa unapojaribu kutumia upakiaji wa moja kwa moja INSERT (msururu au sambamba), pamoja na kidokezo PARALLEL au kifungu, ikiwa kipo.

Nini kitatokea wakati hati ifuatayo itatekelezwa?

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

  • Utekelezaji uliofanikiwa
  • Imeshindwa kutokana na hitilafu ya sintaksia
  • Hitilafu: Muamala Unaojiendesha Sio Sahihi
  • Hitilafu inayohusiana na kuzidi kiwango cha juu zaidi cha kuweka simu
  • Hitilafu ya Ukiukaji Mkuu wa Kigeni
  • Hitilafu inayohusiana na kufuli

KujibuJedwali na trigger huundwa kwa usahihi kabisa na operesheni hii haipaswi kusababisha matatizo. Shughuli za uhuru katika kichochezi pia zinaruhusiwa, vinginevyo ukataji miti haungewezekana, kwa mfano.

Baada ya kuingiza safu ya kwanza, kurusha kwa mafanikio kwa kichocheo kungesababisha safu ya pili kuingizwa, na kusababisha kichochezi kuwaka tena, kuingiza safu ya tatu, na kadhalika hadi taarifa ikashindwa kwa sababu ya kuzidi kiwango cha juu cha simu. Walakini, jambo lingine la hila linakuja. Wakati kichochezi kinatekelezwa, ahadi bado haijakamilika kwa rekodi ya kwanza iliyoingizwa. Kwa hivyo, kichochezi kinachoendesha shughuli ya uhuru hujaribu kuingiza kwenye jedwali safu mlalo inayorejelea ufunguo wa kigeni kwa rekodi ambayo bado haijatekelezwa. Hii inasababisha kusubiri (shughuli ya uhuru inasubiri shughuli kuu ifanye ili kuona ikiwa inaweza kuingiza data) na wakati huo huo shughuli kuu inasubiri shughuli ya uhuru kuendelea kufanya kazi baada ya kichochezi. Msuguano hutokea na, kwa sababu hiyo, shughuli ya uhuru inafutwa kutokana na sababu zinazohusiana na kufuli.

Watumiaji waliojiandikisha pekee ndio wanaweza kushiriki katika utafiti. Weka sahihitafadhali.

Ilikuwa ngumu?

  • Kama vidole viwili, mara moja niliamua kila kitu kwa usahihi.

  • Si kweli, nilikosea kwa maswali kadhaa.

  • Nilitatua nusu yake kwa usahihi.

  • Nilidhani jibu mara mbili!

  • Nitaandika kwenye maoni

Watumiaji 14 walipiga kura. Watumiaji 10 walijizuia.

Chanzo: mapenzi.com

Kuongeza maoni