10 Ağustos 2007 Cuma

Birleşmeli Dizilerin (Associative Arrays) Tanımlanması

Birleşmeli Diziler (Associative Arrays) veya diğer adıyla İndisli Tablolar (Index-by-tables) için şu yazım kuralı (syntax) kullanılır:

TYPE tip_adı IS TABLE OF öğe_tipi [NOT NULL]
INDEX BY [BINARY_INTEGER | PLS_INTEGER | VARCHAR2 (büyüklük_sınırı)];
INDEX BY anahtar_tipi;

anahtar_tipi, BINARY_INTEGER veya PLS_INTEGER tipinde bir sayısal değer olabilir, VARCHAR2 veya alttipleri olan VARCHAR, STRING veya LONG olabilir. LONG haricinde VARCHAR2-tabanlı bir anahtar'ın uzunluğu belirtilmelidir. LONG ise VARCHAR2(32760) tipinde bir anahtar bildirimi anlamına gelir.

Birleşmeli dizilerde şu tipler anahtar olarak kullanılamaz: RAW, LONG RAW, RAWID, CHAR, CHARACTER. Bir başlatma maddesine (initialization clause) gerek yoktur ve buna izin de verilmez.

VARCHAR2-tabanlı bir anahtar kullanan bir birleşmeli dizinin bir öğesine atıfta bulunulduğunda (reference), DATE ve TIMESTAMP gibi diğer tipler de kullanılabilir ancak bu tiplerin TO_CHAR fonksiyonu ile VARCHAR2'ye çevrilebilmesi gerekir.

İndisli tablolar (birleşmeli diziler), ardışık olmayan birincil anahtar değerlerini (primary key values) indis olarak kullanarak veri depolayabilir. Aşağıdaki örnekte indisli tabloda tek bir kayıt tutulmaktadır ve bu kaydın indisi 1 yerine 7468 'dir.

DECLARE
TYPE EmpTabTyp IS TABLE OF emp%ROWTYPE
INDEX BY BINARY_INTEGER;
emp_tab EmpTabTyp;
BEGIN
/* employee (çalışan) kaydına erişim */
SELECT * INTO emp_tab(7468) FROM emp WHERE empno = 7468;
END;

Varraylerin Tanımlanması

Varraylerin tanımlanmasında şu yazım kuralı (syntax) kullanılır:

TYPE tip_adı IS {VARRAY | VARYING ARRAY} (büyüklük_sınırı) OF öğe_tipi [NOT NULL];

tip_adı ve öğe_tipi 'nin anlamları, içiçe tablolardakilerle aynıdır. büyüklük_sınırı, dizideki öğe sayısının sınır değerini gösteren bir pozitif tamsayı literalidir.

Bir VARRAY tipi tanımlanırken sınır büyüklük değeri tanımlanmalıdır. Aşağıdaki örnekte 366 tarihi depolayan bir tip tanımlanmaktadır:

DECLARE
TYPE Takvim IS VARRAY(366) OF DATE;

İçiçe Tabloların (Nested Tables) Tanımlanması

İçiçe tablolar (nested tables) için şu yazım kuralı (syntax) kullanılır:

TYPE tip_adı IS TABLE OF öğe_tipi [NOT NULL];

tip_adı, toplulukların bildirimini yapmakta kullanılan bir tip belirleyicisidir (specifier). PL/SQL içinde bildirimi yapılan içiçe tablolar için öğe_tipi, REF CURSOR haricinde herhangi bir PL/SQL veritipi olabilir.

SQL'de küresel olarak (globally) bildirimi yapılan içiçe tablolar için başka kısıtlamalar söz konusudur; şu öğe tiplerini (element types) kullanamazlar:

BINARY_INTEGER, PLS_INTEGER
BOOLEAN
LONG, LONG RAW
NATURAL, NATURALN
POSITIVE, POSITIVEN
REF CURSOR
SIGNTYPE
STRING

Topluluk Tiplerinin (Collection Types) Tanımlanması

Bir topluluk (collection) oluşturmak için önce topluluk tipi (collection type) tanımlanır sonra bu tipten değişkenlerin bildirimi (declare) yapılır. Herhangi bir PL/SQL bloğunun, altprogramının (subprogram) veya paketinin (package) bildirim kısmında (declarative part) TABLO (TABLE) ve VARRAY tipleri tanımlanabilir.

Topluluklar, diğer tipler ve değişkenler için geçerli olan scope (etkili olma aralığı) ve örneklendirme (instantiation) kurallarına uyarlar. Bir blokta veya altprogramda, bu bloğa veya altprograma giriş yapıldığında topluluklar oluşturulur ve çıkış yapıldığında ise yok edilir.

Bir pakette ise pakete ilk kez atıfta bulunulduğunda (reference) topluluklar oluşturulur ve veritabanı oturumu sona erdirildiğinde yok edilir.

8 Ağustos 2007 Çarşamba

İçiçe Tablolarla Varraylerin Farkları

Kullanılacak öğelerin (elements) sayısı önceden biliniyorsa ve bu öğelere genelde sırayla ulaşılacak ise varray kullanmak yerinde olacaktır. Veritabanında tutulurken varrayler sıralarını ve indislerini korurlar.

Her bir varray tek bir nesne olarak tutulur; 4 KB'tan daha küçükse tablo içinde, 4 KB'tan daha büyükse tablo dışında ama yine aynı tabloalanında (tablespace) depolanır. Varrayin bütün öğelerine aynı anda erişilmelidir veya bunlar aynı anda güncellenmelidir örneğin bütün öğeler üzerinde tek seferinde bir işlem yapılması gibi. Bu durum çok sayıda öğenin depolanmasında ve bunlara erişimde kullanışlı değildir.

İçiçe tablolar (nested tables) seyrek (sparse) olabilir; en sondaki öğeyi kaldırmak yerine herhangi bir öğe silinebilir. İçiçe tablo bir depolama tablosunda sırasız (out-of-line) olarak depolanır, bu depolama tablosu içiçe tablonun kendisiyle ilişkilendirilmiştir ve sistem tarafından oluşturulmuştur.

Bu durum topluluğun (collection) sadece bazı öğelerini etkileyen sorgu ve güncellemelerde içiçe tabloları kullanışlı kılar. Bir içiçe tablo veritabanında depolanırken sırası (order) ve indisler (subscripts) korunmaz, depolama ve erişimler sonrasında bu sıra ve indisler değişebilir.

3 Ağustos 2007 Cuma

İçiçe Tablolarla Birleşmeli Dizilerin Farkları

İçiçe tablolar (nested tables) da birleşmeli diziler (associative arrays) de benzer indis yazımı (subscript notation) kullanır, ancak parametre geçirme kolaylığı ve sürdürülebilirlilk açısından farklı özellikleri vardır.

İçiçe tablolar (nested tables), bir veritabanı sütununda tutulabilir ama birleşmeli diziler (associative arrays) tutulamaz. İçiçe tablolar, kalıcı olarak tutulması gereken önemli veri ilişkileri (data relationships) için uygundur.

Birleşmeli diziler, bir yordam (procedure) çağrıldığında veya bir paket (package) başlatıldığında (initialized), topluluğun (collection) bellekte oluşturulabildiği zamanlarda göreceli olarak küçük arama (lookup) tabloları için uygundur. Büyüklüğü önceden bilinmeyen bilgilerin toplanmasında uygundur çünkü birleşmeli dizilerin büyüklükleri önceden sınırlandırılmamıştır, indis değerleri de esnektir; negatif olabilir, sıralı olmayabilir ve uygun olduğunda indis için sayı yerine string değerleri kullanılabilir.

PL/SQL, sayısal anahtar değerleri (numeric key values) kullanan host dizileri ve birleşmeli dizileri kendiliğinden birbirlerine çevirir. Bir veritabanı sunucusundan veya bir veritabanı sunucusuna toplulukları (collections) geçirmenin en etkili yolu, isimsiz (anonymous) PL/SQL blokları kullanmaktır; bu bloklar girdi ve çıktı (input and output) host dizilerini birleşmeli dizilere topluca bağlamakta (bulk-bind) kullanılır.

Birleşmeli Dizilerde Küreselleşme Ayarları

VARCHAR2 anahtar değerli (key values) birleşmeli diziler (associative arrays) kullanan bir oturumda (session), ulusal dil (national language) ayarları veya küreselleşme ayarları (globalization settings) değişirse, program bir çalışma hatası (runtime error) ile karşılaşabilir.

Örneğin bir oturumda, NLS_COMP veya NLS_SORT gibi başlatma parametrelerinin (initialization parameters) değiştirilmesi NEXT ve PRIOR gibi yöntemlerin (methods) istisna (exception) vermesine neden olabilir, bu yüzden yeni işlem yapılmadan önce bu ayarlar orjinal değerlerine çevrilmelidir.

Anahtar (key) olarak bir stringi kullanan bir birleşmeli dizinin (associative array) bildirimi yapılırken, bildirimde VARCHAR2, STRING veya LONG tipi kullanılmalıdır. TO_CHAR fonksiyonu ile VARCHAR2 'ye çevrilebildiği sürece farklı bir tip de kullanılabilir, örneğin NCHAR, NVARCHAR2 veya DATE gibi.

