Home Map Index Search News Archives Links About LF
[Top Bar]
[BottomBar]
SQL'e giriş ve PostgreSQL'in kurulumu
[no author] [no author]
Yazar: Manuel Soriano
<manu(at)europa3.com>



İngilizce'ye çeviren:
Miguel A Sepulveda <sepulveda(at)linuxfocus.org>


Türkçe'ye çeviren:
Erdal Mutlu <erdal(at)linuxfocus.org>

Content:

 

SQL'e giriş ve PostgreSQL'in kurulumu

[Illustration]

Özet:

Bu kısa kurs üç kısımdan oluşmaktadır. İlk kısımda, SQL hakkında genel bilgi ile kamuya açık (public domain) veritabanı olan PostgreSQL hakkında bilgiler verceğiz. İkinci kısımda SQL buyruklarını daha ayrıntılı olarak işleyeceğiz. Üçünücü kısımda, gelişmiş SQL buyruklar, projelerde kullanılması ilginç olabilecek PostgreSQL'e özgü fonksiyonlar ile herşeyi birden gösteren bir C programını gözden geçireceğiz.
_________________ _________________ _________________

 

Giriş

Verileri veritabanları dışında da saklamak olasıyken, tüm olasılıklar hakkında yazmak, yazımızın amacı dışına çıkacağından, onlar hakkında burada söz etmeyeceğim.

Yakın zamana kadar, verilere olan erişim, belli biçimde tanımlanmış bağlantılar üzerinde yapılıyordu. Böyle yapılan erişimlerin getirileri vardı. Özellikle hız bunlardan biridir. Ancak, götürüleri de yok değilidi. Veriye sadece var olan bir bağlantı üzerinden erişilebilinmesi, en önemli götürülerdendi. Sözgelimi:

     ülke -> eyaletler -> bölgeler
bağlantısı tanımlanmışsa, aşağıdaki gibi bir erişim olamazdı:
     ülke -> bölgeler
Buradaki "->" işareti bağlantıyı simgelemektedir.

Eğer, yukarıdaki ikinci ilişkiyi tanımlamak isteseydik, şemayı yeniden tanımlamamız ve derlememiz gerekecekti ...

Aslında, hiyerarşik veritabanlarındaki ilişkiler durağandır ve değiştirilmeleri gerektiğinde, şemaların yeniden tanımlanması ve daha sonra da derlenmesi gerekir.

İlişkisel veritabanı arkasında yatan düşünce, durağan bağlantıya gereksinim duyulmadan, verileri sorgu sırasında birbirleriyle bir belirteç (identifier) aracılığıyla tam olarak ilişkilendirmektir.

Yukarıdaki cümleyi anlamak için insanın bir aspirine gereksinimi vardır:)

Hiyerarşi içinde aşağılara doğru gidebilmemiz için ilişkisel veritabani yöneticilerinin durağan bağlantılara sahip olmaları gerekmemektedir. Onun yerine, sorgunun sonucu olarak oluşacak geçici ilişkiyi ve ilişki içerisinde yer alan verileri, tekil (unique) belirlemeye yarayan bir kod kullanılmaktadır.

Kimliklendirme bir kod numarasından başka bir şey değildir. Sözgelimi, benim telefon numaram :

1234567

değil, :

34 6 1234567

dir. Aslında benim telefon numaram ülke kodu (34), eyalet kodu (6) ve ilgili aygıt numarası (1234567) ile tanımlanmaktadır.

Yukarıda verdiğim örnek için temel kavramları belirtecek olursam:

     Bir eyalet ve ülkeye ait olan her bölgenin bir kodu vardır.
     Bir ülkeye ait olan her eyaletlerin bir kodu vardır.
     Her ülkenin bir kodu vardır.

Bir eyaletteki tüm bölgeleri elde etmek için, bölgeleri, eyaletler ve ülkelerle, bölge ve ülke kodu aracılığı ile ilişkilendiriyoruz. Bir ülkedeki tüm bölgeleri elde etmek için, bölgeler ile ülkeleri ülke kodu aracılığı ile ilişkilendiriyoruz. Bu ilişkiler geçicidir ve sadece sorgu sırasında varlık göstermektedir.

