21 Temmuz 2009 Salı

db2 da kolon bilgilerini (data tipleri, kolon adları, length, scale, null olup olmama durumu) sorgulamak

db2 üzerine aşağıdaki gibi bir sorgu kullanarak kolon bilgilerini sorgulayabilirsiniz. Özellikle dökümantasyon yaparken kullanışlı bir script olacaktır diye düşünüyorum.

Aşağıdaki script ile kolon isimlerini, kolon data tiplerini, uzunluk ve scale, null değer alma bilgilerini select edebilirsiniz.

select
c.colname as "Column Name",
c.typename as "Type Name",
c.length as "Length",
c.scale as "Scale",
c.nulls as "NULL?"
from syscat.columns c
where c.tabname LIKE 'TABLO_ADI'
and tabschema= 'SEMA_ADI';

Sorguyu kendi isteklerinize göre şekillendirmek için select * from syscat.columns; cümlesi ile tüm bilgilere göz atıp istediğiniz filtreyi uygulayabilirsiniz.

10 Temmuz 2009 Cuma

Oracle da kolonlar üzerinde default değer tanımlamak.

Kullandığımız bazı tablolarda yaptığımız işin gerekliliğine göre kolonlarda default değer kullanmamız gerekebilir. Özellikle tablo üzerinde kayıdın insert edildiği tarihi alan bir kolon olması tablo üzerinde history tutmak için çok faydalı olabilir.
Böyle bir yapı normalde insert edildikten sonra bir trigger tetiklenerek de yapılabilirdi fakat daha kısa ve kolay bir çözümü default değerleri kullanmak.

Örneğin bir mesajlar tablomuz olsun ve içerisinde mesaj_id, gonderen_id, alan_id, konu, mesaj_icerigi, gonderme_tarihi alanlarımız olsun.

DROP TABLE MESAJLAR CASCADE CONSTRAINTS;

CREATE TABLE MESAJLAR
(
MESAJ_ID NUMBER NOT NULL,
GONDEREN_ID NUMBER NOT NULL,
ALAN_ID NUMBER NOT NULL,
KONU VARCHAR2(50 BYTE) NOT NULL,
MESAJ_ICERIGI VARCHAR2(200 BYTE) NOT NULL,
GONDERME_TARIHI DATE DEFAULT sysdate NOT NULL
)

Burada gonderme_tarihi alanına eklediğimiz default değer sayesinde tabloya her kayıt yapıldığında sistem zamanı default olarak yazılacaktır.


Oracle, assigning default values to columns example code.

26 Haziran 2009 Cuma

Parent-Child Tablo ilişkisi ve Cascade Deletion (Kademeli silme) işlemi

Üzerlerinde parent-child ilişkisi tanımlanmış olan tablolar sayesinde tablolardaki verinin bütünlüğünü korumak daha kolay olabilir, örneğin motorlu taşıtların fiyatlarının tutulduğu bir parent tablo üzerinden motorsikletlerin marka ve modellerinin tutulduğu bir child tabloya parent-child ilişkisi tanımlanabilir. Bu şekilde seçilen marka ve modeldeki motorsikletin fiyatına parent tablo üzerinden ulaşılabilir. Bu yapıda Parent-Child ilişkisi kaldırılmadan parent kayıt silinemeyeceğinden her motorsiklet için mutlaka fiyat kaydının olması garanti altına alınmış olacaktır. Böyle bir yapı kurulmuş ise ve eğer veri silinmek isteniyorsa öncelikle child kayıtlar silinmeli ve daha sonra o kayıtlara ait olan parent kayıtlar silinmelidir. Aksi taktirde parentten silme işlemi yapıldığı zaman foreign key constraint hatası alınacaktır.
Ekleme işleminde ise öncelikle parent tabloda fk ilişkisi tanımlanmış alanın verisi girilmiş olmalıdır, daha sonra bu alanla ilişkili child kayıtlar eklenebilecektir. Bu yapı veri ekleme ve silme işlemlerini kısıtlar gibi görünse de tablo üzerindeki veri bütünlüğünü korumaktadır. Ayrıca üzerinde parent-child ilişkisi tablolarda parent tablodaki verinin silinmesi ile onunla ilişkili child kayıtların silinmesini sağlayacak olan bir 'cascade deletion' yapısı mevcuttur. Cascade deletion, seviyeli silme işlemi, parent-child ilişkisinin oluşturulduğu foreign key üzerine tanımlanır.
Aşağıdaki örneklerde parent-child ilişkisinin nasıl kurulacağı, cascade deletion tanımlarının nasıl yapılacağı, üzerine önceden foreign key tanımlamaları yapılmış olan tablolarda cascade deletion işlemi için yapılacak olan değişiklikler basitçe gösterilmiştir.