Bununla beraber anahtar olarak kullanılan değerler tutarlı ve eşsiz olduğunda diğer tiplerin kullanımında dikkatli olunmalıdır. Örneğin NLS_DATE_FORMAT başlatma parametresi (initialization parameter) değişirse, SYSDATE 'in string değeri değişebilir; bu durumda da array_element(SYSDATE) eskiden verdiği sonucu vermez. Benzer şekilde iki farklı NVARCHAR2 değeri aynı VARCHAR2 değerine dönüşebilir (bazı ulusal karakterlerin yerine soru işareti gelerek).

Bir veritabanı bağlantısı (database link) kullanılarak, bir birleşmeli dizi (associative array) parametre olarak uzaktaki bir veritabanına gönderilirse, bu iki veritabanının farklı küreselleşme ayarları (gobalization settings) olabilir.

Uzaktaki veritabanı FIRST ve NEXT gibi işlemler yaptığında kendi karakter düzenini (character order) kullanır, bu topluluğun (collection) ilk olarak oluşturulduğu düzenden farklı olabilir. Bu karakter seti farklılıkları, uzaktaki veritabanında, eşsiz (unique) olan iki anahtarın bu eşsizlik özelliğini ortadan kaldırırsa, program VALUE_ERROR istisnası (exception) verebilir.

31 Temmuz 2007 Salı

İndisli Tablolar (Index-by Tables)

İndisli Tablolar (Index-by Tables) veya diğer adıyla birleşmeli diziler (associative arrays), anahtar-değer çifti (key-value pairs) kümeleridir; her bir anahtar eşsizdir ve dizide karşılık gelen bir değeri gösterir. Anahtar, tamsayı veya string olabilir.

Anahtar kullanarak bir değer atandığında ilk seferinde bu değer diziye eklenir, aynı anahtarı kullanan takip eden atamalarda ise aynı giriş güncellenir (update). Eşsiz bir anahtar seçmek önemlidir; bu SQL tablosundan birincil anahtarı seçerek de yapılabilir veya birtakım stringler birleştirilerek de olabilir.

Birleşmeli dizilerde gelişigüzel büyüklükteki veri kümeleri tutulabilir. Yeri bilinmeyen tek bir öğenin hızlı aranmasında, bütün diziyi baştan sona taramadan bulunması sağlanır, bir SQL tablosunun basit haline benzer, bu bakımdan birleşmeli diziler, bizi hızlı arama sonuçlarının (lookup data) basit geçici depolanmasında, disk alanı kullanmaktan ve ağ işlemlerinden kurtarır.

Birleşmeli diziler geçici verilerin (temporary data) tutulmasına yönelik oldukları için INSERT ve SELECT INTO gibi SQL ifadeleri ile kullanılamazlar. Eğer tip bildirimleri ve değer atamaları (value assignments) bir paketin (package) içinde yapılırsa, birleşmeli diziler, veritabanı oturumunun (database session) ömrü boyunca kalıcı (persistent) hale getirilebilirler.

28 Temmuz 2007 Cumartesi

Varrayler (Değişken Boyutlu Diziler)

VARRAY tipindeki öğelere varray denir. Tek bir belirleyicinin (identifier) bütün bir toplulukla (collection) ilişkilendirilmesine olanak verir. Bir öğeye ulaşmak için standard indisleme yazım kuralı (syntax) kullanılır. Örneğin Grades(3) , Grades adlı varrayin üçüncü öğesini gösterir.

Bir varrayin tip tanımlamasında belirtilmesi zorunlu olan bir maksimum büyüklüğü vardır. İndisinin sabit olan alt sınırı 1'dir, üst sınırı ise genişletilebilir. Bir varrayin hiç öğesi olamayabileceği gibi, tip tanımlamasında belirtilmiş olan maksimum sayıda öğesi de olabilir.

İçiçe Tablolar (Nested Tables)

İçiçe tablolar, veritabanı içinde, tek kolonlu veritabanı tabloları olarak düşünülebilir. Oracle içiçe tablonun satırlarını düzensiz olarak depolar ancak bu tablo bir PL/SQL değişkenine atandığında satırlara 1'den başlayarak ardışık indis değerleri verilir; bu ayrı ayrı satırlara dizi benzeri erişim sağlar. Her bir öğesi bir içiçe tablo olan içiçe tablolar oluşturularak çok boyutlu diziler modellenebilir.

İçiçe tabloları dizilerden ayıran iki önemli özellik vardır:
1) Dizilerin belirlenmiş bir üst sınırı vardır ancak içiçe tablolar sınırlandırılmamıştır ve boyutları dinamik olarak artabilir.

2) Diziler sıkışık olmak zorundadır, yani indisleri ardışık olmalıdır; bu yüzden tek (yalnız) öğeler silinemez. İçiçe tablolar da başta sıkışıktır, ama seyrek hale gelebilirler, yani indisleri ardışık olmayabilir. Bir içiçe tablodan yerleşik yordam (built-in procedure) olan DELETE kullanılarak öğeler silinebilir, bu indiste boşluklar oluşturubilir ama yerleşik (built-in) fonksiyon NEXT, peşpeşe gelen indislerin tekrarlanmasına olanak sağlar.

Topluluk (Collection)

Bir topluluk (collection), hepsi aynı tipten olan düzenli bir grup öğeden oluşur. Her bir öğenin topluluktaki yerini belirleyen yegane (unique) bir indisi (subscript) vardır. PL/SQL şu topluluk tiplerini sunar:

İndisli tablolar (index-by tables) veya birleşmeli dizilerde (associative arrays) gelişigüzel sayılar veya stringler kullanılarak öğelere ulaşılabilir. (Diğer programlama dillerindeki hash tablolarına benzer).

İçiçe tablolar (nested tables) gelişigüzel sayıda öğeyi tutar. İndis olarak sıralı sayıları kullanırlar. İçiçe tablolar veritabanı tablolarında tutularak ve SQL ile idare edilerek eşdeğer SQL tipleri tanımlanabilir.

Varrayler (Değişken boyutlu diziler, Variable-size arrays), sabit sayıda öğe tutarlar ancak bu sayı çalışma zamanında değiştirilebilir. İndis olarak sıralı sayıları kullanırlar. Varraylerin veritabanı tablolarında tutulması sağlanarak eşdeğer SQL tipleri tanımlanabilir. SQL kullanılarak depolanmaları ve erişimleri yapılabilir ancak bu içiçe tablolardaki kadar esnek olmayacaktır.

Öğeleri topluluk olan topluluklar yaratılarak çok boyutlu diziler modellenebilir. Bir uygulamada toplulukları kullanmak için önce PL/SQL tipleri sonra da bu tipte değişkenler tanımlanır. Topluluk tipleri bir yordam (procedure), fonksiyon veya paket (package) içinde tanımlanabilir. Topluluk değişkenleri parametre olarak geçirilebilir.

Tek değerden daha karışık olan verileri aramak için PL/SQL kayıtları (records) veya SQL nesne tipleri topluluklarda tutulabilir. İçiçe tablolar ve varrayler aynı zamanda nesne tiplerinin (object types) nitelikleri (attributes) olabilirler.

NULL İfadesi (NULL Statement)

NULL ifadesi (statement) kontrolü bir sonraki ifadeye geçirmekten başka bir iş yapmaz. Koşulsal bir yapıda (conditional construct), okuyucuya bir olasılığın düşünüldüğünü ancak bir işleme gerek olmadığını gösterir. Aşağıdaki örnekte, isimsiz istisnalar (exceptions) için bir işleme gerek olmadığını gösteriyor:

EXCEPTION
WHEN ZERO_DIVIDE THEN
ROLLBACK;
WHEN VALUE_ERROR THEN
INSERT INTO errors VALUES ...
COMMIT;
WHEN OTHERS THEN
NULL;
END;

NULL ifadesi, IF ifadelerinde ve en az bir yürütülebilir
ifade (executable statement) gerektiren diğer ifadelerde,
yazım kuralına (syntax) uygunluk için kullanılır.
Aşağıdaki örnekte sadece 90'ın üstündeki çalışanlar
ikramiye alıyor:

IF rating > 90 THEN
compute_bonus(emp_id);
ELSE
NULL;
END IF;

NULL ifadesi, test ve debug işlemleri tamamlanmamış
fonksiyon ve yordamların (procedures) geçici olarak
yerlerini tutar (onlar tamamlanana kadar). Aşağıdaki
örnekte NULL ifadesi altprogramda ihtiyaç duyulan
yürütülebilir kısmı (executable part) doldurmaktadır:

PROCEDURE debit_account (acct_id INTEGER, amount REAL) IS
BEGIN
NULL;
END debit_account;

25 Temmuz 2007 Çarşamba

FOR Döngüsü (FOR Loop)

While döngüsünün aksine For döngüsünde tekrar sayısı önceden bellidir, bu tekrarların sınırı tamsayılarla belirlenir. Yazım kuralı (syntax) şöyledir:

FOR Sayac IN [REVERSE] alt_sınır..üst_sınır LOOP
ifadeler
END LOOP;

Sınır değerleri içindeki her bir tamsayı için ifadeler yürütülür ve sayaç bir artırılır. Örneğin:

FOR i IN 1..3 LOOP ---> 1,2,3 değerleri sırayla i'ye atanır
ifadeler ---> 3 kere yürütülür
END LOOP;

