MsSQL

SQL’de Veritabanı İlişkileri ve Normalizasyon

SQL tabanlı veritabanlarında veri bütünlüğünü ve tutarlılığını sağlamanın iki temel taşı, veritabanı ilişkileri ve normalizasyondur. Bu kavramlar, verilerin nasıl depolandığını, birbirleriyle nasıl bağlantı kurduğunu ve gereksiz tekrarların nasıl önlendiğini belirler. Etkili bir veritabanı tasarımı, performansı optimize ederken veri anormalliklerini minimize eder, bu da daha güvenilir ve yönetilebilir sistemler oluşturmanın anahtarıdır. Bu makale, her iki konuyu derinlemesine inceleyecektir.

Veritabanı İlişkilerine Derinlemesine Bakış

Veritabanı ilişkileri, bir ilişkisel veritabanındaki tabloların birbirleriyle nasıl etkileşim kurduğunu tanımlar. Bu ilişkiler, veriler arasındaki mantıksal bağlantıları kurar ve veri bütünlüğünü korumak için hayati öneme sahiptir. Temelde, bir tablonun birincil anahtarı (Primary Key – PK) ile başka bir tablonun yabancı anahtarı (Foreign Key – FK) arasındaki bağlantılar aracılığıyla kurulurlar. Yabancı anahtar, diğer tablodaki birincil anahtara referans vererek iki tablo arasında bir köprü görevi görür.

Bire Bir (One-to-One) İlişki

Bire bir ilişki, bir tablodaki her bir kaydın, ilişkili olduğu diğer tablodaki yalnızca bir kayıtla eşleştiği durumu ifade eder. Bu tür ilişkiler genellikle iki ana nedenden kullanılır: ya çok fazla sütunu olan bir tabloyu bölerek yönetilebilirliği artırmak için ya da hassas verileri ayrı bir tabloda tutarak güvenliği artırmak için. Örneğin, bir Kullanicilar tablosundaki her kullanıcının yalnızca bir KullaniciDetaylari kaydı olabilir. Bu durumda, KullaniciDetaylari tablosunda, Kullanicilar tablosundaki KullaniciID‘yi referans gösteren bir yabancı anahtar bulunur ve bu yabancı anahtara bir benzersiz (UNIQUE) kısıtlaması eklenerek bire bir ilişki sağlanır.


CREATE TABLE Kullanicilar (
    KullaniciID INT PRIMARY KEY,
    KullaniciAdi VARCHAR(50) UNIQUE,
    Eposta VARCHAR(100)
);

CREATE TABLE KullaniciDetaylari (
    DetayID INT PRIMARY KEY,
    KullaniciID INT UNIQUE, -- Bire Bir ilişki için UNIQUE kısıtlaması
    Adres VARCHAR(255),
    Telefon VARCHAR(20),
    FOREIGN KEY (KullaniciID) REFERENCES Kullanicilar(KullaniciID)
);

Bire Çok (One-to-Many) İlişki

Bire çok ilişki, en yaygın veritabanı ilişkisi türüdür. Bu ilişkide, bir tablodaki tek bir kayıt, başka bir tablodaki birden fazla kayıtla ilişkilendirilebilir, ancak diğer tablodaki her bir kayıt, ilk tablodaki yalnızca bir kayıtla ilişkilendirilir. Örneğin, bir Musteriler tablosundaki bir müşteri, Siparisler tablosunda birden fazla siparişe sahip olabilir, ancak her sipariş yalnızca bir müşteriye aittir. Bu ilişki, Siparisler tablosunda Musteriler tablosunun birincil anahtarını (MusteriID) referans gösteren bir yabancı anahtar (MusteriID) tanımlanarak kurulur.


CREATE TABLE Musteriler (
    MusteriID INT PRIMARY KEY,
    Ad VARCHAR(50),
    Soyad VARCHAR(50)
);

CREATE TABLE Siparisler (
    SiparisID INT PRIMARY KEY,
    MusteriID INT, -- Yabancı anahtar
    SiparisTarihi DATE,
    ToplamTutar DECIMAL(10, 2),
    FOREIGN KEY (MusteriID) REFERENCES Musteriler(MusteriID)
);

Çoka Çok (Many-to-Many) İlişki

Çoka çok ilişki, bir tablodaki birden fazla kaydın, başka bir tablodaki birden fazla kayıtla ilişkilendirilebildiği durumu ifade eder. Bu tür ilişkiler doğrudan iki tablo arasında kurulamaz; bunun yerine, genellikle “ilişki tablosu” veya “birleştirici tablo” (junction table) adı verilen üçüncü bir aracı tablo kullanılarak çözülür. Örneğin, bir öğrenci birden fazla ders alabilir ve bir ders birden fazla öğrenciye sahip olabilir. Bu durumu yönetmek için Ogrenciler, Dersler ve OgrenciDersleri adında bir tabloya ihtiyaç duyulur. OgrenciDersleri tablosu, Ogrenciler tablosundan OgrenciID‘yi ve Dersler tablosundan DersID‘yi yabancı anahtar olarak içerir ve genellikle bu iki anahtarın birleşimi birincil anahtarı oluşturur.


CREATE TABLE Ogrenciler (
    OgrenciID INT PRIMARY KEY,
    Ad VARCHAR(50),
    Soyad VARCHAR(50)
);

CREATE TABLE Dersler (
    DersID INT PRIMARY KEY,
    DersAdi VARCHAR(100),
    Kredi INT
);

CREATE TABLE OgrenciDersleri (
    OgrenciID INT,
    DersID INT,
    PRIMARY KEY (OgrenciID, DersID), -- Bileşik birincil anahtar
    FOREIGN KEY (OgrenciID) REFERENCES Ogrenciler(OgrenciID),
    FOREIGN KEY (DersID) REFERENCES Dersler(DersID)
);

Veritabanı Normalizasyonu: Temeller ve Formlar

Normalizasyon, bir veritabanı tasarımını, veri yedekliliğini (redundancy) azaltmak ve veri anormalliklerini (anomalies) önlemek amacıyla belirli kurallar veya “normal formlar” çerçevesinde düzenleme sürecidir. Temel amacı, veri bütünlüğünü sağlamak, veritabanı boyutunu optimize etmek ve ekleme, güncelleme ve silme işlemlerinde ortaya çıkabilecek tutarsızlıkları minimize etmektir. Normalizasyon, bir tablonun hangi formda olduğunu belirlemek için fonksiyonel bağımlılıkları inceler.

  • Ekleme Anormalliği (Insertion Anomaly): Yeni bir veri eklerken, ilgisiz veya eksik veri eklemek zorunda kalma.
  • Silme Anormalliği (Deletion Anomaly): Bir veriyi silerken, başka değerli bir verinin de yanlışlıkla silinmesi.
  • Güncelleme Anormalliği (Update Anomaly): Bir veriyi güncellerken, aynı verinin birden fazla yerde tutulması nedeniyle tüm kopyalarını güncellemeyi unutma ve tutarsızlık yaşanması.

Birinci Normal Form (1NF)

Bir tablonun 1NF’de olabilmesi için şu koşulları sağlaması gerekir:

  1. Her hücrede atomik (bölünemez) değerler bulunmalıdır. Yani, bir hücrede birden fazla değer veya virgülle ayrılmış değerler olmamalıdır.
  2. Her bir sütunun tek bir veri türü olmalı ve tekrarlayan gruplar içermemelidir.
  3. Her bir satır benzersiz olmalıdır (bir birincil anahtar ile tanımlanabilir).

Örnek olarak, bir Calisanlar tablosunda TelefonNumaralari sütunu, bir çalışanın birden fazla telefon numarasına sahip olabileceği ve bunları virgülle ayırarak tuttuğu bir yapı 1NF’ye aykırıdır. Bu durumda, her telefon numarası için ayrı bir satır oluşturulmalı veya telefon numaraları için ayrı bir tablo oluşturulmalıdır.

İkinci Normal Form (2NF)

Bir tablonun 2NF’de olabilmesi için şu koşulları sağlaması gerekir:

  1. 1NF’de olmalıdır.
  2. Anahtar olmayan (non-key) her öznitelik, birincil anahtarın tamamına fonksiyonel olarak bağlı olmalıdır. Yani, birincil anahtar bileşikse (birden fazla sütundan oluşuyorsa), anahtar olmayan hiçbir öznitelik birincil anahtarın yalnızca bir kısmına bağlı olmamalıdır. Bu durum “kısmi bağımlılık” olarak bilinir.

Örnek: Bir SiparisDetaylari tablosu (SiparisID, UrunID, Miktar, UrunAdi, UrunFiyati) birincil anahtarı (SiparisID, UrunID) olsun. Burada UrunAdi ve UrunFiyati sadece UrunID‘ye bağlıdır, SiparisID‘ye değil. Bu, kısmi bağımlılıktır. 2NF için UrunAdi ve UrunFiyati bilgilerini ayrı bir Urunler tablosuna taşımak gerekir.

Üçüncü Normal Form (3NF)

Bir tablonun 3NF’de olabilmesi için şu koşulları sağlaması gerekir:

  1. 2NF’de olmalıdır.
  2. Anahtar olmayan hiçbir öznitelik, birincil anahtarın başka bir anahtar olmayan özniteliğine geçişli (transitive) olarak bağlı olmamalıdır. Yani, A -> B ve B -> C bağımlılıkları varsa (burada A birincil anahtardır ve B anahtar olmayan bir özniteliktir), C özniteliği B’ye geçişli olarak bağlıdır.

Örnek: Bir Personel tablosu (PersonelID, Ad, Soyad, DepartmanAdi, DepartmanTelefonu) olsun ve PersonelID birincil anahtar olsun. Burada DepartmanTelefonu, DepartmanAdi‘na bağlıdır ve DepartmanAdi da PersonelID‘ye bağlıdır. Yani PersonelID -> DepartmanAdi -> DepartmanTelefonu bir geçişli bağımlılıktır. 3NF için DepartmanAdi ve DepartmanTelefonu bilgilerini ayrı bir Departmanlar tablosuna taşımak gerekir.

BCNF (Boyce-Codd Normal Form)

BCNF, 3NF’nin daha katı bir versiyonudur. Bir tablo BCNF’de olmak için 3NF’de olmalı ve ek olarak, her determinat (belirleyici), bir aday anahtar olmalıdır. Yani, bir öznitelik veya öznitelik kümesi başka bir öznitelik veya öznitelik kümesini belirliyorsa, bu belirleyici bir aday anahtar olmak zorundadır. Nadir durumlarda 3NF’de olan ancak BCNF’de olmayan tablolar ortaya çıkabilir, genellikle birden fazla çakışan aday anahtarın bulunduğu durumlar için geçerlidir.

İlişkiler ve Normalizasyonun SQL Uygulamaları

SQL, veritabanı ilişkilerini ve normalizasyon prensiplerini uygulamak için çeşitli mekanizmalar sunar. PRIMARY KEY, FOREIGN KEY ve UNIQUE kısıtlamaları bu yapının temelini oluşturur. PRIMARY KEY, bir tablodaki her satırı benzersiz şekilde tanımlarken, FOREIGN KEY bir tablonun başka bir tablodaki birincil anahtara referans vermesini sağlar ve bu sayede referans bütünlüğünü (referential integrity) korur. UNIQUE kısıtlaması ise, belirli bir sütundaki tüm değerlerin benzersiz olmasını garanti eder ve bire bir ilişkilerin kurulmasında rol oynayabilir.

Bu kısıtlamalar sayesinde, SQL veritabanı motoru, tanımlanan ilişkisel kurallara uymayan herhangi bir veri değişikliğini (ekleme, güncelleme, silme) otomatik olarak reddeder. Örneğin, bir Musteriler tablosunda olmayan bir MusteriID ile Siparisler tablosuna kayıt eklemeye çalışmak, bir yabancı anahtar kısıtlaması ihlaline yol açar ve işlem başarısız olur. Bu, veri tutarlılığının sağlanmasında kritik bir rol oynar.