Öncelikle örnek bir bayi tablosu oluşturalım. Bayi tablosu üzerinde bayi_id ve bayi_adi alanlarını primary key olarak belirleyelim.


CREATE TABLE bayi
( bayi_id numeric(10) not null,
bayi_adi varchar2(50) not null,
iletisim_adi varchar2(50),
CONSTRAINT bayi_pk PRIMARY KEY (bayi_id, bayi_adi)
);


Daha sonra urunler tablosunu oluşturalım ve bu tablo üzerinde bayi tablosuna foreign key olacak alanları belirleyelim.


CREATE TABLE urunler
( urun_id numeric(10) not null,
bayi_id numeric(10) not null,
bayi_adi varchar2(50) not null,
CONSTRAINT fk_bayi
FOREIGN KEY (bayi_id, bayi_adi)
REFERENCES bayi(bayi_id, bayi_adi)
);

Şu anda urunler tablosu ile bayi tablosu arasında bayi_id ve bayi_adi alanlarına göre ilişki kurmuş durumdayız. Artık bayi tablosunun ürünler tablosunun parent tablosu olduğunu ve aynı zamanda urunler tablosunun bayi tablosunun child tablosu olduğunu görebiliriz.
Oluşturmuş olduğumuz tablolara veri ekleyelim:

Öncelikle parent tablo olan bayi tablosuna ekleme yapıyoruz.

INSERT INTO BAYI (
BAYI_ID, BAYI_ADI, ILETISIM_ADI)
VALUES ( 1,'bayi1','bayi1_iletişim_adresi');
INSERT INTO BAYI (
BAYI_ID, BAYI_ADI, ILETISIM_ADI)
VALUES ( 2,'bayi2','bayi2_iletişim_adresi');
INSERT INTO BAYI (
BAYI_ID, BAYI_ADI, ILETISIM_ADI)
VALUES ( 3,'bayi3','bayi3_iletişim_adresi');
INSERT INTO BAYI (
BAYI_ID, BAYI_ADI, ILETISIM_ADI)
VALUES ( 4,'bayi4','bayi4_iletişim_adresi');
COMMIT;

--1 row created.
--1 row created.
--1 row created.
--1 row created.
--Commit complete.

Daha sonra child tablo olan urunler tablosuna ekleme yapıyoruz.

INSERT INTO URUNLER (
URUN_ID, BAYI_ID, BAYI_ADI)
VALUES ( 01,1,'bayi1');
INSERT INTO URUNLER (
URUN_ID, BAYI_ID, BAYI_ADI)
VALUES ( 02,2,'bayi2');
INSERT INTO URUNLER (
URUN_ID, BAYI_ID, BAYI_ADI)
VALUES ( 03,3,'bayi3');
INSERT INTO URUNLER (
URUN_ID, BAYI_ID, BAYI_ADI)
VALUES ( 04,4,'bayi4');
COMMIT;

--1 row created.
--1 row created.
--1 row created.
--1 row created.
--Commit complete.

Kontrollü bir şekilde önce parent sonra ise chil tabloya ekleme yaptığımız için herhangi bir hata ile karşılaşmadık.