'REVERSE' kullanılmazsa sınırlar içindeki tamsayılar küçükten büyüğe atanır, 'REVERSE' kullanılırsa tersten yani büyükten küçüğe atanır ancak sınır değerleri gene küçükten büyüğe yazılmalıdır.

FOR i IN REVERSE 1..3 ---> 3,2,1 değerleri sırayla i'ye atanır
ifadeler ---> 3 kere yürütülür
END LOOP;

Bir For döngüsünün içinde, döngü sayacı bir sabitmiş gibi kullanılabilir ancak kendisine bir değer atanamaz:

FOR ctr IN 1..10 LOOP
IF NOT finished THEN
INSERT INTO ... VALUES (ctr, ...); ---> doğru kullanım
factor := ctr * 2; ---> doğru kullanım
ELSE
ctr := 10; ---> hatalı kullanım
END IF;
END LOOP;

Alttiplerin Kullanımı (Using Subtypes)

Aşağıdaki örnekte Sayac tipinde bir değişkenin bildirimi yapılmaktadır, tipin adı olan 'Sayac' kullanımı hakkında bilgi vermektedir:

DECLARE
SUBTYPE Sayac IS NATURAL;
rows Sayac;

Kullanıcı tanımlı bir alttip (user-defined subtype) türündeki bir değişkenin bildirimi yapılırken aynı zamanda sınırlandırılabilir de, örnek:

DECLARE
SUBTYPE Accumulator IS NUMBER;
total Accumulator(7,2);

Alttiplerin (subtypes) kullanımı, sınır dışına taşan (out-of-range) değerlerin belirlenmesini sağlayarak güvenilirliği artırabilir. Aşağıda Numeral alttipi -9....9 aralığındaki tamsayıları tutacak şekilde sınırlandırılmaktadır, eğer program bu sınırların dışında bir değeri bu değişkende tutmak isterse PL/SQL, istisna (exception) verir:

DECLARE
SUBTYPE Numeral IS NUMBER(1,0);
x_axis Numeral; -- sayı büyüklüklerinin sınırı -9 .. 9
y_axis Numeral;
BEGIN
x_axis := 10; -- VALUE_ERROR verir (hata verir)
...
END;

22 Temmuz 2007 Pazar

Kullanıcı Tanımlı Alttipler (User-Defined Subtypes)

Her bir PL/SQL temel tipi (base type), ona uygulanabilecek bir takım değerler (values) ve işlemler (operations) belirtir. Alttipler de kendi temel tipleri ile aynı işlemleri belirtirler ancak değerlerin sadece bir kısmını belirtirler.

Böylece bir alttip, yeni bir tip değildir ancak temel tipinin sınırlandırılmış bir halidir. Alttipler güvenilirliği artırır, ANSI/ISO tipleri ile uyumluluk sağlar, sabitlerin ve değişkenlerin kullanım amacını göstererek okunurluğu artırır.

PL/SQL 'de CHARACTER ve INTEGER alttipleri şöyle tanımlıdır:
SUBTYPE CHARACTER IS CHAR;
SUBTYPE INTEGER IS NUMBER(38,0); -- sadece tamsayılara izin verir

CHARACTER alttipi sınırlandırılmamış (unconstrained) bir alttiptir çünkü temel tipi olan CHAR ile aynı değerleri belirtir, INTEGER alttipi ise sınırlandırılmış (constrained) bir alttiptir çünkü temel tipi olan NUMBER'ın değerlerinin (values) sadece bir kısmını belirtir.

Tarih ve Zaman (Date and Time) Alttiplerinde Budama (Truncation)

Bazı tarih ve zaman (date and time) tipleri için ayarlanmamış duyarlılıklar (default precisions), mümkün olan en yüksek duyarlılıklardan daha düşüktür. Örneğin, DAY TO SECOND 'da gün (day) için 2, saniye (second) için 6'dır, oysa en yüksek duyarlılıklar her ikisi için de 9'dur.

Değişkenler atanırken ve yordam (procedure) parametreleri geçirilirken, budamadan (truncation) sakınmak için, en yüksek duyarlılık değerlerini kullanan şu alttipler (subtypes) kullanılabilir:

TIMESTAMP_UNCONSTRAINED
TIMESTAMP_TZ_UNCONSTRAINED
TIMESTAMP_LTZ_UNCONSTRAINED
YMINTERVAL_UNCONSTRAINED
DSINTERVAL_UNCONSTRAINED

Günden Saniyeye Aralık Veritipi (Day To Second Interval Datatype)

Günler, saatler, dakikalar ve saniyelerden oluşan aralıkları tutmak ve üzerlerinde değişiklik yapmak için kullanılır. Yazım kuralı (syntax) şöyledir:
INTERVAL DAY[(gün_duyarlılığı)] TO SECOND[(saniye_duyarlılığı)]

duyarlılıklar için 0 ile 9 arasında bir rakam kullanılmalıdır, duyarlılıkların ayarlanmamış (default) değerleri sırasıyla 2 ve 6'dır. Aşağıda günden saniyeye veritipinde bir değişken bildirimi yapılmaktadır:

DECLARE
lag_time INTERVAL DAY(3) TO SECOND(3);
BEGIN IF lag_time > INTERVAL '6' DAY THEN ...
...
END;

Yıldan Aya Aralık Veritipi (Year To Month Interval Datatype)

Yıllardan ve aylardan oluşan zaman aralıklarını tutar. Yazım kuralı (syntax) şöyledir:
INTERVAL YEAR[(duyarlılık)] TO MONTH
duyarlılık, yıl alanındaki basamak sayısını gösterir; 0 ile 4 arasında bir rakam olmalıdır.
Aşağıda aralık veritipine 101 yıl ve 3 ay atanmaktadır:

DECLARE
lifetime INTERVAL YEAR(3) TO MONTH;
BEGIN lifetime := INTERVAL '101-3' YEAR TO MONTH; -- aralık literali
lifetime := '101-3'; -- karakter tipinden dolaylı çevirim
lifetime := INTERVAL '101' YEAR; -- sadece yıllar belirtilebilir
lifetime := INTERVAL '3' MONTH; -- sadece aylar belirtilebilir
...END;

21 Temmuz 2007 Cumartesi

LOB Tipi

LOB (Large Object, Büyük Nesne) veritipi olan BFILE, BLOB, CLOB ve NCLOB, yapılandırılmamış (unstructured) veri bloklarının 4GB'a kadar depolanmasını sağlar (örneğin metin, grafik görüntüleri, video klipleri, ses gibi). Ayrıca veriye, etkili, rastgele ve parça parça erişime olanak verir.

LOB tipleri LONG ve LONG RAW tiplerinden şu şekilde farklıdır: NCLOB dışındaki LOB 'lar, nesnelerin bir niteliği olabilir, LONG ' lar olamaz. Bir LOB en fazla 4 GB, LONG ise 2 GB olabilir.
LOB 'lar veriye rastgele (random) erişimi, LONG 'lar ise sıralı (sequential) erişimi destekler.

LOB tipleri, lob yerleştiricilerini (lob locators) depolar, bunlar da dışsal (external) bir dosyadaki büyük nesnelere işaret eder (satır içinde veya satır dışında). BFILE verileri ise veritabanı dışında, işletim sistemi dosyalarında sakalanır.

PL/SQL, LOB 'lar üzerindeki işlemleri yerleştiricileri (locators) kullanarak yapar. Örneğin bir BLOB kolon değeri seçildiğinde sadece bir yerleştirici döndürülür, işlem ID'si (transaction ID) bunun başka bir işlemde güncelleme için kullanılmasını engeller; benzer şekilde başka bir oturumda da kullanılamaz.

Oracle9i'den itibaren CLOB 'lar CHAR ve VARCHAR2 'ye çevrilebilir, bunun tersi de geçerlidir. BLOB 'lar RAW'a, RAW 'lar da BLOB 'a çevrilebilir. LOB' lar üzerinde okuma, yazma ve parça parça işlemler yapmak için DBMS_LOB paketi kullanılabilir.

20 Temmuz 2007 Cuma

SUNUCU

Öncelikle Oracle ile ilgili iki kavramın iyi anlaşılması gerekir: veritabanı ve instance (örnek).
Veritabanı, işletim sistemi dosyalarının oluşturduğu fiziksel topluluğa denir. Instance (örnek) ise bir takım Oracle işleçlerinden (process) ve de bir tür bellek olan SGA ‘den (System Global Area) oluşur. Bir veritabanı birden çok instance tarafından açılabilir. Instance ‘ın açtığı veritabanı günden güne veya birkaç saat içinde değişebilir.

Oracle’a bir kullanıcının bağlanması iki türlü olabilir: atanmış sunucu (dedicated server) veya MTS (Multi-Threaded Server) (Çoklu iş parçacıklı sunucu). Atanmış sunucuda oturum (session) boyunca bir sunucu işleci (process), kullanıcı işlece atanır. Her bir oturum için, birebir eşleme şeklinde yeni bir atanmış sunucu oluşacaktır. Bu atanmış sunucu gönderilen SQL komutlarını işleyecektir.

MTS modunda ise Oracle, paylaşılmış sunuculardan (shared servers) oluşan bir havuz kullanır. Bunda kullanıcılar gruplar halinde sunucuları paylaşırlar, böylece ihiyaç duyulan sunucu sayısı belirgin oranda azalır.

