Highload++ Siberia 2019 изи менен - ​​Oracle боюнча 8 тапшырма

Силерге тынчтык болсун!

24-25-июнда Новосибирск шаарында Highload++ Сибирь 2019 конференциясы болуп өттү отчет "Oracle контейнердик маалымат базалары (CDB/PDB) жана аларды программалык камсыздоону иштеп чыгуу үчүн практикалык колдонуу", биз бир аздан кийин тексттик версиясын жарыялайбыз. Бул сонун болду, рахмат олегбунин уюштурууга, ошондой эле келгендердин бардыгына.

Highload++ Siberia 2019 изи менен - ​​Oracle боюнча 8 тапшырма
Бул постто биз сиз менен биздин стендде болгон көйгөйлөрдү бөлүшкүбүз келет, андыктан сиз Oracle билимиңизди сынай аласыз. Төмөндө 8 маселе, жооп варианттары жана түшүндүрмө берилген.

Төмөнкү скрипттин аткарылышынын натыйжасында биз көрө турган ырааттуулуктун максималдуу мааниси кандай?

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
  • Жок, ката болот

жоопOracle документтерине ылайык (8.1.6 цитаталанган):
Бир SQL билдирүүсүндө Oracle ырааттуулукту ар бир сапка бир жолу гана көбөйтөт. Эгерде билдирүүдө ырааттуулук үчүн NEXTVALге бирден ашык шилтеме камтылса, Oracle ырааттуулукту бир жолу көбөйтөт жана NEXTVAL бардык көрүнүштөрү үчүн бирдей маанини кайтарат. Эгерде билдирүүдө CURRVAL жана NEXTVAL экөөнө тең шилтемелер камтылса, Oracle ырааттуулукту көбөйтөт жана CURRVAL жана NEXTVAL үчүн бирдей маанини оператордун ичиндеги тартибине карабастан кайтарат.

Ошентип, максималдуу маани саптардын санына туура келет, башкача айтканда 5.

Төмөнкү сценарийди иштетүүнүн натыйжасында таблицада канча сап болот?

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

жоопOracle документтерине ылайык (11.2 цитаталанган):

Кандайдыр бир SQL билдирүүсүн аткаруудан мурун, Oracle жашыруун сактоо пунктун белгилейт (сизге жеткиликтүү эмес). Андан кийин, эгерде билдирме ишке ашпай калса, Oracle аны автоматтык түрдө артка кайтарат жана SQLCAдагы SQLCODEге тиешелүү ката кодун кайтарат. Мисалы, INSERT оператору кайталанма маанини уникалдуу индекске киргизүүгө аракет кылып, ката кетирсе, билдирүү артка жылдырылат.

Кардардан HP чалуу да бир билдирүү катары каралат жана иштетилет. Ошентип, биринчи HP чалуу үч жазууларды киргизүү менен ийгиликтүү аяктады; экинчи HP чалуу ката менен аяктайт жана ал киргизген төртүнчү жазууну артка кайтарат; үчүнчү чалуу ишке ашпай калды, жана таблицада үч жазуу бар.

Төмөнкү сценарийди иштетүүнүн натыйжасында таблицада канча сап болот?

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

жоопOracle документтерине ылайык (11.2 цитаталанган):

Текшерүү чектөөсү таблицадагы ар бир сап канааттандыра турган шартты көрсөтүүгө мүмкүндүк берет. Чектөөлөрдү канааттандыруу үчүн, таблицадагы ар бир сап шартты TRUE же белгисиз (нөлгө байланыштуу) кылышы керек. Oracle белгилүү бир сап үчүн чек чектөө шартын баалаганда, шарттын бардык мамыча аттары ошол саптагы мамычанын маанилерине тиешелүү.

Ошентип, null мааниси текшерүүдөн өтүп, анонимдүү блок 3 маанисин киргизүү аракети жасалганга чейин ийгиликтүү аткарылат. Андан кийин каталарды иштетүү блогу өзгөчө кырдаалды тазалап, артка кайтаруу болбойт жана таблицада төрт катар калат 1, null, 2 жана кайрадан нөл маанилери менен.

