Sayfalar

27 Ocak 2013 Pazar

Şema Nesnelerinin Yönetimi ve Silinen Tabloları Kurtarma

Merhaba arkadaşlar!

Daha önce DDL ve şema nesnelerini anlatan yazılar yazdık. Fakat şema nesneleri üzerinde nasıl değişimler yapacağımız hakkında çok fazla bilgi vermedik. Biraz da bunlardan bahsedelim istiyorum.

Tablolar Üzerinde Değişimler
Daha önce ALTER TABLE komutundan bahsetmiştik. Zaten ALTER komutunu var olan bir nesneyi düzenlemek amacıyla kullandığımızı biliyoruz. Peki ALTER TABLE ile neler yapılabilir?
  • Var olan sütunları değiştirebilirsiniz. Bir sütunda veri tipini, verinin boyutunu ve varsayılan değer kısımlarını değiştirebilirsiniz. Varsayılan değer kısmını değiştirirseniz bu önceki kayıtları etkilemez. Bundan sonraki kayıtlar bu değere göre düzenlenirler.
    ALTER TABE tabloismi
    MODIFY (sütunismi veritipi [DEFAULT varsayilandeger]
    [, düzenlenecek diger sütunlar]);
  • Yeni sütun ekleyebilirsiniz. Eklediğiniz son sütun tabloda en sona yerleşir.
    ALTER TABE tabloismi
    ADD (sütunismi veritipi [DEFAULT varsayilandeger]
    [, eklenecek diger sütunlar]);
  • Var olan bir sütunu silebilirsiniz
    ALTER TABE tabloismi
    DROP sütunismi;
  • Kullanılmayan sütunları "kullanılmayan" olarak işaretleyebilirsiniz. Böylece veritabanındaki performansa pozitif katkıda bulunabilirsiniz. Bir sütunu UNUSED olarak işaretlemek için:
    ALTER TABLE tabloismi
    SET UNUSED [COLUMN] (sütunismi);

    UNUSED durumunu kaldırmak için:
    ALTER TABLE tabloismi
    DROP UNUSED COLUMNS;
  • Kısıt ekleyebilirsiniz. 
    ALTER TABLE tabloismi
    ADD [CONSTRAINT kisitismi]
    Kisittipi (sütunismi);
  • Var olan bir kısıtı kaldırabilirsiniz:
    ALTER TABLE tabloismi
    DROP CONSTRAINT kisitismi;
  • Bir kısıtı ertelenebilir yada hemen aktif hale getirebilirsiniz. Yani oluşturulduğu andan hemen sonra aktif olmaz(DEFERRED). Transaction bittikten sonra kısıt aktifleştirilir. Eğer IMMADIATE seçecek olursanız da ilgili komut çalıştırıldıktan yani kısıt oluşturulduktan hemen sonra kısıt aktif olur.
    ALTER TABLE tabloismi
    ADD [CONSTRAINT kisitismi]
    Kisittipi (sütunismi)
    DEFERRABLE INITIALLY DEFERRED | IMMADIATE;
  • Var olan bir kısıtı erteleyebilir yada aktif edebilirsiniz:
    SET CONSTRAINTS kisitismi DEFERRABLE | IMMADIATE;
  • Açık olan oturumdaki tüm kısıtları erteleyebilir yada aktif edebilirsiniz:
    ALTER SESSION
    SET CONSTRAINTS = DEFERRABLE | IMMADIATE;
  • Kısıtları kapatabilirsiniz veya açabilirsiniz. CASCADE seçeneğini kullanırsanız ilgili bağımlı kısıtlar da kapatılır yada açılır. UNIQUE yada PRIMARY KEY içeren kısıtları tekrar aktif ettiğiniz anda; ilgili UNIQUE indeksi Oracle tarafından otomatik olarak oluşturulur.
    ALTER TABLE tabloismi
    DISABLE | ENABLE CONSTRAINT kisitismi;
  • Bağlantılı kısıtları kaldırma: Eğer bir sütunu kaldırıyorsanız, sütunla bağımlı olan birincil ve tekil anahtar kısıtlarını da kaldırırsınız. Böylelikle veritabanını bir kısıt çöplüğü olmaktan kurtarırsınız DROP COLUMN ile kullanım:
    ALTER TABLE tabloismi
    DROP COLUMN sütunismi CASCADE CONSTRAINTS;
    DROP kisitismi ile kullanımı:
    ALTER TABLE tabloismi
    DROP (kisitisimleri) CASCADE CONSTRAINTS;
  • Var olan sütun isimlerini veya kısıt isimlerini değiştirebilirsiniz:;
    ALTER TABLE tabloismi
    RENAME COLUMN | CONSTRAINT sütunismi | kiaitismi
    TO yeniisim;