MTS ‘de kullanıcı doğrudan sunucu ile bağlantı kuramaz, bunun yerine dağıtıcı (dispatcher) ile bağlantı kurar. Dağıtıcı kullanıcının isteğini SGA ‘deki bir istek kuyruğuna yerleştirir. Boştaki bir sunucu kuyruktan aldığı komutu işler ve sonucu yanıt kuyruğuna yerleştirir. Dağıtıcı, yanıtı kuyruktan alıp kullanıcıya gönderir.

DOSYALAR

Instance ile ilgili olan dosyalar parametre dosyalarıdır. Veritabanı ile ilgili olan dosyalar ise veri dosyaları, redo log dosyaları, kontrol dosyaları, temp dosyalar ve şifre dosyalarıdır.
Parametre dosyalarında kontrol dosyalarının nerde olduğu ve bazı bellek yapılarının büyüklükleri gibi bilgiler tutulur.

Veri dosyaları en önemli dosyalardır, bunlar tablolar, indeksler ve diğer segmentler gibi veritabanını oluşturan temel bilgileri tutarlar. Redo log dosyaları transaction (işlem) kütüklerini (log) tutarlar.

Kontrol dosyaları, veri dosyalarının yerlerini ve durumları hakkındaki bilgiyi tutar. Temp dosyaları disk tabanlı sortları ve geçici depolamaları tutar. Şifre dosyalarında kullanıcı şifreleri tutulur.

Parametre Dosyaları

Bir veritabanının parametre dosyası, init dosyası veya init.ora dosyası olarak bilinir, UNIX’te default adı init.ora ‘dır, Windows’ta ise init%ORACLE_SID%.ora ‘dır. SID ‘si (Site Identifier) tkyte816 olan bir veritabanının init dosyası inittkyte816.ora olacaktır.

Parametre dosyası veritabanının başlatılmasını sağlayan dosyadır, basit bir metin dosyasıdır, dolayısıyla herhangi bir metin editörü ile yazılabilir. Basit bir parametre dosyasında veritabanının adı, veritabanı blok büyüklüğü ve kontrol dosyasının yeri bulunur.

Parametre dosyasının yeri UNIX ‘te $ORACLE_HOME/dbs , Windows’ta ise %ORACLE_HOME%\DATABASE ‘dir. Bu dosyanın içeriği bazen şu şekilde tek bir satır da olabilir:

IFILE=`C:\oracle\admin\tkyte816\pfile\init.ora`

IFILE komutu C’deki #include komutuna benzer şekilde çalışır. Belirtilen yoldaki dosyayı (init.ora) dahil eder.

Veri Dosyaları

Veri dosyaları redo log dosyaları ile birlikte veritabanındaki en önemli dosyalardır. Veritabanındaki bütün veri, en sonunda veri dosyalarında depolanır. Hemen hemen her veritabanında birden fazla veri dosyası olur, en az iki tane olacaktır: biri sistem verileri için biri de kullanıcı verileri için.

Oracle veritabanında nesneleri tutmak için tablespace (tablo alanı), segment (bölüm), extent (kapsam) ve block (blok) gibi paylaşım birimleri kullanır. Depolama alanında yer kaplayan veritabanı nesnelerine segment denir. Bir tablo yarattığımızda tablo segmenti yaratırız. Bölümlü (partitioned) tablo yarattığımızda her bir bölüm için bir segment yaratırız. Aynı şekilde bir index için gene bir index segmenti yaratılır.

Her bir segment bir veya daha fazla extent’ten (kapsam) oluşur. Extent, bir dosyadaki ayrılmış bitişik boşluklardan oluşur. Bir extent tek bir blokla 2GB arasında bir büyüklükte olabilir. Extent, bloklardan oluşur. Blok, Oracle’daki en küçük boşluk paylaştırma birimidir.

Veri satırları, index girişleri ve geçici sort sonuçları bloklarda depolanır. Blok, Oracle’ın diskten okuduğu veya diske yazdığı şeydir. Bloklar genelde 2KB, 4KB veya 8KB büyüklükte olur (16 KB ve 32 KB’a da izin verilmiştir). Blok büyüklüğü veritabanı oluşturulduktan sonra değiştirilemez, veritabanındaki bütün bloklar aynı büyüklüktedir.

Bir blok şu bölümlerden oluşur: Header (başlık), Table Directory (Tablo Dizini), Row Directory (Satır Dizini), Free Space (Boş Alan), Data (Veri). Bunlardan ilk üçüne Block Overhead (Blok Yükü) denir ve Oracle tarafından bloğun yönetiminde kullanılır, buraya veri yazılamaz.

Tabloalanı (Tablespace), segmentleri içeren bir yüklüktür (container). Her bir segment tek bir tabloalanına aittir. Bir segmentin bütün extentleri, segmentin bulunduğu tabloalanında bulunacaktır. Bir tabloalanındaki herhangi bir segmentin bir extenti bütünüyle tek bir veri dosyasında yer alacaktır, ancak bir segment farklı veri dosyalarında bulunan extentlere sahip olabilir.

Bir veritabanı bir veya daha fazla tabloalanından oluşur. Bir tabloalanı bir veya daha fazla veri dosyası içerir ve de segmentleri içerir.

Temp Dosyalar

Oracle’daki geçici veri dosyaları (temp files), özel bir tip veri dosyasıdır. Oracle RAM’da yeterli yer olmadığında sort işlemlerinin ara sonuçlarını ya da sonuç kümesini bu temp dosyalara yazar, kalıcı veri nesneleri bu dosyalarda saklanmaz.

Normalde, Oracle’da bir nesneye yapılan değişiklik redo kütüklerinde (log) saklanır, ancak temp dosyaları için bu geçerli değildir. Temp dosyaları için ise UNDO oluşturulur. Veritabanının yerel yönetimli geçici tabloalanları ile konfigüre edilmesi önerilmektedir. DBA, CREATE TEMPORARY TABLESPACES komutunu kullanmalıdır.

Kontrol Dosyaları

Kontrol dosyası oldukça küçük bir dosyadır, anormal şartlarda 64 MB’a kadar büyüyebilir, Oracle’ın ihtiyaç duyduğu diğer dosyaların dizinini tutar. Parametre dosyası (init.ora dosyası) Oracle instance’ına kontrol dosyalarının nerede olduğunu söyler, kontrol dosyaları da instance’a veritabanının ve online redo log dosyalarının nerede olduğunu söyler ayrıca checkpointler, veritabanının adı ve archive redo log geçmişi (history) hakkında da bilgi verir.

Kontrol dosyaları ya donanımla (RAID) çoklanmalıdır ya da ayrı ayrı disklerde birden fazla kopyası alınmalıdır (diskin bozulma ihtimaline karşın), bu dosyaların kaybolması kurtarma (recovery) işlemini zorlaştırır.

Redo Kütük (Log) Dosyaları

Bu dosyalar Oracle veritabanı için çok önemlidir, veritabanının işlem kütükleridir (transaction logs), sadece kurtarma (recovery) amaçlı kullanılırlar (instance veya ortam bozulmasında) veya destek (standby) veritabanı tutmak için. Instance’ın çökmesi halinde online redo kütükleri (logs) kullanılır.

Sabit diskin bozulması halinde ise hem archived redo kütükleri hem de online redo kütükleri (logs) kullanılır ayrıca bu iki kütük yanlış bir commit işleminin geri alınması için de kullanılabilir.

Online Redo Kütüğü (log)

Her Oracle veritabanı en az iki tane online redo kütüğüne sahiptir ve bunların büyüklükleri sabittir. Oracle bir kütük dosyasına yazmayı bitirdikten sonra diğer kütük dosyasına yazmaya başlar, bu geçişe kütük değiştirme (log switch) denir ve kötü ayarlanmış bir veritabanında veritabanının geçici olarak beklemede kalmasına neden olabilir.

Oracle içindeki bilgileri kullanmayacağına emin değilse, online redo kütüğündeki veriler diske yazılana kadar veritabanı işlemlerini geçici olarak durdurur.

Veritabanı tampon önbelleği (database buffer cache), veritabanı bloklarının geçici olarak depolandığı yerdir, Oracle’ın SGA (System Global Area) kısmında bulunur, bloklar okundukça burada depolanır. Bu önbelleğin görevi fiziksel I/O işlemlerini hızlandırmaktır.

Örneğin bir UPDATE komutu ile bir blokta değişiklik yapılırsa, bu değişiklik tampon önbellekteki (buffer cache) bloklarda yapılır, geri alma için gerekli bilgi redo log tamponunda (redo log buffer) tutulur. COMMIT komutu ile de redo log tamponundaki veriler online redo kütüğüne aktarılır ve böylece veriler sabit hale gelir.

Database block writer (DBWn) işleci (process), arkaplanda (background) çalışır, buffer cache’deki (tampon önbellek) verileri sabit diske yazar. Farklı uygulamalar farklı sayıda online redo kütüklerine ihtiyaç duyar, ihtiyaç tiplerini üçe ayırabiliriz:

Destek Veritabanı (standby database) : Redo kütükleri dolduktan ve veritabanının kopyasına uygulandıktan sonra destek veritabanına gönderiliyorsa çok sayıda küçük redo kütük dosyası kullanmak yerinde olacaktır, böylece destek veritabanı sürekli güncel kalır.

