In seguitu à i passi di Highload++ Siberia 2019 - 8 compiti nantu à Oracle

Hello!

Da u 24 à u 25 di ghjugnu, a cunferenza Highload++ Siberia 2019 hè stata in Novosibirsk. I nostri ragazzi eranu ancu quì. rapportu "Base di dati di containeru Oracle (CDB / PDB) è u so usu praticu per u sviluppu di software", publicheremu una versione di testu un pocu dopu. Era bellu, grazie olegbunin per l'urganisazione, è ancu per tutti quelli chì sò ghjunti.

In seguitu à i passi di Highload++ Siberia 2019 - 8 compiti nantu à Oracle
In questu post, vulemu sparte cun voi i prublemi chì avemu avutu in u nostru stand per chì pudete pruvà a vostra cunniscenza Oracle. Sottu u cut sò 8 prublemi, opzioni di risposta è spiegazione.

Chì ghjè u valore di sequenza massima chì vedemu com'è u risultatu di eseguisce u script seguente?

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
  • Innò, ci sarà un errore

RisposteSicondu a documentazione Oracle (citata da 8.1.6):
In una sola dichjarazione SQL, Oracle aumenterà a sequenza solu una volta per fila. Se una dichjarazione cuntene più di una riferenza à NEXTVAL per una sequenza, Oracle aumenta a sequenza una volta è torna u listessu valore per tutte l'occurrence di NEXTVAL. Se una dichjarazione cuntene riferimenti à CURRVAL è NEXTVAL, Oracle aumenta a sequenza è torna u listessu valore per CURRVAL è NEXTVAL, indipendentemente da u so ordine in a dichjarazione.

Cusì, u valore massimu currisponde à u numeru di linii, vale à dì 5.

Quante fila seranu in a tavula in u risultatu di eseguisce u script seguente?

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

RisposteSicondu a documentazione Oracle (citata da 11.2):

Prima di eseguisce qualsiasi dichjarazione SQL, Oracle marca un puntu di salvezza implicitu (micca dispunibule per voi). Allora, se a dichjarazione falla, Oracle a rimette automaticamente è torna u codice d'errore applicabile à SQLCODE in SQLCA. Per esempiu, se una dichjarazione INSERT provoca un errore per pruvà à inserisce un valore duplicatu in un indice unicu, a dichjarazione hè rinviata.

Chjama HP da u cliente hè ancu cunsideratu è processatu cum'è una sola dichjarazione. Cusì, a prima chjamata HP cumpleta cù successu, dopu avè inseritu trè dischi; a seconda chjamata HP finisce cù un errore è torna u quartu record chì hà sappiutu inserisce; a terza chjama falla, è ci sò trè records in a tavula.

Quante fila seranu in a tavula in u risultatu di eseguisce u script seguente?

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

RisposteSicondu a documentazione Oracle (citata da 11.2):

Una restrizzione di cuntrollu vi permette di specificà una cundizione chì ogni fila in a tavula deve esse soddisfatta. Per suddisfà a limitazione, ogni fila in a tavula deve fà a cundizione sia TRUE o scunnisciuta (per via di un null). Quandu Oracle valuta una cundizione di restrizzione di cuntrollu per una fila particulari, ogni nome di colonna in a cundizione si riferisce à i valori di colonna in quella fila.

Cusì, u valore null passà a verificazione, è u bloccu anònimu serà eseguitu cù successu finu à un tentativu di inserisce u valore 3. Dopu questu, u bloccu di gestione di l'errore sguasserà l'eccezzioni, ùn ci sarà micca rollback, è ci saranu quattru fila in a tavula cù i valori 1, null, 2 è null novu.

Chì coppie di valori piglianu a listessa quantità di spaziu in u bloccu?

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 è X
  • B è Y
  • C è K
  • C è Z
  • K è Z
  • I è J
  • J è X
  • Tutti listati

RisposteEccu estratti da a documentazione (12.1.0.2) nantu à l'almacenamiento di diversi tipi di dati in Oracle.

Tipu di dati CHAR
U tipu di dati CHAR specifica una stringa di caratteri di lunghezza fissa in u set di caratteri di a basa di dati. Specificate u set di caratteri di a basa di dati quandu create a vostra basa di dati. Oracle assicura chì tutti i valori almacenati in una colonna CHAR anu a lunghezza specificata da a dimensione in a semantica di lunghezza scelta. Se inserisci un valore chì hè più cortu di a lunghezza di a colonna, allora Oracle blank-pads u valore à a lunghezza di a colonna.

VARCHAR2 Tipu di dati
U tipu di dati VARCHAR2 specifica una stringa di caratteri di lunghezza variabile in u set di caratteri di a basa di dati. Specificate u set di caratteri di a basa di dati quandu create a vostra basa di dati. Oracle emmagatzema un valore di carattere in una colonna VARCHAR2 esattamente cum'è u specificatu, senza alcunu blank-padding, sempre chì u valore ùn supera a lunghezza di a colonna.