Evet, ALTER TABLE komutu bu kadar marifetli bir komut. Şimdi de indeksler ile ilgili daha önceki yazımızda değinmediğimiz kısımlara biraz bakalım.

İndeksler
Kısaca hatırlarsak indeksler iki yolla oluşturuluyordu:
  • Otomatik olarak Oracle tarafından: Ne zaman bir tabloda PRIMARY KEY yada UNIQUE kısıtı tanımlanırsa Oracle otomatik olarak indeks oluşturur.
  • El ile kullanıcı tarafından: CREATE INDEX yada CREATE TABLE içerisinde komutu yazarak indeks oluşturulabilir.
İndekslerin ne işe yaradığını, ne zaman oluşturulup ne zaman oluşturulmaması gerektiğini ve basit olarak bir indeksin nasıl oluşturulduğunu önceki yazımızda anlattık. Şimdi el ile indeks oluşturma yöntemlerine bir bakalım.

CREATE TABLE ile indeks oluşturma:

CREATE TABLE tablo_ismi
(sütun_ismi sütun_veri_tipi()
PRIMARY KEY USING INDEX
(CREATE INDEX indeks_ismi ON
tablo_ismi(sütun_ismi)),
diger_sütun_isimleri veri_tipleri());


Örnek Kullanım:

CREATE TABLE yoneticiler
(yonetici_id NUMBER(6)
PRIMARY KEY USING INDEX
(CREATE INDEX yon_id_index ON
yoneticiler(yonetici_id)), 
ad VARCHAR2(25),
soyad VARCHAR2(25));
CREATE TABLE succeeded.

Veri Sözlüğünden İndeksleri Görüntüleme:
Kullanıcılar kendi uzaylarındaki tüm nesneleri veri sözlüğünden görebilirler. Veri sözlüğündeki hangi görüntüde hangi bilgilerin saklandığını bir önceki yazımızda paylaştık. Örneğin az önce oluşturduğumuz indeksi veri sözlüğü görüntüsünden takip edebiliriz. Aşağıdaki sorgu işimizi görür.


SELECT INDEX_NAME, TABLE_NAME
FROM   USER_INDEXES
WHERE  TABLE_NAME = 'YONETICILER';
INDEX_NAME                     TABLE_NAME                     
------------------------------ ------------------------------ 
YON_ID_INDEX                   YONETICILER                    

1 rows selected

Veri Sözlüğünden İndeksleri Silme:
Aşağıdaki komutla indeksleri kaldırabilirsiniz:
DROP INDEX indeks_ismi;
Az önceki indeksi kaldırmayı deneyelim:
DROP INDEX YON_ID_INDEX;
Error report:
SQL Error: ORA-02429: benzersiz/birincil anahtarların zorlanması için kullanılan dizin bırakılamaz
Elbette hata alırız. Çünkü birincil anahtar üzerindeki indeksi kaldıramazsınız. Zaten Oracle, biz oluşturmasak da PRIMARY KEY ve UNIQUE anahtarlar üzerinde indeks oluşturur demiştik. YON_ID_INDEX de bir PRIMARY KEY kısıtı olduğu için kaldırılamaz bir indekstir. Bunun dışında bir indeksi hala kaldıramıyorsanız; demek ki size DROP ANY INDEX ayrıcalığı verilmemiş demektir.

Fonksiyon Kullanımı İçin İndeksler:
Sorgularda bir tablodaki bir sütun üzerinde çok sık aynı fonksiyonun kullanıldığını varsayalım. Bu sorguların sonucuna hızlıca erişmek için fonksiyon içeren indeksler oluşturmanız mümkündür. Mesela az önceki oluşturduğumuz tablonun ad sütununa sürekli UPPER fonksiyonu ile erişildiğini düşünelim ve bunu içeren bir indeks tasarlayalım:

CREATE INDEX upper_ad_idx
ON YONETICILER(UPPER(ad));
CREATE INDEX succeeded.
Bu indeks aşağıdaki sorgularda işinizi kolaylaştıracaktır. Fonksiyonsuz sorgular için ayrıca indeks oluşturmanız gerekir.
SELECT *
FROM yoneticiler
WHERE UPPER(ad) = 'John';