Кайсы жуп баалуулуктар блокто бирдей орун ээлейт?

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, 'Д', 'Вася');

  • А жана X
  • Б жана Ы
  • C жана К
  • С жана З
  • К жана З
  • Мен жана Ж
  • J жана X
  • Баары тизмеленген

жоопБул жерде Oracle'да ар кандай типтеги маалыматтарды сактоо боюнча документациядан үзүндүлөр (12.1.0.2).

CHAR маалымат түрү
CHAR маалымат түрү маалымат базасынын символдор топтомундагы туруктуу узундуктагы символ саптарын аныктайт. Маалыматтар базасын түзүүдө сиз маалымат базасынын символдорунун топтомун көрсөтөсүз. Oracle CHAR тилкесинде сакталган бардык маанилердин тандалган узундуктун семантикасында өлчөмү менен көрсөтүлгөн узундукка ээ болушун камсыздайт. Эгер сиз мамычанын узундугунан кыскараак маани киргизсеңиз, анда Oracle маанини мамычанын узундугуна бош коёт.

VARCHAR2 Маалымат түрү
VARCHAR2 маалымат түрү маалымат базасынын символдор топтомундагы өзгөрмө узундуктагы символ саптарын аныктайт. Маалыматтар базасын түзүүдө сиз маалымат базасынын символдорунун топтомун көрсөтөсүз. Oracle символдун маанисин VARCHAR2 тилкесинде так сиз көрсөткөндөй сактайт, эгерде маани тилкенин узундугунан ашпаса.

NUMBER берилиш түрү
NUMBER берилиш түрү нөлдү, ошондой эле 1.0 x 10-130дан 1.0 x 10126га чейинки абсолюттук маанилери бар оң жана терс туруктуу сандарды сактайт. Эгер мааниси абсолюттук маанисинен жогору же барабар болгон арифметикалык туюнтманы көрсөтсөңүз 1.0 x 10126, андан кийин Oracle катаны кайтарат. Ар бир NUMBER маани 1ден 22 байтка чейин талап кылынат. Муну эске алуу менен, NUMBER(p) белгилүү бир сандык маалымат мааниси үчүн байт менен мамычанын өлчөмү, мында p берилген маанинин тактыгы, төмөнкү формула менен эсептелиши мүмкүн: ROUND((length(p)+s)/2))+1 мында s нөлгө барабар, эгерде сан оң болсо, s 1ге барабар, эгерде сан терс болсо.

Мындан тышкары, келгиле, Null маанилерин сактоо боюнча документтерден үзүндү алалы.

Нөл - бул тилкеде маанинин жоктугу. Нөл белгилер жок, белгисиз же колдонулбай турган маалыматтарды көрсөтөт. Эгерде алар берилиштердин маанилери бар тилкелердин ортосунда калса, нөлдөр маалымат базасында сакталат. Бул учурларда, алар мамычанын узундугун (нөл) сактоо үчүн 1 байт талап кылат. Катардагы нөлдөр эч кандай сактоону талап кылбайт, анткени жаңы саптын аталышы мурунку сапта калган тилкелер нөл экенин билдирет. Мисалы, таблицанын акыркы үч мамычасы нөл болсо, анда бул мамычалар үчүн эч кандай маалымат сакталбайт.

Бул маалыматтардын негизинде биз ой жүгүртүүнү түзөбүз. Биз маалымат базасы AL32UTF8 коддоосун колдонот деп ойлойбуз. Бул коддоодо орус тамгалары 2 байтты ээлейт.