Fakat urunler tablosuna bayi_id'si 5 ve bayi_adi bayi5 olan bir kaydı eklemeye çalıştığımızda ORA-02291 kodlu hata ile karşılaşırız. Çünkü parent tabloda bulunmayan bir kayıdı onun child tablosuna insert etmeye çalışıyoruz.

ORA-02291: integrity constraint (CCSOWNER.FK_BAYI) violated - parent key not found

Tam tersi olacak şekilde parent tablo olan URUNLER tablosundaki URUN_ID = 1 olan kayıdı silmeye çalıştığımızda da aşağıdaki gibi bir hata ile karşılaşırız. Parent tablodan silme yaparken child tablodan da silmemiz grektiği için veri bütünlüğü korunmuş olur.

ORA-02292: integrity constraint (MDSTAGE.FK_BAYI) violated - child record found

Bahsedildiği şekilde veri bütünlüğünü korumak bazı çalışmalarda büyük ölçüde istediğimiz bir özelliktir fakat silme yaparken daha büyük bir yapıda hangi tablonun hangisinin parenti olduğu gibi sorunlarla uğraşmak istemeyiz, bunun için parent-child ilişkisindeki yapılarda cascade delete (kademeli silme) özelliğini kullanabiliriz.
Kademeli silme özelliği ile bir parent tablodan veri silindiğinde otomatik olarak tüm bağlı child tablolardaki veri de silinir, ver bu şekilde veri bütünlüğü korunur.

Cascade deletion yapısı için ilişkiyi kurduğumuz ikincil anahtar (foreign key) üzerinde ON DELETE CASCADE tanımı yaparız. URUNLER tablosunu aşağıdaki gibi yeniden düzenleyecek olursak, cascade deletion yapan bir yapıyı elde etmiş oluruz.

CREATE TABLE urunler
( urun_id numeric(10) not null,
bayi_id numeric(10) not null,
bayi_adi varchar2(50) not null,
CONSTRAINT fk_bayi
FOREIGN KEY (bayi_id, bayi_adi)
REFERENCES bayi(bayi_id, bayi_adi)
ON DELETE CASCADE
);

veya bir tablo üzerinde önceden oluşturulmuş olan anahtar alanlarda alter table işlemi ile cascade deletion yapısı oluşturabiliriz.

ALTER TABLE urunler
add CONSTRAINT fk_bayi
FOREIGN KEY (bayi_id )
REFERENCES supplier(bayi_id)
ON DELETE CASCADE;

18 Haziran 2009 Perşembe

Tablo üzerindeki çiftleyen, duplicate, tekrarlayan, mükerrer kayıtların bulunması.

Tablo üzerinde bir alandaki duplicate, çiftleyen, tekrarlayan, mükerrer kayıtları bulmak ve o kayıt için kaç tane tekrarlayan olduğunu listelemek için aşağıdaki cümleyi kullanabilirsiniz.
Having yapısı içerisindeki >1 değerini değiştirerek, sadece 2 den fazla tekrar edenler (>2) gibi değerler için de kullanabilirsiniz.

SELECT kayit_tarihi, COUNT (kayit_tarihi) AS toplam_kayit_sayisi
FROM users
GROUP BY kayit_tarihi
HAVING (COUNT (kayit_tarihi) > 1)

17 Haziran 2009 Çarşamba

Örnek DDL, DCL, DML ve TCL komutları ve bu sorgu tipleri arasındaki farklar.

DDL
Data Definition Language (DDL) cümleleri veritabanı veya şema yapıları tanımlamak için kullanılırlar.
Örneğin:
• CREATE - veritabanında objelerin yaratılması.
• ALTER - değişiklik yapmak üzere bir yapıyı kullanmak.
• DROP - objenin veritabanından kaldırılması.
• TRUNCATE - bir tablonun içerisindeki tüm kayıtların silinmesi.
• RENAME - bir objenin isminin değiştirilmesi.