Konunun zor kavrandığını biliyorum ve aşağıda vereceğim örneklerle ait olma ve kodlar gibi kavramların daha iyi anlaşılacğını umuyorum.

DB yöneticisine yöneltiğim ilk sorgunun sonucunda, DB yöneticisinden ilgili tüm verileri elde ediyorum. Pek iyi ama, gerçekte elde ettiğim veriler nedir? Her bölge için ülke verileriyle, ülke ve eyaletlerin birleşimini elde edeceğim.

İlk sorgum sırasında ülkeler ve bölgelerin kopyasından oluşan, isimsiz yeni bir nesne yaratılmış oldu. Sorgum sona erdiğinde bu nesne ortadan kalkacaktır.

Bir veri kümesine eskiden verilen ad dosya (file) idi. Dosya içerisinde yazmaçlar (register) vardı ve yazmaçlar da kendi içinde alanlardan (field) oluşmaktaydı. İlişkisel veritabanlarında, dosya, tablo adı altında bilinmekte ve bir tablo satırlardan oluşmaktadır. Satırlar da kendi içinde sütünlardan oluşmaktadır. Bunlar, isim değişikliğinden başka bir şey değildir.

Verilere erişim dili olarak, bazı hiyerarşik veritabanı yöneticileri SQL dilinin de kullanılabileceği söylenmekte. Ama bu bir şakadan başka bir şey değildir. SQL dili, ilişkisel veritabanı yöneticilerinin ait bir mal gibidir.

SQL kullanımını gösterebilmek için PostgreSQL ilişkisel veritabanı yöneticisini kullacağız. PostgreSQL her nekadar SQL kurallarıyla tam uygunluk göstermese de, bizim amacımız için yeterilidir. Ayrıca PostgreSQL, çok daha ağır işlerin yöneticisidir.

Yazının amacı SQL olduğunu belirtikten sonra, izin verirseniz, PostgreSQL veritabanı sisteminin kısaca yüklenişini göstereyim. İlk yapmanız gereken www.postgresql.org adresinden kaynak kodlarını ve varsa yamaları indirmektir. Paketi tar xvfz buyruğu ile bir dizinde açın ve cd postgresql-6.3 ile oluşan dizinine geçin:

cd src
./configure --prefix=/the/desired/path
make all >& make.log &
tail -f make.log

export PATH=$PATH:/the/desired/path/pgsql/bin
export MANPATH=$MANPATH:/the/desired/path/pgsql/man
export PGLIB=/the/desired/path/pgsql/lib
export PGDATA=/the/desired/path/pgsql/data

initdb
createdb test
psql test
Welcome to the POSTGRESQL interactive sql monitor:
  Please read the file COPYRIGHT for copyright terms of POSTGRESQL

   type \? for help on slash commands
   type \q to quit
   type \g or terminate with semicolon to execute query
 You are currently connected to the database: postgres

test=>
Yukarıda görmüş olduğunuz satır, postgres'in buyruk imlecidir. Artık buyruklarımızı vermeye başlayabiliriz:
mytest=>create table mytest (field1 varchar(10));
CREATE

mytest=>insert into mytest values ('hello');
INSERT number 1

mytest=>commit work;
NOTICE:EndTransactionBlock and not inprogress/abort state
END

mytest=>select * from mytest;
field1
------
hello
(1 row)

mytest=>drop table mytest;
DROP

mytest=>Ctrl-d
Artık SQL ortamından çıkmış durumdayız.

Postgres95'i derleme ve yüklemede sorun yaşarsanız, paketle birlikte gelen INSTALL dosyasını okumanızı öneririm.

İzin verirseniz bir konu dışı açıklama daha yapmak istiyorum. İlişkisel bir veritabanı genel olarak aşağıdaki bileşenlerden oluşmaktadır:

  1. Veri erişim katmanı
  2. SQL işleme katmanı
  3. SQL ayrıştırma katmanı
  4. Haberleşme katmanı