Pek Çok Kullanıcının Aynı Blokları Değiştirmesi : Diske yazmadan önce bloklar mümkün olduğunca çok defa güncellenmelidir (update) ve de checkpoint sayısını azaltmak için kütükler seyrek değiştirilmelidir, bu yüzden büyük redo kütük dosyaları kullanılamalıdır.

Kurtarma İçin Gereken Süre (Mean Time to Recover) : Küçük ve çok sayıda redo kütüğü kullanmak kurtarma süresini kısaltır ancak veritabanının işleyişini yavaşlatır.

Archived Redo Kütüğü (log)

Bir Oracle veritabanı ARCHIVELOG modunda çalıştırılmalıdır aksi halde eninde sonunda veri kaybı olacaktır. Sadece test veya geliştirme sistemleri NOARCHIVELOG modunda çalıştırılabilir.

RAID desteği bile olsa donanıma fazla güvenilmemelidir çünkü sabit disklerin bozulma ihtimali vardır. Düzgün konfigüre edilmiş bir arşivleme fazla bir yük getirmez. Veri kaybeden hızlı bir sistem kullanışsız olacaktır.

BELLEK YAPILARI

Üç temel bellek yapısı vardır, bunlar:

SGA (System Global Area) (Sistem Küresel Alanı) : Bu büyük paylaşımlı bir bellek bölümüdür, bütün Oracle işleçleri (process) eninde sonunda buraya erişirler.

PGA (Process Global Area) (İşleç Küresel Alanı) : Bu alan tek bir işlece (process) veya iş parçacığına (thread) özeldir, diğerleri bu alana erişemez.

UGA (User Global Area) (Kullanıcı Küresel Alanı) : Bu alan oturum ile ilişkilendirilmiştir. MTS modunda SGA’de bulunur, atanmış sunucu (dedicated server) modunda ise PGA’de bulunur.

PGA ve UGA

PGA tipik olarak C’nin çalışma zamanı çağrısı (run-time call) malloc() ile oluşturulur ve çalışma zamanında küçülüp büyüyebilir. PGA her zaman SGA’in içindedir. UGA ise oturuma aittir ve yeri Oracle’ın konfigüre edilme şekline göre değişir.

PGA ve UGA’in büyüklüğünü etkileyen en önemli etkenlerden biri init.ora ‘daki oturum seviyesi parametreleri olan SORT_AREA_SIZE ve SORT_AREA_RETAINED_SIZE ’dır. Bunlar Oracle’ın diske yazmadan önce verilerin sort işlemi için ne kadar alan ayıracağını ve işlemden sonra bu alanın ne kadarını tutacağını belirler. SORT_AREA_SIZE genelde PGA ‘in dışında yer alır, SORT_AREA_RETAINED_SIZE ise UGA ‘in içinde olur.

SGA

Her bir Oracle instance’ının (örnek) büyük, paylaşımlı bir bellek yapısı vardır, buna topluca SGA (System Global Area) (Sistem Küresel Alanı) denir. Oracle işleçleri (process) bu alana erişirler. SGA’i görüntülemek için V$SGASTAT adlı sihirli (magic) V$ tablosu kullanılabilir.
SGA çeşitli havuzlara (pool) ayrılmıştır, bunlar:

Java pool (Java Havuzu) :Veritabanında çalışan JVM için ayrılmıştır, sabit büyüklüktüktedir.

Large pool (Büyük Havuz): MTS tarafından oturum belleği (session memory) için, Paralel İşlem (Parallel Execution) tarafından mesaj tamponları (message buffers) için ve RMAN (Recovery Manager) Backup (Kurtarma Yöneticisi Yedekleyicisi) tarafından disk I/O tamponları (buffers) için kullanılır.

Shared pool (Paylaşımlı Havuz) : Paylaşımlı kürsörleri, kayıtlı yordamları (stored procedures), durum nesnelerini (state objects), dizin önbelleklerini (directory caches) ve diğer pek çok veriyi tutar.

The ‘Null’ pool : Bu bölümün aslında bir adı yoktur. Üç bellek türünü içerir: Blok tamponları (block buffers) (cached database blocks), redo kütük tamponu (redo log buffer) ve sabit (fixed) SGA.

Sabit SGA (Fixed SGA)

Genellikle çok küçüktür. Büyüklüğü platformdan platforma ve sürümden sürüme değişir. Kurulum sırasında Oracle binary’ye derlenir, bu yüzden sabittir. SGA, bu bölümü SGA’in diğer bölümlerine ve parçalarına erişmek için kullanır. Çeşitli parametre değerlerini tutan ve SGA’in diğer bileşenlerine işaret eden değişkenleri tutar.

Redo Tamponu (Redo Buffer)

Online redo kütüklerine (log) yazılacak veriler diske yazılamadan önce geçici olarak burada tutulur. Redo kütük tamponlarının (redo log buffer) kullanımı veritabanının işleyişini hızlandırabilir. Bu bölümün içeriği şu durumlarda boşaltılır:

3 saniyede bir veya birisi commit (işlemek, teslim etmek) ettiğinde veya üçte biri dolduğunda veya verilerin toplamı 1 MB’a ulaştığında. Bir veritabanı sisteminin bir iki MB’tan daha büyük bir redo tamponuna ihtiyaç duyması çok ender görülen bir durumdur.

Redo tamponunun ayarlanmamış (default) büyüklüğü 512 KB ile (128*CPU sayısı)’dan büyük olanın değerine eşittir, bu init.ora dosyasındaki LOG_BUFFER parametresi ile kontrol edilir. Redo tamponunun en küçük büyüklüğü ise en büyük veri bloğunun dört katıdır.

Blok Tampon Önbelleği (Block Buffer Cache)

Oracle, veritabanı bloklarını diske yazmadan önce ve diskten okuduktan sonra burada depolar. Bu bölüm küçük olursa sorgular çok uzun sürer, büyük olursa diğer işleçler (process) görev yapamaz hale gelir.

Üzerine veri yazılmış bloğa ‘kirli’ blok, henüz üzerine veri yazılmamış yani boş olan bloğa da ‘temiz’ blok denir. Kirli bloklar ayrı bir listede, temiz bloklar ayrı bir listede tutulur. Kirli bloklar Veritabanı Blok Yazıcısı (Database Block Writer, DBWn) tarafından yazılır.

Oracle, her bir blok için ‘dokunma sayısı’ (touch count) şeması tutar. Önbellekteki blok hit aldıkça sayacı bir artırılır. X$BH tablosu, Blok Tampon Önbelleğindeki (BTÖ) bloklar hakkında bilgi verir.

Oracle 8.0’dan itibaren BTÖ’ye çoklu tampon havuzları özelliği eklenmiştir. Bu özellik sayesinde BTÖ’de belirli miktarda bir alan özel segmentler için ayrılabilir (örneğin lookup tabloları için). Bu ayırdığımız alandaki blokların ilgisiz bloklar tarafından yaşlandırılmasını (age out) engeller. Yaşlanmaya dayalı saklamaya, saklama havuzu (KEEP pool) denir.

Geri dönüşüm havuzlarında (RECYCLE pool) ise blok, ihtiyaç duyulmaz hale gelir gelmez yaşlandırılır.

Paylaşımlı Havuz (Shared Pool)

Başarım (performance) ve ölçeklenirlik (scalability) açısından önemlidir. Küçük olursa başarımı durma noktasına kadar düşürebilir, çok büyük olursa da gene aynı etkiyi yapacaktır, yanlış kullanıldığı takdirde de sonuç felaket olacaktır.

Oracle pek çok program veri parçasını burada önbellekler, örneğin bir sorgunun (query) ayrıştırma (parse) sonuçları gibi. Bir sorgu ayrıştırılacağı zaman Oracle öncelikle buraya bakar, daha önce yapılmış mı diye.

PL/SQL kodu burada önbelleklenir, böylece bir dahaki sefere diskten okunması gerekmez ve paylaşılır da, örneğin aynı anda işleyen 1000 tane oturum varsa kodun tek bir kopyası bunlar arasında paylaşılır.
Sistem parametreleri, veri dizin önbelleği (data dictionary cache) ve nesneler hakkındaki önbelleklenmiş bilgi burada tutulur. Paylaşımlı havuz yaklaşık 4 KB büyüklüğündeki bellek parçalarından oluşur ve bellek LRU (Leasy Recently Used) (En Seyrek Kullanılan) ile yönetilir. Paylaşımlı havuz, sorgu planlarının tekrar tekrar kullanılması için tasarlanmıştır.

Büyük Havuz (Large Pool)

Büyük bellek parçalarını tutmak için kullanılır, paylaşımlı havuzun tutmakta zorlanacaklarını. Büyük havuz, geri dönüşüm havuzuna (recycle pool) benzer (yaşlandırma kullnılmaz, veriye ihtiyaç ortadan kalkar kalkmaz silinir). Paylaşımlı havuz ise saklama havuzuna (keep pool) benzer.

Büyük havuzdaki bir bellek parçası serbest bırakıldığı anda bir başka işleç (process) tarafından kullanılabilir. Büyük havuz özellikle
1) MTS tarafından UGA için,
2) İfadelerin paralel yürütülmesi (parallel execution of statements) için,
3) Yedekleme (Backup) için (RMAN disk I/O tamponları için) kullanılır.