1) A жана X, a 'Y' талаасынын мааниси 1 байт, x 'D' талаасынын мааниси 2 байтты алат
2) B жана Y, b ичиндеги "Вася" мааниси 10 белгиге чейин боштуктар менен толтурулат жана 14 байт, d ичиндеги "Вася" 8 байт алат.
3) C жана K. Эки талаа тең NULL маанисине ээ, алардан кийин маанилүү талаалар бар, ошондуктан алар 1 байтты ээлейт.
4) C жана Z. Эки талаада тең NULL мааниси бар, бирок Z талаасы таблицадагы акыркысы, ошондуктан ал орун ээлебейт (0 байт). С талаасы 1 байтты ээлейт.
5) К жана З. Мурунку окуяга окшош. K талаасындагы маани 1 байтты ээлейт, Zде – 0.
6) Мен жана Ж. Документке ылайык, эки маани тең 2 байт алат. Документтен алынган формула боюнча узундукту эсептейбиз: round( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J жана X. J талаасындагы маани 2 байт, X талаасындагы маани 2 байт алат.

Жалпысынан туура варианттар: C жана K, I жана J, J жана X.

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

  • Онго жакын
  • Жүздөгөндөй
  • Миңдегенге жакын
  • Он миңге жакын

жоопOracle документтерине ылайык (12.1 цитаталанган):

B-дарактын индекси үчүн индекстин кластердик фактору индекстин маанисине карата катарлардын физикалык тобун өлчөйт.

Индекс кластерлөө фактору оптимизаторго индексти сканерлөө же толук таблицаны сканерлөө белгилүү бир сурамдар үчүн натыйжалуураак болорун чечүүгө жардам берет). Төмөн кластердик фактор эффективдүү индексти скандоону көрсөтөт.

Таблицадагы блоктордун санына жакын болгон кластердик фактор саптар индекстин ачкычынын жардамы менен таблица блокторунда физикалык иреттелгендигин көрсөтөт. Эгерде маалымат базасы толук таблицаны скандоону аткарса, анда маалымат базасы индекс ачкычы боюнча сорттолгон дискте сакталган саптарды алып чыгууга умтулат. Катарлардын санына жакын болгон кластердик фактор саптар индекс ачкычына карата маалымат базасынын блокторуна туш келди чачыранды экенин көрсөтөт. Эгерде маалымат базасы толук таблицаны скандоону аткарса, анда маалымат базасы бул индекс ачкычы боюнча саптарды эч кандай иреттелген тартипте чыгарбайт.

Бул учурда, маалыматтар идеалдуу иреттелген, ошондуктан кластердик фактор таблицадагы ээлеген блоктордун санына барабар же жакын болот. Стандарттык блоктун көлөмү 8 килобайт үчүн, миңге жакын тар сандык маанилер бир блокко туура келет деп күтсө болот, андыктан блоктордун саны жана натыйжада кластердик фактор болот. ондогонго жакын.

Төмөнкү скрипт стандарттык жөндөөлөрү бар кадимки маалымат базасында N кандай мааниде ийгиликтүү аткарылат?

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

жоопOracle документтерине ылайык (11.2 цитаталанган):

Логикалык маалыматтар базасынын чектери

нерсе
Лимиттин түрү
Limit Value

кёрсёткъчтёр
Индекстелген тилкенин жалпы өлчөмү
75% маалымат базасы блок өлчөмү минус кээ бир кошумча чыгымдар

Ошентип, индекстелген мамычалардын жалпы көлөмү 6Kb ашпоого тийиш. Андан кийин эмне болоору тандалган базалык коддоодон көз каранды. AL32UTF8 коддоо үчүн бир символ максимум 4 байтты ээлей алат, андыктан эң начар сценарийде 6дөй символ 1500 килобайтка туура келет. Ошондуктан, Oracle индексти N = 400дө түзүүгө тыюу салат (эң начар баскычтын узундугу 1600 символ * 4 байт + катар узундугу болгондо), ал эми N = 200 (же андан аз) индексти түзүү көйгөйсүз иштейт.

INSERT оператору APPEND кыйытмасы менен түз режимде маалыматтарды жүктөө үчүн иштелип чыккан. Ал триггер илинип турган үстөлгө колдонулса эмне болот?

  • Маалыматтар түз режимде жүктөлөт, триггер күтүлгөндөй иштейт
  • Маалыматтар түз режимде жүктөлөт, бирок триггер аткарылбайт
  • Маалыматтар кадимки режимде жүктөлөт, триггер каалагандай иштейт
  • Маалыматтар кадимки режимде жүктөлөт, бирок триггер аткарылбайт
  • Маалыматтар жүктөлбөйт, ката жазылат