İstemci olarak sunucuyla yaptığımız haberleşme dolayısıyla bizler, yukarıdakilerden dördüncü katmanı tanıyoruz. Gönderdiğimiz SQL buyrukları, SQL ayrıştırma (parser) katmanına iletilmektedir. Burada buyruklar denetlenmekte ve hata yoksa, ikinci katmana iletilmektedir. Tüm işleme ve sorgulamalar veri katmanının da yardımıyla, bu katmadan yapılmaktadır. Yapılan işlemler arasında, veri toplama, haberleşme katmanı aracılığı ile hataların istemciye iletilmesi sıralanabilir. SQL işleme katmanı istemciyle olan haberleşmesinde, veri aktarımı denetimi, hareketler (transactions) ve kesmeler gibi işlemleri yerine getirirken, istemciyle sürekli iletişim halindedir.

 

İlk adımlar

Yukarıda örnek olarak verilenleri göstermeye yönelik, üç adet tablo (veya dosya) yaratalım:

ülkeler.sql dosyaysı:
create table ulkeler (ulke_kodu integer, adi varchar(30));
insert into ulkeler values (1, 'ülke 1');
insert into ulkeler values (2, 'ülke 2');
insert into ulkeler values (3, 'ülke 3');
commit work;
eyaletler.sql dosyası :
create table eyaletler (eyalet_kodu int,
            ulke_kodu int,
            eyalet_adi varchar(30));
insert into eyaletler values (1, 1, 'Eyalet 1, Ülke 1');
insert into eyaletler values (2, 1, 'Eyalet 2, Ülke 1');
insert into eyaletler values (1, 2, 'Eyalet 1, Ülke 2');
insert into eyaletler values (2, 2, 'Eyalet 2, Ülke 2');
insert into eyaletler values (1, 3, 'Eyalet 1, Ülke 3');
insert into eyaletler values (2, 3, 'Eyalet 2, Ülke 3');
commit work;
bölgeler.sql dosyası:
create table bolgeler (ulke_kodu int,
            eyalet_kodu int,
            bolge_kodu int,
            bolge_adi varchar(60));
insert into bolgeler values (1, 1, 1, 'Bölge 1, Eyalet 1, Ülke 1');
insert into bolgeler values (2, 1, 1, 'Bölge 2, Eyalet 1, Ülke 1');
insert into bolgeler values (3, 1, 1, 'Bölge 3, Eyalet 1, Ülke 1');
insert into bolgeler values (1, 2, 1, 'Bölge 1, Eyalet 2, Ülke 1');
insert into bolgeler values (2, 2, 1, 'Bölge 2, Eyalet 2, Ülke 1');
insert into bolgeler values (3, 2, 1, 'Bölge 3, Eyalet 2, Ülke 1');
insert into bolgeler values (1, 3, 1, 'Bölge 1, Eyalet 3, Ülke 1');
insert into bolgeler values (2, 3, 1, 'Bölge 2, Eyalet 3, Ülke 1');
insert into bolgeler values (3, 3, 1, 'Bölge 3, Eyalet 3, Ülke 1');
insert into bolgeler values (1, 1, 2, 'Bölge 1, Eyalet 1, Ülke 2');
insert into bolgeler values (2, 1, 2, 'Bölge 2, Eyalet 1, Ülke 2');
insert into bolgeler values (3, 1, 2, 'Bölge 3, Eyalet 1, Ülke 2');
insert into bolgeler values (1, 2, 2, 'Bölge 1, Eyalet 2, Ülke 2');
insert into bolgeler values (2, 2, 2, 'Bölge 2, Eyalet 2, Ülke 2');
insert into bolgeler values (3, 2, 2, 'Bölge 3, Eyalet 2, Ülke 2');
insert into bolgeler values (1, 3, 2, 'Bölge 1, Eyalet 3, Ülke 2');
insert into bolgeler values (2, 3, 2, 'Bölge 2, Eyalet 3, Ülke 2');
insert into bolgeler values (3, 3, 2, 'Bölge 3, Eyalet 3, Ülke 2');
insert into bolgeler values (1, 1, 3, 'Bölge 1, Eyalet 1, Ülke 3');
insert into bolgeler values (2, 1, 3, 'Bölge 2, Eyalet 1, Ülke 3');
insert into bolgeler values (3, 1, 3, 'Bölge 3, Eyalet 1, Ülke 3');
insert into bolgeler values (1, 2, 3, 'Bölge 1, Eyalet 2, Ülke 3');
insert into bolgeler values (2, 2, 3, 'Bölge 2, Eyalet 2, Ülke 3');
insert into bolgeler values (3, 2, 3, 'Bölge 3, Eyalet 2, Ülke 3');
insert into bolgeler values (1, 3, 3, 'Bölge 1, Eyalet 3, Ülke 3');
insert into bolgeler values (2, 3, 3, 'Bölge 2, Eyalet 3, Ülke 3');
insert into bolgeler values (3, 3, 3, 'Bölge 3, Eyalet 3, Ülke 3');
commit work;

