Merhaba, yaklaşık bir yıldır Oracle kullanıyorum. Bu süre zarfında öğrendiğim bilgileri belki birilerinin işine yarar umuduyla bloguma yazmaya başladım. Bu makalemde anlatacağım Oracle ile alakalı olan konu ise Sequence. Sequence nedir, nasıl ve nerede kullanılır, değeri nasıl setlenir gibi soruları bildiğim kadarıyla cevaplamaya çalışacağım. Herhangi bir hata veya eksiklik görürseniz yorum yazabilirsiniz. Ben de yorumlarınız doğrultusunda makaleyi güncellerim.
Sequence Nedir?
Sequence, basit tanımıyla Oracle’da bir objedir. Bu tanımı biraz açarsak, sequence aslında otomatik olarak artan number tipindeki bir objedir, değişkendir. SQL Server veya MySQL veritabanlarıyla çalıştıysanız aşağı yukarı hepiniz auto increment (otomatik artan) özelliğinde bir kolon oluşturmuşsunuzdur (muhtemelen ID kolonu). Oracle’da bu tarz bir özellik bulunmamakta. Bu özelliği sağlayabilmek içinse sequence + trigger ikilisi kullanılıyor. Detaylı bilgi için bir önceki yazımı (Oracle Auto Increment Yapısı) okuyabilirsiniz.
Nasıl Oluşturulur?
Veritabanındaki bir çok obje gibi sequence da create komutuyla oluşturulur. En basit şekliyle yazarsak:
create sequence sequence_adi;
Yukarıdaki komut ile sequence_adi isminde bir sequence oluşturmuş olduk. Bu basit kullanımın yanı sıra, sequence oluştururken kullanabileceğimiz bazı seçenekler mevcut. En çok kullanılabilecek olanları açıklamalarıyla beraber aşağıya yazdım.
- increment by : sequence’in artış miktarını belirler. Pozitif veya negatif bir tamsayı olabilir; ancak 0 (sıfır) olamaz.
- start with : sequence’in başlangıç değerini belirler.
- maxvalue : sequence’in alabileceği maksimum değeri belirler.
- minvalue : sequence’in alabileceği minimum değeri belirler.
- cycle : sequence maksimum/minimum değere ulaştıktan sonra başa dönmesine izin verir.
- nocycle : sequence maksimum/minimum değere ulaştıktan sonra başa dönmemesini sağlar, bunun yerine hata fırlatır. Varsayılan davranış budur.
- cache : sequence’e hızlı erişim için bellekte ne kadarlık değer saklanacağını belirler. En küçük değer olarak 2 verilebilir. Not: cache ile ilgili detaylı bilgiyi yazının devamında bulabilirsiniz.
- nocache : cache özelliğini devre dışı bırakır. cache veya nocache seçeneği belirtilmezse varsayılan olarak cache 20 kullanılır.
Yukarıdaki seçenekleri kullanarak birkaç örnek sequence oluşturalım:
create sequence s_user start with 10 increment by 2; --10'dan başlayıp 2'şer 2'şer artar
create sequence s_stock start with 1000 increment by -1; --1000'den başlayıp 1'er 1'er azalır
create sequence s_person cache 5 maxvalue 1000 cycle; --1'er 1'er artar ve 1000 olunca baştan başlar
create sequence s_log cache 100 nocycle; --1'er 1'er artar
Nasıl ve Nerede Kullanılır?
Benim gördüğüm en yaygın kullanım tipi az önce bahsettiğim auto increment yapısındaki kullanım. Örneğin ilk oluşturmuş olduğumuz sequence_adi isimli sequence, 1’den başlayıp 1’er 1’er artmaya devam eder. Peki sequence’i nasıl kullanırız? Örneğin user isimli bir tablomuz olsun ve biz bu tabloya insert yaparken ID kolonuna sequence (s_user) değerini koymak istiyoruz. O zaman şöyle bir sorgu yazmamız gerekiyor:
insert into user (ID, Name, Surname) values (s_user.nextval, 'Kemal', 'Kefeli');
s_user sequence’ini az önce yukarıda oluşturmuştuk. Dolayısıyla bu insert sorgusundaki ID değeri 10 oldu. Diyelim ki ben bu ID’yi başka bir tabloya referans olarak geçmek istiyorum. Örneğin az önceki insert sonucu elde ettiğim 10 değerini person tablosundaki UserID kolonuna koymak istiyorum. O zaman da şu şekilde bir sorgu yazmamız gerekiyor:
insert into user (ID, Name, Surname) values (s_user.nextval, 'Kemal', 'Kefeli');
insert into person (ID, UserID, CitizenNo) values (s_person.nextval, s_user.currval, '11111111111');
Gördüğünüz gibi bu işlemi currval sayesinde yaptık. Yalnız burada dikkat edilmesi gereken bir nokta, currval çağırmadan önce ilgili session’da en az bir kez nextval ile sequence’i çağırmamız gerekli. Eğer nextval kullanmadan direkt currval kullanmak isterseniz hata ile karşılaşacaksınız.
Cache Özelliği Nedir?
Cache özelliği, sequence’a hızlı bir şekilde erişilebilmesi için oluşturulmuş bir özelliktir. Bir örnek ile açıklamaya çalışayım. İki adet sequence olsun. Bunlardan biri cache 20 (C) ile diğeri de nocache (N) ile oluşturulsun. N’yi her N.nextval ile çağırdığımızda herhangi bir cache mekanizması olmadığından veritabanı bu değeri, sequence’in asıl tutulduğu yerden (muhtemelen diskteki bir tablodan) okuyacaktır ve işin içine disk girdiği için bu işlem biraz yavaş olacaktır. Ufak çaplı projelerde siz bu farkı anlayamayabilirsiniz; ancak örneğin bir bankacılık uygulamasında log tablosunu bu şekilde yaparsanız çok fazla diskten okuma olacağı için sistem bir süre sonra çalışmaz hale gelecektir. Diğer yandan C sequence’ine bakacak olursak, C’yi ilk nextval ile kullandığımızda ilgili değer diskten okunacak ve belleğe yazılacaktır. Bu ilk okuma esnasında sonraki 19 sayı da (cache 20 olduğu için) rezerve edilecektir. Dolayısıyla ikinci kez nextval kullandığımızda diske tekrar gitmek yerine sequence değeri bellekten getirilecektir ve tabi ki diskten okumaya göre yüksek performans sağlayacaktır.
Cache ile alakalı olarak bir konudan daha bahsetmek istiyorum. nocache kullandıysanız bunun bir önemi yok; ancak cache 10 gibi bir değer kullanmışsanız, yani cache özelliğini kullanıyorsanız, rezerve işlemi session bazlı yapılacaktır. Dolayısıyla siz herhangi bir session için 10-20 arasını rezerve ettiğinizde, aynı sequence’i kullanmak isteyen bir başkası 20-30 arasını alacaktır. Eğer siz rezerve etmiş olduğunuz alanın tamamını kullanmadan işinizi bitirirseniz (örneğin 14’ten sonrasını kullanmadınız), kalan kısımlar için tabloda boşluk oluşacaktır. Yani örneğin ID kolonu için değerler şu şekilde olabilir: 10,11,12,13,14,20,21,22…
Sequence Nasıl Setlenir?
Herhangi bir sebepten dolayı sequence’in mevcut konumunu değiştirmek istiyorsunuz diyelim. s_user sequence’inin mevcut değeri 10 ve siz bunu 100 yapmak istiyorsunuz. Keşke A := 100 diyebilseydik, o zaman her şey çok güzel olurdu. Maalesef böyle bir kullanım söz konusu değil. Aslında sequence setleme diye bir olay da yok, aşağıdaki kodu gördüğünüzde ne demek istediğimi daha iyi anlayacaksınız:
alter sequence s_user increment by 89; --Aradaki farkın 1 eksiği kadar increment tanımlıyoruz
select s_user.nextval from dual; --Sonraki değeri alıyoruz yani 99 dönüyor
alter sequence s_user increment by 1; --Son olarak increment değerini tekrar 1 olarak setliyoruz
--Bir sonraki çağrımda bize 100 değerini dönüyor
Gördüğünüz gibi aslında setleme yok, gereksiz yere birkaç çağrı yaparak sequence değerini değiştirmiş oluyoruz. Sequence değerini arttırmak yerine benzer şekilde azaltma da yapabilirsiniz.
Sequence Nasıl Silinir?
Yine veritabanındaki bir çok objeyi silmek için kullandığımız drop komutunu burada da kullanıyoruz:
drop sequence s_user;
Makalemin başında da söylediğim gibi, eksik veya hatalı yazdığım yerler varsa lütfen yorum bırakmayı unutmayın…