NUMBER Tipu di Dati
U tipu di dati NUMERU guarda cero è numeri fissi pusitivi è negativi cù valori assoluti da 1.0 x 10-130 à ma senza include 1.0 x 10126. Se specificate una espressione aritmetica chì u valore hà un valore assolutu più grande o uguale à 1.0 x 10126, allora Oracle torna un errore. Ogni valore NUMBER richiede da 1 à 22 bytes. Pigliendu questu in contu, a dimensione di a colonna in byte per un valore di dati numericu particulari NUMBER (p), induve p hè a precisione di un valore determinatu, pò esse calculatu cù a seguente formula: TONTU ((lunghezza (p)+s)/2))+1 induve s hè uguali à zero se u numeru hè pusitivu, è s uguali à 1 se u numeru hè negativu.

Inoltre, pigliemu un estrattu da a ducumentazione nantu à l'almacenamiento di valori Null.

Un null hè l'assenza di un valore in una colonna. I nulli indicanu dati mancanti, scunnisciuti o inapplicabili. I nulli sò stati guardati in a basa di dati si cadenu trà e colonne cù valori di dati. In questi casi, necessitanu 1 byte per almacenà a lunghezza di a colonna (zero). I nulli di fine in una fila ùn necessitanu micca almacenamentu perchè un novu capu di fila signala chì e colonne rimanenti in a fila precedente sò nulle. Per esempiu, se l'ultimi trè culonni di una tavula sò nulli, allora nisuna data hè almacenata per queste colonne.

Basatu nantu à sti dati, custruemu ragiunamentu. Assumimu chì a basa di dati usa codificazione AL32UTF8. In questa codificazione, e lettere russe occupanu 2 bytes.