SQL buyruklarını içeren bir dosyayı pgsql ile aşağıdaki gibi verebilirsiniz:

\i dosya_adı

Buyrukları kopyala ve yapıştır yöntemiyle de verebilirdik.

Şimdi var olan bölgeleri görelim:

manu=> select * from bolgeler;
ulke_kodu|eyalet_kodu|bolge_kodu|bolge_adi
---------+-----------+----------+----------------------------
        1|          1|         1|Bölge 1, Eyalet 1, Ülke 1
        2|          1|         1|Bölge 2, Eyalet 1, Ülke 1
        3|          1|         1|Bölge 3, Eyalet 1, Ülke 1
        1|          2|         1|Bölge 1, Eyalet 2, Ülke 1
        2|          2|         1|Bölge 2, Eyalet 2, Ülke 1
        3|          2|         1|Bölge 3, Eyalet 2, Ülke 1
        1|          3|         1|Bölge 1, Eyalet 3, Ülke 1
        2|          3|         1|Bölge 2, Eyalet 3, Ülke 1
        3|          3|         1|Bölge 3, Eyalet 3, Ülke 1
        1|          1|         2|Bölge 1, Eyalet 1, Ülke 2
        2|          1|         2|Bölge 2, Eyalet 1, Ülke 2
        3|          1|         2|Bölge 3, Eyalet 1, Ülke 2
        1|          2|         2|Bölge 1, Eyalet 2, Ülke 2
        2|          2|         2|Bölge 2, Eyalet 2, Ülke 2
        3|          2|         2|Bölge 3, Eyalet 2, Ülke 2
        1|          3|         2|Bölge 1, Eyalet 3, Ülke 2
        2|          3|         2|Bölge 2, Eyalet 3, Ülke 2
        3|          3|         2|Bölge 3, Eyalet 3, Ülke 2
        1|          1|         3|Bölge 1, Eyalet 1, Ülke 3
        2|          1|         3|Bölge 2, Eyalet 1, Ülke 3
        3|          1|         3|Bölge 3, Eyalet 1, Ülke 3
        1|          2|         3|Bölge 1, Eyalet 2, Ülke 3
        2|          2|         3|Bölge 2, Eyalet 2, Ülke 3
        3|          2|         3|Bölge 3, Eyalet 2, Ülke 3
        1|          3|         3|Bölge 1, Eyalet 3, Ülke 3
        2|          3|         3|Bölge 2, Eyalet 3, Ülke 3
        3|          3|         3|Bölge 3, Eyalet 3, Ülke 3