DML
Data Manipulation Language (DML) cümleleri veritabanı objelerine ait verinin gösterilmesi, silinmesi, güncellenmesi, birleştirilmesi, değiştirilmesi, yönetilmesi gibi işlemler için kullanılırlar.
Örneğin:
• SELECT - veritabanından veri çekmek, listelemek, göstermek.
• INSERT - tablo içerisine veri eklemek.
• UPDATE - tablo içerisindeki veriyi güncellemek, değiştirmek.
• DELETE - tablodaki verilerin silinmesi.
• MERGE - UPSERT operasyonunun yapılması, (insert etmek, eğer insert hata alırsa update etmek işlemi).
• CALL - bir PL/SQL veya Java programının çalıştırılması.
• LOCK TABLE - kontrol altında tutma işlemleri.

DCL
Data Control Language (DCL) cümleleri yetki tanımlama gibi kontrol unsurlarını içeren cümlelerdir.
Örneğin:
• GRANT - kullanıcıya veritabanı üzerinde yetki tanımlama
• REVOKE - yetkilerin iptal edilmesi

TCL
Transaction Control (TCL) cümleleri DML cümleleri tarafından yapılan işlemlerin mantıklı bir şekilde gruplanmasını ve kontrol edilmesini sağlar.
Örneğin:
• COMMIT - işlem bittiğinde kayıt edilmesi.
• SAVEPOINT - daha sonra rollbak yapılmak üzere bir nokta belirlenmesi
• ROLLBACK - veritabanını en son commit edilen hale getirmek için yapılan işlemlerin iptal edilmesi
• SET TRANSACTION - Transaction ayarlarının değiştirilmesi, rollback segmentlerinin belirlenmesi gibi işlemler.

Oracleda procedure trigger gibi db objeleri içinde arama yapmak.

Oracle da prosedürler, triggerlar, fonksiyonlar, şema sahipleri gibi obje tipleri içerisinde arama yapabilmek veya belli bir şemaya ait içeriği listeleyebilmek için 'all_source' tablosunu kullanabiliriz. Bu tabloda objeler kullanıcı(owner), isim(name), tip(type), objede kelimenin geçtiği satır(line), obje içeriği(text) gibi özellikleriyle birlikte tutulmaktadır.

Buna göre prosedürler içerisinde arama yapabilmek için aşağıdaki sorgu kullanılabilir.

select * from all_source
where name = '' and type = 'PROCEDURE'
order by line;

Yine aynı tablo kullanılarak bir tablonun hangi objeler tarafından kullanıldığını belirleyebilmek için objelerin içeriklerinde aşağıdaki gibi aratma yapabiliriz.

select * from all_source
where text like '%%'
order by name;

Eğer aramayı belirli bir kullanıcı için kısıtlamak istiyorsak 'all_source' tablosu yerine login olduğumuz kullanıcıya ait objeleri tutan 'user_source' tablosunu kullanabiliriz. Veya 'all_source' tablosunda owner alanı için bir değer belirleyerek sorgumuzun where kısmına ekleyebiliriz.

27 Mayıs 2009 Çarşamba

ORACLE VERSIYONUNU ÖĞRENMEK

Kullandığımız Oracle versiyonu bazı özelliklerin kullanılıp kullanılmması açısından önemli olabilir, yeni eklenen özellikleri eski versiyonlar çalıştırmayacağından bu tip özellikleri kullanmadan önce aşağıdaki sorgular yardımı ile versiyonu öğrenmekte fayda var.

select * from product_component_version;


PRODUCT VERSION STATUS

NLSRTL 10.2.0.4.0 Production
Oracle Database 10g Enterprise Edition 10.2.0.4.0 64bi
PL/SQL 10.2.0.4.0 Production
TNS for IBM/AIX RISC System/6000: 10.2.0.4.0 Productio

veya

select * from v$version ;


BANNER

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.4.0 - Productio
NLSRTL Version 10.2.0.4.0 - Production

15 Mayıs 2009 Cuma

NVARCHAR ve VARCHAR veri tipleri arasındaki farklar