MTS kullanırken büyük havuz kullanılması zorunlu değildir ancak kullanılaması tavsiye edilir ayrıca büyük havuz büyüklüğünün elle ayarlanması tavsiye edilir. Ayarlanmamış değer durumunuz için uygun olmayacaktır.

Java Havuzu (Java Pool)

Javada bir kayıtlı yordam (stored procedure) kodlanırsa veya veritabanına EJB (Enterprise JavaBean) eklenirse, Oracle bu kodları işlemek için Java Havuzunu kullanır, çalışma moduna göre kullanım şekli değişir.

Atanmış sunucu (dedicated server) modunda her bir java sınıfının paylaşılan kısımlarını içerir ki bunlar aslında her oturum başına kullanılırlar, her sınıf başına 4-8 KB’lık salt okunur (read-only) kısımlardır. Atanmış sunucu modunda oturum başına durum (per-session state) UGA’da tutulur.

MTS modunda Java havuzu şunları içerir: her bir java sınıfının paylaşılan kısmı ve her bir oturumun, oturum başına durumu için kullanılan UGA’nın bir kısmı. Java havuzunun toplam büyüklüğü sabittir bu yüzden uygulamaların bellek ihtiyacı ile oturum sayısının çarpımı bilinmelidir. “MTS modunda Java havuzu çok büyük hale gelebilir çünkü eşzamanlı (concurrent) kullanıcıların sayısına bağlıdır.

İŞLEÇLER (The Processes)

Bir Oracle instance’ını (örnek) bellek ve işleçler oluşturur. İşleç dediğimiz şeylerin windowstaki karşılığı iş parçacığıdır (thread). Üç tip işleç vardır:

1) Sunucu İşleçleri (Server Processes) : Bir kullanıcının isteği üzerine çalışır; atanmış ve paylaşımlı sunucular gibi.
2) Arkaplan İşleçleri (Background Processes) : Veritabanının başlatılması ile çalışırlar ve çeşitli bakım görevleri yaparlar; blokları diske yazmak, online redo kütüğünün bakımı, bitirilen işleçlerin temizlenmesi gibi.
3) Esir İşleçler (Slave Processes) : Arkaplan işleçlerine benzerler ancak bir arkaplan veya sunucu işleci adına fazladan iş yaparlar.

Sunucu İşleçleri (Server Processes)

Atanmış ve paylaşımlı sunucular aynı işi yapar; onlara verilen SQL’i işler. Bir sorgu gönderildiğinde bunu ayrıştırır ve paylaşımlı havuza koyarlar (veya orda bulurlar). Sorgu planını bu işleç oluşturur, gerekli veriyi tampon önbellekten okur veya diskten tampon önbelleğe okur. En fazla CPU zamanını bu işleçler kullanır; sort, sum ve birleştirme (join) işlemlerini yaparlar.

Atanmış sunucu modunda kullanıcı oturumu ile sunucu işleci arasında birebir eşleme vardır; 100 oturum varsa 100 işleç olacaktır. Kullanıcı ile sunucu arasında Net8 ağ (network) yazılımı/protokolü kullanılır. Atanmış sunucular için Oracle Net8 Dinleyici İşleci (Listener Process) şart değildir ancak paylaşımlı sunucular için şarttır.

Atanmış Sunucuya Karşı Paylaşımlı Sunucu

SQL tabanlı uygulamalar Oracle veritabanına bağlanmak için en yaygın olarak atanmış sunucu modunu kullanırlar (kurması daha kolaydır, hiç/çok az konfigürasyon gerektirir, MTS ise birkaç basit basamak daha gerektirir). Kullanıcı oturumu ile sunucu arasında, atanmış sunucu modunda birebir eşleme varken MTS’de bireçok eşleme vardır; çok kullanıcıdan tek paylaşımlı sunucuya.

MTS, kısa ve sık işlemli (transaction) OLTP sistemleri için çok uygundur ancak veri depoları (data warehouse) için hiç uygun değildir, bunlarda bir sorgu 1, 3, 5 dakika ya da daha fazla sürebilir. Atanmış sunucu ve MTS, tek bir instance’da (örnek) birlikte kullanılabilir. MTS’in avantajları şunlardır:

1) İşletim sistemi (OS) işleçlerinin ve iş parçacıklarının sayısını azaltır : Çok kullanıcılı sistemlerde kullanıcıların sadece küçük bir kısmı aynı anda aktiftir (örneğin %1).
2) Eşzamanlılığın (concurrency) derecesinin suni olarak ayarlanmasına izin verir : Belli bir sınıra kadar eşzamanlı kullanıcı sayısı arttıkça işlem (transaction) sayısı da artar, sonra artış durur ve eşzamanlı kullanıcı arttığı halde işlem sayısı düşmeye başlar. En yüksek işlem hacmi (throughput) için, en yüksek eşzamanlılık bu nokta ile sınırlanmalıdır.
3) Sistemde ihtiyaç duyulan belleği azaltır: MTS kullanıldığında UGA, SGA’in içinde tutulur. MTS kullanılırken ne kadar UGA belleğe ihtiyaç duyulacağı iyice belirlenmelidir. Her bir atanmış/paylaşımlı sunucu PGA kullanır, MTS kullanıldığında ihtiyaç duyulan PGA azalır böylece daha az bellek kullanılır.

ODAKLI ARKAPLAN İŞLEÇLERİ (Focused Background Processes)

PMON – İşleç Denetleyicisi (The Process Monitor)

Anormal bir şekilde sonlandırılan bağlantıları temizlemekle sorumludur. Örneğin atanmış sunucu başarısız olursa veya öldürülürse, kullandığı kaynakların geri verilmesinden PMON sorumludur; commit edilmemiş çalışmayı geri yuvarlar (rollback), kilitleri ve SGA kaynaklarını serbest bırakır.

PMON ayrıca gerekli durumlarda diğer arkaplan işleçlerini de çalıştırır, ayrıca Net8 dinleyicisi (listener) ile bağlantı kurar. Oracle için kullanılan ayarlanmamış (default) port 1521’dir.

SMON – Sistem Denetleyicisi (The System Monitor)

Veritabanının çöp toplayıcısıdır (garbage collector). Sorumlu olduğu işlerin bazıları şunlardır:
Geçici alanların (Temporary Space) temizlenmesi – Örneğin bir index sonlandırıldığında onunla ilişkili extentleri temizler.
Çökme kurtarma (Crash Recovery)
Boş alanları birleştirme
– Dizin yönetimli tabloalanlarında (dictionary-manged tablespaces) boş ve bitişik olan extentleri tek bir büyük boş extente çevirir.
Kullanılamayan dosyalara yönelik aktif işlemlerin (transactions) kurtarılması
OPS’deki başarısız düğümün (node) instance’ının kurtarılması – Oracle Paralel Sunucu konfigürasyonunda instance’ın başka bir düğümü (node) başarısız düğümün redo kütük dosyalarını açarak bütün verileri kurtarır.
OBJ$’ı temizlemek – OBJ$, düşük seviyeli bir veri dizini tablosudur (data dictionary table), hemen hemen her nesne için bir giriş içerir. SMON, silinmiş veya ulaşılamayan neselere ait satırları siler.
Rollback segmentlerinin otomatik olarak ideal büyüklüğüne döndürülmesi
Rollback segmentlerini ‘offline’ yapar – DBA, aktif işlemleri olan bir rollback segmentini ‘offline’ veya kullanılamaz yapabilir.

RECO – Dağınık Veritabanı kurtarma (Distributed Database Recovery)

İki evreli commit (two-phase commit,2PC) sırasında, çökmeden veya bağlantı kopmasından dolayı hazır durumda bırakılmış işlemleri kurtarır. 2PC, dağınık bir protokoldür, birbirinden farklı pek çok veritabanındaki değişiklikle atomik commit’e imkan verir, commit edilmeden önce dağınık başarısızlığa (failure) karşı pencereyi kapatmaya çalışır.

CKPT – Checkpoint İşleci

Checkpoint işlemi yapmaz, veri dosyalarının başlıklarını güncelleyerek checkpoint işlemine yardımcı olur.

DBWn – Veritabanı Blok Yazıcısı (Database Block Writer)

DBWn, kirli (içinde veri olan) blokları asychronous I/O kullanarak diske yazar, çok sayıda dağınık (scattered) yazım yapar oysa LGWR (Log Writer) redo kütüğüne sıralı yazım yapar. DBWn, checkpointi ilerletmek için veya yer açmak için tampon önbellekten (buffer cache) diske yazar.

Görevini yeterince hızlı yapamazsa FREE_BUFFER_WAITS veya ‘Write Complete Waits’ mesajlarını görebiliriz. 10 tane DBWn konfigüre edilebilir, bunun için init.ora parametresi DB_BLOCK_LRU_LATCHES yükseltilmelidir.

LGWR – Kütük Yazıcısı (Log Writer)

SGA’deki redo kütük tamponunun (redo log buffer) içeriğini sıralı (sequential) olarak diske yazar, bunu 3 saniyede bir yapar veya birisi commit ettiğinde vaya üçte biri dolduğunda veya veri toplamı 1 MB’a ulaştığında yapar. Bu Yüzden çok büyük bir redo kütük tamponu kullanışlı değildir.


ARCn – Arşiv İşleci (Archive Process)