(27 rows)
manu=>
Sonuç 27 satırdan oluştu ve şu anda pgsql bizden bir sonraki buyruğu vermemizi beklemektedir. Aşağıdaki buyruğu deneyin:
manu=> select * from ulkeler, eyaletler;
ulke_kodu  |adi   |eyalet_kodue|ulke_kodu|eyalet_adi
-----------+------+------------+---------+------------------
          1|ülke 1|           1|        1|Eyalet 1, Ülke 1
          2|ülke 2|           1|        1|Eyalet 1, Ülke 1
          3|ülke 3|           1|        1|Eyalet 1, Ülke 1
          1|ülke 1|           2|        1|Eyalet 2, Ülke 1
          2|ülke 2|           2|        1|Eyalet 2, Ülke 1
          3|ülke 3|           2|        1|Eyalet 2, Ülke 1
          1|ülke 1|           1|        2|Eyalet 1, Ülke 2
          2|ülke 2|           1|        2|Eyalet 1, Ülke 2
          3|ülke 3|           1|        2|Eyalet 1, Ülke 2
          1|ülke 1|           2|        2|Eyalet 2, Ülke 2
          2|ülke 2|           2|        2|Eyalet 2, Ülke 2
          3|ülke 3|           2|        2|Eyalet 2, Ülke 2
          1|ülke 1|           1|        3|Eyalet 1, Ülke 3
          2|ülke 2|           1|        3|Eyalet 1, Ülke 3
          3|ülke 3|           1|        3|Eyalet 1, Ülke 3
          1|ülke 1|           2|        3|Eyalet 2, Ülke 3
          2|ülke 2|           2|        3|Eyalet 2, Ülke 3
          3|ülke 3|           2|        3|Eyalet 2, Ülke 3
(18 rows)
18 satır mı? Ama bu nasıl olur? Biz sadece 3 ülke ve 6 eyalet girmiştik. Nasıl oluyor da 18 satır elde ediyoruz?

Son buyruk, iki tablonun birleşimini oluşturdu. pgsql'e birleşimde kullanılacak kuralı belirtmediğimizden, ulkeler ve eyaletler tablosunu ilişkilendiren pgsql, oluşabilecek tüm olasılıkları yarattı. 3 adet ülke ile 6 adet eyaleti çarptığınızda toplam 18 adet kayıt ortaya çıkar. Bu sonuç hem mantıksız ve hem de kullanışsızdır. İyisimi biz, aşağıdaki gibi yapalım:

manu=> select * from ulkeler, eyaletler
manu-> where ulkeler.ulke_kodu = eyaletler.ulke_kodu;
ulke_kodu  |adı   |eyalet_kodu|ulke_kodu|eyalet_adi
----------+-------+---------+-----------+------------------
          1|ülke 1|        1|          1|Eyalet 1, Ülke 1
          1|ülke 1|        2|          1|Eyalet 2, Ülke 1
          2|ülke 2|        1|          2|Eyalet 1, Ülke 2
          2|ülke 2|        2|          2|Eyalet 2, Ülke 2
          3|ülke 3|        1|          3|Eyalet 1, Ülke 3
          3|ülke 3|        2|          3|Eyalet 2, Ülke 3
(6 rows)
Evet, bu sonuç daha akla yatkın gelmeye başladı. Toplam altı satır, doğru, öyle değil mi?

Evet, toplam altı bölge var ve herbiri bir ülkede bulunmaktadır. Sonucun toplam bölge sayısı kadar çıkması akla yatkın, çünkü bölgelerin bir özelliği ülke içerisinde bulunmalarıdır. Ülkeler tablosuyla bölgeler tablosunu ülke kodu aracılığı ile ilişkilendiriyoruz. Hatırlarsanız, ülkeler ve bölgeler tablolarının her ikisinde de ait oldukları ülkenin kodu bulunmaktadır.

Neden ulkeler.ulke_kodu = eyaletler.ulke_kodu ?

Hem ulkeler ve hem de bölgeler tablosundaki ulke_kodu aynı isme sahiptir:

ulke_kodu=ulke_kodu
yazsaydık mantıksız olurdu, çünkü yorumlayıcı, hangisinin hangi tabloya ait olduğunu bilemezdi ve aşağıdaki gibi bir hata elde ederdiniz:
select * from ulkeler, eyaletler
        where ulke_kodu = ulke_kodu;