Referans bütünlüğü kısıtlamaları, SQL’de ON DELETE ve ON UPDATE kuralları ile daha da esneklik kazanır:

  • CASCADE: Ana tablodaki kayıt silindiğinde/güncellendiğinde, ilişkili tablodaki tüm ilgili kayıtları da siler/günceller.
  • SET NULL: Ana tablodaki kayıt silindiğinde/güncellendiğinde, ilişkili tablodaki yabancı anahtar sütununu NULL yapar (eğer NULL değerine izin veriyorsa).
  • RESTRICT (varsayılan): İlişkili tablolarda ilgili kayıtlar varken ana tablodaki kaydın silinmesini/güncellenmesini engeller.
  • NO ACTION: RESTRICT’e benzer, ancak standartlar arasında küçük farkları olabilir.

-- Normalizasyon ve ilişkileri gösteren örnek tablo yapıları
CREATE TABLE Departmanlar (
    DepartmanID INT PRIMARY KEY,
    DepartmanAdi VARCHAR(100) UNIQUE,
    Lokasyon VARCHAR(100)
);

CREATE TABLE Calisanlar (
    CalisanID INT PRIMARY KEY,
    Ad VARCHAR(50),
    Soyad VARCHAR(50),
    DepartmanID INT, -- Yabancı anahtar
    Maas DECIMAL(10, 2),
    FOREIGN KEY (DepartmanID) REFERENCES Departmanlar(DepartmanID)
        ON DELETE RESTRICT ON UPDATE CASCADE -- İlişkisel eylemler
);

CREATE TABLE Projeler (
    ProjeID INT PRIMARY KEY,
    ProjeAdi VARCHAR(100),
    Butce DECIMAL(15, 2)
);

CREATE TABLE CalisanProjeleri (
    CalisanID INT,
    ProjeID INT,
    AtanmaTarihi DATE,
    PRIMARY KEY (CalisanID, ProjeID),
    FOREIGN KEY (CalisanID) REFERENCES Calisanlar(CalisanID) ON DELETE CASCADE,
    FOREIGN KEY (ProjeID) REFERENCES Projeler(ProjeID) ON DELETE CASCADE
);

Veritabanı ilişkileri ve normalizasyon, modern SQL veritabanı tasarımının temel taşlarıdır. Doğru ilişkileri kurmak ve veritabanını uygun normal formlara getirmek, veri bütünlüğünü artırır, veri tekrarlarını azaltır ve olası anormallikleri önler. Bu prensipler, daha sağlam, ölçeklenebilir ve yönetilebilir veritabanı sistemleri oluşturarak uygulamanın performansını ve güvenilirliğini doğrudan etkiler. Bu nedenle, her veritabanı geliştiricisinin bu kavramlara hakim olması kritik öneme sahiptir.


SQL’de Görünümler (VIEW) ve Sanal Tablolar

SQL veritabanlarında Görünümler (VIEW), kullanıcıların veya uygulamaların temel tablolardaki verilere daha organize, güvenli ve basitleştirilmiş bir şekilde erişmesini sağlayan güçlü araçlardır. Fiziksel olarak veri depolamazlar ancak bir veya daha fazla tablodan türetilmiş, önceden tanımlanmış bir sorgunun sonucunu sunan sanal tablolar olarak işlev görürler. Bu “sanal tablolar”, veri erişimini soyutlayarak karmaşıklığı azaltır ve güvenlik katmanları ekler.

Görünüm (View) Nedir?

Bir Görünüm, temel (fiziksel) tablolardaki belirli verileri mantıksal olarak temsil eden, ancak kendisi veri depolamayan sanal bir tablodur. Temelde, bir SQL sorgusunun kaydedilmiş halidir. Bir görünüm sorgulandığında, kaydedildiği zaman tanımlanan temel sorgu çalıştırılır ve sonucu tıpkı fiziksel bir tabloymuş gibi döndürülür. Bu sayede, kullanıcılar veya uygulamalar, karmaşık join’ler, filtrelemeler veya hesaplamalar içerebilen bir dizi temel tablo yerine basitçe görünüme sorgu gönderebilirler.

Görünümler Neden Kullanılır?

Görünümlerin kullanımı, veritabanı yönetiminde birçok avantaj sunar:

Veri Güvenliği

Görünümler, hassas verilerin gizlenmesi için etkili bir yöntem sunar. Örneğin, bir personel tablosu maaş veya kişisel bilgileri içerebilir. Bu bilgilere tüm kullanıcıların erişmesi gerekmeyebilir. Bir görünüm oluşturarak, yalnızca belirli sütunlara (örn. Ad, Soyad, Departman) veya belirli satırlara (örn. Yalnızca kendi departmanının çalışanları) erişimi kısıtlayabilirsiniz. Böylece, kullanıcılara doğrudan temel tablolara erişim izni vermek yerine görünümlere erişim izni verilerek güvenlik artırılır.


CREATE VIEW CalisanPublicBilgiler AS
SELECT CalisanID, Ad, Soyad, Departman
FROM Calisanlar;

Karmaşık Sorguları Basitleştirme

Birden fazla tablodan veri birleştiren, filtreleyen veya hesaplamalar içeren karmaşık SQL sorguları, görünümler aracılığıyla basitleştirilebilir. Geliştiriciler veya son kullanıcılar, bu karmaşık mantığı her seferinde yeniden yazmak zorunda kalmadan, önceden tanımlanmış görünümleri basit bir SELECT deyimiyle sorgulayabilirler. Bu, sorgu geliştirme süresini azaltır ve hataları minimize eder.


CREATE VIEW MusteriSiparisOzeti AS
SELECT
    M.MusteriAd,
    S.SiparisTarihi,
    SUM(SD.Miktar * U.BirimFiyat) AS ToplamTutar
FROM
    Musteriler M
JOIN
    Siparisler S ON M.MusteriID = S.MusteriID
JOIN
    SiparisDetaylari SD ON S.SiparisID = SD.SiparisID
JOIN
    Urunler U ON SD.UrunID = U.UrunID
GROUP BY
    M.MusteriAd, S.SiparisTarihi;

Artık bu karmaşık sorgu yerine sadece SELECT * FROM MusteriSiparisOzeti; kullanılabilir.

Veri Soyutlama ve Tutarlılık

Görünümler, temel tablolardaki yapısal değişikliklerin (örneğin, bir sütunun adı değiştirildiğinde veya yeni bir tablo eklendiğinde) uygulamaları doğrudan etkilemesini engelleyebilir. Görünüm, temel tablolardaki değişikliklere rağmen aynı çıktıyı sağlayacak şekilde yeniden tanımlanabilir. Bu, uygulamaların temel veri yapısından soyutlanmasını sağlayarak veri bağımsızlığını artırır ve tutarlı bir arayüz sunar.

Yeniden Kullanılabilir Mantık

Belirli bir iş kuralını veya veri perspektifini içeren bir sorgu, bir görünüm olarak tanımlanarak veritabanının farklı bölümlerinde veya farklı uygulamalarda tekrar tekrar kullanılabilir. Bu, kod tekrarını önler ve bakım kolaylığı sağlar.

Görünüm Oluşturma ve Güncelleme

Bir görünüm, CREATE VIEW komutuyla oluşturulur. Mevcut bir görünümün tanımını değiştirmek için ALTER VIEW veya CREATE OR REPLACE VIEW (destekleyen veritabanlarında) kullanılır. Bir görünümü kaldırmak için ise DROP VIEW komutu kullanılır.


-- Görünüm Oluşturma
CREATE VIEW AktifMusteriler AS
SELECT MusteriID, Ad, Soyad, Email
FROM Musteriler
WHERE Durum = 'Aktif';

-- Görünüm Güncelleme (ALTER VIEW)
ALTER VIEW AktifMusteriler AS
SELECT MusteriID, Ad, Soyad, Email, Telefon
FROM Musteriler
WHERE Durum = 'Aktif';

-- Görünüm Güncelleme (CREATE OR REPLACE VIEW) - PostgreSQL, Oracle
CREATE OR REPLACE VIEW AktifMusteriler AS
SELECT MusteriID, Ad, Soyad, Email, Telefon
FROM Musteriler
WHERE Durum = 'Aktif' AND KayitTarihi > '2023-01-01';

-- Görünüm Silme
DROP VIEW AktifMusteriler;

Güncellenebilir Görünümler (Updatable Views)

Tüm görünümler güncellenebilir değildir. Bir görünüm aracılığıyla temel tablolardaki verileri INSERT, UPDATE veya DELETE işlemleriyle değiştirebilmek için belirli koşulların sağlanması gerekir:

  • Görünüm tek bir temel tabloya dayanmalıdır.
  • Görünüm, DISTINCT, GROUP BY, HAVING, kümeleme fonksiyonları (SUM, AVG, COUNT) veya UNION gibi yapılar içermemelidir.
  • Görünüm, hesaplanmış sütunlar içermemelidir.
  • Join içeren görünümler genellikle güncellenemez (bazı veritabanları belirli koşullar altında basit join’li görünümlere izin verebilir).

WITH CHECK OPTION ifadesi, bir görünüm aracılığıyla eklenen veya güncellenen satırların görünümün WHERE koşuluna uymasını sağlar. Eğer uymazsa, işlem reddedilir.


CREATE VIEW DüsükMaasliCalisanlar AS
SELECT CalisanID, Ad, Soyad, Maas
FROM Calisanlar
WHERE Maas < 50000
WITH CHECK OPTION;

-- Bu işlem başarılı olur
INSERT INTO DüsükMaasliCalisanlar (CalisanID, Ad, Soyad, Maas)
VALUES (101, 'Ayşe', 'Yılmaz', 45000);

-- Bu işlem WITH CHECK OPTION nedeniyle başarısız olur
-- INSERT INTO DüsükMaasliCalisanlar (CalisanID, Ad, Soyad, Maas)
-- VALUES (102, 'Mehmet', 'Demir', 60000);

Sanal Tablolar ve Görünümler İlişkisi

“Sanal Tablo” terimi genellikle Görünüm (View) ile eş anlamlı olarak kullanılır. Görünümler, veri depolamadan, temel tabloların veya diğer görünümlerin verilerini bir sorgu sonucu olarak sunan mantıksal yapılardır. Bu nedenle, veritabanı sisteminde fiziksel olarak diskte yer kaplayan ve veri içeren “gerçek” tabloların aksine “sanal” bir tablo görünümü sunarlar.

Görünümler, geçici tablolar (temporary tables) veya tablo değerli fonksiyonlar (table-valued functions) ile karıştırılmamalıdır. Geçici tablolar, oturuma özel olarak oluşturulan ve veri depolayan fiziksel tablolardır. Tablo değerli fonksiyonlar ise, parametre alabilen ve bir tablo döndüren programatik bir yapıdır; bir sorgunun sonucunu döndürme konusunda görünümlere benzerler ancak daha dinamik ve parametre odaklıdırlar.

Performans ve Sınırlamalar

Görünümler, kendileri veri depolamadıkları için performansı doğrudan artırmazlar; bir görünüm sorgulandığında, altında yatan temel sorgu çalıştırılır. Çok karmaşık görünümler veya iyi indekslenmemiş temel tablolar üzerinde yapılan sorgular, performans sorunlarına yol açabilir. Bu gibi durumlarda, bazı veritabanı sistemleri “İndekslenmiş Görünümler” (SQL Server) veya “Materialized Views” (Oracle, PostgreSQL) gibi seçenekler sunar. Bu yapılar, görünümün sonucunu fiziksel olarak depolayarak sorgu performansını artırabilir, ancak bu durumda veri tazeliği ve depolama alanı gibi ek yönetim gereksinimleri ortaya çıkar.

SQL’deki görünümler veya sanal tablolar, veritabanı tasarımını ve yönetimini önemli ölçüde geliştiren vazgeçilmez araçlardır. Güvenliği artırırken karmaşık veri erişimini basitleştirir, veri soyutlama sağlayarak veritabanı yapısındaki değişikliklerin etkisini azaltır ve tekrar kullanılabilir mantık sunar. Görünümleri etkili bir şekilde kullanmak için onların nasıl çalıştığını, ne zaman güncellenebilir olduklarını ve performans etkilerini iyi anlamak, daha sağlam ve yönetilebilir veritabanı çözümleri oluşturmak için kritik öneme sahiptir.