NVARCHAR ve VARCHAR çok fazla kullandığımız veri tipleri arasında, fakat geçenlerde bir sohbet sırasında iki veri tipi arasındaki farkları tam olarak bilmediğimi/yanlış bildiğimi farkettim ve hemen araştırdım.
Sonuç olarak iki veri tipi arasındaki tek fark veriyi saklama biçimleri olarak görünüyor, NVARCHAR tipinde multilingual/çokludil olarak UNICODE verileri tutmak mümkün olurken VARCHAR tipinde ise UNICODE olmayan ASCII karakterler tutuluyor.
Faydası ve zararları nelerdir? NVARCHAR tipinde her bir karakter 16bit (2 BYTE) yer kaplarken fakat UNICODE özelliği sayesinde multilingual bir veri tipi sunarken, VARCHAR tipinde her karakter 8 bit (1 BYTE) yer kaplıyor ve multilingual bir veri tipi sunmuyor.
Yani kullanacağınız verinin içeriğine göre veya bellekten tahammül edilebilecek kullanıma göre veri tipini belirlemek size kalıyor.

Bu araştırma kapsamında okuduğum eğlenceli yorumu da sizinle paylaşmak istiyorum.

Jeffrey L Whitledge'in Yorumu
An nvarchar column can store any Unicode data. A varchar column is restricted to an 8-bit codepage. Some people think that varchar should be used because it takes up less space. I believe this is not the correct answer. Codepage incompatabilities are a pain, and Unicode is the cure for codepage problems. With cheap disk and memory nowadays, there is really no reason to waste time mucking around with code pages anymore.
Restricting yourself to an 8-bit codepage is a very backward-thinking way to do data storage. This is the 21st century, people! Unicode is here, and it is the future. Let's abandon all that old 8-bit junk, it has no place in any new system.
OK, I feel better now. You may now go about your business. Thank you.

17 Nisan 2009 Cuma

Oracle NULL

Oracle’a ilk başladığınız zamanlarda eğer önceden farklı veri tabanları ile çalışmışsanız null olan değerler size biraz ilginç gelebilir.
Null hücreler değeri belli olmayan, değeri bilinmeyen hücrelerdir.
Bu nedenle aşağıdaki sorgunun sonucu doğal olarak belirsiz bir değer çıkacaktır, bu da null’a eşittir.
select 5+7+null+9 from dual;

Fakat kullandığımız Oracle Fonksiyonları bu mantıkta çalışmazlar, örneğin SUM() fonksiyonu kullanıldığında null olan değerleri ihmal ederek diğer değerlerin toplamını verir. Benzer şekilde diğer fonksiyonlar da null değerleri ihmal ederler.
Null değerleri daha iyi anlamak için boolean değişkenler ile beraber mantıksal işlemlerlerinin sonucunu gösteren aşağıdaki doğruluk tablosunu inceleyebilirsiniz.
b1 b2| and or
------+--------
1 1| 1 1 ------------ 1: true
1 0| 0 1 ------------ 0: false
1 n| n 1 ------------ n: null value
0 1| 0 1
0 0| 0 0
0 n| 0 n
n 1| n 1
n 0| 0 n
n n| n n

null değerler ile Oracle’da karşılaştırma yapacak ise bilmemiz gereken şey, null değerlerin tipinin string olduğudur, yani null değerler Oracle’da yan yana iki tek tırnak işareti arasındaki ('')karakteri ifade eden STRING('') değeridir. Bu yüzden boş bir stringin uzunluğu(length) 0 değil null dır.
Başka bir özellik olarak Oracle sıralama yaparken null değerleri diğer değerlerden daha büyük olarak kabul eder, sıralama yaptığımız tabloda MAXVALUE hariç bütün null değerler en büyük değerlerdir.

Oracle Table Partitioning