ERROR:  Column ulke_kodu is ambiguous
Sütun isimleri için başka isimler de kullanabiliriz:
manu=> select * from ulkeler a, eyaletler b
manu-> where a.ulke_kodu = b.ulke_kodu;
ulke_kodu|adi        |eyalet_kodu|ulke_kodu|eyalet_adi
-----------+---------+---------+-----------+------------------
          1|ülke 1|        1|          1|Eyalet 1, Ülke 1
          1|ülke 1|        2|          1|Eyalet 2, Ülke 1
          2|ülke 2|        1|          2|Eyalet 1, Ülke 2
          2|ülke 2|        2|          2|Eyalet 2, Ülke 2
          3|ülke 3|        1|          3|Eyalet 1, Ülke 3
          3|ülke 3|        2|          3|Eyalet 2, Ülke 3
(6 rows)
Pek iyi, veritabanı yöneticisinden elde ettiğimiz sonuç nedir?
ulke_kodu, adi, eyalet_kodu, ulke_kodu eyalet_adi.

"select * from ulkeler, eyaletler" sorgusunda HERŞEY anlamına gelen * işaretini kullandığımızdan, ülkeler tablosundaki iki ve eyaletler tablosundaki üç sütunu birlikte elde ettik. Şimdi ise, daha belirleyici olalım:

manu=> select a.ulke_kodu, eyalet_kodu, adi, eyalet_adi
manu-> from ulkeler a, eyaletler b
manu-> where a.ulke_kodu = b.ulke_kodu;
ulke_kodu  |eyalet_kodu|adi    |eyalet_adi
-----------+---------+---------+------------------
          1|        1|ülke 1|Eyalet 1, Ülke 1
          1|        2|ülke 1|Eyalet 2, Ülke 1
          2|        1|ülke 2|Eyalet 1, Ülke 2
          2|        2|ülke 2|Eyalet 2, Ülke 2
          3|        1|ülke 3|Eyalet 1, Ülke 3
          3|        2|ülke 3|Eyalet 2, Ülke 3
(6 rows)
Son sorgumuzda, ülke kodu, eyalet kodu, ülke ve eyalet adlarını belirtmiştik. Dikkat ederseniz, a.ulke_kodu gibi bazı sütunlar özel isimlendirilmiş, eyalet_adi gibi bazıları da isimlerini korumuşlardır. Bunun nedeni, ulke_kodu alanının her iki tabloda da yer almasıdır. Buna karşın olarak eyalet_adi sadece eyaletler tablosunda bulunmaktadır. Sadece bir defa yer alan alan isimlerinin özel isimlendirilmesine gerek yoktur.

İsterseniz olayı biraz daha karıştıralım:

manu=> select a.ulke_kodu, eyalet_kodu, adi, eyalet_adi
manu-> from ulkeler a, eyaletler b
manu-> where a.ulke_kodu = b.ulke_kodu
manu-> and a.ulke_kodu = 3;
ulke_kodu  |eyalet_kodu|adi     |eyalet_adi
-----------+---------+---------+------------------
          3|        1|ülke 3|Eyalet 1, Ülke 3
          3|        2|ülke 3|Eyalet 2, Ülke 3
(2 rows)
Bu sefer, sorgumuzu 3 numaralı ülke ile sınırlamış olduk.  

Fonksiyonlar

Aşağıda, satır sayısını veren count() fonksiyonunun kullanımına bir örnek görmektesiniz:
select count(*) from eyaletler;

count
-----
   27
(1 row)
Sorgu, bölgeler tablosundaki satır sayısını vermektedir.
manu=> select ulke_kodu, count(*) from eyaletler
manu-> group by cod_ülke;
ulke_kodu  |count
-----------+-----
          1|    2
          2|    2
          3|    2
(3 rows)
Sorgusu, AYNI ülke koduna sahip satırların sayısını vermektedir. ulke_kodu alanının burada kullanılmasının nedeni budur.

İşte size daha güzel bir örnek:

manu=> select adi, count(*) from ulkeler a, eyaletler b
manu-> where a.ulke_kodu = b.ulke_kodu
manu-> group by adi;
adi      |count
---------+-----
ülke 1|    2
ülke 2|    2
ülke 3|    2
(3 rows)
Biz yine aynı üç satırı elde ediyoruz, ancak bu sefer sonuç daha açıklayıcıdır.