SQL’de Alt Sorgular (Subquery) ve İç İçe Sorgular

SQL veritabanlarında karmaşık veri manipülasyonları ve sorgulamaları için güçlü bir araç olan alt sorgular (subquery) ve iç içe sorgular, temel SQL komutlarının ötesinde esneklik sunar. Bu yapılar, tek bir sorgu içinde birden fazla sorguyu birleştirerek daha spesifik ve detaylı sonuçlar elde etmemizi sağlar. Veri analizi, raporlama ve dinamik filtreleme gibi birçok senaryoda vazgeçilmez bir role sahiptirler, SQL yetkinliğinizi derinleştirmenin anahtarıdır.

Alt Sorgu (Subquery) Nedir?

Alt sorgu, bir SQL sorgusunun başka bir SQL sorgusunun içine gömülmesiyle oluşan yapıdır. Ana sorgu tarafından kullanılan bir değer, satır seti veya tablo seti döndürür. Genellikle parantez içine alınır ve ana sorgudan önce yürütülür (korele alt sorgular hariç). Alt sorgular, belirli bir koşulu karşılayan verileri filtrelemek, başka bir tablodan türetilmiş değerlerle karşılaştırmak veya dinamik olarak oluşturulan veri setlerini kullanmak için kullanılır.

Alt Sorguların Kullanım Alanları ve Türleri

Alt sorgular, SELECT, FROM, WHERE, HAVING cümlelerinde ve hatta INSERT, UPDATE, DELETE ifadelerinde kullanılabilir. Temel olarak üç ana türe ayrılırlar:

1. Skaler Alt Sorgular (Scalar Subqueries)

Tek bir değer (tek bir satır, tek bir sütun) döndüren alt sorgulardır. Genellikle SELECT veya WHERE cümlelerinde kullanılırlar.

Örnek: Belirli bir ürün kategorisindeki en yüksek fiyatı bulmak ve bu fiyata sahip ürünleri listelemek.

SELECT UrunAdi, Fiyat
FROM Urunler
WHERE Fiyat = (SELECT MAX(Fiyat) FROM Urunler WHERE KategoriID = 1);

Bu örnekte, (SELECT MAX(Fiyat) FROM Urunler WHERE KategoriID = 1) kısmı skaler bir alt sorgudur ve KategoriID’si 1 olan ürünlerin en yüksek fiyatını döndürür.

2. Satır Alt Sorguları (Row Subqueries)

Tek bir satır ancak birden fazla sütun döndüren alt sorgulardır. Genellikle WHERE veya HAVING cümlelerinde, karşılaştırma operatörleriyle (=, >, <) birlikte kullanılırlar.

Örnek: En yüksek fiyata sahip ürünün hem fiyatını hem de kategori ID’sini bulmak.

SELECT UrunAdi, Fiyat, KategoriID
FROM Urunler
WHERE (Fiyat, KategoriID) = (SELECT MAX(Fiyat), KategoriID FROM Urunler GROUP BY KategoriID ORDER BY MAX(Fiyat) DESC LIMIT 1);

Bu örnekte, ana sorgu sadece tek bir (Fiyat, KategoriID) ikilisi ile eşleşen bir ürünü döndürecektir. LIMIT 1 kullanımı, alt sorgunun tek bir satır döndürmesini sağlar.

3. Tablo Alt Sorguları (Table Subqueries)

Birden fazla satır ve birden fazla sütun döndüren alt sorgulardır. Genellikle FROM cümlesinde, türetilmiş bir tablo olarak kullanılırlar. Bunlara “İç İçe Sorgular” da denir ve geçici bir tablo gibi davranırlar.

Örnek: Her kategorideki ortalama ürün fiyatını bulup, bu ortalamadan daha pahalı olan ürünleri listelemek.

SELECT U.UrunAdi, U.Fiyat, K.KategoriAdi, OrtFiyatlar.OrtalamaFiyat
FROM Urunler U
INNER JOIN Kategoriler K ON U.KategoriID = K.KategoriID
INNER JOIN (
    SELECT KategoriID, AVG(Fiyat) AS OrtalamaFiyat
    FROM Urunler
    GROUP BY KategoriID
) AS OrtFiyatlar ON U.KategoriID = OrtFiyatlar.KategoriID
WHERE U.Fiyat > OrtFiyatlar.OrtalamaFiyat;

Bu örnekte, (SELECT KategoriID, AVG(Fiyat) AS OrtalamaFiyat FROM Urunler GROUP BY KategoriID) kısmı tablo alt sorgusudur ve her kategori için ortalama fiyatı hesaplayan bir türetilmiş tablo oluşturur. Bu türetilmiş tablo daha sonra ana sorgu ile birleştirilir.

Alt Sorguların Diğer Kullanım Senaryoları

WHERE ve HAVING ile Birlikte Kullanım:

  • IN, NOT IN, EXISTS, NOT EXISTS operatörleriyle sıkça kullanılırlar.

IN Örneği: Belirli bir şehirdeki müşterilerin verdiği siparişleri listele.

SELECT SiparisID, MusteriID, SiparisTarihi
FROM Siparisler
WHERE MusteriID IN (SELECT MusteriID FROM Musteriler WHERE Sehir = 'Ankara');

EXISTS Örneği: Hiç sipariş vermemiş müşterileri bul (Korele alt sorgu örneği).

SELECT MusteriAdi, Eposta
FROM Musteriler M
WHERE NOT EXISTS (SELECT 1 FROM Siparisler S WHERE S.MusteriID = M.MusteriID);

Burada, EXISTS ana sorgunun her satırı için iç sorguyu çalıştırır. Eğer iç sorgu herhangi bir sonuç döndürürse (EXISTS true olur), ana sorgu o satırı filtrelemez.

Korele (Correlated) Alt Sorgular:

Bu tür alt sorgular, dış (ana) sorgunun her satırı için bir kez çalışır ve dış sorgudan bir değer alır. Yukarıdaki EXISTS örneği buna güzel bir örnektir. Korele alt sorgular genellikle NOT EXISTS veya EXISTS ile birlikte kullanılır ve performansı etkileyebilirler, bu yüzden dikkatli kullanılmalıdırlar.

Örnek: Kendi kategorisindeki ortalama fiyattan daha pahalı olan ürünleri listele.

SELECT UrunAdi, Fiyat, KategoriID
FROM Urunler U1
WHERE Fiyat > (SELECT AVG(Fiyat) FROM Urunler U2 WHERE U2.KategoriID = U1.KategoriID);

Burada, U1.KategoriID ana sorgudan gelen bir değerdir ve iç sorgunun her çalışmasında değişir.

INSERT, UPDATE, DELETE ile Kullanım:

Alt sorgular, veri manipülasyonu (DML) ifadelerinde de dinamik değerler veya koşullar sağlamak için kullanılabilir.

INSERT Örneği: Bir tablodan seçilen verileri başka bir tabloya ekle.

INSERT INTO ArsivUrunler (UrunAdi, Fiyat, EklenmeTarihi)
SELECT UrunAdi, Fiyat, GETDATE() -- veya CURRENT_TIMESTAMP
FROM Urunler
WHERE StokAdedi = 0;

UPDATE Örneği: Belirli bir kategorideki ürün fiyatlarını, o kategorinin ortalama fiyatının %10 üzerine çıkar.

UPDATE Urunler U1
SET Fiyat = (SELECT AVG(Fiyat) * 1.10 FROM Urunler U2 WHERE U2.KategoriID = U1.KategoriID)
WHERE KategoriID IN (SELECT KategoriID FROM Kategoriler WHERE KategoriAdi = 'Elektronik');

Alt Sorguların Avantajları ve Dezavantajları

Avantajlar:

  • Kod Okunabilirliği: Karmaşık birleştirme (JOIN) işlemleri yerine, daha mantıksal ve okunabilir bir yol sunabilirler.
  • Modülerlik: Sorguyu daha küçük, yönetilebilir parçalara ayırır.
  • Esneklik: Neredeyse her SQL cümlesinde kullanılabilir ve çok çeşitli senaryolara uyum sağlar.
  • Dinamik Filtreleme: Statik değerler yerine dinamik olarak hesaplanan değerlerle filtreleme imkanı sunar.

Dezavantajlar:

  • Performans: Özellikle korele alt sorgular veya çok fazla iç içe geçmiş alt sorgular, performansı olumsuz etkileyebilir. Her dış satır için yeniden çalıştırılma maliyeti olabilir.
  • Anlaşılabilirlik (Yanlış Kullanımda): Aşırı iç içe geçmiş veya kötü yazılmış alt sorgular, okunabilirliği ve hata ayıklamayı zorlaştırabilir.
  • Alternatifler: Bazı durumlarda JOIN işlemleri, CTE’ler (Common Table Expressions) veya türetilmiş tablolar, alt sorgulara göre daha performanslı veya okunabilir çözümler sunabilir.

Ne Zaman ve Nasıl Kullanmalı?

Alt sorgular, bir değeri veya bir dizi değeri başka bir sorgunun sonucu olarak dinamik olarak belirlemeniz gerektiğinde idealdir. Genellikle, bir tablodaki veriyi aynı tablodaki veya başka bir tablodaki diğer verilerle karşılaştırmanız gerektiğinde tercih edilir. Performans endişesi taşıdığınızda, özellikle büyük veri setlerinde, alt sorguyu birleştirme (JOIN) işlemine dönüştürmenin mümkün olup olmadığını veya CTE kullanıp kullanamayacağınızı düşünmek faydalı olacaktır.

Sonuç

SQL’deki alt sorgular ve iç içe sorgular, veri manipülasyonunda ve analizinde esneklik ile güç sağlayan temel yapılardır. Skaler, satır ve tablo alt sorguları gibi çeşitli türleriyle, karmaşık iş mantığını tek bir sorgu içinde ifade etmenizi mümkün kılarlar. Doğru anlaşıldığında ve uygun şekilde kullanıldığında, SQL sorgularınızın okunabilirliğini artırırken, dinamik ve güçlü filtreleme yetenekleri sunarlar. Performans üzerindeki potansiyel etkileri nedeniyle dikkatli optimizasyon ve alternatiflerle değerlendirilmelidirler.


SQL’de Toplu İşlemler ve Gruplama (GROUP BY, HAVING)

SQL, büyük veri setlerini yönetme ve analiz etmede vazgeçilmez bir araçtır. Bu makalede, veri setlerini özetlemek ve anlamlı bilgiler çıkarmak için kullanılan toplu işlemleri, yani COUNT, SUM, AVG, MIN, MAX gibi fonksiyonları ele alacağız. Ardından, verileri belirli kriterlere göre gruplandıran GROUP BY yan tümcesinin ve bu gruplanmış veriler üzerinde koşul uygulayan HAVING yan tümcesinin derinlemesine incelenmesi yapılacaktır. Bu yaklaşımlar, karmaşık raporlama ve analiz ihtiyaçlarını karşılamak için kritik öneme sahiptir.

SQL’de Toplu İşlemler (Aggregate Functions)

Toplu işlemler, bir grup üzerinde hesaplama yapan ve tek bir sonuç değeri döndüren SQL fonksiyonlarıdır. Bu fonksiyonlar genellikle veri setlerinin özetlenmesi, raporlanması ve analiz edilmesi süreçlerinde kullanılır. İşte en yaygın kullanılan toplu fonksiyonlar:

  • COUNT(): Belirtilen ölçüte uyan satır sayısını döndürür. Örneğin, bir tablodaki toplam kayıt sayısını veya belirli bir koşulu sağlayan kayıt sayısını saymak için kullanılır.
  • SUM(): Bir sayısal sütundaki tüm değerlerin toplamını hesaplar. Örneğin, toplam satış miktarını veya toplam geliri bulmak için idealdir.
  • AVG(): Bir sayısal sütundaki tüm değerlerin ortalamasını hesaplar. Ortalama puanları, ortalama sipariş değerlerini veya ortalama yaşları bulmak için kullanılabilir.
  • MIN(): Bir sütundaki en küçük değeri döndürür. En düşük fiyatı, en erken tarihi veya en küçük sayısal değeri bulmak için faydalıdır.
  • MAX(): Bir sütundaki en büyük değeri döndürür. En yüksek fiyatı, en geç tarihi veya en büyük sayısal değeri bulmak için kullanılır.