1) A è X, u valore di u campu a 'Y' piglia 1 byte, u valore di u campu x 'D' piglia 2 byte
2) B è Y, 'Vasya' in b u valore sarà padded cù spazii fin'à 10 caratteri è piglià 14 bytes, 'Vasya' in d pigghia 8 bytes.
3) C è K. I dui campi anu u valore NULL, dopu à elli ci sò campi significati, perchè occupanu 1 byte.
4) C è Z. I dui campi anu u valore NULL, ma u campu Z hè l'ultimu in a tavula, perchè ùn occupa micca spaziu (0 bytes). U campu C occupa 1 byte.
5) K è Z. Simile à u casu precedente. U valore in u campu K occupa 1 byte, in Z - 0.
6) I è J. Sicondu a documentazione, i dui valori piglianu 2 bytes. Calculemu a lunghezza cù a formula presa da a documentazione: round( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J è X. U valore in u campu J piglià 2 bytes, u valore in u campu X piglià 2 bytes.

In totale, l'opzioni curretti sò: C è K, I è J, J è X.

Chì sarà approximativamente u fattore di clustering di l'indice 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);

  • Circa decine
  • Circa centinaie
  • Circa millaie
  • Circa decine di millaie

RisposteSicondu a documentazione Oracle (citata da 12.1):

Per un indice B-tree, u fattore di clustering di l'indici misura u raggruppamentu fisicu di fila in relazione à un valore d'indice.

U fattore di clustering di l'indici aiuta à l'ottimisatore decide se una scansione d'indici o una scansione di tavula completa hè più efficiente per certe dumande). Un fattore di clustering bassu indica una scansione d'indice efficiente.

Un fattore di clustering chì hè vicinu à u nùmeru di blocchi in una tavula indica chì e fila sò fisicamenti urdinati in i blocchi di tavula da a chjave d'indici. Se a basa di dati eseguisce una scansione completa di a tavola, allora a basa di dati tende à ricuperà e fila cum'è sò stati guardati nantu à u discu ordinatu da a chjave d'indici. Un fattore di clustering chì hè vicinu à u nùmeru di fila indica chì e fila sò spargugliati aleatoriamente in i blocchi di basa di dati in relazione à a chjave d'indici. Se a basa di dati eseguisce una scansione di a tavola completa, allora a basa di dati ùn ricuperà e fila in ogni ordine ordinatu da questa chjave d'indici.

In questu casu, i dati sò idealmente ordenati, cusì u fattore di clustering serà uguale o vicinu à u numeru di blocchi occupati in a tavula. Per una dimensione di bloccu standard di 8 kilobytes, pudete aspittà chì circa mille valori di numeri stretti si metteranu in un bloccu, cusì u numeru di blocchi, è in u risultatu, u fattore di clustering serà. circa decine.

À chì valori di N u seguente script serà eseguitu cù successu in una basa di dati regulare cù paràmetri standard?

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

RisposteSicondu a documentazione Oracle (citata da 11.2):

Limiti di basa di dati logica

Item
Tipu di Limitu
Valore limite

Indices
Dimensione tutale di a colonna indexata
75% di a dimensione di u bloccu di a basa di dati minus some overhead

Cusì, a dimensione tutale di e colonne indexate ùn deve micca più di 6Kb. Ciò chì succede dopu dipende da a codificazione di basa scelta. Per a codificazione AL32UTF8, un caratteru pò occupà un massimu di 4 bytes, cusì in u peghju casu, 6 kilobytes si adattanu à circa 1500 caratteri. Dunque, Oracle ùn permetterà a creazione d'indici à N = 400 (quandu a lunghezza di chjave di u peghju casu hè 1600 caratteri * 4 bytes + lunghezza rowid), mentri à N = 200 (o menu) crià l'indici funzionerà senza prublemi.

L'operatore INSERT cù l'indicazione APPEND hè pensatu per carica dati in modu direttu. Chì succede s'ellu hè appiicatu à a tavula nantu à quale u grillu pende?

  • I dati seranu caricati in modu direttu, u trigger hà da travaglià cum'è previstu
  • I dati seranu carricati in modu direttu, ma u trigger ùn serà micca eseguitu
  • I dati seranu carricati in modu cunvinziunali, u trigger hà da travaglià cumu si deve
  • I dati seranu carricati in modu cunvinziunali, ma u trigger ùn serà micca eseguitu
  • I dati ùn saranu micca caricati, un errore serà registratu

RisposteIn fondu, questu hè più una quistione di logica. Per truvà a risposta curretta, suggerissi u seguente mudellu di ragiunamentu:

  1. L'inserimentu in modu direttu hè realizatu da a furmazione diretta di un bloccu di dati, sguassendu u mutore SQL, chì assicura una alta velocità. Cusì, assicurendu l'esekzione di u trigger hè assai difficiuli, se micca impussibile, è ùn ci hè micca un puntu in questu, postu chì sempre rallentarà radicalmente l'inserzione.
  2. A fallimentu di eseguisce u trigger porta à u fattu chì, se i dati in a tavula sò listessi, u statu di a basa di dati cum'è un sanu (altri tavulini) dependerà di u modu in quale sta dati hè stata inserita. Questu ovviamente distrughjerà l'integrità di e dati è ùn pò micca esse appiicatu cum'è suluzione in a produzzione.
  3. L'incapacità di fà l'operazione dumandata hè generalmente trattata cum'è un errore. Ma quì duvemu ricurdà chì APPEND hè un suggerimentu, è a logica generale di i suggerimenti hè chì sò cunsiderate s'ellu hè pussibule, ma s'ellu ùn hè micca, l'operatore hè eseguitu senza piglià l'indicazione in contu.

Allora a risposta prevista hè i dati seranu carricati in u modu normale (SQL), u grillu spararà.

Sicondu a documentazione Oracle (citata da 8.04):

A violazione di e restrizioni pruvucarà a dichjarazione per eseguisce in serie, utilizendu u percorsu di inserimentu convenzionale, senza avvisi o messagi d'errore. Un'eccezzioni hè a restrizzione à e dichjarazioni chì accede à a stessa tavola più di una volta in una transazzione, chì pò causà messagi d'errore.
Per esempiu, se i triggers o l'integrità referenziale sò prisenti nantu à a tavula, allura l'indicazione APPEND serà ignorata quandu pruvate d'utilizà INSERT à carica diretta (seriale o parallela), è ancu l'indicazione PARALLEL o clause, se ne esiste.

Chì succederà quandu u seguente script hè eseguitu?

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

  • Esecuzione successu
  • Fiascu per un errore di sintassi
  • Errore: a transazzione autonoma ùn hè micca valida
  • Errore ligatu à u sopra à u massimu di nidificazione di chjama
  • Errore di violazione di chjave straniera
  • Errore ligatu à i serrature

RisposteA tavula è u trigger sò creati abbastanza currettamente è sta operazione ùn deve micca purtà à prublemi. E transazzione autònuma in un trigger sò ancu permessi, altrimente u logu ùn saria micca pussibule, per esempiu.

Dopu l'inserimentu di a prima fila, un tiru di scatula di successu pruvucarà a seconda fila per esse inserita, pruvucannu u trigger à u focu di novu, inserisce una terza fila, è cusì finu à chì a dichjarazione hà fiascatu per esse superatu u massimu nidificatu di chjama. Tuttavia, un altru puntu sottile entra in ghjocu. À u mumentu chì u trigger hè eseguitu, l'impegnu ùn hè ancu statu finitu per u primu record inseritu. Dunque, un trigger in una transazzione autònuma prova di inserisce in a tavula una fila chì riferisce una chjave straniera à un registru chì ùn hè ancu statu impegnatu. Questu risultatu in una attesa (a transazzione autònuma aspetta per a transazzione principale per impegnà per vede s'ellu pò inserisce dati) è à u stessu tempu a transazzione principale aspetta chì a transazzione autònuma cuntinueghja à travaglià dopu à u trigger. Un bloccu si trova è, in u risultatu, a transazzione autònuma hè annullata per ragioni ligati à i chjusi..

Solu l'utilizatori registrati ponu participà à l'indagine. Firmà lu, per piacè.

Era difficiule?

  • Cum'è dui dita, aghju subitu decisu tuttu bè.

  • Micca veramente, aghju sbagliatu nantu à un paru di dumande.

  • Aghju risoltu a mità currettamente.

  • Aghju indovinatu a risposta duie volte!

  • Scriveraghju in i cumenti

14 utilizatori anu vutatu. 10 utilizatori si sò astenuti.

Source: www.habr.com

Add a comment