Güzel, şimdiye kadar sadece ısınma harekleri yaptık ve konuya giriş nitelindiğinde örnekler verdik:-)

 

Kavramların gözden geçirilmesi

Şimdiye kader SQL'in bazı temel kavramlarına deyindik. Burada en önemli olan nokta, SQL'in kendisidir. Artık belli verilerle değil, veri elemanlarıyla çaılışıyoruz. Veri elemanı, veritabanının soyut bir kavramıdır. Eğer, basitçe ifade etmek gerekirse : "Var olanların içinden sadece bir kısmını elde et."

Şimdiye kadar görmüş olduğumuz buyrukları aşağıda özetledik:

CREATE TABLE Bu buyruk, alanlarıyla birlikte bir tablo yaratmaktadır.
DROP TABLE Tabloyu yok etmekte.
SELECT Sadece ilgili alanlarının verileriyle doldurulmuş geçici bir tablo yaratan bu buyruk, SQL'in temelidir. SELECT buyruğu, fonksiyon, karmaşık ifadeler ve alt select'ler olmak üzere, çeşitli paremetreler alabilir:
select count(*) from eyaletler
    where ulke_kodu in (select ulke_kodu from ulkeler);

count
-----
   27
(1 row)
BEGIN WORK Bu da temel buyruklardan biridir. Buyruğu vermekle, veritabanı yöneticisine BEGIN WORK anına kadar yapılan TÜM değişikliklerin onaylandığını ve yerine getirilmesi emrini vermekteyiz. Bizim kullandığımız veritabanı yöneticisi, BEGIN WORK hareketlerin başını işaretlemektedir. Diğer bazı veritabanı yöneticilerinde ise, veri değiştirilmesine yönelik ilk buyruk verildiğinde bu işaret konulmaktadır. PostgreSQL'de ise, BEGIN WORK buyruğu verilmediğinde, veri değiştirilmesine yönelik tüm buyruklar doğrudan iş görecektir.

Uyarı: veritabanı yapısını (schema) değiştirmeye yarayan buyruklar, COMMIT WORK buyruğunu kendiliğinden vermektedir. Bu yüzden, BEGIN WORK buyruğu ile hareketler başlatılmış ve veritabanı yapısını değiştirmeye yönelik buyruklardan bir verilmişse, hareketler hemen durudurulmakta ve daha sonra ROLLBACK WORK buyruğunu vermek bir işe yaramamaktadır. Yapılan değişiklikler geriye alınamamaktadır.

Kullanıcılardan biri hareketler içerisinde iken, bu kullanıcı diğer kullanıcılarının, kendi verilerine olan erişimi aşağıdaki gibi tanımlayabilir:

  • Değiştirilmiş verilere olan erişime izin ver.
  • Transaksiyondan önceki asıl verilere erişmesini sağla.
  • Veri erişimini engelle.
COMMIT WORK Değiştirilmiş verileri veritabanı içerinde etkin kılarak, hareketleri sonlandırır. ROLLBACK WORK buyruğu ise, hareketlerin başında veriler ne durumda ise, o duruma geri dönülmesini sağlar. Başka bir deyişle, yapılan değişiklikleri iptal eder.


Hata oluştuğunda, hareketler içerisinde yapılan değişiklikleri iptal edilebiliniyorsa, hareketler çok önemli bir araçtır. İsterseniz bu işlemi deneyebiliriz. Önceki hareketleri sonlandırmak için rollback work buyruğunu vermeliyiz:
manu=> select * from ulkeler;
ulke_kodu|adi
-----------+---------
          1|ülke 1
          2|ülke 2
          3|ülke 3
(3 rows)
Üç adet satır var.
begin work;
Transaksiyon başlangıcı işaretler.
insert into ulkeler values (5, 'Ülke gerçek değil');
Bir satır ekledik. Bu satırın gerçekte eklenip eklenmediğine bir bakalım:
manu=> select * from ulkeler;
ulke_kodu|adi
-----------+----------------
          1|ülke 1
          2|ülke 2
          3|ülke 3
          5|Ülke gerçek değil
