Ben Mühendisiniz LogoBen Mühendisiniz
Ana SayfaHizmetlerProjelerBlogKurslarEğlenceHakkımdaİletişim
Mehmet Karataş LogoMehmet Karataş

Bilgisayar Mühendisi. Modern web ve mobil teknolojiler ile yenilikçi çözümler üretiyorum.

Hızlı Linkler

  • Ana Sayfa
  • Hizmetler
  • Projeler
  • Blog
  • Kurslar
  • Eğlence
  • Hakkımda
  • İletişim
  • CV / Özgeçmiş

İletişim

  • benmuhendisiniz@gmail.com
  • Diyarbakır, Türkiye

© 2026 Mehmet Karataş. Tüm hakları saklıdır.

Ana SayfaBlogTutorialPostgreSQL Nedir? SQL Sorguları ve Veritabanı Tasarımı Rehberi 2025
Tüm Yazılar
Tutorial
12 Aralık 2025
34
15 dk okuma

PostgreSQL Nedir? SQL Sorguları ve Veritabanı Tasarımı Rehberi 2025

PostgreSQL nedir ve neden 2025'in en popüler açık kaynaklı veritabanı yönetim sistemi? Bu kapsamlı rehberde PostgreSQL'in temellerini, SQL sorgularını ve ilişkisel veritabanı tasarım prensiplerini öğreneceksiniz. MySQL ve MongoDB karşılaştırması, pratik SQL komutları (SELECT, INSERT, UPDATE, DELETE), JOIN işlemleri, normalizasyon teknikleri ve performans optimizasyonu ipuçlarını içeren bu kılavuz, hem yeni başlayanlar hem de deneyimli geliştiriciler için hazırlanmıştır. Instagram, Spotify ve Netflix gibi dev şirketlerin tercih ettiği PostgreSQL'i Supabase ile birlikte kullanarak modern web uygulamaları geliştirmeyi öğrenin. Blog sitesi ve e-ticaret örnekleriyle pratik yapın, ACID uyumluluğu ve Row Level Security (RLS) gibi güvenlik özelliklerini keşfedin.

Mehmet Karataş

Mehmet Karataş

Yazar

PostgreSQL Nedir? SQL Sorguları ve Veritabanı Tasarımı Rehberi 2025

PostgreSQL'e Giriş: Veritabanının Kralı 🐘

Dostum, Veri Yönetiminin Temellerini Öğrenme Zamanı

Otur bi kahve al, sana PostgreSQL'den bahsedeceğim. Bu sadece bir veritabanı değil, neredeyse tüm modern web uygulamalarının kalbinde atan bir güç merkezi.

PostgreSQL Nedir?

Bak şimdi, her uygulama veriyi bir yerde saklamak zorunda. Kullanıcı bilgileri, blog yazıları, siparişler, yorumlar... Her şey bir yerde duruyor olmalı.

PostgreSQL (ya da kısaca Postgres) tam olarak bu işi yapan, açık kaynaklı, güçlü ve güvenilir bir ilişkisel veritabanı yönetim sistemi.

İlişkisel ne demek?

Verilerin tablolar halinde saklandığı ve bu tabloların birbirleriyle ilişkili olduğu bir sistem. Tıpkı Excel'deki tablolar gibi, ama çok daha güçlü ve organize.

Neden PostgreSQL?

Piyasada MySQL, MongoDB, SQLite gibi alternatifleri varken neden Postgres?

1. Güçlü ve Kararlı

30 yılı aşkın geliştirme geçmişi var. Bu kadar uzun süre ayakta kalan bir yazılım, işini iyi yapıyordur.

2. Açık Kaynak ve Ücretsiz

Lisans ücreti yok, topluluk desteği güçlü. İstediğin gibi kullan, istediğin gibi özelleştir.

3. ACID Uyumlu

  • Atomicity (Bütünlük)

  • Consistency (Tutarlılık)

  • Isolation (Yalıtım)

  • Durability (Kalıcılık)

Ne demek bu? Verinin güvenli, tutarlı ve kaybolmadan saklanacağı anlamına gelir.

4. JSON Desteği