жоопНегизинен бул логикага байланыштуу суроо. Туура жооп табуу үчүн мен төмөнкү ой жүгүртүү моделин сунуштайт элем:

  1. Түз режимде киргизүү жогорку ылдамдыкты камсыз кылган SQL кыймылдаткычын кыйгап өтүп, маалымат блогун түз түзүү аркылуу ишке ашырылат. Ошентип, триггердин аткарылышын камсыз кылуу өтө кыйын, мүмкүн болбосо да, мунун эч кандай мааниси жок, анткени ал дагы эле киргизүүнү кескин басаңдатат.
  2. Триггердин аткарылбай калышы, эгерде таблицадагы маалыматтар бирдей болсо, жалпы маалымат базасынын абалы (башка таблицалар) бул маалыматтар киргизилген режимге жараша болот. Бул, албетте, маалыматтардын бүтүндүгүн жок кылат жана өндүрүштө чечим катары колдонулушу мүмкүн эмес.
  3. Суралган операцияны аткаруу мүмкүн эместиги жалпысынан ката катары каралат. Бирок бул жерде биз APPEND бул ишарат экенин эстен чыгарбашыбыз керек жана кыйытмалардын жалпы логикасы - эгерде мүмкүн болсо, алар эске алынат, бирок эгер андай болбосо, оператор кыйытты эске албастан аткарылат.

Ошентип, күтүлгөн жооп маалыматтар кадимки (SQL) режиминде жүктөлөт, триггер күйөт.

Oracle документтерине ылайык (8.04 цитаталанган):

Чектөөлөрдүн бузулушу билдирүүнү эскертүүсүз же ката кабарларысыз, кадимки кыстаруу жолу менен сериялык түрдө аткарууга алып келет. Транзакцияда бир эле таблицага бир нече жолу кирүүчү билдирүүлөргө болгон чектөө, ката билдирүүлөрдү пайда кылышы мүмкүн.
Мисалы, эгерде столдо триггерлер же шилтеме бүтүндүгү бар болсо, анда түз жүктөө INSERT (сериялуу же параллелдүү) колдонууга аракет кылганыңызда APPEND кыйытмасы этибарга алынбай калат, ошондой эле PARALLEL кыйытмасы же эгер бар болсо.

Төмөнкү скрипт аткарылганда эмне болот?

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

  • Ийгиликтүү бүтүрүү
  • Синтаксис катасынан улам ката
  • Ката: Автономдуу транзакция жараксыз
  • Чалуулардын максималдуу уясынан ашканына байланыштуу ката
  • Тышкы ачкыч бузуу катасы
  • Кулпуларга байланыштуу ката

жоопТаблица жана триггер абдан туура түзүлгөн жана бул операция көйгөйлөргө алып келбеши керек. Триггердеги автономдуу транзакцияларга да уруксат берилет, антпесе, мисалы, журналды каттоо мүмкүн эмес.

Биринчи сапты киргизгенден кийин, триггердин ийгиликтүү иштетилиши экинчи саптын киргизилишине алып келет, триггер кайра күйүп, үчүнчү сапты кыстаруу жана башкалар чалуулардын максималдуу уясынан ашып кеткендиктен билдирүү ишке ашпай калганга чейин уланат. Бирок, дагы бир тымызын жагдай оюнга келет. Триггер аткарылып жаткан учурда, биринчи киргизилген жазуу үчүн милдеттенме аягына чыга элек. Демек, автономдуу транзакцияда иштеп жаткан триггер таблицага али аткарыла элек жазууга тышкы ачкычка шилтеме берген сапты киргизүүгө аракет кылат. Бул күтүүгө алып келет (автономдуу транзакция негизги транзакциянын дайындарды киргизе алар-албасын көрүү үчүн күтөт) жана ошол эле учурда негизги транзакция триггерден кийин автономдуу транзакциянын ишин улантуусун күтөт. Туюктук пайда болуп, натыйжада автономдуу транзакция кулпуларга байланыштуу себептерден улам жокко чыгарылат..

Сурамжылоого катталган колдонуучулар гана катыша алышат. Кирүү, өтүнөмүн.

Бул кыйын болду?

  • Эки манжадай дароо баарын туура чечтим.

  • Чынында эмес, бир эки суроодо жаңылыптырмын.

  • Анын жарымын туура чечтим.

  • Жоопту эки жолу ойлодум!

  • Мен комментарийге жазам

14 колдонуучу добуш берди. 10 колдонуучу добуш берүүдөн баш тартты.

Source: www.habr.com

Комментарий кошуу