Bu fonksiyonlar genellikle SELECT ifadesinde tek başına veya GROUP BY yan tümcesi ile birlikte kullanılır.

SELECT COUNT(*) AS ToplamMusteriSayisi FROM Musteriler;
SELECT SUM(SatisTutari) AS ToplamSatis FROM Siparisler;
SELECT AVG(Fiyat) AS OrtalamaFiyat FROM Urunler;

GROUP BY Yan Tümcesi

GROUP BY yan tümcesi, SQL sorgularında benzer değerlere sahip satırları gruplandırmak için kullanılır. Bu gruplama işlemi, toplu fonksiyonların her bir grup için ayrı ayrı uygulanmasını sağlar. Yani, veri setinizdeki her benzersiz kategori veya değer için ayrı bir özet satırı elde edersiniz.

GROUP BY Ne İşe Yarar?

Diyelim ki bir satış tablonuz var ve her bir müşteri için toplam satış tutarını görmek istiyorsunuz. GROUP BY olmadan bu işlemi yapmak zor veya imkansızdır. GROUP BY ile müşteri ID’sine göre gruplandırma yaparak, her bir müşterinin tüm siparişlerini tek bir grupta toplayabilir ve ardından bu grup üzerinde SUM() fonksiyonunu uygulayarak toplam satış tutarını bulabilirsiniz.

GROUP BY Sözdizimi ve Kullanımı

GROUP BY yan tümcesi, FROM ve WHERE yan tümcelerinden sonra, ORDER BY yan tümcesinden önce gelir. SELECT listesinde yer alan, toplu fonksiyonda kullanılmayan tüm sütunların GROUP BY yan tümcesinde belirtilmesi gerekir.

SELECT sutun1, COUNT(sutun2)
FROM tablo_adi
WHERE kosul
GROUP BY sutun1
ORDER BY sutun1;

Örnek: Müşterilere Göre Toplam Sipariş Sayısı ve Tutarı

Bir Siparisler tablonuz olduğunu ve bu tabloda MusteriID, SiparisID ve SiparisTutari sütunlarının bulunduğunu varsayalım:

SELECT
    MusteriID,
    COUNT(SiparisID) AS ToplamSiparisSayisi,
    SUM(SiparisTutari) AS ToplamSiparisTutari
FROM
    Siparisler
GROUP BY
    MusteriID
ORDER BY
    ToplamSiparisTutari DESC;

Bu sorgu, her bir müşteri için kaç sipariş verdiklerini ve bu siparişlerin toplam tutarını hesaplar. Sonuçlar, toplam sipariş tutarına göre azalan şekilde sıralanır.

HAVING Yan Tümcesi

HAVING yan tümcesi, GROUP BY tarafından oluşturulan grupları filtrelemek için kullanılır. WHERE yan tümcesi bireysel satırları gruplamadan önce filtrelerken, HAVING yan tümcesi toplu fonksiyon sonuçlarına dayalı olarak grupları filtreler. Bu ayrım kritik öneme sahiptir.

WHERE ve HAVING Arasındaki Fark

  • WHERE: Tabloda bulunan ham veriye uygulanır, yani gruplama yapılmadan önce tek tek satırlar üzerinde koşul kontrolü yapar. Toplu fonksiyonlar WHERE içinde doğrudan kullanılamaz.
  • HAVING: GROUP BY işleminden sonra, toplu fonksiyonların sonuçlarına uygulanır. Gruplanmış veriler üzerinde koşul kontrolü yapar.

HAVING Sözdizimi ve Kullanımı

HAVING yan tümcesi, GROUP BY yan tümcesinden sonra gelir.

SELECT sutun1, COUNT(sutun2)
FROM tablo_adi
WHERE kosul
GROUP BY sutun1
HAVING toplu_fonksiyon_kosulu
ORDER BY sutun1;

Örnek: Toplam Sipariş Tutarı 1000 TL’yi Aşan Müşteriler

Yukarıdaki Siparisler tablosu örneğini kullanarak, sadece toplam sipariş tutarı 1000 TL’yi aşan müşterileri listelemek isteyelim:

SELECT
    MusteriID,
    COUNT(SiparisID) AS ToplamSiparisSayisi,
    SUM(SiparisTutari) AS ToplamSiparisTutari
FROM
    Siparisler
GROUP BY
    MusteriID
HAVING
    SUM(SiparisTutari) > 1000
ORDER BY
    ToplamSiparisTutari DESC;

Bu sorgu, önce her müşteri için siparişleri gruplar, sonra her grubun toplam sipariş tutarını hesaplar ve son olarak sadece toplam tutarı 1000’den büyük olan grupları (müşterileri) listeler.

GROUP BY ve HAVING ile İleri Seviye Kullanım Senaryoları

Bu iki yan tümce, karmaşık veri analizi ve raporlama ihtiyaçlarını karşılamak için birleştirildiğinde gerçek gücünü gösterir. Örneğin, belirli bir ürün kategorisinde ortalama satış tutarı belirli bir değerin üzerinde olan bölgeleri veya son 6 ayda belirli sayıda üründen fazla satan personeli bulmak gibi senaryolar bu yapılarla kolayca çözülebilir.

-- Örnek: Belirli bir tarihten sonra 5'ten fazla sipariş veren müşteriler
SELECT
    MusteriID,
    COUNT(SiparisID) AS ToplamSiparisSayisi
FROM
    Siparisler
WHERE
    SiparisTarihi > '2023-01-01'
GROUP BY
    MusteriID
HAVING
    COUNT(SiparisID) > 5;

Burada WHERE, ilk olarak belirli bir tarihten sonraki siparişleri filtreler. Ardından GROUP BY, kalan siparişleri müşteri bazında gruplar. Son olarak HAVING, bu gruplardan sadece 5’ten fazla siparişi olanları seçer.

Performans İpuçları

Büyük veri setleriyle çalışırken GROUP BY ve HAVING kullanırken performansı göz önünde bulundurmak önemlidir:

  • İlgili sütunlar üzerinde indeksler oluşturmak, sorgu performansını önemli ölçüde artırabilir. Özellikle GROUP BY içinde kullanılan sütunlar indekslenmelidir.
  • WHERE yan tümcesini mümkün olduğunca erken ve etkili bir şekilde kullanarak veri setini küçültmek, GROUP BY ve HAVING işlemlerinin daha az veri üzerinde çalışmasını sağlar.
  • Gereksiz sütunları SELECT listesine dahil etmeyin. Sadece ihtiyacınız olan verileri çekmek, sorgu optimizasyonuna yardımcı olur.

GROUP BY ve HAVING yan tümceleri, SQL’de veri analizi ve raporlama için güçlü araçlardır. Bu makalede ele alınan toplu fonksiyonlarla birleştiğinde, büyük veri setlerinden derinlemesine içgörüler elde etmek mümkün hale gelir. Verileri anlamlı gruplara ayırmak ve bu gruplar üzerinde koşullar uygulamak, işletmelerin bilinçli kararlar almasına yardımcı olur. Doğru kullanıldığında, bu SQL yapıları veri tabanlarından maksimum verimlilikle bilgi çekme yeteneğinizi önemli ölçüde artırır. Bu yetkinlik, modern veri odaklı dünyada hayati öneme sahiptir.


SQL’de Mantıksal ve Karşılaştırma Operatörleri

SQL (Structured Query Language), veritabanlarından bilgi almak ve manipüle etmek için temel bir araçtır. Bu gücün merkezinde, verileri belirli koşullara göre filtrelememizi ve işlememizi sağlayan mantıksal ve karşılaştırma operatörleri bulunur. Bu operatörler, karmaşık sorgular oluşturarak sadece ihtiyaç duyduğumuz bilgilere erişmenin anahtarıdır. Etkili veritabanı yönetimi ve analizinde vazgeçilmez bir rol oynarlar.

SQL Karşılaştırma Operatörleri

Karşılaştırma operatörleri, bir sorguda iki ifadeyi karşılaştırarak bir koşulun doğru mu, yanlış mı yoksa bilinmeyen mi olduğunu belirlemek için kullanılır. Genellikle WHERE yan tümcesinde yer alırlar ve sorgu sonuçlarını daraltmak için temel bir mekanizmadır. Bu operatörler, sayısal, metinsel ve tarihsel değerleri karşılaştırmak için kullanılabilir.

Temel Karşılaştırma Operatörleri

  • = (Eşittir): İki değerin birbirine eşit olup olmadığını kontrol eder.
  • != veya <> (Eşit Değildir): İki değerin birbirine eşit olup olmadığını kontrol eder (farklı olup olmadıklarını).
  • > (Büyüktür): Sol taraftaki değerin sağ taraftaki değerden büyük olup olmadığını kontrol eder.
  • < (Küçüktür): Sol taraftaki değerin sağ taraftaki değerden küçük olup olmadığını kontrol eder.
  • >= (Büyük Eşittir): Sol taraftaki değerin sağ taraftaki değerden büyük veya eşit olup olmadığını kontrol eder.
  • <= (Küçük Eşittir): Sol taraftaki değerin sağ taraftaki değerden küçük veya eşit olup olmadığını kontrol eder.

Örnekler:

Aşağıdaki örneklerde, basit bir Urunler tablosu üzerinden bu operatörlerin nasıl kullanıldığını inceleyelim:


-- Fiyatı 50.00 olan ürünleri listele
SELECT UrunAdi, Fiyat FROM Urunler WHERE Fiyat = 50.00;

-- Fiyatı 100.00 olmayan ürünleri listele
SELECT UrunAdi, Fiyat FROM Urunler WHERE Fiyat != 100.00; -- Veya Fiyat <> 100.00;

-- Stok miktarı 20'den fazla olan ürünleri listele
SELECT UrunAdi, StokMiktari FROM Urunler WHERE StokMiktari > 20;

-- Fiyatı 30.00'dan az olan ürünleri listele
SELECT UrunAdi, Fiyat FROM Urunler WHERE Fiyat < 30.00;

-- Stok miktarı 10 veya daha fazla olan ürünleri listele
SELECT UrunAdi, StokMiktari FROM Urunler WHERE StokMiktari >= 10;

-- Fiyatı 75.00 veya daha az olan ürünleri listele
SELECT UrunAdi, Fiyat FROM Urunler WHERE Fiyat <= 75.00;

SQL Mantıksal Operatörler

Mantıksal operatörler, bir sorguda birden fazla koşulu birleştirmek veya mevcut bir koşulu tersine çevirmek için kullanılır. Bu operatörler, karmaşık filtreleme mantıkları oluşturarak daha spesifik veri setlerine ulaşmayı mümkün kılar. Boolean değerler (DOĞRU/YANLIŞ) üzerinde çalışırlar.

Temel Mantıksal Operatörler

  • AND: İki koşulun da doğru olması durumunda genel koşul doğru olur.
  • OR: İki koşuldan en az birinin doğru olması durumunda genel koşul doğru olur.
  • NOT: Bir koşulun mantıksal tersini alır; koşul doğruysa yanlış, yanlışsa doğru yapar.

Örnekler:

Yukarıdaki örnek tablomuzu kullanarak mantıksal operatörlerin kullanımına bakalım:


-- Kategori 'Elektronik' olan VE Fiyatı 50.00'dan yüksek olan ürünleri listele
SELECT UrunAdi, Kategori, Fiyat FROM Urunler WHERE Kategori = 'Elektronik' AND Fiyat > 50.00;