Modern uygulamalarda JSON kullanımı çok yaygın. Postgres hem ilişkisel hem de JSON verisi saklayabiliyor. İkisinin en iyisi.

5. Ölçeklenebilir

Küçük bir blog sitesinden başla, milyonlarca kullanıcılı bir platforma dönüş. Postgres hepsini kaldırır.

6. Büyük Şirketlerin Tercihi

Instagram, Spotify, Netflix, Reddit... Hepsi Postgres kullanıyor. Sebepsiz değil.

PostgreSQL vs MySQL vs MongoDB

Hızlıca karşılaştıralım:

PostgreSQL:

  • İlişkisel veritabanı

  • ACID uyumlu

  • Karmaşık sorgular için mükemmel

  • JSON desteği var

  • Daha strict (kuralcı)

MySQL:

  • İlişkisel veritabanı

  • Basit, hızlı kurulum

  • Daha yaygın

  • Wordpress gibi platformlarda popüler

MongoDB:

  • NoSQL veritabanı

  • Esnek yapı

  • Şema gerekmez

  • Hızlı prototipleme için iyi

  • Karmaşık ilişkilerde zayıf

Benim tavsiyem: Eğer düzgün bir veritabanı yapısı kurmak istiyorsan, PostgreSQL öğren. Hem ilişkisel hem modern özellikleri birleştiriyor.

Temel Kavramlar

Veritabanı (Database)

Tüm verinin saklandığı ana konteyner. Bir proje = bir veritabanı genellikle.

Tablo (Table)

Verilerin satır ve sütunlar halinde tutulduğu yapı.

Sütun (Column)

Tablodaki her bir veri alanı. Örnek: id, username, email

Satır (Row)

Tablodaki her bir kayıt. Örnek: Ahmet'in tüm bilgileri bir satır.

Primary Key (Birincil Anahtar)

Her satırı benzersiz şekilde tanımlayan alan. Genellikle id kullanılır.

Foreign Key (Yabancı Anahtar)

Bir tablonun başka bir tabloyla ilişkisini sağlayan alan.

İlk Adımlar: Basit Bir Blog Veritabanı Tasarlayalım

Diyelim ki bir blog yapıyorsun. Neye ihtiyacın var?

1. Users Tablosu

CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR(50) UNIQUE NOT NULL,
  email VARCHAR(100) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Açıklama:

  • SERIAL = otomatik artan sayı (1, 2, 3...)

  • PRIMARY KEY = benzersiz tanımlayıcı

  • VARCHAR(50) = maksimum 50 karakter

  • UNIQUE = aynısından iki tane olamaz

  • NOT NULL = boş bırakılamaz

  • TIMESTAMP = tarih ve saat

2. Posts Tablosu