Gittikçe büyüyen ve data yükü artan tablolar üzerinde sorgu çalıştırmak veya tablo bakımına ait diğer işlemleri gerçekleştirmek zamanla çeşitli problemlere sebep olmaktadır. Problemleri ortadan kaldırmanın kullanışlı ve etkili yollarından birisi tabloyu bütünlüğünü koruyacak şekilde parçalara ayırmak ve ilgili işlemleri sadece gerekli olan parçalar üzerinde yapmaktır. Partitioning kavramı bahsedilen bu işlemleri gerçekleştirebileceğimiz bir yapı sunmaktadır, tablonun bütünlüğü korunarak üzerindeki işlemlerin daha hızlı gerçekleştirilebileceği parçalara ayrılır.

Partitioning kavramı üzerinde bahsedilmesi gereken ayrıntılarla devam etmek istiyorum, tablo üzerinde partition oluşturmak tablonun genel bütünlüğünü bozmayacağından tablo üzerinde çalıştırılan sorgularda değişiklik yapmaya gerek yoktur. Bu nedenle işleyen sistemler üzerinde uygun partition metodunu seçerek kullanılan sorguları değiştirmeden partitioning işlemi gerçekleştirilebilir. Aynı zamanda partitioning metoduna bağlı olarak ayrılan her parçanın kendi ismi ile sadece ayrılan parçaya ait işlemler de gerçekleştirilebilir. Parçalar ayrı ayrı drop/truncate edilebilir, üzerlerinde farklı bir index oluşturulabilir. Partitioning in diğer avantajı ise küçük parçalar ile uğraştığından sorgularda çok daha performanslı olmasıdır. Ayrıca partitioning yapılmamış bir tabloya sonradan partitioning yapıldığında tablo üzerinde çalışan sorgu ve DML lerde herhangi bir değişikliğe gerek olmaması bu yapının oldukça esnek olarak kullanılmasını sağlamaktadır.

Partition lara ayrılan bir tabloda herbir satır tek bir parçaya ait olabilir, satırın ait olacağı parçanın belirlenmesi için partition key kullanılır. Partition key null alabilen bir değerden de oluşabilir.

Yukarda bahsettiğim gibi bazı işlemlerin gerçeklenebilmesi tablo üzerindeki partitioning metoduna bağlıdır. Partitioning metodlarını daha yakından inceleyecek olursak:

Oracle tarafından 4 farklı partitioning yöntemi desteklenmektedir:

· Range Partitioning.

· List Partititoning

· Hash Partitioning

· Composite Partitioning

Range Partitioning Metodu

Range metodu ile partition işleminde partition keyi üzerinde belirli aralıklardaki değerlere göre parçalar oluşturulur. Örneğin tablo üzerinde yılların tutulduğu bir alana sahibiz, bu alanı partition key olarak belirleyip yıllara göre parçalar oluşturabilir, artık kullanmayacağımız yılların datalarını direk ilgili partitionu kullanarak drop/truncate edebilir veya belirli bir yıla göre sorgularımızı gerçekleştirebiliriz. Veya illere göre verilerin tutulduğu bir tabloda il kolonu üzerinde partition yapılarak sadece ilgilenilen ilin datası ile işlemler yapılabilir. Partitionda less than ile belirtilen değerden daha küçük olan aralık alınır, MAXVALUE değeri ile ise bir üst sınır belirlenir, belirlenen en büyük değerin dışına çıkan ve null olan değerler bu parça içerisine dahil olacaklardır.

Number tipe gore range partition örneği:

CREATE TABLE emp (
   empno NUMBER(4), 
   ename VARCHAR2(30), 
   sal   NUMBER
) 
PARTITION BY RANGE(empno) (
  partition e1 values less than (1000)     tablespace ts1, 
  partition e2 values less than (2000)     tablespace ts2, 
  partition e3 values less than (MAXVALUE) tablespace ts3
); 

Emp tablosu üzerinde empno keyi kullanılarak bir partition oluşturulmuştur ve 1000 den küçük olan numaralar, 1000-2000 arası olan numaralar ve 2000 den büyük olan numaralar ayrı partitionlarda yer alacaklardır.

Varchar2 string tipe gore partition örneği:

CREATE TABLE emp
( id        NUMBER(5)    PRIMARY KEY,
  name      VARCHAR2(50) NOT NULL,
  phone     VARCHAR2(15),
  email     VARCHAR2(100) )