(4 rows)
Tüm satırlar tamam. Daha sonra
rollback work;
buyruğuyla, hareketleri iptal edelim ve
manu=> select * from ulkeler;
ulke_kodu|adi
-----------+---------
          1|ülke 1
          2|ülke 2
          3|ülke 3
(3 rows)
satır sayısına baktığımızda, tabloda sadece eski satırların, yani 3 adet satırın yer aldığını görürüz.

INSERT Bu buyruk, daha önce de gördüğümüz gibi, bir tabloya kayıt veya satır girilmesini sağlar.
CREATE TABLE Önemli buyruklardan biri daha. Buyruk, bir tabloyu alanlarıyla birlikte yaratılmasını sağlamaktadır. Alanların sahip olabilecekleri veri türleri aşağıda verilmiştir:
char(sığa): Karakter ve sayıların saklanmasından kullanılan ve sabit sayıda (sığa 1,2,3,4 vs değerlerini alabilir.) karakter alabilen bir veri türüdür.
varchar(sığa): Karakter ve sayıların saklanmasından kullanılan ve en fazla sığa kadar sayıda (sığa 1,2,3,4 vs değerlerini alabilir.) karakter alabilen değişken uzunlukta bir veri türüdür. En fazla 30 byte uzunluğunda olabilir.
int2: İki byte bellek kaplayan ve -2**-15 ile 2**15 aralığında tam sayı değerleri alabilen bir veri türüdür.
int4: Dört byte bellek kaplayan ve -2**-31 ile 2**31 aralığında tam sayı değerleri alabilen bir veri türüdür.
money: Sabit uzunluklu sayısal veri türüdür. Sözgelimi, money(6,3) olarak tanımlanırsa, 6 basamak virgülden önce, 3 basamak da virgülden sonrasına, yani küsürata ayrılmış olacaktır.
time: HH:MM:SS:CCC saat, dakika, saniye ve saniyenin binde biri şeklinde zaman değeri alabilen bir veri türüdür.
date: YYYY/MM/DD yıl, ay ve gün şeklinde tarih değeri alabilen bir veri türüdür.
timestamp: Bu yukarıdaki time ve date veri türlerinin bir bileşimini, YYYY/MM/DD:HH:MM:SS:CCC şekklinde alabilen bir veri türüdür.
float(n): Duyarlığı az gerçek sayı alabilen bir veri türüdür.
float3: float'un iki katı duyarlığa sahip ve gerçek sayı alabilen bir veri türüdür.
Veri türü tanımlamaları veritabanı yöneticileri arasında farklılık göstermektedir. Ancak, çeşitli veri türlerini ve özelliklerini tanımlayan bir SQL ölçünü (standardı) (Sonuncusunun adı ANSI/92 veya SQL/3 idi.) da vardır. Bu kurs içerisinde SQL veri türlerinden PostgreSQL'e özgü sadece bir iki adedini göreceğiz.
DELETE Tablodaki satırların silinmesini sağlar.
UPDATE Bir tablonun satırlarında yer alan alanların değiştirilmesini sağlar.
 

Özet

Garip anlatımıma karşın, bir ilişkisel veritabanı yüklemiş ve SQL'e giriş yapmış olduk.

SQL, verilerin üzerine soyut bir katman yaratmamızı ve verilere olan erişimi istediğimiz doğrultuda yapmamızı sağlamaktadır.

Buraya kadar anlatılanlardan akla şu soru gelebilir: SQL uygulamalar içerisinde nasıl kullanılıyor?

Sorunun yanıtı, C ile SQL kullanımı hakkında yazacağımız bir yazıda verilecektir.


Görselyöre sayfalarının bakımı, LinuxFocus Editörleri tarafından yapılmaktadır.
© Manuel Soriano, FDL
LinuxFocus.org
Çeviri bilgisi:
es --> -- : Manuel Soriano <manu(at)europa3.com>
es --> en: Miguel A Sepulveda <sepulveda(at)linuxfocus.org>
en --> tr : Erdal Mutlu <erdal(at)linuxfocus.org>