-- Kategori 'Giyim' olan VEYA Stok Miktarı 5'ten az olan ürünleri listele
SELECT UrunAdi, Kategori, StokMiktari FROM Urunler WHERE Kategori = 'Giyim' OR StokMiktari < 5;

-- Kategori 'Gıda' OLMAYAN tüm ürünleri listele
SELECT UrunAdi, Kategori FROM Urunler WHERE NOT Kategori = 'Gıda'; -- Veya Kategori != 'Gıda';

Diğer Önemli Karşılaştırma ve Mantıksal Operatörler

SQL, daha spesifik senaryolar için ek operatörler sunar. Bunlar, karşılaştırma ve mantıksal işlevleri genişleterek daha güçlü ve okunabilir sorgular yazmamızı sağlar.

  • BETWEEN: Belirli bir aralıktaki değerleri kontrol eder (dahil).
  • IN: Bir sütunun bir listedeki değerlerden herhangi birine eşit olup olmadığını kontrol eder.
  • LIKE: Bir sütunun belirli bir desene uyup uymadığını kontrol eder (metin aramaları için).
  • IS NULL / IS NOT NULL: Bir sütunun boş (NULL) olup olmadığını kontrol eder.

Örnekler:


-- Fiyatı 20.00 ile 80.00 arasında olan ürünleri listele (20 ve 80 dahil)
SELECT UrunAdi, Fiyat FROM Urunler WHERE Fiyat BETWEEN 20.00 AND 80.00;

-- Kategori 'Elektronik' veya 'Ev Gereçleri' olan ürünleri listele
SELECT UrunAdi, Kategori FROM Urunler WHERE Kategori IN ('Elektronik', 'Ev Gereçleri');

-- Ürün adında 'Bilgisayar' kelimesi geçen ürünleri listele
SELECT UrunAdi FROM Urunler WHERE UrunAdi LIKE '%Bilgisayar%'; -- % herhangi bir karakter dizisini temsil eder

-- Stok Miktarı NULL olan ürünleri listele (yani stok bilgisi girilmemiş)
SELECT UrunAdi, StokMiktari FROM Urunler WHERE StokMiktari IS NULL;

-- Stok Miktarı NULL olmayan ürünleri listele
SELECT UrunAdi, StokMiktari FROM Urunler WHERE StokMiktari IS NOT NULL;

Operatör Önceliği ve Parantez Kullanımı

Birden fazla mantıksal ve karşılaştırma operatörü içeren karmaşık sorgularda, SQL'in bir operatör önceliği kuralı vardır. Genellikle, NOT operatörü en yüksek önceliğe sahipken, ardından AND ve sonra OR gelir. Bu öncelik sırası, sorgunuzun nasıl değerlendirileceğini etkiler.

Belirli bir değerlendirme sırasını zorlamak veya varsayılan önceliği geçersiz kılmak için parantezler () kullanılır. Parantez içindeki ifadeler her zaman önce değerlendirilir, bu da sorgu mantığınızı daha okunabilir ve öngörülebilir hale getirir.

Örnek:


-- Hatalı örnek (öncelik hatası olabilir):
-- SELECT UrunAdi FROM Urunler WHERE Kategori = 'Elektronik' OR Kategori = 'Aksesuar' AND Fiyat > 100;
-- Bu sorgu, 'Aksesuar' kategorisindeki ve Fiyatı > 100 olanlar ile 'Elektronik' kategorisindeki tüm ürünleri getirecektir.

-- Doğru kullanım (parantezlerle önceliği belirtmek):
SELECT UrunAdi, Kategori, Fiyat FROM Urunler 
WHERE (Kategori = 'Elektronik' OR Kategori = 'Aksesuar') AND Fiyat > 100;
-- Bu sorgu, Kategori 'Elektronik' VEYA 'Aksesuar' olan ürünlerden, Fiyatı 100'den büyük olanları getirecektir.

Özetle, SQL'deki mantıksal ve karşılaştırma operatörleri, veritabanı sorgularının kalbini oluşturur. Bu operatörler, milyonlarca satır arasından belirli kriterlere uyan verileri hızla ayıklamamızı, karmaşık koşulları birleştirmemizi ve istenmeyen bilgileri dışarıda bırakmamızı sağlar. Etkin bir SQL kullanıcısı olmak için bu operatörleri derinlemesine anlamak ve doğru şekilde uygulamak hayati önem taşır; bunlar, veri analizi ve raporlamanın temelini oluşturur.


SQL’de Veri Sorgulama (SELECT)

SQL’de veri sorgulama, bir veritabanından bilgi çekmenin temelini oluşturur. SELECT deyimi, bu sürecin kalbidir ve istediğimiz veriyi, belirli koşullara göre seçmemizi sağlar. Bu güçlü komut sayesinde, tablolarımızdaki milyonlarca kayıttan sadece ihtiyacımız olanları hızlı ve etkin bir şekilde alabiliriz. Veri analizi, raporlama ve uygulama geliştirme için vazgeçilmez bir araçtır.

Temel SELECT Deyimi: Veri Çekmeye Giriş

SELECT deyimi, bir veritabanı tablosundan veya birden fazla tablodan veri almak için kullanılır. En basit haliyle, bir tablodaki tüm sütunları veya belirli sütunları seçmenize olanak tanır.

Tüm Sütunları Seçme

Bir tablodaki tüm sütunlardaki verileri almak için yıldız (*) operatörünü kullanırız. Bu, tablonun tüm yapısını ve içeriğini görmenin hızlı bir yoludur.

SELECT *
FROM Musteriler;

Bu sorgu, Musteriler tablosundaki her sütundaki tüm kayıtları döndürecektir.

Belirli Sütunları Seçme

Genellikle, bir tablonun tüm sütunlarına değil, sadece belirli bilgilere ihtiyacımız olur. Bu durumda, almak istediğiniz sütun adlarını virgülle ayırarak belirtiriz.

SELECT MusteriAdi, Sehir, Ulke
FROM Musteriler;

Bu sorgu, Musteriler tablosundan yalnızca MusteriAdi, Sehir ve Ulke sütunlarını getirecektir.

Verileri Filtreleme: WHERE Yan Tümcesi

WHERE yan tümcesi, SELECT deyiminin en güçlü bileşenlerinden biridir ve sorgu sonuçlarını belirli kriterlere göre filtrelemenizi sağlar. Yalnızca belirtilen koşulları karşılayan satırlar döndürülür.

Karşılaştırma Operatörleri

Verileri filtrelemek için çeşitli karşılaştırma operatörleri kullanılır:

  • = (Eşittir)
  • <> veya != (Eşit Değildir)
  • > (Büyüktür)
  • < (Küçüktür)
  • >= (Büyük veya Eşittir)
  • <= (Küçük veya Eşittir)
SELECT MusteriAdi, Sehir
FROM Musteriler
WHERE Ulke = 'Almanya';

Bu sorgu, sadece ülkesi ‘Almanya’ olan müşterileri getirecektir.

Mantıksal Operatörler: AND, OR, NOT

Daha karmaşık filtreleme koşulları oluşturmak için mantıksal operatörler kullanılır:

  • AND: Tüm koşullar doğruysa doğru döner.
  • OR: Koşullardan herhangi biri doğruysa doğru döner.
  • NOT: Koşulu tersine çevirir.
SELECT MusteriAdi, Sehir, Ulke
FROM Musteriler
WHERE Ulke = 'Almanya' AND Sehir = 'Berlin';
SELECT MusteriAdi, Sehir, Ulke
FROM Musteriler
WHERE Ulke = 'Almanya' OR Ulke = 'Fransa';

Desen Eşleştirme: LIKE Operatörü

LIKE operatörü, belirli bir deseni içeren değerleri aramak için kullanılır. Joker karakterler (wildcard characters) ile birlikte kullanılır:

  • %: Sıfır veya daha fazla karakteri temsil eder.
  • _ (alt çizgi): Tek bir karakteri temsil eder.
SELECT MusteriAdi
FROM Musteriler
WHERE MusteriAdi LIKE 'A%'; -- 'A' ile başlayan isimler
SELECT MusteriAdi
FROM Musteriler
WHERE MusteriAdi LIKE '%an%'; -- 'an' içeren isimler

Diğer Faydalı Filtreleme Operatörleri

  • IN: Belirtilen değer listesi içinde olanları seçer.
  • SELECT MusteriAdi, Sehir
    FROM Musteriler
    WHERE Sehir IN ('Berlin', 'Londra', 'Paris');
  • BETWEEN: Belirli bir aralıkta olan değerleri seçer (dahil).
  • SELECT UrunAdi, Fiyat
    FROM Urunler
    WHERE Fiyat BETWEEN 100 AND 500;
  • IS NULL / IS NOT NULL: Sütun değeri boş (NULL) olup olmadığını kontrol eder.
  • SELECT MusteriAdi, Telefon
    FROM Musteriler
    WHERE Telefon IS NULL;

Sonuçları Sıralama: ORDER BY Yan Tümcesi

ORDER BY yan tümcesi, SELECT deyiminden dönen sonuç kümesini belirli bir sütun veya sütunlara göre artan (ASC – varsayılan) veya azalan (DESC) sıraya göre sıralar.

SELECT MusteriAdi, Sehir, Ulke
FROM Musteriler
ORDER BY Ulke ASC, Sehir DESC;

Bu sorgu, önce ülkeye göre artan, ardından aynı ülkedeki şehirleri azalan sıraya göre sıralayacaktır.

Sonuç Sayısını Sınırlandırma: LIMIT / TOP Yan Tümcesi

Büyük veri kümeleriyle çalışırken, tüm sonuçları almak yerine yalnızca ilk birkaç satırı görmek isteyebilirsiniz. Bu amaçla LIMIT (MySQL, PostgreSQL) veya TOP (SQL Server) kullanılır.

-- MySQL/PostgreSQL
SELECT UrunAdi, Fiyat
FROM Urunler
ORDER BY Fiyat DESC
LIMIT 10;
-- SQL Server
SELECT TOP 10 UrunAdi, Fiyat
FROM Urunler
ORDER BY Fiyat DESC;

Her iki sorgu da en pahalı 10 ürünü listeler.

Verileri Gruplama ve Özetleme: GROUP BY ve Aggregate Fonksiyonları

GROUP BY yan tümcesi, aynı değere sahip satırları bir veya daha fazla sütuna göre gruplandırır. Bu, genellikle COUNT(), SUM(), AVG(), MIN(), MAX() gibi aggregate (toplama) fonksiyonlarıyla birlikte kullanılır.

SELECT Ulke, COUNT(MusteriID) AS ToplamMusteri
FROM Musteriler
GROUP BY Ulke
ORDER BY ToplamMusteri DESC;

Bu sorgu, her ülkedeki müşteri sayısını sayar ve en çok müşterisi olan ülkeden başlayarak listeler.

Grupları Filtreleme: HAVING Yan Tümcesi

WHERE yan tümcesi bireysel satırları filtrelerken, HAVING yan tümcesi GROUP BY ile oluşturulan grupları filtrelemek için kullanılır.

SELECT Ulke, COUNT(MusteriID) AS ToplamMusteri
FROM Musteriler
GROUP BY Ulke
HAVING COUNT(MusteriID) > 5;

Bu sorgu, sadece 5’ten fazla müşterisi olan ülkeleri ve müşteri sayılarını listeler.

Birden Fazla Tablodan Veri Sorgulama: JOIN İşlemleri

Veritabanları genellikle ilişkisel yapıdadır ve bilgiler birden fazla tabloda saklanır. JOIN deyimleri, bu tabloları birleştirerek ilgili verileri tek bir sonuç kümesinde almanızı sağlar. Örneğin, INNER JOIN, iki tabloda da eşleşen kayıtlara sahip satırları döndürür.

SELECT M.MusteriAdi, S.SiparisTarihi, S.ToplamTutar
FROM Musteriler M
INNER JOIN Siparisler S ON M.MusteriID = S.MusteriID
WHERE S.SiparisTarihi > '2023-01-01';

Bu örnek, 2023’ten sonra sipariş veren müşterilerin adlarını ve sipariş bilgilerini birleştirerek gösterir.