ARCn işlecinin görevi, LGWR onu doldurduktan sonra, online redo kütük dosyasını başka en az iki farklı yere kopyalamaktır, bu dosyalar daha sonra ortam kurtarma (media recovery) için kullanılabilir. Online redo kütüğü bir güç kesintisinde veri dosyalarını onarmak için kullanılır, arşiv redo kütükleri ise sabit diskin bozulması durumunda veri dosyalarını onarmada kullanılır.

BSP- Blok Sunucu İşleci (Block Server Process)

Sadece Oracle Paralel Sunucu (OPS) ortamında kullanılır. OPS’de birden fazla instance aynı veritabanını açar. Bunun için SGA blok tampon önbellekleri (block buffer caches), birbirlerine karşı tutarlı durumda tutulmalıdır, BSP’nin ana amacı budur.

LMON – Kilit Denetleyici İşleç (Lock Monitor Process)

Sadece Oracle Paralel Sunucu (OPS) ortamında kullanılır. Bir başarısızlık durumuna karşı bir öbekteki (cluster) bütün instanceları denetler, başarısız olan instance’ın küresel kilitlerini kurtarır, dağınık kilit yöneticisi (distributed lock manager, DLM) ile birlikte.

LMD – Kilit Yöneticisi Daemonu (Lock Manager Daemon)

Sadece Oracle Paralel Sunucu (OPS) ortamında kullanılır. Öbekli ortamda (clustered environment) blok tampon önbelleği için küresel kilitleri ve kaynakları kontrol eder. Ayrıca küresel deadlock denetimini ve çözümlemesini (resolution) de yapar.

LCKn – Kilit İşleci (Lock Process)

Sadece Oracle Paralel Sunucu (OPS) ortamında kullanılır. İşlev olarak LMD’ye çok benzer, ancak bütün küresel kaynaklar için olan istekleri değerlendirir.

KULLANIŞLI ARKAPLAN İŞLEÇLERİ (Utility Background Processes)

Bu işleçler bütünüyle seçimseldir, yani isteğe bağlıdır.

SNPn – Snapshot İşleçleri (Snapshot Processes) İş Kuyrukları (Job Queues)

36 tane iş kuyruğu işleci olabilir, adları şöyle olacaktır: SNP0, SNP1,…, SNP9, SNPA, …, SNPZ. SNPn işleçleri atanmış sunucuyla paylaşımlı sunucunun karışımı gibidir. İşleri birbiri ardına yaparlar ama belleği atanmış sunucu gibi kullanırlar. Her bir iş kuyruğu her seferinde tek bir iş yapacaktır.

QMNn – Kuyruk Denetleyici İşleçler (Queue Monitor Processes)

Gelişmiş kuyrukları (Advanced Queues) denetlerler ve bir mesaj elverişli hale geldiklerinde bekleyenleri haberdar ederler. Ayrıca kuyruk oluşturulmasından da sorumludurlar. init.ora parametresi AQ_TM_PROCESS ile 10 tane oluşturulabilir; QMN0, …, QMN9.



EMNn – Olay Denetleyici İşleçler (Event Monitor Processes)

Gelişmiş kuyruk (Advanced Queue) mimarisinin bir parçasıdır, kuyruk abonelerine asynchoronous olarak mesajlar gönderir.

ESİR İŞLEÇLER (Slave Processes)

I/O Esirleri

Asynchronous I/O ‘yu desteklemeyen sistemlerde (kasetler (tape) gibi), asynchoronous I/O etkisini oluşturmak için kullanılırlar. İşleç önce büyük bir miktar veriyi yığın olarak tutar ve bu yazıldıktan sonra bittiğini haber verir, böylece yavaş aygıt için I/O esirleri bekler ve işlem hacmi (throughput) artar. DBWn, LGWR ve RMAN, I/O esirlerini kullanır.

Paralel Sorgu Esirleri (Parallel Query Slaves)

SQL komutları için (örneğin SELECT, CREATE TABLE, UPDATE gibi), tek bir yürütme (execution) planı yerine pek çok yürütme planı aynı anda paralel olarak uygulanır. Her bir planın sonuçları birleştirilerek tek bir büyük sonuç elde edilir. Böylece işlem daha hızlı yapılmış olur (sıralıya (sequential) göre).

11 Temmuz 2007 Çarşamba

UTF8 ve AL16UTF16 kodlamaları

Ulusal karakter seti, verileri Unicode olarak tutar; UTF8 veya AL16UTF16 kodlamalarından birini kullanarak. AL16UTF16 kodlamasında her bir karakter 2 byte yer kaplar. Bu özellik, farklı programlama dilleri karıştırıldığında, budama (truncation) hatalarının önlenmesi için string uzunluklarının belirlenmesinde kolaylık sağlar, bununla beraber çoğu ASCII karakterlerinden oluşan stringlerin depolanmasında fazladan depolama yüküne neden olur.

UTF8 kodlamasında her bir karakter 1, 2 veya 3 byte uzunluğunda yer tutar. Eğer çoğu karakter tek bir byte ile gösterilebilirse, bir değişkene veya bir tablo kolonuna daha fazla karakter sığdırılabilir; ancak veri, uzunluğu bytelarla sınrlı bir tampona aktarılırken budama (truncation) hataları oluşabilir.

Oracle şirketi, en yüksek çalışma zamanı güvenilirliği için, elverişli olan yerlerde AL16UTF16 kodlamasının kullanılamasını öneriyor. Ayrıca bir Unicode stringini tutmak için ne kadar yer gerektiğinin belirlenmesi gerekirse LENGTH fonksiyonu yerine LENGTHB fonksioyonunun kullanılması daha iyi olur.

LONG ve LONG RAW veritipleri

LONG veritipi değişken uzunluklu karakter stringlerinin depolanmasında kullanılır ve uzunluğu 32760 byte ile sınırlıdır, bunun haricinde VARCHAR2 veritipine benzer. LONG RAW veritipi ise ikili (binary) verilerin ve byte stringlerinin depolanmasında kullanılır, uzunluğu en fazla 32760 byte olabilir, LONG veritipine benzer, ondan farkı ise PL/SQL tarafından yorumlanmamasıdır.

Oracle' ın tavsiyesi LONG verilerinin CLOB' a, LONG RAW verilerinin ise BLOB' a çevrilmesidir. Bir veritabanında LONG kolonu 2**31 byte uzunluğunda olabilir, bu yüzden herhangi bir LONG değeri LONG kolonuna yerleştirilebilir.

Ancak LONG kolonundan LONG değişkenine 32760 bytetan daha büyük bir değer aktarılamaz, bu sınırlamalar LONG RAW veritipi için de aynı şekilde geçerlidir. LONG kolonları metin, karakter dizileri, hatta kısa belgeler bile depolayabilirler.

LONG kolonlarına UPDATE ve INSERT deyimlerinde ve çoğu SELECT deyiminde atıfta bulunulabilir ancak ifadelerde (expressions), fonksiyon çağrılarında ve WHERE, GROUP BY, CONNECT BY gibi SQL maddelerinde (clause) LONG kolonlarına atıfta bulunulamaz.

5 Temmuz 2007 Perşembe

PLS_INTEGER VERİTİPİ

PLS_INTEGER veritipi, işaretli tamsayıları depolamak için kullanılır. Sınır değeleri -2^31 ile 2^31 'dir, NUMBER tipine göre bellekte daha az yer kaplar. PLS_INTEGER işlemleri makina aritmetiği kullanır, bu yüzden kütüphane aritmetiği kullanan NUMBER ve BINARY_INTEGER işlemlerinden daha hızlıdır. Verimlilik açısından sınır değerleri arasında kalan hesaplamalarda PLS_INTEGER veritipinin kullanılması daha uygundur.

PLS_INTEGER ve BINARY_INTEGER 'ın sınır değeleri aynı olduğu halde bu iki veritipi tamamen uyumlu değildir. PLS_INTEGER 'da hesaplamada bir taşma (overflow) olursa istisna (exception) verir. Bu taşma BINARY_INTEGER 'da olursa eğer sonuç bir NUMBER değişkenine atanmışsa istisna vermez.

Eski uygulamalarda uyumluluk açısından BINARY_INTEGER kullanılmaya devam edilebilir, yeni uygulamalarda ise PLS_INTEGER veritipinin kullanılması daha iyi bir performans sağlayacaktır.

3 Temmuz 2007 Salı

Karşılaştırma ve Koşul İfadelerinde NULL Değerleri

Şu kurallar önemlidir ve gözardı edilmemelidir:

1) Karşılaştırmalarda eğer herhangi bir değer NULL ise sonuç NULL çıkar.
2) NULL bir değere, NOT mantık operatörü uygulanırsa sonuç gene NULL 'dır.
3) Koşullu kontrol ifadelerinde eğer koşulun sonucu NULL ise bu koşula bağlı ifadeler işleme konulmaz.
4) CASE bildirimlerinde veya CASE ifadelerinde, ifadenin sonucu NULL ise, WHEN NULL kullanılarak bu durum belirlenemez. Bunun yerine WHEN ifade IS NULL kullanılmalıdır.

Aşağıdaki örnekte y'nin değeri NULL olduğundan IF karşılaştırmasının sonucu da NULL çıkacaktır ve karşılaştırmaya bağlı ifade işleme konmayacaktır.