PARTITION BY RANGE ( name )
        ( 
        PARTITION p1 VALUES LESS THAN ('L')      TABLESPACE ts1,
        PARTITION p2 VALUES LESS THAN (MAXVALUE) TABLESPACE ts2 
        )

Date tipe gore range partitioning örneği:

CREATE TABLE t1 (id NUMBER, c1 DATE)
PARTITION BY RANGE (c1)
  (PARTITION t1p1 VALUES LESS THAN (TO_DATE('2007-11-01', 'YYYY-MM-DD')),
   PARTITION t1p2 VALUES LESS THAN (TO_DATE('2007-12-01', 'YYYY-MM-DD')),
   PARTITION t1p3 VALUES LESS THAN (TO_DATE('2008-01-01', 'YYYY-MM-DD')),
   PARTITION t1p4 VALUES LESS THAN (MAXVALUE)
  );

Hash Partitioning Metodu

Hash partitioning metodu daha çok key olarak range metodundaki gibi bir sınır belirlenemeyecek olan alanlar üzerinde kullanılır, örneğin kimlik numaralarının tutulduğu bir alan üzerinde oluşturulabilir.

Örnekler:

 
create table emp2 (
   empno number(4), 
   ename varchar2(30), 
   sal   number
) 
partition by hash(empno) (
  partition e1 tablespace emp1, 
  partition e2 tablespace emp2, 
  partition e3 tablespace emp3,
  partition e4 tablespace emp4
); 

Emp2 tablosu üzerinde farklı tablespaceler kullanılıp empno alanı key olarak kullanılmış ve partition oluşturulmuştur.

create table emp2 (
   empno number(4), 
   ename varchar2(30), 
   sal   number
) 
PARTITION BY HASH(empno)
PARTITIONS 3
STORE IN (empts1, empts2, empts3);

Hash Partitioning yönteminde partitionlar round robin mantığı ile oluşturulurlar.

List partitioning

List partitioning methodu ile belirlenen bir liste değerini içerek key üzerinden tablo partitionlara ayrılır.

Örnek:

CREATE TABLE myemp_work (

emp# NUMBER PRIMARY KEY,

ename VARCHAR2(30),

salary NUMBER(8,2),

deptno NUMBER)

PARTITION BY LIST (deptno) ( -- Add list partitioning

PARTITION p10 VALUES (10),

PARTITION p20 VALUES (20),

PARTITION p30 VALUES (30,40));

deptno alanı key olarak kullanılmış ve bu alan için belirlenen değerler için tablo içerisinde parçalar oluşturulmuştur.

List partition için ayrıca listede belirtilmeyen veya listede yer almayıp sonradan eklenebilecek olan değerler ve null değerler için DEFAULT VALUE kullanılır.

CREATE TABLE myemp_work (

emp# NUMBER PRIMARY KEY,

ename VARCHAR2(30),

salary NUMBER(8,2),

deptno NUMBER)

PARTITION BY LIST (deptno) ( -- Add list partitioning

PARTITION p10 VALUES (10),

PARTITION p20 VALUES (20),

PARTITION p30 VALUES (30,40)

PARTITION PDEF VALUES(DEFAULT));

Composite Partitioning

Composite partitioning yöntemi diğer kullanılan yöntemlerin beraber kullanılması ile elde edilen bir yöntemdir. Daha önceden üzerinde partitioning oluşturulmuş olan bir tablodaki parçalar üzerindeki alt parçalar da parçalara ayrılarak verinin içeriğine ve kullanım amacına göre daha kullanışlı bir yapı sağlanabilir.

Range-hash ve range-list metodları birlikte kullanılarak yerine göre avantajlı olan özelliklerinden faydalanılabilir.

Örnek range-hash partitioning yapısı oluşturma:

CREATE TABLE orders(
 ord#       NUMBER,
 orderdate  DATE,
 prod#      NUMBER,
 quantity   NUMBER)