SELECT deyimi, SQL’in en temel ve en güçlü araçlarından biridir. Basit sorgulardan karmaşık analizlere kadar, veritabanından bilgi çekmenin her aşamasında kritik bir rol oynar. WHERE, ORDER BY, GROUP BY gibi yan tümcelerle birleştiğinde, kullanıcıların spesifik ihtiyaçlarına göre özelleştirilmiş veri kümeleri oluşturma esnekliği sunar. Veri odaklı dünyamızda, bu komutta ustalaşmak, her geliştirici ve analist için paha biçilmez bir beceridir.


SQL’de Veri Ekleme, Güncelleme ve Silme (INSERT, UPDATE, DELETE)

Veritabanı yönetimi, sadece mevcut verileri sorgulamaktan ibaret değildir; aynı zamanda bu verilerin yaşam döngüsünü de kapsar. SQL’deki Veri Manipülasyon Dili (DML) komutları, bir veritabanının dinamik yapısını korumanın temelini oluşturur. `INSERT`, `UPDATE` ve `DELETE` komutları, verileri etkili bir şekilde eklemek, mevcut kayıtları değiştirmek ve gereksiz bilgileri ortadan kaldırmak için vazgeçilmez araçlardır. Bu komutlara hakim olmak, her veri profesyonelinin temel becerilerinden biridir.

Veri Ekleme: INSERT Komutu

INSERT komutu, bir tabloya yeni kayıtlar (satırlar) eklemek için kullanılır. Bu, bir veritabanının büyümesini ve güncel kalmasını sağlayan ilk adımdır. Yeni verilerin eklenmesi, genellikle uygulamanızdaki yeni bir kullanıcının kaydı, bir ürünün envantere eklenmesi veya bir işlem kaydının oluşturulması gibi senaryolarda karşımıza çıkar.

Temel INSERT Sözdizimi

INSERT komutunu kullanmanın en yaygın yolu, eklenecek sütunları belirtmek ve ardından ilgili değerleri sağlamaktır:

INSERT INTO tablo_adi (sutun1, sutun2, sutun3, ...)
VALUES (deger1, deger2, deger3, ...);

Örnek:

INSERT INTO Musteriler (MusteriID, Ad, Soyad, Sehir)
VALUES (1, 'Ayşe', 'Yılmaz', 'İstanbul');

Bu örnekte, Musteriler tablosuna yeni bir müşteri kaydı eklenir. Belirtilen sütunlara karşılık gelen değerler sırasıyla atanır.

Tüm Sütunlara Veri Ekleme

Eğer tablonun tüm sütunlarına, tanımlandıkları sırayla veri ekliyorsanız, sütun adlarını belirtmek zorunda kalmazsınız. Ancak bu yöntem, tablonun yapısı değiştiğinde (yeni bir sütun eklendiğinde) hata yapma riskini artırabilir ve okunabilirliği düşürebilir:

INSERT INTO tablo_adi
VALUES (deger1, deger2, deger3, ...);

Örnek:

INSERT INTO Urunler
VALUES (101, 'Klavye', 250.00, 50, 'Elektronik');

Bu komut, Urunler tablosunun tüm sütunlarına (varsayımsal olarak UrunID, UrunAdi, Fiyat, StokAdedi, Kategori) sırasıyla değerler ekler.

Başka Bir Sorgudan Veri Ekleme

Bazen, bir tablodan belirli verileri alıp başka bir tabloya eklemek isteyebilirsiniz. Bu, INSERT INTO ... SELECT yapısıyla gerçekleştirilir:

INSERT INTO hedef_tablo (sutun1, sutun2, ...)
SELECT sutunA, sutunB, ...
FROM kaynak_tablo
WHERE kosul;

Örnek:

INSERT INTO EskiMusteriler (MusteriID, Ad, Soyad)
SELECT MusteriID, Ad, Soyad
FROM Musteriler
WHERE KayitTarihi < '2020-01-01';

Bu örnek, Musteriler tablosundan belirli bir tarihten önce kaydolan müşterileri seçerek, bu verileri EskiMusteriler tablosuna ekler.

Veri Güncelleme: UPDATE Komutu

UPDATE komutu, bir veya daha fazla kaydın mevcut değerlerini değiştirmek için kullanılır. Bu, bir kullanıcının adresini değiştirmesi, bir ürünün fiyatının güncellenmesi veya bir siparişin durumunun değiştirilmesi gibi senaryolarda kritik öneme sahiptir.

Temel UPDATE Sözdizimi

UPDATE komutu, hangi tablonun güncelleneceğini, hangi sütunların hangi değerlerle değiştirileceğini (SET yan tümcesi) ve hangi kayıtların güncelleneceğini (WHERE yan tümcesi) belirtir:

UPDATE tablo_adi
SET sutun1 = yeni_deger1, sutun2 = yeni_deger2, ...
WHERE kosul;

WHERE yan tümcesi, güncellenecek satırları filtrelemek için hayati öneme sahiptir. Eğer WHERE yan tümcesini kullanmazsanız, tablodaki *tüm* kayıtlar güncellenecektir, ki bu genellikle istenmeyen bir durumdur.

Örnek:

UPDATE Urunler
SET Fiyat = 275.00, StokAdedi = 45
WHERE UrunID = 101;

Bu komut, UrunID‘si 101 olan ürünün fiyatını ve stok adedini günceller.

Birden Fazla Satırı Güncelleme

WHERE yan tümcesi, birden fazla satırı etkileyecek şekilde de yazılabilir:

UPDATE Calisanlar
SET Maas = Maas * 1.10
WHERE Departman = 'Satış';

Bu örnekte, ‘Satış’ departmanındaki tüm çalışanların maaşı %10 artırılır.

Başka Bir Tablodan Veri ile Güncelleme

Bazı veritabanı sistemleri (örneğin SQL Server, MySQL), birleştirme (JOIN) veya alt sorgu (subquery) kullanarak başka bir tablodaki verilere göre güncelleme yapmaya izin verir:

-- SQL Server/MySQL Benzeri Syntax
UPDATE A
SET A.Kolon = B.Deger
FROM TabloA A
JOIN TabloB B ON A.OrtakKolon = B.OrtakKolon
WHERE A.Durum = 'Beklemede';
-- Standart SQL (Alt Sorgu ile)
UPDATE TabloA
SET Kolon = (SELECT Deger FROM TabloB WHERE TabloB.OrtakKolon = TabloA.OrtakKolon)
WHERE Durum = 'Beklemede';

Bu tür senaryolar, daha karmaşık veri tutarlılığı gerektiren durumlarda kullanılır.

Veri Silme: DELETE Komutu

DELETE komutu, bir veya daha fazla kaydı bir tablodan kalıcı olarak kaldırmak için kullanılır. Bu, gereksiz verileri temizlemek, eski kayıtları arşivlemek veya bir kullanıcının hesabını silmek gibi durumlarda gereklidir.

Temel DELETE Sözdizimi

DELETE komutu, hangi tablodan silineceğini ve hangi satırların silineceğini (WHERE yan tümcesi) belirtir:

DELETE FROM tablo_adi
WHERE kosul;

WHERE yan tümcesi, silinecek satırları filtrelemek için UPDATE komutunda olduğu gibi kritik öneme sahiptir. WHERE yan tümcesi olmadan DELETE komutu çalıştırılırsa, tablodaki *tüm* kayıtlar silinecektir.

Örnek:

DELETE FROM Musteriler
WHERE MusteriID = 1;

Bu komut, MusteriID‘si 1 olan müşteri kaydını Musteriler tablosundan siler.

Birden Fazla Satırı Silme

WHERE yan tümcesi, birden fazla satırı hedefleyecek şekilde de kullanılabilir:

DELETE FROM Siparisler
WHERE SiparisTarihi < '2023-01-01' AND Durum = 'Tamamlandı';

Bu örnek, 2023 yılından önce tamamlanmış tüm siparişleri Siparisler tablosundan siler.

Tüm Satırları Silme

Eğer tablodaki tüm satırları silmek istiyorsanız, WHERE yan tümcesini atlayabilirsiniz:

DELETE FROM tablo_adi;

Örnek:

DELETE FROM GeciciVeriler;

Bu komut, GeciciVeriler tablosundaki tüm kayıtları siler. Bu işlem, genellikle daha az kaynak tüketen ve daha hızlı çalışan TRUNCATE TABLE komutu ile karıştırılmamalıdır. DELETE her bir satırı loglarken ve geri alınabilirken, TRUNCATE TABLE veriyi sayfa bazında siler, daha az loglama yapar ve kimlik sütunlarını sıfırlar; bu nedenle genellikle geri alınamaz.

Sonuç

SQL’deki INSERT, UPDATE ve DELETE komutları, bir veritabanının dinamik doğasını şekillendiren temel DML operasyonlarıdır. Veri ekleme, değiştirme ve silme yeteneği, uygulamaların gerçek dünya ihtiyaçlarını karşılamasını sağlar. Bu komutları doğru ve dikkatli bir şekilde kullanmak, veritabanının bütünlüğünü, tutarlılığını ve performansını korumak için kritik öneme sahiptir. Her SQL kullanıcısı için bu komutlara hakim olmak, veri yönetimi becerilerinin ayrılmaz bir parçasıdır.


SQL’de Veritabanı ve Tablo Düzenleme (ALTER DATABASE / ALTER TABLE)

SQL veritabanı yönetiminde, mevcut yapıları değiştirmek sıkça karşılaşılan bir ihtiyaçtır. Veritabanının veya tabloların ilk oluşturulduğu haliyle kalması nadirdir; iş gereksinimleri zamanla evrilir. İşte bu noktada ALTER DATABASE ve ALTER TABLE komutları devreye girer. Bu güçlü SQL ifadeleri, veri kaybını en aza indirerek veritabanı şemalarını dinamik olarak güncellemenizi sağlar, sistemlerinizi güncel ve verimli tutar.

Veritabanı Yapılarını Düzenleme: ALTER DATABASE

ALTER DATABASE komutu, bir veritabanının genel özelliklerini, dosya gruplarını, dosya yollarını, kurtarma modelini veya diğer yapısal ayarlarını değiştirmek için kullanılır. Bu komut, bir veritabanının adını değiştirmek veya sistem performansını ve kullanılabilirliğini etkileyen özelliklerini ayarlamak gibi geniş kapsamlı değişiklikler yapmaya olanak tanır.

Veritabanı Adı Değiştirme

Bir veritabanının adını değiştirmek, genellikle sistemler arası geçişlerde veya isimlendirme standartlarını güncellemek gerektiğinde uygulanır. Bu işlem, veritabanı kapalı konumdayken yapılmalıdır.


-- SQL Server için örnek
ALTER DATABASE EskiVeritabaniAdi MODIFY NAME = YeniVeritabaniAdi;

-- MySQL için örnek
RENAME DATABASE EskiVeritabaniAdi TO YeniVeritabaniAdi;

Veritabanı Seçeneklerini Değiştirme

Kurtarma modeli, uyumluluk düzeyi, erişim modu (salt okunur, tek kullanıcı vb.) gibi birçok veritabanı seçeneği ALTER DATABASE ile değiştirilebilir.


-- Bir veritabanının kurtarma modelini basit olarak değiştirme (SQL Server)
ALTER DATABASE VeritabaniAdi
SET RECOVERY SIMPLE;

-- Veritabanını tek kullanıcı moduna alma (SQL Server)
ALTER DATABASE VeritabaniAdi
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE; -- Bağlantıları hemen sonlandırır

-- Veritabanını çoklu kullanıcı moduna geri alma
ALTER DATABASE VeritabaniAdi
SET MULTI_USER;

Veritabanı Dosyalarını Yönetme

Veritabanı dosyalarının boyutunu, maksimum boyutunu veya otomatik büyütme ayarlarını değiştirmek de ALTER DATABASE ile mümkündür. Bu, disk alanı yönetimi ve performans optimizasyonu için kritik öneme sahiptir.