Silinen Tabloları Kurtarma
Biliyoruz ki DROP TABLE tablo_ismi komutu ile tablolarımız siliniyor. Ama tam anlamıyla siliniyor mu? Oracle güvenliği her daim düşünen bir sistem olduğu için silinen verilerinizi eğer yanlışlıkla silme söz konusu ise geri döndürmek için her şeyi yapan bir sistemdir. Basit bir DROP TABLE komutunda elbette bazen kasten olmayan silinmeler olabilir. İşte silinen bu tablolar aslında veritabanınızdan uçup gitmezler. Tıpkı bir Windows sisteminde bir dosyayı Del ile siliyormuşsunuz gibi Geri Dönüşüm kutusunda bekletilirler. Bu kutuyu boşaltmadıkça tablolarınızı buradan geri döndürmeniz mümkündür. Şimdi adım adım bu işlemleri uygulayalım. Yukarıdaki oluşturduğumuz tabloyu siliyorum:
DROP TABLE YONETICILER;
DROP TABLE YONETICILER succeeded.
Veri çekmeye çalışırsak hata alacağız;
SELECT * FROM YONETICILER;
Error report:
SQL Error: ORA-00942: tablo veya görüntü mevcut degil
Halbuki durum böyle değil. Bu tablo geri dönüşüm kutusunda kurtarılmayı bekliyor. Geri dönüşüm kutusuna da ulaşmanız mümkün. Aşağıdaki sorgu ile geri dönüşüm kutusunda neler var görebiliriz:
SELECT * FROM RECYCLEBIN;
Burada daha önce silinen verilerin geri dönüşüm kutusundaki ismi, orijinal ismi, hangi komutla silindiği, ne zaman oluşturulduğu, ne zaman silindiği gibi meta verileri görebilirsiniz. Biz aşağıdaki komutla bizim için önemli olan ismi bulalım:
SELECT OBJECT_NAME, ORIGINAL_NAME FROM RECYCLEBIN;

OBJECT_NAME                    ORIGINAL_NAME                    
------------------------------ -------------------------------- 
BIN$MGpk7TBXTQqOcetNgESrCQ==$0 TEST                             
BIN$4ZAzJ0n3R9K08auSgnjUeg==$0 YONETICI 
...

BIN$UCq8II9gRd6pTZ28VcnTeg==$0 YONETICILER                         
BIN$k+OEssmeRbaoKBCTf/RlMA==$0 YON_ID_INDEX                     
9 rows selected
Altta görünen tablo yeni sildiğimiz yoneticiler tablosu. Tarihlerden bunu anlayabiliyoruz. Onun altındaki indeks ise yine bizim oluşturduğumuz indeks. Tablo silindiği için bu indeks de Oracle tarafından siliniyor. Şimdi sildiğimiz tabloyu kurtaralım. Bunu FLASHBACK TABLE tabloismi; komutu ile yapacağız:

FLASHBACK TABLE YONETICILER TO BEFORE DROP;
FLASHBACK TABLE succeeded.
SELECT * FROM YONETICILER;

YONETICI_ID            AD                        SOYAD                     
---------------------- ------------------------- ----------------

0 rows selected

Böylelikle tablomuzu kurtarmış olduk. Tablonuz silinmeden önceki haliyle elinize ulaşır. Buna kısıtlar, indeksler de dahil. Peki ya tabloyu geri dönüşümsüz olarak silmek istersek?
Tabloyu Veritabanından Tamemen Kaldırma
Bunun için şu komut işimizi görecek;

DROP TABLE YONETICILER PURGE;
DROP TABLE YONETICILER succeeded.

Şimdi geri döndürmeyi deneyelim:
FLASHBACK TABLE YONETICILER TO BEFORE DROP;

Error report:
SQL Error: ORA-38305: nesne RECYCLE BIN içinde değil
Tabloyu geri döndürmek için artık daha profesyonel yollar denemeniz gerekiyor. Log dosyalarından faydalanmak gibi... Biliyorsunuz ki Oracle'da neredeyse 0 veri kaybı yaşanmaktadır. Yani verilerinizin uçup gitmesini istiyorsanız bunun için çaba sarf etmeniz gerekecektir :) Şimdi geri dönüşüm kutusundan var olan eski YONETICI tablosunu nasıl sileceğimizi de görelim:
PURGE TABLE YONETICI;
PURGE TABLE YONETICI succeeded.
Yani DROP TABLE tabloismi PURGE komutunu bu şekilde iki aşamalı olarak da kullanabiliyoruz.

Konuyu burada noktalıyorum. İyi çalışmalar!

Hiç yorum yok:

Yorum Gönder