x := 5;
y := NULL;
...
IF x != y THEN -- sonuç NULL çıkar yani TRUE değil
sequence_of_statements; -- işleme konmaz
END IF;

2 Temmuz 2007 Pazartesi

Kestirme Değerlendirme (Short-Circuit Evaluation)

PL/SQL 'de AND ve OR mantık operatörleri çalışırken belli durumlar için sadece ilk elemana bakarlar, ikinci elamanı göz ardı edip, değerlendirmezler, şöyle ki:
AND 'in TRUE döndürmesi için her iki elemanın da TRUE olması gerekir.

Eğer ilk eleman FALSE ise sonucun FALSE çıkacağı bellidir, bu durumda PL/SQL ikinci elemana hiç bakmayacaktır. OR için ise sonucun TRUE çıkması için iki elemanın sadece birinin TRUE olması yeterlidir. OR 'un ilk elemanı TRUE ise PL/SQL ikinci elemana hiç bakmayacaktır çünkü sonucun TRUE çıkacağı ilk elemandan bellidir.

PL/SQL 'in bu kestirme değerlendirme özelliğinden dolayı bazı hatalı yazımlarda hata mesajı ile karşılaşılmayabilir. Örneğin aşağıdaki örnekte OR operatörünün ikinci elemanında sıfıra bölme hatası olduğu halde bir hata mesajı alınmaz:

DECLARE
...
on_hand INTEGER;
on_order INTEGER;
BEGIN
...
IF (on_hand = 0) OR ((on_order / on_hand) < 5) THEN
...
END IF;
END;

30 Haziran 2007 Cumartesi

Ayrılmış Sözcükler (Reserved Words)

Bazı sözcükler PL/SQL'de ayrılmış (reserved) oldukları halde SQL'de ayrılmış olmayabilirler. Örneğin CREATE TABLE (tablo yarat) ifadesinde, bir veritabanı kolonunu adlandırmak için, PL/SQL'de ayrılmış bir sözcük olan TYPE 'ın kullanıldığını düşünelim.

Bir SQL ifadesi, programımızdaki bu kolona (TYPE) atıfta bulunursa, bir derleme hatası oluşur; şu komutta olduğu gibi:

SELECT acct, type, bal INTO ... ----> derleme hatası

Ancak kolon adı (TYPE) çift tırnak içine alınırsa bu derleme hatası önlenebilir:

SELECT acct, "TYPE", bal INTO ... ----> hata vermez

Ancak tırnak içinde yazılan kısmın kolon adıyla tamamen aynı olması gerekir; "type" veya "Type" gene derleme hatasına yol açar.

İkinci bir seçenek olarak, sorunlu kolonu yeniden adlandıran bir görüntü (view) oluşturulabilir, sonra da bu görüntü SQL ifadelerindeki temel tablo'nun (base table) yerine kullanılabilir.

29 Haziran 2007 Cuma

Belirleyiciler (Identifiers)

Belirleyiciler PL/SQL program öğe ve birimlerini adlandırmada kullanılır; sabitler, değişkenler, istisnalar, kürsörler, kürsör değişkenleri, altprogramlar ve paketler gibi. Belirleyiciler en fazla 30 karakter uzunluğunda olabilirler.

BEGIN , END , CLOSE , DO , ARRAY , BODY , CURSOR , MAX , MIN gibi ayrılmış sözcükler (reserved words) belirleyici olarak kullanılamazlar.

Belirleyiciler, büyük-küçük harf farkına duyarlı değildir; bundan dolayı lastname, LastName ve LASTNAME'in üçü de aynı belirleyiciyi gösterecektir. Belirleyicilerin adlandırılmasında dolar işareti, numara işareti ve altçizginin kullanımına izin verilmiştir, bundan dolayı şunlar geçerlidir:

X , t2 , phone# , credit_limit , LastName , oracle$number , money$$$tree , SN## , try_again_

Ancak belirleyicilerde kısa çizgi, slash, ampersand ve boşluk kullanımına izin verilmez, bundan dolayı şunlar geçersizdir:

mine&yours , debit-amount , on/off , user id

28 Haziran 2007 Perşembe

Sayıların Bilimsel Gösterimi (Scientific Notation)

Sayıların bilimsel gösteriminde üs anlamına gelen Exponent sözcüğünün baş harfi olan E kullanılır. E, sayının yanına kaç tane sıfır geleceğini gösterir. Örneğin:

2E3 sayısı 2000 anlamına gelir. 3.141E2 ise 314.1 anlamına gelir.
3.1415E0 ise 3.1415 anlamına gelir. -3E2 ise -300 'dür.

E'den sonra bir eksi işareti geliyorsa, eksiden sonraki sayı kadar virgül sola kaydırılır. Örneğin:

4E-2 = 0.04'tür. 6E-4 = 0.0006'dır. -7.5E-2 = -0.075'dir.

PL/SQL'de üslü sayılar 1E-130 ile 10E125 arasında sınırlandırılmıştır. Bundan daha büyük ve daha küçük sayılar derleme hatasına neden olur. Örneğin bir sayıya 10E128 veya 1E-132 atanması derleme hatasına neden olacaktır.

27 Haziran 2007 Çarşamba

%TYPE Niteliği

PL/SQL değişkenlerinin ve kürsörlerinin nitelikleri (attribute) vardır. Bu nitelikler sayesinde bir öğenin tanımını tekrarlamadan o öğenin yapısına ve veritipine atıfta bulunulabilir. Veritabanı kolonları ve tabloları da benzer niteliklere sahiptir, bunlar bakım işlemlerinin kolaylaştırılmasında kullanılabilir. Yüzde işareti (%) niteliği göstermede kullanılır.

%TYPE niteliği bir değişkenin veya bir veritabanı kolonunun veritipini döndürür. Bu özellikle veritabanı değerlerini tutacak değişkenlerin tanımlanmasında kullanışlıdır. Örneğin books adlı bir tablonun title adlı kolonunun tipinde bir değişken tanımlamak için aşağıdaki komut kullanılabilir:

my_title books.title%TYPE;

Bu şekilde yeni oluşturulan my_title değişkeni title kolonunun tipinde olacaktır. İlerde veritabanında title kolonunun tipi değiştirilirse my_title değişkeni de otomatik olarak değişecektir.

26 Haziran 2007 Salı

Kürsörler

Oracle, PL/SQL ifadelerini işlemek ve işlem bilgilerini depolamak için çalışma alanları kullanır. Bir PL/SQL yapısı olan kürsör, bir çalışma alanını isimlendirip orda depolanmış bilgiye ulaşmamızı sağlar. Kürsörler ikiye ayrılır: kendiliğinden ve açıkça belirtilmiş.

PL/SQL, sadece tek bir satır döndüren sorgular da dahil olmak üzere bütün veri işleme ifadeleri için kendiliğinden bir kürsör deklare eder. Tek bir satırdan fazla sonuç döndüren sorgular için, satırları tek tek işlemek için, kendiniz açıkça bir kürsör belirtebilirsiniz.

Çok satırlı bir sorgunun döndürdüğü sonuçlara sonuç kümesi denir; büyüklüğü sorgu kriterine uyan satırların sayısı kadardır. Açıkça belirtilmiş bir kürsör, sonuç kümesindeki hali hazırdaki satıra işaret eder. Böylece her seferinde tek bir satır işlenebilir. Aşağıdaki örnekte c1 adlı kürsör deklare edilmektedir.

DECLARE
CURSOR c1 IS
SELECT empno, ename, job FROM emp WHERE deptno = 20;

Bir kürsörü kontrol etmek için OPEN (aç), FETCH (al) ve CLOSE (kapat) komutları kullanılır. OPEN komutu kürsörle ilişkilendirilmiş sorguyu uygular, sonuç kümesini belirler ve kürsörü ilk satırın başına yerleştirir. FETCH komutu hali hazırdaki satırı alır ve kürsörü bir sonraki satırın başına yerleştirir. Son satır da işlendikten sonra CLOSE komutu kürsörü devre dışı bırakır.

25 Haziran 2007 Pazartesi

Kürsör FOR döngüleri

Bilindiği gibi PL/SQL'de veritabanından bir recordu (kaydı) çağırmak için üç komut gereklidir; bunlar da OPEN (aç), FETCH (al), ve CLOSE (kapat) komutlarıdır, ancak kodunuzu kısaltmak istiyorsanız bu üç komut yerine bir kürsör FOR döngüsü kullanabilirsiniz.

Bir kürsör FOR döngüsü, kendiliğinden döngü indisini, veri tabanından alınmış bir satırı temsil eden bir record (kayıt) olarak deklare eder. Daha sonra bir kürsör açıp, sonuç kümesinin içinden değer satırlarını alıp, recordun (kaydın) alanlarına atar.

Bütün satırlar işlendikten sonra kürsörü kapatır. Aşağıdaki örnekte emp_rec, döngü içinde kendiliğinden bir record olarak deklare edilmiş olmaktadır.

DECLARE
CURSOR c1 IS
SELECT ename, sal, hiredate, deptno FROM emp;
...
BEGIN
FOR emp_rec IN c1 LOOP
...
salary_total := salary_total + emp_rec.sal;
END LOOP;

Bir kaydın ayrı alanlarını kullanmak için nokta kullanılır; emp_rec.sal gibi; emp_rec kaydının sal alanı için.