-- Bir veri dosyasının boyutunu ve otomatik büyüme ayarlarını değiştirme (SQL Server)
ALTER DATABASE VeritabaniAdi
MODIFY FILE (NAME = VeriDosyaAdi,
             SIZE = 2GB,
             MAXSIZE = 10GB,
             FILEGROWTH = 256MB);

-- Yeni bir veri dosyası ekleme
ALTER DATABASE VeritabaniAdi
ADD FILE (NAME = YeniVeriDosyasi,
          FILENAME = 'D:\SQLData\YeniVeriDosyasi.ndf',
          SIZE = 1GB,
          MAXSIZE = 5GB,
          FILEGROWTH = 128MB);

Tablo Yapılarını Düzenleme: ALTER TABLE

Genel Bakış

ALTER TABLE, SQL’de en sık kullanılan düzenleme komutlarından biridir. Mevcut bir tablonun yapısını değiştirmek, yani sütun eklemek, silmek, değiştirmek, kısıtlamalar eklemek veya kaldırmak için kullanılır. Bu komut, yazılım geliştirme sürecindeki gereksinim değişikliklerine hızlıca uyum sağlamak veya bir veritabanının evrimini yönetmek için hayati öneme sahiptir.

Sütun İşlemleri

Sütun Ekleme: ADD COLUMN

Mevcut bir tabloya yeni bir sütun eklemek için kullanılır. Eklenen sütun, varsayılan bir değerle veya boş (NULL) olarak doldurulabilir.


ALTER TABLE Musteriler
ADD COLUMN Eposta VARCHAR(100) UNIQUE;

ALTER TABLE Urunler
ADD COLUMN StokAdedi INT NOT NULL DEFAULT 0;

Sütun Silme: DROP COLUMN

Bir tablodan mevcut bir sütunu ve bu sütuna ait tüm verileri silmek için kullanılır. Bu işlem geri alınamaz olduğundan, dikkatli bir şekilde uygulanmalıdır.


ALTER TABLE Musteriler
DROP COLUMN TelefonNumarasi;

-- Eğer sütunda kısıtlamalar varsa, önce kısıtlamaların silinmesi gerekebilir (veritabanına göre değişir)
-- SQL Server'da kısıtlamayı otomatik siler

Sütun Veri Tipi veya Boyutunu Değiştirme: ALTER COLUMN

Bir sütunun veri tipini, boyutunu veya boş geçilebilirlik (NULL/NOT NULL) özelliklerini değiştirmek için kullanılır. Bu işlem, mevcut verilerin yeni tipe uygun olup olmadığını kontrol eder. Uygun olmayan durumlarda hata verebilir veya veri kaybına neden olabilir.


-- VARCHAR sütunun boyutunu büyütme
ALTER TABLE Urunler
ALTER COLUMN UrunAdi VARCHAR(200);

-- Sütunun veri tipini ve NULL özelliğini değiştirme (PostgreSQL/Oracle)
ALTER TABLE Siparisler
ALTER COLUMN SiparisTarihi TYPE TIMESTAMP NOT NULL;

-- SQL Server için syntax
ALTER TABLE Siparisler
ALTER COLUMN SiparisTarihi DATETIME NOT NULL;

Sütun Adı Değiştirme

Bir sütunun adını değiştirmek için veritabanı sistemine göre farklı komutlar kullanılabilir. Çoğu modern RDBMS, ALTER TABLE RENAME COLUMN syntax’ını desteklerken, SQL Server gibi bazıları özel saklı yordamlar kullanır.


-- PostgreSQL / Oracle için örnek
ALTER TABLE Musteriler
RENAME COLUMN Eposta TO MusteriEpostasi;

-- SQL Server için örnek (sp_rename saklı yordamı kullanılır)
EXEC sp_rename 'Musteriler.Eposta', 'MusteriEpostasi', 'COLUMN';

Kısıtlama İşlemleri

Tabloların veri bütünlüğünü sağlamak için kısıtlamalar (constraints) kullanılır. ALTER TABLE ile bu kısıtlamalar eklenebilir veya kaldırılabilir.

Kısıtlama Ekleme: ADD CONSTRAINT

Yeni birincil anahtar (PRIMARY KEY), dış anahtar (FOREIGN KEY), benzersiz (UNIQUE), kontrol (CHECK) veya varsayılan değer (DEFAULT) kısıtlamaları eklemek için kullanılır.


-- Birincil Anahtar Ekleme
ALTER TABLE Siparisler
ADD CONSTRAINT PK_Siparisler PRIMARY KEY (SiparisID);

-- Dış Anahtar Ekleme
ALTER TABLE SiparisKalemleri
ADD CONSTRAINT FK_SiparisKalemleri_Siparisler FOREIGN KEY (SiparisID)
REFERENCES Siparisler (SiparisID);

-- Benzersiz Kısıtlama Ekleme
ALTER TABLE Kullanicilar
ADD CONSTRAINT UQ_KullaniciAdi UNIQUE (KullaniciAdi);