CREATE TABLE posts (
  id SERIAL PRIMARY KEY,
  title VARCHAR(200) NOT NULL,
  slug VARCHAR(200) UNIQUE NOT NULL,
  content TEXT NOT NULL,
  author_id INTEGER REFERENCES users(id),
  published BOOLEAN DEFAULT false,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Açıklama:

  • TEXT = sınırsız uzunlukta metin

  • REFERENCES users(id) = users tablosuna bağlantı (Foreign Key)

  • BOOLEAN = true/false

3. Comments Tablosu

CREATE TABLE comments (
  id SERIAL PRIMARY KEY,
  post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
  user_id INTEGER REFERENCES users(id),
  content TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Açıklama:

  • ON DELETE CASCADE = post silinirse, yorumlar da silinir

Temel SQL Komutları

Veri Ekleme (INSERT)

-- Kullanıcı ekle
INSERT INTO users (username, email, password_hash)
VALUES ('mehmet', 'mehmet@email.com', 'hashed_password_123');

-- Blog yazısı ekle
INSERT INTO posts (title, slug, content, author_id, published)
VALUES (
  'PostgreSQL Öğreniyorum',
  'postgresql-ogreniyorum',
  'Bu benim ilk blog yazım!',
  1,
  true
);

Veri Çekme (SELECT)

-- Tüm kullanıcıları getir
SELECT * FROM users;

-- Sadece username ve email getir
SELECT username, email FROM users;

-- Yayınlanmış yazıları getir
SELECT * FROM posts WHERE published = true;

-- En yeni 10 yazıyı getir
SELECT * FROM posts ORDER BY created_at DESC LIMIT 10;

Veri Güncelleme (UPDATE)

-- Kullanıcının email'ini güncelle
UPDATE users 
SET email = 'yeni@email.com' 
WHERE id = 1;

-- Yazıyı yayınla
UPDATE posts 
SET published = true, updated_at = CURRENT_TIMESTAMP 
WHERE id = 1;

Veri Silme (DELETE)

-- Bir yorumu sil
DELETE FROM comments WHERE id = 1;

-- Yayınlanmamış yazıları sil
DELETE FROM posts WHERE published = false;

İlişkiler ve JOIN'ler

İşin sihirli kısmı burası. Tabloları birleştirip anlamlı bilgiler çıkartabilirsin.

INNER JOIN

-- Yazıları yazarlarıyla birlikte getir
SELECT 
  posts.title, 
  posts.content, 
  users.username as author
FROM posts
INNER JOIN users ON posts.author_id = users.id;

LEFT JOIN

-- Tüm kullanıcıları, yazı yazmamış olanları da getir
SELECT 
  users.username,
  COUNT(posts.id) as post_count
FROM users
LEFT JOIN posts ON users.id = posts.author_id
GROUP BY users.username;

Karmaşık Sorgular

-- Her yazının yorum sayısını getir
SELECT 
  posts.title,
  users.username as author,
  COUNT(comments.id) as comment_count
FROM posts
INNER JOIN users ON posts.author_id = users.id
LEFT JOIN comments ON posts.id = comments.post_id
WHERE posts.published = true
GROUP BY posts.id, posts.title, users.username
ORDER BY comment_count DESC;

Veritabanı Tasarım İlkeleri

1. Normalizasyon

Veriyi tekrar etmemek için yapılan düzenleme.

Kötü Tasarım ❌

Sorun: Ahmet'in emaili her satırda tekrar ediyor. Email değişirse tüm satırları güncellemen gerek.


İyi Tasarım ✅

Çözüm: Email sadece users tablosunda bir kere. Değişirse tek yerden güncellersin.

2. İndeksleme

Sorguları hızlandırmak için kullanılır.

-- Email'e göre sık arama yapıyorsan
CREATE INDEX idx_users_email ON users(email);

-- Slug'a göre sık arama yapıyorsan
CREATE INDEX idx_posts_slug ON posts(slug);

Indeks yoksa veritabanı tüm satırları tarar. Indeks varsa direkt bulur.

3. Veri Tipleri Seçimi

Doğru veri tipini kullan:

  • Sayılar: INTEGER, BIGINT, DECIMAL

  • Metinler: VARCHAR, TEXT

  • Tarihler: DATE, TIMESTAMP

  • Boolean: BOOLEAN

  • JSON: JSON, JSONB

4. Constraint'ler (Kısıtlamalar)

Veri bütünlüğünü korumak için:

CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  price DECIMAL(10, 2) CHECK (price > 0),
  stock INTEGER CHECK (stock >= 0),
  category_id INTEGER REFERENCES categories(id)
);

Supabase ile PostgreSQL

Supabase kullanıyorsan, zaten PostgreSQL kullanıyorsun demektir. Supabase, PostgreSQL'in üzerine kurulmuş bir platform.

Supabase'de Tablo Oluşturma

  1. Dashboard'dan:

    • Table Editor'e git

    • "New Table" butonuna tıkla

    • Sütunları ekle

    • Save

  2. SQL Editor'den:

-- Supabase SQL Editor'de çalıştır
CREATE TABLE todos (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID REFERENCES auth.users(id),
  task TEXT NOT NULL,
  completed BOOLEAN DEFAULT false,
  created_at TIMESTAMP DEFAULT NOW()
);

Row Level Security (RLS)

Supabase'in en güçlü özelliği. Veritabanı seviyesinde güvenlik:

-- Kullanıcılar sadece kendi todo'larını görsün
CREATE POLICY "Users can view own todos"
ON todos FOR SELECT
USING (auth.uid() = user_id);

-- Kullanıcılar sadece kendi todo'larını ekleyebilsin
CREATE POLICY "Users can insert own todos"
ON todos FOR INSERT
WITH CHECK (auth.uid() = user_id);

Pratik Örnekler

Örnek 1: Blog Sitesi

İhtiyaçlar:

  • Kullanıcılar

  • Blog yazıları

  • Kategoriler

  • Yorumlar

  • Etiketler

Tablo yapısı:

-- Kullanıcılar
CREATE TABLE users (
  id SERIAL PRIMARY KEY,
  username VARCHAR(50) UNIQUE NOT NULL,
  email VARCHAR(100) UNIQUE NOT NULL,
  bio TEXT,
  avatar_url TEXT,
  created_at TIMESTAMP DEFAULT NOW()
);

-- Kategoriler
CREATE TABLE categories (
  id SERIAL PRIMARY KEY,
  name VARCHAR(50) UNIQUE NOT NULL,
  slug VARCHAR(50) UNIQUE NOT NULL
);

-- Yazılar
CREATE TABLE posts (
  id SERIAL PRIMARY KEY,
  title VARCHAR(200) NOT NULL,
  slug VARCHAR(200) UNIQUE NOT NULL,
  content TEXT NOT NULL,
  excerpt TEXT,
  cover_image TEXT,
  author_id INTEGER REFERENCES users(id),
  category_id INTEGER REFERENCES categories(id),
  published BOOLEAN DEFAULT false,
  view_count INTEGER DEFAULT 0,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Etiketler
CREATE TABLE tags (
  id SERIAL PRIMARY KEY,
  name VARCHAR(50) UNIQUE NOT NULL
);

-- Yazı-Etiket ilişkisi (Many-to-Many)
CREATE TABLE post_tags (
  post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
  tag_id INTEGER REFERENCES tags(id) ON DELETE CASCADE,
  PRIMARY KEY (post_id, tag_id)
);

-- Yorumlar
CREATE TABLE comments (
  id SERIAL PRIMARY KEY,
  post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
  user_id INTEGER REFERENCES users(id),
  parent_id INTEGER REFERENCES comments(id),
  content TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

Örnek 2: E-Ticaret Sitesi

İhtiyaçlar:

  • Ürünler

  • Kategoriler

  • Sipariş sistemi

  • Sepet

  • İncelemeler

-- Ürünler
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(200) NOT NULL,
  slug VARCHAR(200) UNIQUE NOT NULL,
  description TEXT,
  price DECIMAL(10, 2) NOT NULL CHECK (price >= 0),
  stock INTEGER NOT NULL DEFAULT 0 CHECK (stock >= 0),
  category_id INTEGER REFERENCES categories(id),
  image_url TEXT,
  created_at TIMESTAMP DEFAULT NOW()
);

-- Siparişler
CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  user_id INTEGER REFERENCES users(id),
  total_amount DECIMAL(10, 2) NOT NULL,
  status VARCHAR(20) DEFAULT 'pending',
  shipping_address TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

-- Sipariş detayları
CREATE TABLE order_items (
  id SERIAL PRIMARY KEY,
  order_id INTEGER REFERENCES orders(id) ON DELETE CASCADE,
  product_id INTEGER REFERENCES products(id),
  quantity INTEGER NOT NULL CHECK (quantity > 0),
  price DECIMAL(10, 2) NOT NULL,
  subtotal DECIMAL(10, 2) NOT NULL
);

-- İncelemeler
CREATE TABLE reviews (
  id SERIAL PRIMARY KEY,
  product_id INTEGER REFERENCES products(id) ON DELETE CASCADE,
  user_id INTEGER REFERENCES users(id),
  rating INTEGER CHECK (rating >= 1 AND rating <= 5),
  comment TEXT,
  created_at TIMESTAMP DEFAULT NOW()
);

Performans İpuçları

1. EXPLAIN Kullan

Sorgunun nasıl çalıştığını görmek için:

EXPLAIN ANALYZE
SELECT * FROM posts WHERE author_id = 1;

2. İndeksle

Sık kullanılan sütunları indeksle:

CREATE INDEX idx_posts_author ON posts(author_id);
CREATE INDEX idx_posts_slug ON posts(slug);
CREATE INDEX idx_posts_published ON posts(published);

3. LIMIT Kullan

Gereksiz veri çekme:

-- Kötü
SELECT * FROM posts;

-- İyi
SELECT * FROM posts LIMIT 20;

4. SELECT * Kullanma

Sadece ihtiyacın olanı çek:

-- Kötü
SELECT * FROM users;

-- İyi
SELECT id, username, email FROM users;

Yaygın Hatalar ve Çözümleri

1. N+1 Problem

-- Kötü: Her yazı için ayrı sorgu
SELECT * FROM posts;
-- Sonra her post için:
SELECT * FROM users WHERE id = post.author_id;

-- İyi: Tek sorguda al
SELECT 
  posts.*, 
  users.username 
FROM posts 
JOIN users ON posts.author_id = users.id;

2. Cascade Silme Unutmak

-- İlişkili verileri otomatik sil
FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE

3. İndeks Eksikliği

WHERE, JOIN ve ORDER BY'da kullanılan sütunları indeksle.

4. Veri Tipi Hatası

-- Yanlış
age VARCHAR(10)  -- Yaş string mi?

-- Doğru
age INTEGER

Sonuç: PostgreSQL Neden Önemli?

Dostum, her modern uygulama veriyi bir yerde saklamak zorunda. PostgreSQL bu işin standardı haline gelmiş durumda.

Neden öğrenmelisin?

  1. Temel Beceri: Full-stack developer olmak istiyorsan şart

  2. Güçlü: Küçük projeden dev uygulamaya kadar her şeyi kaldırır

  3. Popüler: İş ilanlarının çoğunda aranan beceri

  4. Ücretsiz: Açık kaynak, maliyet yok

  5. Modern: Hem SQL hem JSON, ikisinin gücü

Nereden başla?

  1. Supabase üzerinden pratik yap (ücretsiz)

  2. Basit bir TODO app yap

  3. Blog projesi yap

  4. E-ticaret sitesi tasarla

  5. Her projede veri modelini düşün

PostgreSQL öğrenmek biraz zaman alır ama değer. Bir kere öğrendin mi, tüm veritabanı dünyası sana açılır.

Başla, pratik yap, hata yap, öğren. Veri yönetimi gücü senin elinde olsun.

Kod yazmak için varız!

Yorumlar (0)

Henüz yorum yapılmamış. İlk yorumu sen yap!

Yorum Yap

Yorum Yaz
Mehmet Karataş

Mehmet Karataş

Bilgisayar Mühendisi

Hakkımda
İlgili Yazılar
  • Web Tasarlamaya Yeni Baslayanlar Icin Rehber: HTML CSS JavaScript React Django ve ASP.NET Hangisi?

    Web geliştirmeye sıfırdan başlayanlar için hazırlanmış bu kapsamlı rehberde HTML, CSS, JavaScript, React, Next.js, Django ve ASP.NET arasındaki farkları basit ve anlaşılır bir dille öğrenin. Hangi teknolojiyle başlamanız gerektiğini adım adım keşfedin.

  • Flutter mı React Native mi? 2025 Mobil Uygulama Geliştirme Rehberi

    Mobil uygulama geliştirmede devlerin savaşı: Flutter mı React Native mi? İki popüler yapının avantajlarını, dezavantajlarını ve proje seçim kriterlerini samimi bir dille inceledik. Hangi teknoloji senin için doğru? Hemen keşfet!

  • Supabase mi Firebase mi? Gerçek Bir Proje Üzerinden 2025 Karşılaştırması

    Gerçek bir örnek proje üzerinden Supabase ve Firebase’i adım adım karşılaştırıyoruz. Hangi projede hangisi mantıklı, avantajları, dezavantajları ve karar rehberi bu yazıda.

Projeler
  • Vucut Akademi Profesyonel Fitness Kocluk ve Kisisel Antrenor Hizmetleri

    Incele →

  • YerGoster - Satilik ve Kiralik Emlak Ilanlari, Harita Uzerinden Kolay Arama

    Incele →

  • Arşivim - Kişisel Belge Arşiv Uygulaması

    Incele →

Tüm Projeler
Blog'a DönBenimle Çalışın