PARTITION    BY RANGE(orderdate)
SUBPARTITION BY HASH(prod#) SUBPARTITIONS 4 -- STORE IN(ts1, ts2, ts3, ts4)
( PARTITION q1 VALUES LESS THAN (TO_DATE('01-APR-2009', 'DD-MON-YYYY')),
  PARTITION q2 VALUES LESS THAN (TO_DATE('01-JUL-2009', 'DD-MON-YYYY')),
  PARTITION q3 VALUES LESS THAN (TO_DATE('01-OCT-2009', 'DD-MON-YYYY')),
  PARTITION q4 VALUES LESS THAN (MAXVALUE)
);

Bahsedilen partitioning methodlarından en uygun olanını seçmek verinin tipine, sunuluş şekline göre değişiklik gösterecektir, bu aşamada hepsinin avantajlı olan kısımlarını göz önünde bulundurarak seçim yapmak gerektiğini göz önünde bulundurmalıyız.

Partition işlemleri yaptığımız tablo üzerinde partitionlara ayrılmış kısımlar hakkında detylı bilgilere aşağıdaki sorguyu kullanarak bakabiliriz.

SELECT * FROM dba_tab_partitions WHERE table_name = '';

10 Nisan 2009 Cuma

ORACLE Auto Increment Kolon/Alan Oluşturma

MS-SQL kullanmış olanlar bilirler auto increment kolon oluşturmak iki tıklama kadar kolaydır fakat ORACLE a gelince işler biraz farklı yürüyor, öncelikle tablo üzerinde bir SEQUENCE oluşturmak gerekiyor ve bu SEQUENCE i kullanarak tabloya yapılan işlemler esnasında bir TRIGGER ile bu SEQUENCE içerisindeki next değeri almak gerekiyor.

Önce bir tablo oluşturalım:

SQL> CREATE TABLE test
(id NUMBER PRIMARY KEY,
name VARCHAR2(30));

Daha sonra bir SEQUENCE oluşturalım:

-- increment faktörünü ve başlangıç değerini 1 olarak belirledik.
SQL> CREATE SEQUENCE test_sequence
START WITH 1
INCREMENT BY 1;

Şimdi oluşturduğumuz SEQUENCE i tabloya insert öncesinde kullanabiliriz:

CREATE OR REPLACE TRIGGER test_trigger
BEFORE INSERT
ON test
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT test_sequence.nextval INTO :NEW.ID FROM dual;
END;
/

Trigger i de yarattığımıza göre artık birkaç insert cümlesi ile testimizi yapabiliriz:

-- Burada öemli olan insert edeceğimiz value lar içerisinde id ye yer vermememiz, id değeri zaten auto increment bir değer olduğundan SEQUENCE i kullanarak bir sonraki değerini otomatik olarak alacaktır.

SQL> INSERT INTO test (name) VALUES ('Jon');

1 row created.

SQL> INSERT INTO test (name) VALUES (’Bork’);

1 row created.

SQL> INSERT INTO test (name) VALUES (’Matt’);

1 row created.

Sonuçlara bakarsak id değerinin otomatik değerler aldığını görürüz:

SQL> SELECT * FROM test;

ID NAME
———- ——————————
1 Jon
2 Bork
3 Matt

SEQUENCE in bağımsız olarak commit edildikten sonra update edilmesi sayesinde birden fazla kullanıcının aynı tabloya aynı anda insert etmesi bir sorun oluşturmayacaktır.

ORACLE Bir Şemadaki Bütün Tabloların İçerdiği Kayıt Sayıları

-- ORACLE Bir Şemadaki Bütün Tabloların İçerdiği Kayıt Sayıları

select owner, table_name, num_rows from sys.dba_tables where owner = 'USER_NAME' ORDER BY num_rows desc;

ORACLE Bir Şemadaki Tüm Tabloların Sayısı

-- Bir Şemadaki Tabloların Sayısını

select count(*) from sys.dba_tables where owner = 'USER_NAME' ORDER BY num_rows desc ;

Popüler Yayınlar