-- Kontrol Kısıtlaması Ekleme (yaşın 18'den büyük olmasını sağlama)
ALTER TABLE Calisanlar
ADD CONSTRAINT CK_CalisanYas CHECK (Yas >= 18);

-- Varsayılan Değer Kısıtlaması Ekleme
ALTER TABLE Urunler
ADD CONSTRAINT DF_UrunFiyati DEFAULT 0.00 FOR Fiyat;

Kısıtlama Silme: DROP CONSTRAINT

Bir tablodan mevcut bir kısıtlamayı, kısıtlama adını kullanarak kaldırmak için kullanılır.


ALTER TABLE Musteriler
DROP CONSTRAINT UQ_MusteriEpostasi;

ALTER TABLE SiparisKalemleri
DROP CONSTRAINT FK_SiparisKalemleri_Siparisler;

Tablo Adı Değiştirme: RENAME TABLE

Bir tablonun adını değiştirmek için kullanılır. Bu da veritabanına göre farklı syntax’lara sahip olabilir.


-- PostgreSQL / MySQL / Oracle için örnek
ALTER TABLE EskiTabloAdi
RENAME TO YeniTabloAdi;

-- SQL Server için örnek
EXEC sp_rename 'EskiTabloAdi', 'YeniTabloAdi';

Özetle, ALTER DATABASE ve ALTER TABLE komutları SQL veritabanı yönetiminin temel taşlarındandır. Bu komutlar, zamanla değişen iş ihtiyaçlarına uyum sağlamak için mevcut veritabanı ve tablo yapılarını güvenli bir şekilde düzenleme esnekliği sunar. Ancak, bu işlemlerin dikkatlice planlanması ve test edilmesi büyük önem taşır; zira yanlış uygulamalar veri bütünlüğünü olumsuz etkileyebilir. Doğru kullanıldığında, dinamik ve ölçeklenebilir veritabanı sistemlerinin anahtarıdırlar.


SQL’de Veritabanı ve Tablo Oluşturma (CREATE DATABASE / CREATE TABLE)

Veritabanları, modern uygulamaların ve işletmelerin kalbinde yer alır; tüm verilerin düzenli ve erişilebilir bir şekilde saklanmasını sağlar. SQL, bu veritabanlarını ve içindeki tabloları oluşturmanın temel dilidir. Bu makalede, bir veritabanının yapısını oluşturan ilk adımlar olan CREATE DATABASE ve CREATE TABLE komutlarını ayrıntılı olarak inceleyeceğiz. Doğru yapılandırma, verimlilik ve veri bütünlüğü için hayati önem taşır.

SQL’de Veritabanı Oluşturma: CREATE DATABASE

Veritabanı, ilgili verilerin bir araya getirildiği ve yönetildiği mantıksal bir konteynerdir. Uygulamanızın tüm verileri (kullanıcılar, ürünler, siparişler vb.) bu veritabanı içinde depolanır. SQL’de yeni bir veritabanı oluşturmak için CREATE DATABASE komutu kullanılır. Bu komut, belirtilen ada sahip boş bir veritabanı yapısı oluşturur.

Sözdizimi ve Örnek

CREATE DATABASE komutunun sözdizimi oldukça basittir:

CREATE DATABASE veritabani_adi;

Örneğin, bir e-ticaret uygulaması için bir veritabanı oluşturmak istediğinizde:

CREATE DATABASE ECommerceDB;

Bu komut, ECommerceDB adında boş bir veritabanı oluşturacaktır. Veritabanı oluşturulduktan sonra, üzerinde tablolar oluşturmak veya veri eklemek gibi işlemler yapabilmek için onu seçmeniz (aktif hale getirmeniz) gerekir. Bu işlem USE komutu ile gerçekleştirilir:

USE ECommerceDB;

Artık tüm SQL komutlarınız (tablo oluşturma, veri ekleme, sorgulama vb.) ECommerceDB veritabanı bağlamında çalışacaktır.

Tabloları Anlamak ve Yapılandırmak

Veritabanları içindeki veriler, satır ve sütunlardan oluşan tablolarda organize edilir. Her tablo belirli bir varlığı (örneğin, “Kullanıcılar” veya “Ürünler”) temsil eder ve sütunlar bu varlığın özelliklerini (örneğin, kullanıcının adı, ürünün fiyatı) tanımlar. Her satır ise o varlığın tek bir kaydını ifade eder. Bir tablonun sütunlarını tanımlarken, her sütun için bir veri tipi ve gerektiğinde kısıtlamalar belirtmek esastır.

Veri Tipleri

Veri tipleri, bir sütunda hangi tür verinin depolanacağını (metin, sayı, tarih vb.) belirler. Doğru veri tipi seçimi, depolama verimliliği ve veri tutarlılığı açısından önemlidir. Yaygın kullanılan bazı veri tipleri şunlardır:

  • INT: Tam sayılar için kullanılır (örneğin, kullanıcı ID’si, ürün adedi).
  • VARCHAR(boyut): Değişken uzunlukta karakter dizileri için. boyut, saklanabilecek maksimum karakter sayısını belirtir (örneğin, isimler, e-posta adresleri).
  • TEXT: Uzun metin blokları için (örneğin, ürün açıklamaları, yorumlar).
  • DATE: Tarih değerleri için (örneğin, ‘YYYY-MM-DD’).
  • DATETIME / TIMESTAMP: Tarih ve saat değerleri için.
  • DECIMAL(p, s): Ondalıklı sayılar için. p toplam basamak sayısını, s ondalık noktadan sonraki basamak sayısını belirtir (örneğin, fiyatlar, para birimleri).
  • BOOLEAN / TINYINT(1): Doğru/yanlış veya evet/hayır değerleri için.

Tablo Kısıtlamaları (Constraints)

Kısıtlamalar, bir tablodaki verilerin doğruluğunu ve bütünlüğünü sağlamak için kurallar koyar. Bu kurallar, hatalı veya tutarsız veri girişini engeller.

  • NOT NULL: Bu sütunun boş (NULL) değerler içeremeyeceğini belirtir. Bu, o sütuna her zaman bir değer girilmesi gerektiği anlamına gelir.
  • UNIQUE: Bu sütundaki tüm değerlerin benzersiz olması gerektiğini garanti eder. Yani, hiçbir iki satırın bu sütunda aynı değere sahip olamaz.
  • PRIMARY KEY: Tablodaki her satırı benzersiz bir şekilde tanımlayan bir sütun veya sütun kombinasyonudur. NOT NULL ve UNIQUE özelliklerini otomatik olarak içerir. Bir tabloda yalnızca bir tane PRIMARY KEY olabilir ve bu, tablolar arası ilişkilerin kurulmasında temel bir rol oynar.
  • FOREIGN KEY: Başka bir tablodaki birincil anahtara (PRIMARY KEY) referans veren bir sütundur. İki tablo arasındaki bağlantıyı kurarak referans bütünlüğünü sağlar. Örneğin, bir sipariş tablosundaki kullanici_id, kullanıcılar tablosundaki kullanici_id‘ye bir FOREIGN KEY olarak bağlanabilir.
  • DEFAULT değer: Eğer bir sütun için değer belirtilmezse, bu DEFAULT değerin kullanılacağını belirtir.
  • CHECK koşul: Bir sütuna girilebilecek değerler için belirli bir koşulun sağlanmasını zorunlu kılar (örneğin, yaşın 18’den büyük olması).

SQL’de Tablo Oluşturma: CREATE TABLE

Bir veritabanı içinde tablo oluşturmak için CREATE TABLE komutu kullanılır. Bu komut, tablonun adını, her bir sütunun adını, veri tipini ve herhangi bir kısıtlamayı belirtmenizi gerektirir.

Genel Sözdizimi

CREATE TABLE tablo_adi (
    sutun1_adi VERI_TIPI KISITLAMA(LAR),
    sutun2_adi VERI_TIPI KISITLAMA(LAR),
    ...
    sutunN_adi VERI_TIPI KISITLAMA(LAR),
    PRIMARY KEY (birincil_anahtar_sutunu_veya_sutunlari),
    FOREIGN KEY (yabanci_anahtar_sutunu) REFERENCES diger_tablo(referans_sutunu)
);

Örnek: “Kullanıcılar” ve “Siparişler” Tabloları Oluşturma

Öncelikle, daha önce oluşturduğumuz ECommerceDB veritabanını seçelim:

USE ECommerceDB;

Şimdi bir “Kullanıcılar” tablosu oluşturalım:

CREATE TABLE Kullanicilar (
    kullanici_id INT PRIMARY KEY AUTO_INCREMENT, -- Otomatik artan birincil anahtar (MySQL)
    ad VARCHAR(50) NOT NULL,
    soyad VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    sifre_hash VARCHAR(255) NOT NULL,
    kayit_tarihi DATE DEFAULT CURRENT_DATE
);

Bu örnekte:

  • kullanici_id: Her kullanıcıyı benzersiz bir şekilde tanımlayan birincil anahtar. AUTO_INCREMENT, yeni kayıt eklendikçe ID’nin otomatik olarak artmasını sağlar (MySQL için; diğer RDBMS’lerde IDENTITY veya SERIAL gibi karşılıkları vardır).
  • ad, soyad, email, sifre_hash: NOT NULL kısıtlaması ile bu alanların boş bırakılamayacağını belirtir.
  • email: UNIQUE kısıtlaması sayesinde her kullanıcının farklı bir e-posta adresine sahip olması sağlanır.
  • kayit_tarihi: Eğer bir tarih belirtilmezse, DEFAULT CURRENT_DATE sayesinde otomatik olarak geçerli tarihi alır.

Şimdi de “Siparişler” tablosunu oluşturalım ve “Kullanıcılar” tablosu ile ilişkilendirelim:

CREATE TABLE Siparisler (
    siparis_id INT PRIMARY KEY AUTO_INCREMENT,
    kullanici_id INT NOT NULL,
    siparis_tarihi DATETIME DEFAULT CURRENT_TIMESTAMP,
    toplam_tutar DECIMAL(10, 2) NOT NULL CHECK (toplam_tutar > 0),
    FOREIGN KEY (kullanici_id) REFERENCES Kullanicilar(kullanici_id)
);

Bu örnekte:

  • siparis_id: “Siparişler” tablosunun birincil anahtarı.
  • kullanici_id: “Kullanıcılar” tablosundaki kullanici_id‘ye referans veren bir FOREIGN KEY. Bu kısıtlama, yalnızca mevcut bir kullanıcının sipariş verebilmesini sağlar ve iki tablo arasında güçlü bir referans bütünlüğü bağlantısı kurar.
  • siparis_tarihi: Değer belirtilmezse otomatik olarak geçerli tarih ve saati alır.
  • toplam_tutar: DECIMAL(10, 2) ile ondalıklı sayıları saklar (toplam 10 basamak, ondalık kısmından sonra 2 basamak) ve CHECK (toplam_tutar > 0) kısıtlaması ile sipariş tutarının sıfırdan büyük olmasını zorunlu kılar.

Bu örnekler, CREATE TABLE komutunun veri tipleri ve kısıtlamalarla birlikte nasıl kullanıldığını ve tablolar arası ilişkilerin FOREIGN KEY ile nasıl kurulduğunu açıkça göstermektedir. Bu sayede, hem veri depolama yapısı oluşturulur hem de verilerin doğruluğu ve ilişkisel bütünlüğü garanti altına alınır.

SQL’deki CREATE DATABASE ve CREATE TABLE komutları, herhangi bir veri yönetim sisteminin temelini oluşturur. Bu komutlar sayesinde veritabanı yapısını tanımlayabilir, verilerinizi organize edebilir ve bütünlüğünü sağlayabilirsiniz. Doğru veri tipleri ve kısıtlamalar kullanarak güçlü ve güvenilir bir veri mimarisi inşa etmek, uygulamanızın performansını ve gelecekteki ölçeklenebilirliğini doğrudan etkiler. Bu temel adımları atarak, veri tabanınızın üzerine inşa edeceğiniz diğer tüm işlemleri sağlam bir temel üzerine oturtmuş olursunuz.


SQL’e Giriş: Nedir, Ne İşe Yarar?


Veri, günümüz dijital dünyasının kalbi ve işleyişini sağlayan temel unsurdur. Şirketler, uygulamalar ve sistemler sürekli olarak büyük miktarda veri üretmekte ve bu veriyi depolamak, yönetmek ve anlamlandırmak zorundadır. İşte bu noktada SQL devreye girer. SQL, ilişkisel veritabanı yönetim sistemleriyle etkileşim kurmak için tasarlanmış güçlü ve standart bir programlama dilidir. Verilerinizi sorgulamanın, manipüle etmenin ve yönetmenin anahtarıdır.

SQL Nedir?

SQL, açılımıyla Structured Query Language (Yapısal Sorgulama Dili), ilişkisel veritabanlarını yönetmek ve manipüle etmek için kullanılan standart bir programlama dilidir. İlk olarak 1970’li yılların başlarında IBM tarafından geliştirilen ve Edgar F. Codd’un ilişkisel modeline dayanan SQL, veritabanları ile iletişim kurmanın evrensel aracı haline gelmiştir. SQL’in temel amacı, bir veritabanından veri almak, veritabanına veri eklemek, mevcut verileri güncellemek veya silmek gibi işlemleri gerçekleştirmektir. Unutulmamalıdır ki SQL bir veritabanı değildir; aksine, MySQL, PostgreSQL, SQL Server, Oracle ve SQLite gibi çeşitli ilişkisel veritabanı yönetim sistemleri (RDBMS) ile konuşmak için kullanılan bir dildir.

SQL Ne İşe Yarar ve Neden Önemlidir?

SQL’in temel işlevi, veritabanları içindeki verileri etkili bir şekilde yönetmektir. Bu işlevsellik, veri tanımlama, veri işleme, veri kontrolü ve işlem kontrolü gibi dört ana kategoriye ayrılabilir:

1. Veri Tanımlama Dili (Data Definition Language – DDL)

DDL komutları, veritabanı yapısını ve şemasını oluşturmak, değiştirmek veya silmek için kullanılır. Bu, veritabanı objelerinin (tablolar, indeksler, görünümler vb.) tanımlanmasını sağlar.

  • CREATE: Yeni bir veritabanı, tablo, görünüm veya indeks oluşturmak için kullanılır.
    CREATE TABLE Calisanlar (
        CalisanID INT PRIMARY KEY,
        Ad VARCHAR(50),
        Soyad VARCHAR(50),
        DepartmanID INT
    );
  • ALTER: Mevcut bir tablonun yapısını değiştirmek (sütun eklemek, silmek, veri tipini değiştirmek) için kullanılır.
    ALTER TABLE Calisanlar ADD COLUMN Maas DECIMAL(10, 2);
  • DROP: Mevcut bir tablo, görünüm veya veritabanını silmek için kullanılır.
    DROP TABLE Calisanlar;

2. Veri İşleme Dili (Data Manipulation Language – DML)

DML komutları, veritabanındaki verileri sorgulamak, eklemek, güncellemek veya silmek için kullanılır. Bu, kullanıcıların gerçek veri içeriğiyle etkileşim kurmasını sağlar.

  • SELECT: Veritabanından veri almak için kullanılır. En sık kullanılan SQL komutudur.
    SELECT Ad, Soyad FROM Calisanlar WHERE DepartmanID = 101;
  • INSERT INTO: Bir tabloya yeni kayıtlar eklemek için kullanılır.
    INSERT INTO Calisanlar (CalisanID, Ad, Soyad, DepartmanID, Maas) VALUES (1, 'Ayşe', 'Yılmaz', 101, 60000.00);
  • UPDATE: Mevcut bir tablodaki verileri değiştirmek için kullanılır.
    UPDATE Calisanlar SET Maas = 65000.00 WHERE CalisanID = 1;
  • DELETE FROM: Bir tablodan kayıtları silmek için kullanılır.
    DELETE FROM Calisanlar WHERE CalisanID = 1;

3. Veri Kontrol Dili (Data Control Language – DCL)

DCL komutları, veritabanı erişim izinlerini ve yetkilerini yönetmek için kullanılır. Bu, veritabanı güvenliğini sağlamak için kritik öneme sahiptir.

  • GRANT: Kullanıcılara veya rollere belirli veritabanı ayrıcalıkları vermek için kullanılır (örneğin, bir tabloya SELECT veya INSERT izni vermek).
    GRANT SELECT ON Calisanlar TO kullanici_adi;
  • REVOKE: Daha önce verilmiş ayrıcalıkları geri almak için kullanılır.
    REVOKE SELECT ON Calisanlar FROM kullanici_adi;

4. İşlem Kontrol Dili (Transaction Control Language – TCL)

TCL komutları, bir veritabanı işlemindeki değişiklikleri yönetmek için kullanılır. İşlemler, bir dizi SQL komutunun mantıksal bir birimi olarak kabul edilir ve ya hepsi başarılı olur ya da hiçbiri olmaz (atomiklik).

  • COMMIT: Bir işlemdeki tüm değişiklikleri kalıcı olarak kaydetmek için kullanılır.
    COMMIT;
  • ROLLBACK: Bir işlemdeki tüm değişiklikleri geri almak ve veritabanını işlemin başlangıç durumuna döndürmek için kullanılır.
    ROLLBACK;
  • SAVEPOINT: Bir işlemin içinde geri döndürülebilecek belirli bir noktayı tanımlamak için kullanılır.

SQL’in önemi, günümüzün veri odaklı dünyasında veri toplama, depolama, analiz etme ve raporlama yeteneğinden kaynaklanmaktadır. Web uygulamalarından finans sistemlerine, sağlık hizmetlerinden bilimsel araştırmalara kadar her alanda merkezi bir rol oynar. Büyük veri analizi, iş zekası, yapay zeka ve makine öğrenimi gibi alanlarda dahi SQL becerileri temel bir gerekliliktir.

SQL Nasıl Çalışır?

SQL, genellikle bir istemci-sunucu mimarisi üzerinde çalışır. Bir kullanıcı veya uygulama (istemci), SQL sorgularını veritabanı sunucusuna gönderir. Veritabanı sunucusu, sorguyu alır, bir sorgu işlemcisi (query processor) aracılığıyla ayrıştırır, optimize eder ve yürütür. Sunucu, sorgunun sonucunu veritabanından alır ve istemciye geri gönderir. Bu süreç, verilerin hızlı ve etkin bir şekilde erişilebilir olmasını sağlar.

SQL, ilişkisel veritabanlarının temel taşıdır ve veriyi yönetmek, analiz etmek ve ondan değer elde etmek isteyen herkes için vazgeçilmez bir beceridir. Veri tanımlamasından manipülasyonuna, güvenlik yönetiminden işlem kontrolüne kadar geniş bir yelpazede yetenekler sunar. Dijitalleşen dünyada veri okuryazarlığı ve SQL bilgisi, sadece geliştiriciler için değil, aynı zamanda iş analistleri, veri bilimcileri ve yöneticiler için de kritik bir avantaj sağlamaktadır.



© 2002 kiziltas.com - Kamil KIZILTAŞ. Her hakkı saklıdır.