MenzeletDB
MenzeletDB, yüksek performanslı, sütun tabanlı (columnar) bir SQL veritabanı sistemidir.
Geleneksel veritabanlarının satır tabanlı hantallığı yerine, analitik sorgularda (OLAP) yüksek hızda sonuç veren modern bir depolama ve sorgu motoru felsefesini benimser.
Öne Çıkan Özellikler
- Tam SQL desteği —
SELECT,WHERE,ORDER BY,JOIN,GROUP BY, CTE, alt sorgu… - 200+ yerleşik fonksiyon — Zengin aggregate, scalar, window, tarih/saat fonksiyonları
- 10 JOIN türü — INNER, LEFT/RIGHT/FULL OUTER, CROSS, NATURAL, LEFT/RIGHT SEMI, LEFT/RIGHT ANTI
- Güvenli kimlik doğrulama — Şifreler hash + salt ile korunur, zamanlama saldırısı önlemi
- Rol tabanlı erişim kontrolü (RBAC) — Hassas yetki yönetimi
- Çok dilli arayüz — Türkçe, İngilizce, İspanyolca
- WAL koruması — Write-Ahead Log ile çökme kurtarma
- Dil duyarlı sıralama — Türkçe ı/i ayrımı, Unicode collation
- Hiyerarşik ad alanı — Farklı veritabanlarında aynı isimli tablolar
- Çoklu platform — Windows, Linux, macOS
Temel Kavramlar
| Kavram | Açıklama |
|---|---|
| Veritabanı (DB) | Tabloları gruplayarak organize eden mantıksal birim. Dosya sisteminde bir klasördür (data/<db_adı>/). |
| Tablo | Satır ve sütunlardan oluşan veri kümesi. Sıkıştırılmış sütun tabanlı formatta saklanır. |
| Flush | Bellekteki yazma tamponunun diske yazılması. Otomatik veya COMPACT komutuyla tetiklenir. |
| WAL | Her yazma işleminin önce kaydedildiği çökme kurtarma günlüğü. |
| İndeks | Belirli sütunlarda hızlı arama yapısı (aralık veya eşitlik sorguları için). |
| Katalog | Tablo şema meta verilerini yöneten sistem. |
Bu Kitap Hakkında
Bu dokümantasyon aşağıdaki bölümlerden oluşur:
- Başlangıç — Kurulum, ilk çalıştırma ve istemci bağlantısı
- SQL Referansı — Veritabanı, tablo, sütun tipleri, veri işlemleri, fonksiyonlar, JOIN’ler, indeksler
- Yönetim — Kimlik doğrulama, kullanıcı/rol yönetimi, konfigürasyon, yedekleme
- Operasyon — Derleme, Docker, izleme (monitoring)
- Ekler — Diğer veritabanlarından göç, sorun giderme, komut referansı
Kurulum
Kurulum Sihirbazı ile Kurulum (Önerilen)
En kolay kurulum yöntemi, grafiksel kurulum sihirbazını (menzelet-setup) kullanmaktır. Bu araç adım adım sizi yönlendirir ve tüm yapılandırmayı otomatik yapar.
İndirme
GitHub Releases sayfasından işletim sisteminize uygun paketi indirin:
| Platform | Dosya |
|---|---|
| Windows | menzelet-setup.exe |
| Linux | menzelet-setup-<versiyon>-linux-x86_64.tar.gz |
Çalıştırma
Windows:
menzelet-setup.exe
Linux:
tar xzf menzelet-setup-*.tar.gz
chmod +x menzelet-setup
./menzelet-setup
Sihirbaz Adımları
Kurulum sihirbazı şu adımları içerir:
- Hoş Geldiniz — Karşılama ekranı
- Dil Seçimi — Türkçe, İngilizce veya İspanyolca
- SA Şifresi — Süper kullanıcı (
sa) şifresi belirleme - Özet — Seçimlerin onayı
- İlerleme — Yapılandırma dosyası oluşturma, master DB hazırlama, servis kurulumu
- Tamamlandı — Kurulum sonucu
Varsayılan Dizinler
Kurulum sihirbazı aşağıdaki varsayılan dizinleri kullanır:
| Bileşen | Windows | Linux |
|---|---|---|
| Veri | C:\ProgramData\MenzeletDB\data | /var/lib/menzelet/data |
| Yapılandırma | C:\Program Files\MenzeletDB\menzelet.toml | /etc/menzelet/menzelet.toml |
| Binary | C:\Program Files\MenzeletDB | /opt/menzelet |
Docker ile Hızlı Başlangıç
Geliştirme ortamı kurmadan MenzeletDB’yi hemen denemek için Docker kullanın:
# Docker image oluştur (repo kök dizininden)
docker build -t atifdag/menzelet:latest -f build/docker/Dockerfile .
# Tek komutla başlat
docker run -d \
--name menzelet \
-p 4600:4600 \
-e MENZELET_SA_PASSWORD=güçlüŞifre123 \
atifdag/menzelet:latest
# İstemci ile bağlan
docker exec -it menzelet /opt/menzelet/menzelet-cli 127.0.0.1:4600
Docker Compose ile başlatma ve detaylı Docker yapılandırması için bkz: Docker
İlk Çalıştırma
MenzeletDB’yi ilk kez çalıştırmanın iki yolu vardır: Kurulum Sihirbazı (önerilen) veya Docker.
Kurulum Sihirbazı ile (Önerilen)
Kurulum sihirbazını (menzelet-setup) kullandıysanız, tüm yapılandırma ve bootstrap işlemleri otomatik olarak tamamlanmıştır. Sunucuyu doğrudan başlatabilirsiniz:
Windows:
"C:\Program Files\MenzeletDB\menzelet-server.exe"
Linux:
/opt/menzelet/menzelet-server
Veya servis olarak kurulduysa:
Linux (systemd):
sudo systemctl start menzelet
sudo systemctl status menzelet
Windows (servis):
Start-Service MenzeletDB
Get-Service MenzeletDB
Kurulum sihirbazı hakkında detaylı bilgi için bkz: Kurulum
Konsol ile Bootstrap
Kurulum sihirbazı kullanmadan, sunucuyu doğrudan çalıştırarak da ilk kurulumu yapabilirsiniz.
Windows:
"C:\Program Files\MenzeletDB\menzelet-server.exe" --config "C:\Program Files\MenzeletDB\menzelet.toml"
Linux:
/opt/menzelet/menzelet-server --config /etc/menzelet/menzelet.toml
Bootstrap (İlk Kurulum)
Sunucu ilk kez başlatıldığında data/master/ dizini otomatik oluşturulur. Bu sırada konsoldan sa (süper kullanıcı) şifresi istenir:
menzelet başlıyor...
Konfigürasyon yüklendi: menzelet.toml
İlk kurulum: sa şifresi belirleniyor...
sa şifresi: ________
sa şifresi (tekrar): ________
master DB oluşturuldu.
TCP sunucu başladı: 127.0.0.1:4600
Önemli:
saşifresini güvenli bir yerde saklayın. Bu şifre tek yönlü hash olarak saklanır ve geri alınamaz.
Bootstrap Sırasında Neler Olur?
data/kök dizini kontrol edilir, yoksa oluşturulurdata/master/klasörü oluşturulur- Konsoldan
saşifresi iki kez alınır (doğrulama) - 16-byte rastgele salt üretilir
- Şifre hash’lenerek güvenli biçimde saklanır
- Sistem Parquet dosyaları seed verileriyle oluşturulur:
| Dosya | İçerik |
|---|---|
mnz_users.parquet | sa kullanıcısı (hash + salt) |
mnz_roles.parquet | 4 yerleşik rol |
mnz_user_roles.parquet | sa → mnz_sys_admin eşlemesi |
mnz_role_permissions.parquet | Rol-permission eşlemeleri |
mnz_tables.parquet | Tablo katalog meta verileri (boş) |
Normal Başlatma
İlk kurulumdan sonraki her başlatmada:
data/master/dizini tespit edilir- Sistem tabloları kaydedilir
- Katalog meta verileri yüklenir (
mnz_tables.parquet+catalog.delta) - Kullanıcı veritabanları taranır ve tabloları kaydedilir
- WAL dosyaları kontrol edilir; varsa kurtarma (replay) yapılır
- Bloom filter dosyaları yüklenir
- Hiyerarşik ad alanı oluşturulur
- Bağlantı havuzu ön-ısınma (warm_up) yapılır
- TCP sunucu başlatılır
TCP sunucu başladı: 127.0.0.1:4600
Docker ile İlk Çalıştırma
Docker kullanılırken sa şifresi ortam değişkeniyle belirlenir:
docker run -d \
--name menzelet \
-p 4600:4600 \
-e MENZELET_SA_PASSWORD=güçlüŞifre123 \
atifdag/menzelet:latest
Not:
MENZELET_SA_PASSWORDortam değişkeni yalnızca ilk kurulumda (bootstrap) kullanılır. Sonraki başlatmalarda etkisizdir.
İstemci Bağlantısı
menzelet-cli
MenzeletDB istemcisi, interaktif bir komut satırı arayüzüdür. Sunucuyla TCP üzerinden length-prefix framing protokolü ile haberleşir.
Bağlanma
# Geliştirme modunda:
cargo run -p menzelet_cli -- 127.0.0.1:4600
# Release modunda:
./target/release/menzelet-cli 127.0.0.1:4600
# Varsayılan adres (menzelet.toml'dan okunur):
./target/release/menzelet-cli
# Docker container içinden:
docker exec -it menzelet /opt/menzelet/menzelet-cli 127.0.0.1:4600
CLI Bayrakları
| Bayrak | Açıklama |
|---|---|
--lang <dil> | Arayüz dilini geçersiz kılar (tr, en, es) |
--ping | Sunucu sağlık kontrolü (PING/PONG), hemen çıkar |
--help | Kullanım bilgisi gösterir |
Bağlantı Başarılı Olduğunda
menzelet v0.2.0
Bağlandı: 127.0.0.1:4600
Kimlik doğrulaması için: LOGIN <kullanıcı_adı> <parola>
menzelet>
Kimlik Doğrulama
Her yeni bağlantıda LOGIN komutu zorunludur. Kimlik doğrulamadan önce SQL veya INDEX komutları reddedilir.
menzelet> LOGIN sa güçlüŞifre123
Giriş başarılı. Hoş geldiniz, sa!
menzelet>
Hatalı şifrede bağlantı otomatik olarak kapatılır (güvenlik nedeniyle).
Hızlı Başlangıç Senaryosu
Bağlantı kurduktan ve giriş yaptıktan sonra temel işlemler:
-- Veritabanı oluştur
CREATE DATABASE test_db
-- Veritabanını seç
USE test_db
-- Tablo oluştur
CREATE TABLE musteriler (id INT NOT NULL, ad VARCHAR, sehir VARCHAR)
-- Veri ekle
INSERT INTO musteriler VALUES (1, 'Ahmet', 'İstanbul')
INSERT INTO musteriler VALUES (2, 'Mehmet', 'Ankara')
INSERT INTO musteriler VALUES (3, 'Ayşe', 'İzmir')
-- Sorgula
SELECT * FROM musteriler WHERE sehir = 'İstanbul'
-- Türkçe sıralama
SELECT ad, sehir FROM musteriler ORDER BY collate(ad)
Bağlantıyı Kapatma
menzelet> EXIT
veya QUIT komutu.
Protokol Notu
MenzeletDB, length-prefix framing protokolü kullanır (her mesajın başına 4 byte u32 big-endian uzunluk eklenir). Bu nedenle:
telnetvenc(netcat) gibi satır tabanlı araçlar kullanılamaz- Her zaman
menzelet-cliikili dosyası kullanılmalıdır - Sağlık kontrolü için:
menzelet-cli --ping
Veritabanı (DATABASE)
MenzeletDB klasör bazlı yaklaşım kullanır: her veritabanı dosya sisteminde bir klasördür (data/<db_adı>/).
Oluşturma (CREATE DATABASE)
CREATE DATABASE musteri_db
data/musteri_db/klasörü oluşturulur- Veritabanı adı küçük harf, boşluksuz olmalıdır
- Aynı isimli veritabanı varsa hata döner
Birden fazla veritabanı oluşturma:
CREATE DATABASE satis_db
CREATE DATABASE analitik_db
CREATE DATABASE test_db
Seçme (USE)
USE musteri_db
- Sonraki tüm tablo işlemleri seçilen veritabanı üzerinde çalışır
USEkomutu çalıştırılmadan tablo işlemleri yapılamaz (masterDB dışında)
Listeleme (SHOW DATABASES)
SHOW DATABASES
Örnek çıktı:
master
musteri_db
satis_db
analitik_db
Silme (DROP DATABASE)
DROP DATABASE test_db
data/test_db/klasörü ve içindeki tüm Parquet/WAL/flush dosyaları silinir- Bu işlem geri alınamaz
Koruma Kuralları
| Kural | Örnek | Sonuç |
|---|---|---|
master DB silinemez | DROP DATABASE master | Hata |
| Aktif bağlantısı olan DB silinebilir | DROP DATABASE musteri_db | Başarılı (dikkatli kullanın) |
Güncelleme
MenzeletDB’de veritabanı adı değiştirme (ALTER DATABASE RENAME) komutu desteklenmez.
Alternatif yöntem:
-- 1. Yeni veritabanı oluştur
CREATE DATABASE musteri_db_v2
-- 2. Yeni veritabanında tabloları oluştur ve verileri taşı
USE musteri_db_v2
CREATE TABLE siparisler (id INT NOT NULL, tutar FLOAT)
INSERT INTO siparisler SELECT * FROM menzelet.musteri_db.siparisler
-- 3. Eski veritabanını sil
DROP DATABASE musteri_db
Hiyerarşik ad alanı: Tablolara tam nitelikli isimle de erişilebilir:
menzelet.<db_adı>.<tablo_adı>. Bu sayede farklı veritabanlarındaki tablolaraUSEkomutu olmadan erişmek mümkündür.
Dosya Sistemi Eşlemesi
| SQL Komutu | Dosya Sistemi İşlemi |
|---|---|
CREATE DATABASE x | mkdir data/x/ |
DROP DATABASE x | rmdir data/x/ (tüm içerikle birlikte) |
USE x | Session’ın aktif DB’sini değiştir |
SHOW DATABASES | data/ altındaki klasörleri listele |
master Veritabanı
master, MenzeletDB’nin sistem veritabanıdır. İlk kurulumda (bootstrap) otomatik oluşturulur ve silinemez.
İçindeki sistem tabloları:
| Tablo | İçerik |
|---|---|
mnz_users | Kullanıcılar (şifreler hash + salt ile korunur) |
mnz_roles | Roller (4 yerleşik + kullanıcı tanımlı) |
mnz_user_roles | Kullanıcı-rol eşlemeleri |
mnz_role_permissions | Rol-permission eşlemeleri |
mnz_tables | Tablo katalog meta verileri |
Tablo (TABLE)
Her tablo dosya sisteminde sıkıştırılmış bir dosya olarak saklanır (data/<db_adı>/<tablo_adı>.parquet).
Oluşturma (CREATE TABLE)
Söz dizimi:
CREATE TABLE <tablo_adı> (<sütun1> <tip> [NOT NULL], <sütun2> <tip>, ...)
Temel örnek:
CREATE TABLE urunler (id INT, urun_adi VARCHAR, fiyat FLOAT)
NOT NULL kısıtı ile:
CREATE TABLE siparisler (
id INT NOT NULL,
musteri_id INT NOT NULL,
siparis_tarihi DATE,
toplam_tutar DECIMAL,
durum VARCHAR
)
Tüm veri tiplerini gösteren örnek:
CREATE TABLE tip_ornekleri (
tam_sayi INT,
buyuk_sayi BIGINT,
kucuk_sayi SMALLINT,
minik_sayi TINYINT,
ondalikli FLOAT,
ondalikli32 FLOAT32,
metin VARCHAR,
mantiksal BOOL,
tarih DATE,
zaman_damgasi TIMESTAMP,
zaman_utc TIMESTAMPTZ,
sabit_ondalik DECIMAL,
ikili_veri BLOB,
benzersiz_id UUID
)
Not: Tip adları büyük/küçük harf duyarsızdır.
INT,int,Int— hepsi geçerlidir.
Desteklenen veri tipleri hakkında detaylı bilgi için bkz: Sütun Tipleri
Listeleme (SHOW TABLES)
SHOW TABLES
Aktif veritabanındaki tüm tabloları listeler.
Tablo Şemasını Görüntüleme (DESCRIBE TABLE)
DESCRIBE TABLE urunler
-- veya kısaca:
DESCRIBE urunler
Örnek çıktı:
Column | Type | Nullable
--------------+----------+---------
id | Int32 | NO
urun_adi | Utf8 | YES
fiyat | Float64 | YES
aktif | Boolean | YES
CLI kısayolu:
\d urunlerkomutu ile aynı sonuç alınabilir.
Silme (DROP TABLE)
DROP TABLE urunler
data/<db_adı>/urunler.parquetdosyası silinir- İlişkili yardımcı dosyalar (flush, WAL, Bloom filter) da temizlenir
- Bu işlem geri alınamaz
Koruma Kuralları
| Kural | Örnek | Sonuç |
|---|---|---|
| Sistem tabloları silinemez | DROP TABLE mnz_users | Hata |
mnz_ ön ekli tablolar korunur | DROP TABLE mnz_roles | Hata |
Güncelleme (ALTER TABLE)
MenzeletDB aşağıdaki ALTER TABLE işlemlerini destekler:
Sütun Ekleme (ADD COLUMN)
Mevcut bir tabloya yeni bir nullable sütun ekler. Mevcut satırlarda yeni sütun NULL değerini alır.
ALTER TABLE urunler ADD COLUMN stok INT
ALTER TABLE urunler ADD COLUMN aciklama VARCHAR
ALTER TABLE urunler ADD COLUMN olusturma_tarihi TIMESTAMP
NOT NULL + DEFAULT ile Sütun Ekleme (ADD COLUMN NOT NULL DEFAULT)
Mevcut bir tabloya NOT NULL kısıtlı ve varsayılan değerli bir sütun ekler. Mevcut tüm satırlara belirtilen varsayılan değer yazılır.
ALTER TABLE urunler ADD COLUMN durum VARCHAR NOT NULL DEFAULT 'aktif'
ALTER TABLE urunler ADD COLUMN sira INT NOT NULL DEFAULT 0
Not: DEFAULT değeri metin için tek tırnak içinde, sayısal değerler için doğrudan yazılır.
Sütun Silme (DROP COLUMN)
Mevcut bir tablodan sütun siler. Mevcut veri yeniden yazılır.
ALTER TABLE urunler DROP COLUMN eski_sutun
Dikkat: Sistem tablolarının sütunları silinemez.
Sütunu NOT NULL Yapma (SET NOT NULL)
Mevcut bir sütunu NOT NULL kısıtlı olarak işaretler. Mevcut veride NULL değer varsa işlem reddedilir.
ALTER TABLE urunler ALTER COLUMN urun_adi SET NOT NULL
Önemli: Önce tablodaki NULL değerleri temizleyin veya güncelleyin, ardından SET NOT NULL uygulayabilirsiniz.
Tablo Yeniden Adlandırma (RENAME TO)
Mevcut bir tabloyu yeni bir isimle yeniden adlandırır. İlişkili tüm dosyalar da yeniden adlandırılır.
ALTER TABLE urunler RENAME TO malzemeler
Not: İlişkili indeksler yeniden oluşturulmalıdır. Sistem tabloları (
mnz_ön ekli) yeniden adlandırılamaz.
Desteklenmeyen ALTER TABLE İşlemleri
Aşağıdaki işlemler henüz desteklenmez:
-- Bu komutlar çalışmaz:
ALTER TABLE urunler ALTER COLUMN fiyat TYPE BIGINT -- Tip değişikliği
ALTER TABLE urunler ADD CONSTRAINT pk PRIMARY KEY (id) -- Kısıt ekleme
ALTER TABLE urunler RENAME COLUMN eski TO yeni -- Sütun yeniden adlandırma
Dosya Sistemi Eşlemesi
| SQL Komutu | Dosya Sistemi İşlemi |
|---|---|
CREATE TABLE t (...) | data/<db>/t.parquet oluştur |
DROP TABLE t | data/<db>/t.parquet ve ilişkili dosyaları sil |
SHOW TABLES | Aktif veritabanındaki tabloları listele |
Tablo Dosya Yapısı
Bir tablonun disk üzerindeki görünümü:
data/musteri_db/
├── siparisler.parquet ← Ana veri dosyası
├── siparisler.wal ← Çökme kurtarma günlüğü
├── siparisler.bloom ← Tekrar kontrol filtresi
├── siparisler-flush-0001.parquet ← 1. flush dosyası
├── siparisler-flush-0002.parquet ← 2. flush dosyası
└── urunler.parquet ← Başka bir tablo
Compaction
Flush dosyalarını ana veri dosyasıyla birleştirmek için:
COMPACT siparisler
Bu işlem:
- Tüm flush dosyalarını (
siparisler-flush-*.parquet) okur - Base Parquet ile birleştirir
- Tek bir yeni base Parquet dosyası yazar
- Eski flush dosyalarını siler
Sütun Tipleri
Desteklenen Veri Tipleri
Tip adları büyük/küçük harf duyarsızdır. INT, int, Int — hepsi geçerlidir.
| SQL Tipi | Eşdeğerler | Boyut | Açıklama |
|---|---|---|---|
INT | INTEGER, INT32 | 4 byte | 32-bit tam sayı (-2^31 … 2^31-1) |
BIGINT | INT64 | 8 byte | 64-bit tam sayı |
SMALLINT | INT16 | 2 byte | 16-bit tam sayı (-32768 … 32767) |
TINYINT | INT8 | 1 byte | 8-bit tam sayı (-128 … 127) |
FLOAT | FLOAT64 | 8 byte | Çift hassasiyetli ondalıklı sayı |
FLOAT32 | — | 4 byte | Tek hassasiyetli ondalıklı sayı |
VARCHAR | TEXT, STRING | Değişken | UTF-8 metin |
BOOL | BOOLEAN | 1 bit | true / false |
DATE | — | 4 byte | Tarih (YYYY-MM-DD) |
TIMESTAMP | — | 8 byte | Zaman damgası (mikrosaniye hassasiyeti) |
TIMESTAMPTZ | — | 8 byte | Zaman damgası + UTC |
DECIMAL | — | 16 byte | 38 basamak, 10 ondalık |
BLOB | — | Değişken | İkili veri |
UUID | — | 16 byte | 128-bit benzersiz tanımlayıcı |
Tip Eşanlamlıları
Aşağıdaki tip grupları dahili olarak aynı Arrow tipine eşlenir:
- VARCHAR / TEXT / STRING →
Utf8(performans ve depolama farkı yoktur) - INT / INTEGER / INT32 →
Int32 - BIGINT / INT64 →
Int64 - FLOAT / FLOAT64 →
Float64 - BOOL / BOOLEAN →
Boolean
NOT NULL Kısıtı
Sütun tanımlarına NOT NULL eklenebilir:
CREATE TABLE urunler (
id INT NOT NULL,
urun_adi VARCHAR NOT NULL,
fiyat FLOAT
)
NOT NULLkısıtı şema meta verilerinde korunur- Sunucu yeniden başlatıldığında da geçerli kalır
UUID Sütunları
UUID değerleri 16-byte sabit boyutlu binary olarak saklanır.
UUID Üretimi
MenzeletDB uuid() fonksiyonunu içerir. Bu fonksiyon UUID v4 formatında rastgele bir benzersiz tanımlayıcı üretir ve VARCHAR (metin) tipinde döner:
-- uuid() ile otomatik UUID üretimi
SELECT uuid() AS yeni_id
-- Sonuç: "c4a1f2e8-3b7d-4a9c-8f1e-6d2a5b8c9e0f"
Not:
uuid()fonksiyonu metin tipinde değer döner, ancak MenzeletDB UUID sütunlarını binary olarak saklar. Doğrudan INSERT için istemci tarafında dönüşüm gerekebilir.
UUID İndeksleme
UUID sütunlarında Hash ve BTree indeksleme desteklenir.
NULL Davranışı
| Durum | Davranış |
|---|---|
| Aggregate fonksiyonlar (SUM, AVG, MIN, MAX) | NULL değerleri atlar |
COUNT(*) | NULL dahil tüm satırları sayar |
COUNT(sütun) | NULL hariç sayar |
COALESCE(a, b, ...) | İlk NULL olmayan değeri döner |
NULLIF(a, b) | a = b ise NULL döner |
IS NULL / IS NOT NULL | NULL kontrolü |
-- NULL kontrolü örnekleri
SELECT * FROM urunler WHERE fiyat IS NOT NULL
SELECT COALESCE(fiyat, 0.0) AS fiyat FROM urunler
SELECT NULLIF(indirimli_fiyat, 0.0) FROM urunler
Tip Dönüşümü (CAST)
-- INT → VARCHAR
SELECT CAST(id AS VARCHAR) FROM urunler
-- VARCHAR → INT
SELECT CAST('42' AS INT)
-- FLOAT → INT (ondalık kısmı kesilir)
SELECT CAST(3.7 AS INT) -- Sonuç: 3
-- Tarih dönüşümleri
SELECT CAST('2024-01-15' AS DATE)
SELECT CAST('2024-01-15 10:30:00' AS TIMESTAMP)
Veri İşlemleri (DML)
INSERT — Veri Ekleme
Strict Mod (Varsayılan)
Aynı birincil anahtarla tekrar INSERT yapılırsa hata döner. Birincil anahtar ilk sütun değeridir.
INSERT INTO urunler VALUES (1, 'Klavye', 450.00, true)
INSERT INTO urunler VALUES (2, 'Mouse', 250.00, true)
INSERT INTO urunler VALUES (3, 'Monitör', 3500.00, true)
-- Aynı anahtar tekrar eklenirse hata:
INSERT INTO urunler VALUES (1, 'Kulaklık', 200.00, true)
-- Hata: Anahtar zaten mevcut: '1'
Upsert Mod (INSERT OR REPLACE)
Mevcut anahtarı sessizce günceller:
INSERT OR REPLACE INTO urunler VALUES (1, 'Kulaklık', 200.00, true)
-- OK: id=1 satırı 'Kulaklık' olarak güncellendi
Veri Akışı
INSERT → WAL (günlüe yaz) → Bellek tamponu
→ Tampon doldu mu?
→ Evet → Diske flush (sıkıştırılmış dosya)
→ Hayır → Bellekte bekle
SELECT — Veri Sorgulama
Temel Sorgular
-- Tüm satırları getir
SELECT * FROM urunler
-- Belirli sütunlar
SELECT urun_adi, fiyat FROM urunler
-- Koşullu sorgu
SELECT * FROM urunler WHERE fiyat > 100
-- Sıralama
SELECT urun_adi, fiyat FROM urunler ORDER BY fiyat DESC
-- Limit
SELECT * FROM urunler ORDER BY fiyat DESC LIMIT 10
Birden Fazla Koşul
-- AND / OR
SELECT * FROM siparisler WHERE musteri_id = 5 AND durum = 'tamamlandi'
SELECT * FROM urunler WHERE fiyat < 100 OR aktif = false
-- IN listesi
SELECT * FROM urunler WHERE id IN (1, 3, 5, 7)
-- BETWEEN
SELECT * FROM urunler WHERE fiyat BETWEEN 100 AND 500
-- LIKE kalıp eşlemesi
SELECT * FROM urunler WHERE urun_adi LIKE '%Klavye%'
-- IS NULL / IS NOT NULL
SELECT * FROM urunler WHERE fiyat IS NOT NULL
Gruplama ve Toplama
-- Basit gruplama
SELECT musteri_id, COUNT(*) AS siparis_sayisi
FROM siparisler
GROUP BY musteri_id
ORDER BY siparis_sayisi DESC
-- Birden fazla aggregate
SELECT musteri_id,
COUNT(*) AS siparis_sayisi,
SUM(tutar) AS toplam,
AVG(tutar) AS ortalama
FROM siparisler
GROUP BY musteri_id
-- HAVING filtresi
SELECT musteri_id, COUNT(*) AS siparis_sayisi
FROM siparisler
GROUP BY musteri_id
HAVING COUNT(*) > 5
DISTINCT
SELECT DISTINCT musteri_id FROM siparisler
SELECT DISTINCT sehir FROM musteriler ORDER BY collate(sehir)
CASE İfadesi
SELECT urun_adi, fiyat,
CASE
WHEN fiyat < 100 THEN 'ucuz'
WHEN fiyat < 1000 THEN 'orta'
ELSE 'pahalı'
END AS fiyat_grubu
FROM urunler
Alt Sorgu (Subquery)
-- WHERE'de alt sorgu
SELECT * FROM urunler
WHERE fiyat > (SELECT AVG(fiyat) FROM urunler)
-- IN ile alt sorgu
SELECT * FROM musteriler
WHERE id IN (SELECT musteri_id FROM siparisler WHERE tutar > 1000)
CTE (Common Table Expression)
WITH aylik_satis AS (
SELECT date_part('month', tarih) AS ay,
SUM(tutar) AS toplam
FROM siparisler
GROUP BY date_part('month', tarih)
)
SELECT ay, toplam
FROM aylik_satis
WHERE toplam > 10000
ORDER BY ay
UNION
SELECT urun_adi FROM urunler WHERE fiyat < 100
UNION ALL
SELECT urun_adi FROM urunler WHERE aktif = false
-- UNION (tekrarlıları kaldırır)
SELECT sehir FROM musteriler
UNION
SELECT sehir FROM tedarikciler
Dil Duyarlı Sıralama
-- Türkçe alfabetik sıralama (ı, i, ö, ü, ç, ş, ğ düzgün sıralanır)
SELECT isim FROM musteriler ORDER BY collate(isim)
-- Azalan sırada
SELECT urun_adi, fiyat FROM urunler ORDER BY collate(urun_adi) DESC
-- Birden fazla kriter
SELECT isim, sehir FROM musteriler ORDER BY collate(sehir), collate(isim)
collate() fonksiyonu locale-duyarlı sıralama anahtarı üretir. Varsayılan locale menzelet.toml dosyasındaki [collation] default_locale ayarıyla belirlenir.
Türkçe sıralama kuralları:
| Kural | Açıklama |
|---|---|
| ç, c’den sonra gelir | cay < çay < dağ |
| ğ, g’den sonra gelir | gaz < ğül < hal |
| ı ve i farklı harflerdir | ışık < istanbul |
| ö, o’dan sonra gelir | ordu < öğle < para |
| ş, s’den sonra gelir | sal < şal < tal |
| ü, u’dan sonra gelir | uzay < üzüm < vadi |
Not:
collate()olmadanORDER BY isimUnicode byte sıralaması kullanır; Türkçe için yanlış sonuç verebilir.
JOIN Sorguları
SELECT s.siparis_id, u.urun_adi, s.miktar
FROM siparisler s
JOIN urunler u ON s.urun_id = u.id
Tüm JOIN türleri ve detaylı örnekler için bkz: JOIN Türleri
UPDATE — Veri Güncelleme
-- Tek sütun güncelle
UPDATE urunler SET fiyat = 500.00 WHERE id = 1
-- Birden fazla sütun
UPDATE urunler SET fiyat = 600.00, aktif = false WHERE id = 2
-- Koşullu güncelleme
UPDATE siparisler SET durum = 'iptal' WHERE toplam_tutar = 0
DELETE — Veri Silme
-- Koşullu silme
DELETE FROM urunler WHERE id = 3
-- Birden fazla koşul
DELETE FROM siparisler WHERE durum = 'iptal' AND tarih < '2024-01-01'
SQL Fonksiyonları
MenzeletDB, 200’den fazla yerleşik SQL fonksiyonu destekler. Ayrıca dil duyarlı sıralama için collate() özel fonksiyonu sunucuya kayıtlıdır.
Aggregate (Toplama) Fonksiyonları
Aggregate fonksiyonlar NULL değerleri atlar (COUNT(*) hariç).
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
COUNT(*) | Tüm satırları sayar (NULL dahil) | SELECT COUNT(*) FROM urunler |
COUNT(sütun) | NULL olmayan satırları sayar | SELECT COUNT(fiyat) FROM urunler |
SUM(sütun) | Sayısal toplam | SELECT SUM(fiyat) FROM urunler |
AVG(sütun) | Ortalama | SELECT AVG(fiyat) FROM urunler |
MIN(sütun) | Minimum değer | SELECT MIN(fiyat) FROM urunler |
MAX(sütun) | Maksimum değer | SELECT MAX(fiyat) FROM urunler |
MEDIAN(sütun) | Medyan değer | SELECT MEDIAN(fiyat) FROM urunler |
ARRAY_AGG(sütun) | Değerleri diziye toplar | SELECT ARRAY_AGG(urun_adi) FROM urunler |
BIT_AND(sütun) | Bitwise AND | SELECT BIT_AND(bayraklar) FROM ayarlar |
BIT_OR(sütun) | Bitwise OR | SELECT BIT_OR(bayraklar) FROM ayarlar |
BOOL_AND(sütun) | Tümü true mi? | SELECT BOOL_AND(aktif) FROM urunler |
BOOL_OR(sütun) | Herhangi biri true mi? | SELECT BOOL_OR(aktif) FROM urunler |
STDDEV(sütun) | Standart sapma | SELECT STDDEV(fiyat) FROM urunler |
VARIANCE(sütun) | Varyans | SELECT VARIANCE(fiyat) FROM urunler |
Gruplama Örnekleri
SELECT musteri_id,
COUNT(*) AS siparis_sayisi,
SUM(tutar) AS toplam,
AVG(tutar) AS ortalama,
MIN(tutar) AS en_dusuk,
MAX(tutar) AS en_yuksek
FROM siparisler
GROUP BY musteri_id
HAVING SUM(tutar) > 10000
ORDER BY toplam DESC
Metin (String) Fonksiyonları
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
LOWER(s) | Küçük harfe çevirir | SELECT LOWER('MENZELeT') → 'menzelet' |
UPPER(s) | Büyük harfe çevirir | SELECT UPPER('menzelet') → 'MENZELET' |
LENGTH(s) | Karakter sayısı | SELECT LENGTH('merhaba') → 7 |
CHAR_LENGTH(s) | LENGTH ile aynı | SELECT CHAR_LENGTH('abc') → 3 |
BIT_LENGTH(s) | Bit cinsinden uzunluk | SELECT BIT_LENGTH('abc') → 24 |
OCTET_LENGTH(s) | Byte cinsinden uzunluk | SELECT OCTET_LENGTH('abc') → 3 |
SUBSTR(s, pos, len) | Alt metin çıkarır (1-tabanlı) | SELECT SUBSTR('menzelet', 1, 3) → 'men' |
LEFT(s, n) | Soldan n karakter | SELECT LEFT('menzelet', 3) → 'men' |
RIGHT(s, n) | Sağdan n karakter | SELECT RIGHT('menzelet', 3) → 'let' |
CONCAT(a, b, ...) | Birleştirir | SELECT CONCAT('men', 'ze', 'let') → 'menzelet' |
CONCAT_WS(sep, ...) | Ayırıcı ile birleştirir | SELECT CONCAT_WS('-', 'a', 'b', 'c') → 'a-b-c' |
REPLACE(s, old, new) | Metin değiştirir | SELECT REPLACE('abc', 'b', 'x') → 'axc' |
REVERSE(s) | Ters çevirir | SELECT REVERSE('abc') → 'cba' |
REPEAT(s, n) | Tekrarlar | SELECT REPEAT('ab', 3) → 'ababab' |
TRIM(s) | Baş/son boşluk siler | SELECT TRIM(' abc ') → 'abc' |
LTRIM(s) | Soldan boşluk siler | SELECT LTRIM(' abc') → 'abc' |
RTRIM(s) | Sağdan boşluk siler | SELECT RTRIM('abc ') → 'abc' |
LPAD(s, len, fill) | Soldan doldurur | SELECT LPAD('42', 5, '0') → '00042' |
RPAD(s, len, fill) | Sağdan doldurur | SELECT RPAD('42', 5, '0') → '42000' |
INITCAP(s) | Her kelimenin baş harfi büyük | SELECT INITCAP('hello world') → 'Hello World' |
ASCII(s) | İlk karakterin ASCII kodu | SELECT ASCII('A') → 65 |
CHR(n) | ASCII koddan karakter | SELECT CHR(65) → 'A' |
STARTS_WITH(s, prefix) | Ön ek kontrolü | SELECT STARTS_WITH('abc', 'ab') → true |
ENDS_WITH(s, suffix) | Son ek kontrolü | SELECT ENDS_WITH('abc', 'bc') → true |
CONTAINS(s, sub) | İçerik kontrolü | SELECT CONTAINS('abc', 'bc') → true |
STRPOS(s, sub) | Alt metin pozisyonu | SELECT STRPOS('abcdef', 'cd') → 3 |
SPLIT_PART(s, d, n) | Ayırıcıyla böl, n. parça | SELECT SPLIT_PART('a-b-c', '-', 2) → 'b' |
TRANSLATE(s, from, to) | Karakter çevirisi | SELECT TRANSLATE('abc', 'abc', 'xyz') → 'xyz' |
TO_HEX(n) | Sayıyı hex metin yapar | SELECT TO_HEX(255) → 'ff' |
LEVENSHTEIN(a, b) | Düzenleme mesafesi | SELECT LEVENSHTEIN('abc', 'axc') → 1 |
uuid() | Rastgele UUID v4 üretir | SELECT uuid() → 'c4a1...' |
OVERLAY(s, r, pos, len) | Metin üzerine yazar | SELECT OVERLAY('abcdef' PLACING 'XX' FROM 3 FOR 2) |
Matematik Fonksiyonları
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
ABS(x) | Mutlak değer | SELECT ABS(-5) → 5 |
CEIL(x) | Yukarı yuvarlama | SELECT CEIL(3.2) → 4 |
FLOOR(x) | Aşağı yuvarlama | SELECT FLOOR(3.8) → 3 |
ROUND(x, d) | Yuvarla | SELECT ROUND(3.456, 2) → 3.46 |
TRUNC(x, d) | Kes | SELECT TRUNC(3.456, 2) → 3.45 |
SQRT(x) | Karekök | SELECT SQRT(16) → 4 |
CBRT(x) | Küpkök | SELECT CBRT(27) → 3 |
POW(x, y) | Üs alma | SELECT POW(2, 10) → 1024 |
EXP(x) | e^x | SELECT EXP(1) → 2.718... |
LN(x) | Doğal logaritma | SELECT LN(2.718) → ~1.0 |
LOG(base, x) | Logaritma | SELECT LOG(10, 100) → 2 |
LOG10(x) | 10 tabanında log | SELECT LOG10(1000) → 3 |
LOG2(x) | 2 tabanında log | SELECT LOG2(8) → 3 |
PI() | Pi sabiti | SELECT PI() → 3.14159... |
RANDOM() | 0-1 arası rastgele | SELECT RANDOM() |
SIGN(x) | İşaret (-1, 0, 1) | SELECT SIGN(-5) → -1 |
FACTORIAL(n) | Faktöriyel | SELECT FACTORIAL(5) → 120 |
GCD(a, b) | En büyük ortak bölen | SELECT GCD(12, 8) → 4 |
LCM(a, b) | En küçük ortak kat | SELECT LCM(4, 6) → 12 |
DEGREES(rad) | Radyandan dereceye | SELECT DEGREES(PI()) → 180 |
RADIANS(deg) | Dereceden radyana | SELECT RADIANS(180) → 3.14... |
SIN(x) | Sinüs | SELECT SIN(PI()/2) → 1 |
COS(x) | Kosinüs | SELECT COS(0) → 1 |
TAN(x) | Tanjant | SELECT TAN(PI()/4) → ~1 |
ASIN(x) | Ark sinüs | SELECT ASIN(1) → 1.5707... |
ACOS(x) | Ark kosinüs | SELECT ACOS(1) → 0 |
ATAN(x) | Ark tanjant | SELECT ATAN(1) → 0.7853... |
ATAN2(y, x) | İki argümanlı ark tanjant | SELECT ATAN2(1, 1) → 0.7853... |
ISNAN(x) | NaN kontrolü | SELECT ISNAN(0.0/0.0) |
ISZERO(x) | Sıfır kontrolü | SELECT ISZERO(0) → true |
NANVL(x, alt) | NaN ise alternatif | SELECT NANVL(val, 0.0) |
Koşullu Fonksiyonlar
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
COALESCE(a, b, ...) | İlk NULL olmayan | SELECT COALESCE(fiyat, 0.0) |
NULLIF(a, b) | Eşitse NULL | SELECT NULLIF(fiyat, 0.0) |
GREATEST(a, b, ...) | En büyük değer | SELECT GREATEST(3, 7, 1) → 7 |
LEAST(a, b, ...) | En küçük değer | SELECT LEAST(3, 7, 1) → 1 |
IFNULL(a, b) | NULL ise b döner | SELECT IFNULL(fiyat, 0.0) |
NVL(a, b) | IFNULL ile aynı | SELECT NVL(fiyat, 0.0) |
NVL2(a, b, c) | a NULL değilse b, NULL ise c | SELECT NVL2(fiyat, 'var', 'yok') |
Tarih / Saat Fonksiyonları
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
NOW() | Geçerli UTC zaman damgası | SELECT NOW() |
CURRENT_DATE | Bugünün tarihi | SELECT CURRENT_DATE |
CURRENT_TIME | Şu anki saat | SELECT CURRENT_TIME |
CURRENT_TIMESTAMP | NOW() ile aynı | SELECT CURRENT_TIMESTAMP |
TODAY() | CURRENT_DATE ile aynı | SELECT TODAY() |
date_part(birim, tarih) | Tarih bileşeni çıkarır | SELECT date_part('year', NOW()) |
EXTRACT(birim FROM tarih) | SQL standart bileşen çıkarma | SELECT EXTRACT(MONTH FROM tarih) |
date_trunc(birim, tarih) | Tarihi keser | SELECT date_trunc('month', NOW()) |
date_bin(interval, ts, origin) | Zaman aralığına hizalar | SELECT date_bin(INTERVAL '1 hour', ts, '2024-01-01') |
to_timestamp(s) | Metinden timestamp | SELECT to_timestamp('2024-01-15 10:30:00') |
to_date(s, fmt) | Metinden tarih | SELECT to_date('15/01/2024', '%d/%m/%Y') |
to_char(ts, fmt) | Tarihten metin | SELECT to_char(NOW(), '%Y-%m-%d') |
from_unixtime(epoch) | Unix epoch’tan timestamp | SELECT from_unixtime(1705315800) |
to_unixtime(ts) | Timestamp’tan epoch | SELECT to_unixtime(NOW()) |
make_date(y, m, d) | Bileşenlerden tarih | SELECT make_date(2024, 1, 15) |
make_time(h, m, s) | Bileşenlerden saat | SELECT make_time(10, 30, 0) |
| Interval aritmetiği | Tarihe süre ekleme | SELECT NOW() + INTERVAL '10 days' |
Tarih Bileşenleri (date_part / EXTRACT)
Kullanılabilir birimler: year, month, day, hour, minute, second, week, dow (haftanın günü), doy (yılın günü), quarter, epoch
SELECT date_part('year', siparis_tarihi) AS yil,
date_part('month', siparis_tarihi) AS ay,
COUNT(*) AS siparis_sayisi
FROM siparisler
GROUP BY yil, ay
ORDER BY yil, ay
Regex Fonksiyonları
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
REGEXP_LIKE(s, pattern) | Kalıp eşleşmesi | SELECT REGEXP_LIKE('abc123', '[0-9]+') → true |
REGEXP_MATCH(s, pattern) | Eşleşen grubu döner | SELECT REGEXP_MATCH('abc123', '([0-9]+)') |
REGEXP_REPLACE(s, p, r) | Kalıpla değiştirir | SELECT REGEXP_REPLACE('abc123', '[0-9]', 'X') |
REGEXP_COUNT(s, pattern) | Eşleşme sayısı | SELECT REGEXP_COUNT('abcabc', 'abc') → 2 |
Hash Fonksiyonları
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
MD5(s) | MD5 hash | SELECT MD5('menzelet') |
SHA224(s) | SHA-224 hash | SELECT SHA224('menzelet') |
SHA256(s) | SHA-256 hash | SELECT SHA256('menzelet') |
SHA384(s) | SHA-384 hash | SELECT SHA384('menzelet') |
SHA512(s) | SHA-512 hash | SELECT SHA512('menzelet') |
DIGEST(s, algo) | Belirtilen algoritma | SELECT DIGEST('abc', 'blake3') |
Kodlama Fonksiyonları
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
ENCODE(veri, format) | Binary → metin | SELECT ENCODE(blob_sutun, 'base64') |
DECODE(metin, format) | Metin → binary | SELECT DECODE('AQID', 'base64') |
Desteklenen formatlar: base64, hex
Window (Pencere) Fonksiyonları
Window fonksiyonları OVER (...) ifadesiyle kullanılır.
| Fonksiyon | Açıklama |
|---|---|
ROW_NUMBER() | Satır numarası (1’den başlar) |
RANK() | Sıralama (eşitlerde aynı numara, sonraki atlar) |
DENSE_RANK() | Sıralama (eşitlerde aynı numara, sonraki atlamaz) |
NTILE(n) | n gruba eşit böler |
LAG(sütun, n) | n satır önceki değer |
LEAD(sütun, n) | n satır sonraki değer |
FIRST_VALUE(sütun) | Penceredeki ilk değer |
LAST_VALUE(sütun) | Penceredeki son değer |
NTH_VALUE(sütun, n) | Penceredeki n. değer |
CUME_DIST() | Kümülatif dağılım |
PERCENT_RANK() | Yüzdelik sıralama |
Window Örnekleri
-- Satır numarası
SELECT ROW_NUMBER() OVER (ORDER BY fiyat DESC) AS sira,
urun_adi, fiyat
FROM urunler
-- Bölüm bazlı sıralama
SELECT kategori, urun_adi, fiyat,
RANK() OVER (PARTITION BY kategori ORDER BY fiyat DESC) AS sira
FROM urunler
-- Bir önceki değerle karşılaştırma
SELECT tarih, tutar,
LAG(tutar, 1) OVER (ORDER BY tarih) AS onceki_tutar,
tutar - LAG(tutar, 1) OVER (ORDER BY tarih) AS fark
FROM gunluk_satis
-- Kümülatif toplam
SELECT tarih, tutar,
SUM(tutar) OVER (ORDER BY tarih) AS kumulatif_toplam
FROM gunluk_satis
-- LAST_VALUE (pencere çerçevesi gerekir)
SELECT urun_adi,
LAST_VALUE(urun_adi) OVER (
ORDER BY fiyat
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS en_pahali
FROM urunler
Özel Fonksiyon: collate()
MenzeletDB’ye özgü, locale-duyarlı sıralama fonksiyonu:
-- Türkçe alfabetik sıralama
SELECT isim FROM musteriler ORDER BY collate(isim)
Detaylı kullanım için bkz: Veri İşlemleri — Dil Duyarlı Sıralama
Diğer Fonksiyonlar
| Fonksiyon | Açıklama | Örnek |
|---|---|---|
VERSION() | Sunucu sürümü | SELECT VERSION() |
JOIN Türleri
MenzeletDB 10 farklı JOIN türünü destekler. JOIN stratejisi optimizer tarafından otomatik seçilir.
Örnek Tablolar
Bu bölümdeki tüm örnekler aşağıdaki tablolara dayanır:
-- Tablo tanımları
CREATE TABLE musteriler (id INT NOT NULL, ad VARCHAR, sehir VARCHAR)
CREATE TABLE siparisler (id INT NOT NULL, musteri_id INT, tutar FLOAT, tarih DATE)
CREATE TABLE urunler (id INT NOT NULL, ad VARCHAR, fiyat FLOAT)
CREATE TABLE siparis_detay (siparis_id INT, urun_id INT, miktar INT)
-- Örnek veriler
INSERT INTO musteriler VALUES (1, 'Ahmet', 'İstanbul')
INSERT INTO musteriler VALUES (2, 'Mehmet', 'Ankara')
INSERT INTO musteriler VALUES (3, 'Ayşe', 'İzmir')
INSERT INTO musteriler VALUES (4, 'Fatma', 'Bursa')
INSERT INTO siparisler VALUES (101, 1, 500.00, '2024-01-15')
INSERT INTO siparisler VALUES (102, 2, 750.00, '2024-01-20')
INSERT INTO siparisler VALUES (103, 1, 300.00, '2024-02-10')
INSERT INTO siparisler VALUES (104, 5, 100.00, '2024-02-15')
1. INNER JOIN
Her iki tabloda eşleşen satırları döner.
SELECT m.ad, s.tutar, s.tarih
FROM musteriler m
INNER JOIN siparisler s ON m.id = s.musteri_id
| ad | tutar | tarih |
|---|---|---|
| Ahmet | 500.00 | 2024-01-15 |
| Mehmet | 750.00 | 2024-01-20 |
| Ahmet | 300.00 | 2024-02-10 |
musteri_id=5 (siparisler) ve id=3,4 (musteriler) eşleşme olmadığı için sonuçta yer almaz.
2. LEFT OUTER JOIN
Sol tablodaki tüm satırları döner; sağda eşleşme yoksa NULL.
SELECT m.ad, s.tutar
FROM musteriler m
LEFT JOIN siparisler s ON m.id = s.musteri_id
| ad | tutar |
|---|---|
| Ahmet | 500.00 |
| Ahmet | 300.00 |
| Mehmet | 750.00 |
| Ayşe | NULL |
| Fatma | NULL |
Ayşe ve Fatma’nın siparişi yok ama sonuçta yer alır (tutar = NULL).
3. RIGHT OUTER JOIN
Sağ tablodaki tüm satırları döner; solda eşleşme yoksa NULL.
SELECT m.ad, s.tutar, s.musteri_id
FROM musteriler m
RIGHT JOIN siparisler s ON m.id = s.musteri_id
| ad | tutar | musteri_id |
|---|---|---|
| Ahmet | 500.00 | 1 |
| Mehmet | 750.00 | 2 |
| Ahmet | 300.00 | 1 |
| NULL | 100.00 | 5 |
musteri_id=5 olan siparişin müşterisi yok (ad = NULL).
4. FULL OUTER JOIN
Her iki tablodaki tüm satırları döner; eşleşme yoksa NULL.
SELECT m.ad, s.tutar
FROM musteriler m
FULL OUTER JOIN siparisler s ON m.id = s.musteri_id
| ad | tutar |
|---|---|
| Ahmet | 500.00 |
| Ahmet | 300.00 |
| Mehmet | 750.00 |
| Ayşe | NULL |
| Fatma | NULL |
| NULL | 100.00 |
5. CROSS JOIN
Kartezyen çarpım — her satır diğer tablodaki her satırla eşleşir.
SELECT m.ad, u.ad AS urun
FROM musteriler m
CROSS JOIN urunler u
4 müşteri x N ürün = 4N satır sonuç.
6. NATURAL JOIN
Aynı isimli sütunlarda otomatik eşleşme yapar.
-- Her iki tabloda 'id' sütunu varsa otomatik eşleşir
SELECT * FROM musteriler NATURAL JOIN siparisler
Dikkat: Sütun isimlerinin tam olarak eşleşmesi gerekir. Beklenmedik sonuçlara yol açabileceğinden açık
ONkoşulu tercih edilir.
7. LEFT SEMI JOIN
Sol tabloda sağla eşleşen satırları döner; sağ tablo sütunları dahil edilmez.
SELECT m.ad, m.sehir
FROM musteriler m
LEFT SEMI JOIN siparisler s ON m.id = s.musteri_id
| ad | sehir |
|---|---|
| Ahmet | İstanbul |
| Mehmet | Ankara |
Siparişi olan müşteriler.
INveyaEXISTSalt sorgusunun performanslı alternatifi.
Eşdeğer standart SQL:
SELECT ad, sehir FROM musteriler
WHERE id IN (SELECT musteri_id FROM siparisler)
8. RIGHT SEMI JOIN
Sağ tabloda solla eşleşen satırları döner; sol tablo sütunları dahil edilmez.
SELECT s.id, s.tutar
FROM musteriler m
RIGHT SEMI JOIN siparisler s ON m.id = s.musteri_id
9. LEFT ANTI JOIN
Sol tabloda sağla eşleşmeyen satırları döner.
SELECT m.ad, m.sehir
FROM musteriler m
LEFT ANTI JOIN siparisler s ON m.id = s.musteri_id
| ad | sehir |
|---|---|
| Ayşe | İzmir |
| Fatma | Bursa |
Hiç siparişi olmayan müşteriler.
NOT INveyaNOT EXISTSalt sorgusunun performanslı alternatifi.
Eşdeğer standart SQL:
SELECT ad, sehir FROM musteriler
WHERE id NOT IN (SELECT musteri_id FROM siparisler)
10. RIGHT ANTI JOIN
Sağ tabloda solla eşleşmeyen satırları döner.
SELECT s.id, s.tutar, s.musteri_id
FROM musteriler m
RIGHT ANTI JOIN siparisler s ON m.id = s.musteri_id
| id | tutar | musteri_id |
|---|---|---|
| 104 | 100.00 | 5 |
Müşteri kaydı olmayan (geçersiz müşteri ID) siparişler.
Çoklu JOIN
SELECT m.ad AS musteri,
u.ad AS urun,
sd.miktar,
u.fiyat * sd.miktar AS toplam
FROM siparisler s
INNER JOIN musteriler m ON s.musteri_id = m.id
INNER JOIN siparis_detay sd ON s.id = sd.siparis_id
INNER JOIN urunler u ON sd.urun_id = u.id
ORDER BY toplam DESC
Self JOIN
Aynı tabloyu kendisiyle birleştirir:
-- Aynı şehirdeki müşteri çiftleri
SELECT a.ad AS musteri1, b.ad AS musteri2, a.sehir
FROM musteriler a
INNER JOIN musteriler b ON a.sehir = b.sehir AND a.id < b.id
JOIN Optimizasyonu
MenzeletDB optimizer’ı JOIN stratejisini otomatik seçer:
| Strateji | Kullanım Durumu |
|---|---|
| Hash Join | Eşitlik koşulu (ON a.id = b.id), büyük tablolar |
| Nested Loop | Eşitsizlik koşulları, küçük tablolar |
| Sort-Merge Join | Her iki tablo sıralı olduğunda |
Sorgu planını görmek için
EXPLAINkullanılabilir:EXPLAIN SELECT m.ad, s.tutar FROM musteriler m JOIN siparisler s ON m.id = s.musteri_id
İndeks Kullanımı
MenzeletDB, büyük tablolarda hızlı arama için bellek içi (in-memory) indeksler destekler.
İndeks Türleri
| Tür | En İyi Kullanım | Karmaşıklık |
|---|---|---|
| Hash | Eşitlik aramaları (WHERE id = 5) | O(1) |
| BTree | Aralık aramaları (WHERE fiyat BETWEEN 100 AND 500) | O(log N) |
İndeks Komutları
İndeks Listesi
INDEX LIST
Tüm aktif in-memory indeksleri gösterir.
Eşitlik Araması (Hash İndeks)
INDEX LOOKUP urunler urun_adi Klavye
urunler tablosunda urun_adi sütununda Klavye değerini arar.
Aralık Araması (BTree İndeks)
INDEX SCAN urunler fiyat 100 500
urunler tablosunda fiyat sütununda 100 ile 500 arasındaki değerleri arar.
Desteklenen İndeks Değer Tipleri
| Tip | Açıklama |
|---|---|
Int | Tam sayı |
Str | Metin |
Date | Tarih |
Timestamp | Zaman damgası |
Decimal | Ondalıklı sayı |
Uuid | 16-byte binary UUID |
Otomatik İndeks Kullanımı
MenzeletDB optimizer’ı WHERE koşullarında indeks kullanılabilir sütunları otomatik tespit eder:
- IndexLookupRule: Mantıksal planda
Filter + TableScankalıbını tespit eder ve varolan indeks üzerinden arama yapar - Boş sonuç optimizasyonu: İndeks araması boş dönerse
EmptyRelationile gerçek disk taraması yapılmaz - Epoch doğrulaması: İndeks versiyon numarası (epoch) ile tablo versiyon numarası (data_version) eşleşmezse indeks kullanılmaz (stale indeks koruması)
Bloom Filter
MenzeletDB, INSERT işlemlerinde duplicate key kontrolü için Bloom filter kullanır:
- Her tablo için
{tablo}.bloomdosyası oluşturulabilir - Kirschner-Mitzenmacher double hashing, FPR (False Positive Rate) ~%0.1
- Bincode ile diske kalıcı olarak saklanır (
save()/load()) - INSERT strict modda: Bloom filter “yok” derse kesin yok; “var” derse Parquet’ten doğrulanır
Desteklenmeyen ve Kısmi Desteklenen Özellikler
MenzeletDB, sütun tabanlı (columnar) bir analitik veritabanıdır. Geleneksel RDBMS’lerden (SQL Server, Oracle, PostgreSQL) farklı olarak bazı özellikler kasıtlı olarak desteklenmez, bazıları ise kısmi destek sunar.
Kısmi Destek
Transaction (İşlem)
Durum: Kısmi destek — yalnızca INSERT buffer’lama
MenzeletDB, BEGIN / COMMIT / ROLLBACK komutlarını destekler, ancak yalnızca INSERT (ve INSERT OR REPLACE) komutları transaction kapsamında buffer’lanır. DDL komutları (CREATE/DROP/ALTER TABLE, CREATE/DROP VIEW vb.) transaction içinde engellenir.
-- Desteklenen akış:
BEGIN
INSERT INTO urunler VALUES (1, 'Klavye', 450.00)
INSERT INTO urunler VALUES (2, 'Mouse', 250.00)
COMMIT -- Her iki INSERT sırasıyla çalıştırılır
-- Geri alma:
BEGIN
INSERT INTO urunler VALUES (3, 'Monitör', 3500.00)
ROLLBACK -- Buffer temizlenir, hiçbir veri yazılmaz
Davranış detayları:
BEGIN/BEGIN TRANSACTION: Transaction modunu başlatır. İç içe BEGIN engellenir.COMMIT: Buffer’daki INSERT’leri sırasıyla çalıştırır. Kısmi başarı durumunda kaç komutun başarılı/başarısız olduğu raporlanır.ROLLBACK: Buffer’ı temizler, hiçbir yazma gerçekleşmez.- DDL komutları (CREATE TABLE, DROP VIEW vb.) transaction içinde reddedilir.
- SELECT, SHOW gibi okuma komutları transaction içinde normal çalışır.
Desteklenmeyen:
-- Bu komutlar MenzeletDB'de çalışmaz:
SAVEPOINT sp1;
ROLLBACK TO SAVEPOINT sp1;
| ACID Özelliği | Durum | Açıklama |
|---|---|---|
| Atomicity | Kısmi | BEGIN/COMMIT ile INSERT grubu atomik; kısmi hata raporlanır |
| Consistency | Evet | NOT NULL kısıtı, tip kontrolü |
| Isolation | Yok | Eşzamanlı yazmalarda izolasyon seviyesi yok |
| Durability | Evet | WAL ile çökme kurtarma |
ALTER TABLE
Durum: Kısmi destek — 5 işlem türü
Desteklenen işlemler:
-- Nullable sütun ekleme
ALTER TABLE urunler ADD COLUMN stok INT
-- NOT NULL + DEFAULT ile sütun ekleme (mevcut satırlara default yazılır)
ALTER TABLE urunler ADD COLUMN durum VARCHAR NOT NULL DEFAULT 'aktif'
-- Sütun silme
ALTER TABLE urunler DROP COLUMN eski_sutun
-- Sütunu NOT NULL olarak işaretleme (mevcut NULL kontrolü yapılır)
ALTER TABLE urunler ALTER COLUMN ad SET NOT NULL
-- Tablo yeniden adlandırma
ALTER TABLE urunler RENAME TO malzemeler
Desteklenmeyen işlemler:
-- Bu komutlar MenzeletDB'de çalışmaz:
ALTER TABLE urunler ALTER COLUMN fiyat TYPE BIGINT; -- Tip değişikliği
ALTER TABLE urunler ADD CONSTRAINT pk PRIMARY KEY (id); -- Kısıt ekleme
ALTER TABLE urunler RENAME COLUMN eski TO yeni; -- Sütun yeniden adlandırma
Detaylı ALTER TABLE kullanımı için bkz: Tablo Güncelleme
Desteklenmiyor
Stored Procedure (Saklı Yordam)
Durum: Desteklenmiyor
-- Bu komutlar MenzeletDB'de çalışmaz:
CREATE PROCEDURE rapor_olustur(tarih DATE) ...;
EXEC rapor_olustur('2024-01-01');
DROP PROCEDURE rapor_olustur;
Neden: MenzeletDB bir sorgu motorudur, prosédüral programlama ortamı değildir. PL/SQL veya T-SQL benzeri bir dil katmanı bulunmaz.
Alternatif: İş mantığı istemci tarafında uygulanabilir. Karmaşık sorgular için CTE kullanılabilir:
WITH aylik_satis AS (
SELECT date_part('month', tarih) AS ay, SUM(tutar) AS toplam
FROM siparisler
GROUP BY date_part('month', tarih)
),
yillik_ozet AS (
SELECT ay, toplam,
SUM(toplam) OVER (ORDER BY ay) AS kumulatif
FROM aylik_satis
)
SELECT * FROM yillik_ozet ORDER BY ay
Trigger (Tetikleyici)
Durum: Desteklenmiyor
-- Bu komutlar MenzeletDB'de çalışmaz:
CREATE TRIGGER stok_guncelle AFTER INSERT ON siparisler ...;
DROP TRIGGER stok_guncelle;
Neden: MenzeletDB olay tabanlı (event-driven) bir mekanizma içermez. Tetikleyiciler geleneksel OLTP veritabanlarının özellikleridir; MenzeletDB analitik (OLAP) odaklıdır.
Alternatif: Uygulama katmanında olay işlemecileri (event handlers) ile benzer işlevsellik sağlanabilir.
Kullanıcı Tanımlı Fonksiyon (UDF)
Durum: Kullanıcı tarafından SQL üzerinden oluşturulamaz
-- Bu komutlar MenzeletDB'de çalışmaz:
CREATE FUNCTION hesapla(x INT) RETURNS INT ...;
DROP FUNCTION hesapla;
Mevcut durum: MenzeletDB, 200+ yerleşik fonksiyonu destekler. Ayrıca sunucu içinde kayıtlı özel fonksiyonlar bulunur (ör. collate()). Ancak kullanıcıların SQL üzerinden yeni fonksiyon tanımlaması desteklenmez.
Tüm kullanılabilir fonksiyonlar için bkz: SQL Fonksiyonları
Karşılaştırma Tablosu
| Özellik | SQL Server | PostgreSQL | Oracle | MySQL | MenzeletDB |
|---|---|---|---|---|---|
| CREATE/DROP TABLE | Evet | Evet | Evet | Evet | Evet |
| ALTER TABLE | Evet | Evet | Evet | Evet | Kısmi (5 işlem) |
| VIEW | Evet | Evet | Evet | Evet | Evet |
| Stored Procedure | Evet | Evet | Evet | Evet | Hayır |
| Trigger | Evet | Evet | Evet | Evet | Hayır |
| Transaction (ACID) | Evet | Evet | Evet | Evet | Kısmi (INSERT) |
| JOIN (10 tür) | Evet | Evet | Evet | Kısmi | Evet |
| Window Functions | Evet | Evet | Evet | Evet | Evet |
| CTE | Evet | Evet | Evet | Evet | Evet |
| Subquery | Evet | Evet | Evet | Evet | Evet |
| RBAC | Evet | Evet | Evet | Evet | Evet |
| DESCRIBE TABLE | Evet | Evet | Evet | Evet | Evet |
| UDF (SQL ile) | Evet | Evet | Evet | Evet | Hayır |
| Columnar Storage | Hayır | Hayır | Hayır | Hayır | Evet |
| Parquet Format | Hayır | Hayır | Hayır | Hayır | Evet |
Not: MenzeletDB, OLTP (işlemsel) değil OLAP (analitik) odaklıdır. Desteklenmeyen özellikler, projenin sütun tabanlı analitik mimarisinin bilinçli tasarım kararlarıdır.
Diğer veritabanlarından geçiş yaparken detaylı eşleme tablosu için bkz: Göç Rehberi
Kimlik Doğrulama
Bağlantı Durum Makinesi
Her TCP bağlantısı WaitingForAuth durumunda başlar. Veritabanı işlemlerine erişim yalnızca kimlik doğrulama sonrasında mümkündür.
┌─────────────────┐ LOGIN <kullanıcı> <parola> ┌───────────────────┐
│ WaitingForAuth │ ────────────────────────────► │ Authenticated │
│ (başlangıç) │ (doğrulama başarılı) │ { username } │
└─────────────────┘ └───────────────────┘
│ │
Hatalı parola / EXIT SQL / INDEX / EXIT
→ bağlantı kapatılır → normal işleme
LOGIN Komutu
LOGIN <kullanıcı_adı> <parola>
Başarılı Giriş
menzelet> LOGIN sa güçlüŞifre123
Giriş başarılı. Hoş geldiniz, sa!
Başarısız Giriş
Hatalı şifre veya geçersiz kullanıcı durumunda bağlantı otomatik olarak kapatılır (güvenlik nedeniyle).
Giriş Zorunluluğu
- Her yeni bağlantıda
LOGINkomutu zorunludur - Kimlik doğrulamadan önce SQL veya INDEX komutları reddedilir
- Giriş başarısız olursa bağlantı güvenle sonlandırılır
Şifreleme
| Özellik | Değer |
|---|---|
| Algoritma | Kriptografik hash (tek yönlü) |
| Salt | 16-byte rastgele (kullanıcıya özgü) |
| Yöntem | hash(salt + şifre) |
| Karşılaştırma | Sabit süreli (zamanlama saldırısı önlemi) |
Güvenlik Garantileri
| Koruma | Yöntem |
|---|---|
| Şifre saklama | Hash + kullanıcıya özgü 16-byte salt |
| Zamanlama saldırısı | Sabit süreli karşılaştırma |
| DoS koruması | Maksimum eşzamanlı bağlantı limiti |
| Bağlantı limiti aşımı | Hata mesajı gönderilip bağlantı güvenle kapatılır |
| Erken komut koruması | Kimlik doğrulama öncesi SQL komutları reddedilir |
AUDIT Kaydı
Her Authenticated komut sunucu loglarına kaydedilir:
[AUDIT] sa@127.0.0.1:54321 -> CREATE TABLE urunler (id INT, fiyat FLOAT)
[AUDIT] mehmet@192.168.1.50:42100 -> SELECT * FROM siparisler
Kullanıcı ve Rol Yönetimi
Bu işlemler mnz_sys_admin rolüne sahip kullanıcılar (ör. sa) tarafından yapılabilir.
Kullanıcı İşlemleri
Oluşturma (CREATE USER)
CREATE USER mehmet PASSWORD 'güçlüŞifre456'
- Kullanıcı adı benzersiz olmalıdır
- Şifre hash + salt ile korunarak saklanır
- Yeni kullanıcının varsayılan olarak hiçbir yetkisi yoktur
Şifre Güncelleme (ALTER USER PASSWORD)
ALTER USER mehmet PASSWORD 'yeniŞifre789'
Aktiflik Durumu Değiştirme (ALTER USER SET ACTIVE)
-- Pasifleştir (giriş yapamaz)
ALTER USER mehmet SET ACTIVE FALSE
-- Tekrar aktifleştir
ALTER USER mehmet SET ACTIVE TRUE
Silme (DROP USER)
DROP USER mehmet
Listeleme (SHOW USERS)
SHOW USERS
Koruma Kuralları
| Kural | Açıklama |
|---|---|
sa silinemez | DROP USER sa → hata |
sa pasifleştirilemez | ALTER USER sa SET ACTIVE FALSE → hata |
Rol İşlemleri
Oluşturma (CREATE ROLE)
CREATE ROLE rapor_admin
Silme (DROP ROLE)
DROP ROLE rapor_admin
Listeleme (SHOW ROLES)
SHOW ROLES
Koruma Kuralları
| Kural | Açıklama |
|---|---|
| Yerleşik roller silinemez | DROP ROLE mnz_sys_admin → hata |
mnz_ ön eki rezerve | CREATE ROLE mnz_ozel → hata |
Yerleşik Roller
| Rol | Kapsam | Yetkiler |
|---|---|---|
mnz_sys_admin | Sistem geneli | Tüm yetkiler — her DB’de tam erişim |
mnz_db_owner | Tek veritabanı | DDL + DML (tam erişim) |
mnz_db_reader | Tek veritabanı | Sadece SELECT |
mnz_db_writer | Tek veritabanı | SELECT, INSERT, UPDATE, DELETE |
Yetki Atama (GRANT)
-- Yerleşik rol ata
GRANT mnz_db_reader ON DATABASE musteri_db TO mehmet
GRANT mnz_db_writer ON DATABASE analitik_db TO ali
-- Belirli izinler ver
GRANT select, insert ON DATABASE musteri_db TO rapor_admin
Yetki Geri Alma (REVOKE)
REVOKE insert ON DATABASE musteri_db FROM rapor_admin
Yetki Sorgulama (SHOW GRANTS)
SHOW GRANTS FOR mehmet
Permission Listesi
Sistem Seviyesi
| Permission | Açıklama |
|---|---|
create_database | Veritabanı oluşturma |
drop_database | Veritabanı silme |
create_user | Kullanıcı oluşturma |
alter_user | Kullanıcı güncelleme |
drop_user | Kullanıcı silme |
create_role | Rol oluşturma |
drop_role | Rol silme |
assign_permission | Yetki atama (GRANT) |
revoke_permission | Yetki geri alma (REVOKE) |
server_admin | Sunucu konfigürasyonu |
Veritabanı Seviyesi
| Permission | Açıklama |
|---|---|
create_table | Tablo oluşturma |
drop_table | Tablo silme |
alter_table | Tablo güncelleme (ADD COLUMN, DROP COLUMN, RENAME, SET NOT NULL) |
select | Veri okuma |
insert | Veri ekleme |
update | Veri güncelleme |
delete | Veri silme |
create_index | İndeks oluşturma |
drop_index | İndeks silme |
create_view | Görünüm (VIEW) oluşturma |
drop_view | Görünüm (VIEW) silme |
Tam Senaryo Örneği
-- sa olarak giriş yap
LOGIN sa güçlüŞifre123
-- Yeni veritabanı oluştur
CREATE DATABASE proje_db
-- Yeni kullanıcı oluştur
CREATE USER gelistirici PASSWORD 'dev2024!'
-- Okuma + yazma yetkisi ver
GRANT mnz_db_writer ON DATABASE proje_db TO gelistirici
-- Özel rol oluştur
CREATE ROLE rapor_okuyucu
-- Role sadece okuma izni ver
GRANT select ON DATABASE proje_db TO rapor_okuyucu
-- Yeni bir kullanıcıya özel rolü ata
CREATE USER analist PASSWORD 'analiz2024!'
GRANT rapor_okuyucu ON DATABASE proje_db TO analist
-- Yetkileri kontrol et
SHOW GRANTS FOR gelistirici
SHOW GRANTS FOR analist
Konfigürasyon
Sunucu ayarları src/menzelet.toml dosyasından okunur. Dosya yoksa varsayılan değerlerle çalışır.
Tam Konfigürasyon Dosyası
[server]
# Dinlenecek IP adresi
# "127.0.0.1" = Sadece yerel erişim (önerilen)
# "0.0.0.0" = Tüm ağ arayüzleri (uzak erişim / Docker için)
host = "127.0.0.1"
# TCP port numarası
port = 4600
# Maksimum eşzamanlı bağlantı sayısı (Semaphore limiti)
max_connections = 100
[storage]
# Veritabanı klasörlerinin kök dizini
data_dir = "data"
[collation]
# Varsayılan dil duyarlı sıralama dili
# Desteklenen değerler: tr, en, de, ar, fr, es, ...
default_locale = "tr"
# Collation hassasiyet seviyesi
# primary = Temel karakter farkları (a ≠ b)
# secondary = Aksanlar (a ≠ á)
# tertiary = Büyük/küçük harf (a ≠ A)
strength = "tertiary"
[security]
# TLS sertifika dosyası (isteğe bağlı)
# tls_cert_path = "certs/server.pem"
# tls_key_path = "certs/server-key.pem"
[pool]
# Sunucu başlatıldığında önceden oluşturulacak bağlantı havuzu sayısı
min_idle = 5
# Havuzda tutulabilecek maksimum boşta bağlantı sayısı
max_idle = 20
[metrics]
# Prometheus metrik HTTP endpoint'i aktif mi?
enabled = true
# Metrik sunucusunun dinleyeceği IP adresi
host = "127.0.0.1"
# Metrik HTTP port numarası
port = 9100
[optimizer]
# Sorgu optimizasyonu ayarları
[wal]
# WAL (Write-Ahead Log) ayarları
# format = "ndjson" # veya "bincode" (kompakt format)
Önemli Ayarlar
Uzak Erişim
Sunucuya başka makinelerden erişmek için:
[server]
host = "0.0.0.0"
port = 4600
./menzelet-cli 192.168.1.100:4600
Docker İçin
Docker container içinde host = "0.0.0.0" gereklidir (dışarıdan erişim için). entrypoint.sh bunu otomatik ayarlar.
Bağlantı Havuzu
| Ayar | Varsayılan | Açıklama |
|---|---|---|
pool.min_idle | 5 | Başlangıçta ön-ısınma ile oluşturulacak bağlantı sayısı |
pool.max_idle | 20 | Havuzda tutulabilecek maksimum boşta bağlantı sayısı |
WAL Formatı
| Format | Boyut | Hız | Okunabilirlik |
|---|---|---|---|
ndjson (varsayılan) | Normal | Normal | Okunabilir, debug dostu |
bincode | ~3x küçük | ~5x hızlı | Binary, okunabilir değil |
Yedekleme ve Geri Yükleme
Veri Dizin Yapısı
MenzeletDB verileri klasör bazlı olarak saklar:
data/ ← Kök veri dizini (config: data_dir)
├── master/ ← Sistem DB (silinemez, bootstrap'ta oluşur)
│ ├── mnz_users.parquet ← Kullanıcılar (şifreler korunmuş)
│ ├── mnz_roles.parquet ← Roller
│ ├── mnz_user_roles.parquet ← Kullanıcı-rol eşlemeleri
│ ├── mnz_role_permissions.parquet ← Rol-permission eşlemeleri
│ ├── mnz_tables.parquet ← Tablo katalog meta verileri
│ ├── catalog.delta ← Katalog değişiklik günlüğü
│ └── user_mgmt.delta ← Kullanıcı/rol değişiklik günlüğü
│
├── musteri_db/ ← Kullanıcı veritabanı
│ ├── siparisler.parquet ← Base Parquet (LZ4)
│ ├── siparisler.wal ← WAL dosyası
│ ├── siparisler.bloom ← Bloom filter
│ ├── siparisler-flush-0001.parquet ← Flush dosyası #1
│ ├── siparisler-flush-0002.parquet ← Flush dosyası #2
│ └── urunler.parquet
│
└── analitik_db/ ← Başka bir kullanıcı veritabanı
└── satislar.parquet
Yedekleme
Verilerinizi yedeklemek için data/ dizinini kopyalamanız yeterlidir:
# Linux/macOS
cp -r data/ data_backup_$(date +%Y%m%d)/
# Windows PowerShell
Copy-Item -Recurse data\ "data_backup_$(Get-Date -Format 'yyyyMMdd')\"
Tutarlı Yedekleme
En tutarlı yedek için:
- Sunucuyu durdurun (bellekteki tüm veriler diske yazılır)
data/dizinini kopyalayın- Sunucuyu yeniden başlatın
Sunucu çalışırken yapılan yedeğe WAL dosyaları dahil olduğundan, geri yükleme sonrası WAL replay ile tutarlılık sağlanır.
Geri Yükleme
- Sunucuyu durdurun
- Mevcut
data/dizinini yedekle (güvenlik için) data/dizinini yedeğiyle değiştirin- Sunucuyu yeniden başlatın
# Linux/macOS
systemctl stop menzelet-server
mv data/ data_old/
cp -r data_backup_20240115/ data/
systemctl start menzelet-server
# Windows PowerShell
Stop-Service menzelet-server
Rename-Item data data_old
Copy-Item -Recurse data_backup_20240115\ data\
Start-Service menzelet-server
Tek Veritabanı Yedekleme
Sadece belirli bir veritabanını yedeklemek için:
# musteri_db yedeği
cp -r data/musteri_db/ backup_musteri_db/
# Geri yükleme
cp -r backup_musteri_db/ data/musteri_db/
Not:
masterveritabanı güvenlik meta verilerini içerir. Tam geri yükleme içinmaster/klasörü de dahil edilmelidir.
Delta Log Dosyaları
| Dosya | İçerik | Konum |
|---|---|---|
catalog.delta | Tablo oluşturma/silme işlemleri | data/master/ |
user_mgmt.delta | Kullanıcı/rol yönetimi işlemleri | data/master/ |
Bu dosyalar ekleme-tabanlı (append-only) formattadır. Belirli bir eşiği aştığında kompaksiyon tetiklenir ve tüm değişiklikler ana veri dosyasına yazılır.
İzleme ve Metrikler
Prometheus Metrikleri
MenzeletDB, Prometheus text format uyumlu HTTP endpoint sunar.
Konfigürasyon
[metrics]
enabled = true
host = "127.0.0.1" # "0.0.0.0" = uzak erişim
port = 9100
Endpoint
GET http://127.0.0.1:9100/metrics
Metrik Kategorileri
Bağlantı Metrikleri
| Metrik | Tip | Açıklama |
|---|---|---|
connections_total | Counter | Toplam TCP bağlantı sayısı |
connections_active | Gauge | Anlık aktif bağlantı sayısı |
connections_rejected | Counter | Limit aşımı reddedilen bağlantılar |
Kimlik Doğrulama
| Metrik | Tip | Açıklama |
|---|---|---|
auth_success_total | Counter | Başarılı giriş sayısı |
auth_failure_total | Counter | Başarısız giriş sayısı |
Sorgu Metrikleri
| Metrik | Tip | Açıklama |
|---|---|---|
queries_total | Counter | Toplam sorgu sayısı |
queries_select | Counter | SELECT sorgu sayısı |
queries_insert | Counter | INSERT sorgu sayısı |
queries_ddl | Counter | DDL komut sayısı |
İndeks Metrikleri
| Metrik | Tip | Açıklama |
|---|---|---|
index_builds_total | Counter | İndeks inşa sayısı |
index_lookups_total | Counter | İndeks arama sayısı |
Depolama / Havuz Metrikleri
| Metrik | Tip | Açıklama |
|---|---|---|
wal_appends_total | Counter | WAL yazma sayısı |
flush_total | Counter | Flush işlem sayısı |
pool_active | Gauge | Anlık kullanılan context sayısı |
pool_idle | Gauge | Anlık boşta context sayısı |
pool_created | Counter | Toplam oluşturulan context |
pool_reused | Counter | Havuzdan yeniden kullanılan context |
Metrik Türleri
| Tip | Açıklama | Örnek |
|---|---|---|
AtomicCounter | Monoton artan sayaç | connections_total, queries_total |
AtomicGauge | Anlık değer (yükselir/düşer) | connections_active, pool_idle |
Performans
- ~1-2 ns maliyet (x86-64
LOCK XADDtalimatı) - ~200 byte bellek tüketimi (tüm metrikler için)
- Lock-free: Mutex/RwLock kullanılmaz
Örnek Prometheus Çıktısı
# HELP connections_total Toplam bağlantı sayısı
# TYPE connections_total counter
connections_total 1523
# HELP connections_active Anlık aktif bağlantı
# TYPE connections_active gauge
connections_active 12
# HELP queries_total Toplam sorgu sayısı
# TYPE queries_total counter
queries_total 45678
# HELP pool_active Aktif context
# TYPE pool_active gauge
pool_active 8
# HELP pool_idle Boşta context
# TYPE pool_idle gauge
pool_idle 12
Grafana Entegrasyonu
Prometheus veri kaynağını yapılandırdıktan sonra aşağıdaki sorgularla dashboard oluşturulabilir:
| Panel | PromQL |
|---|---|
| Anlık bağlantılar | connections_active |
| Sorgu hızı (req/s) | rate(queries_total[5m]) |
| Havuz doluluk oranı | pool_active / (pool_active + pool_idle) |
| Auth başarısızlık oranı | rate(auth_failure_total[5m]) |
Yük Testi Aracı
menzelet_loadgen ile stres testi yapılabilir:
cargo run -p menzelet_loadgen -- \
--host 127.0.0.1:4600 \
--scenario mixed \
--concurrency 50 \
--iterations 1000
Senaryolar: read, write, mixed, auth, ddl
Göç Rehberi
Bu rehber, diğer veritabanı sistemlerinden MenzeletDB’ye geçiş yaparken dikkat edilmesi gerekenleri içerir.
SQL Server’dan Göç
| SQL Server | MenzeletDB | Not |
|---|---|---|
CREATE DATABASE x | CREATE DATABASE x | Aynı |
USE x | USE x | Aynı |
CREATE TABLE t (id INT IDENTITY) | CREATE TABLE t (id INT) | IDENTITY yok, uuid() kullanılabilir |
ALTER TABLE t ADD col INT | ALTER TABLE t ADD COLUMN col INT | ADD/DROP COLUMN, SET NOT NULL, RENAME desteklenir |
CREATE VIEW v AS ... | CREATE VIEW v AS ... | Desteklenir (CREATE VIEW / DROP VIEW / SHOW VIEWS) |
CREATE PROCEDURE p ... | Desteklenmiyor | İstemci tarafında uygula |
CREATE TRIGGER tr ... | Desteklenmiyor | Uygulama katmanında event handler |
BEGIN TRAN ... COMMIT | BEGIN ... COMMIT | INSERT tamponlama desteklenir (DDL transaction icinde engellenir) |
GETDATE() | NOW() | Yerleşik fonksiyon |
ISNULL(x, y) | COALESCE(x, y) | SQL standardı |
TOP 10 | LIMIT 10 | SQL standardı |
NEWID() | uuid() | Yerleşik fonksiyon |
LEN(str) | LENGTH(str) | SQL standardı |
CHARINDEX(a, b) | STRPOS(b, a) | Parametre sırası farklı |
DATEDIFF(day, a, b) | date_part('epoch', b) - date_part('epoch', a) | Manuel hesaplama |
DATEADD(day, 10, d) | d + INTERVAL '10 days' | Interval aritmetiği |
CONVERT(type, val) | CAST(val AS type) | SQL standardı |
@@ROWCOUNT | Desteklenmiyor | – |
Veri Tipi Eşlemesi
| SQL Server | MenzeletDB |
|---|---|
INT | INT |
BIGINT | BIGINT |
SMALLINT | SMALLINT |
TINYINT | TINYINT |
FLOAT | FLOAT |
REAL | FLOAT32 |
VARCHAR(n) | VARCHAR (sabit uzunluk yok) |
NVARCHAR(n) | VARCHAR (UTF-8 varsayılan) |
BIT | BOOL |
DATE | DATE |
DATETIME | TIMESTAMP |
DATETIMEOFFSET | TIMESTAMPTZ |
DECIMAL(p,s) | DECIMAL (38,10 sabit) |
VARBINARY | BLOB |
UNIQUEIDENTIFIER | UUID |
PostgreSQL’den Göç
| PostgreSQL | MenzeletDB | Not |
|---|---|---|
CREATE DATABASE | CREATE DATABASE | Aynı |
CREATE TABLE ... SERIAL | CREATE TABLE ... INT | SERIAL yok, uuid() kullanılabilir |
ALTER TABLE | ALTER TABLE | ADD/DROP COLUMN, SET NOT NULL, RENAME TO desteklenir |
CREATE VIEW | CREATE VIEW | Desteklenir (CREATE VIEW / DROP VIEW / SHOW VIEWS) |
CREATE FUNCTION | Desteklenmiyor | 200+ yerleşik fonksiyon |
CREATE TRIGGER | Desteklenmiyor | Uygulama katmanında |
BEGIN ... COMMIT | BEGIN ... COMMIT | INSERT tamponlama desteklenir (DDL engellenir) |
gen_random_uuid() | uuid() | Yerleşik fonksiyon |
NOW() | NOW() | Aynı |
EXTRACT(...) | EXTRACT(...) | Aynı |
string_agg() | string_agg() | Aynı |
array_agg() | array_agg() | Aynı |
Oracle’dan Göç
| Oracle | MenzeletDB | Not |
|---|---|---|
SYS_GUID() | uuid() | Yerleşik fonksiyon |
SYSDATE | NOW() | UTC döndürür |
NVL(x, y) | COALESCE(x, y) | SQL standardı |
ROWNUM <= 10 | LIMIT 10 | SQL standardı |
DECODE(x, a, b, c) | CASE WHEN x=a THEN b ELSE c END | SQL standardı |
TO_CHAR(date, fmt) | to_char(date, fmt) | Benzer |
CREATE SEQUENCE | Desteklenmiyor | uuid() veya istemci-taraflı |
CREATE SYNONYM | Desteklenmiyor | – |
CREATE MATERIALIZED VIEW | Desteklenmiyor | – |
MySQL’den Göç
| MySQL | MenzeletDB | Not |
|---|---|---|
AUTO_INCREMENT | Desteklenmiyor | uuid() veya istemci-taraflı |
IFNULL(x, y) | COALESCE(x, y) | SQL standardı |
UUID() | uuid() | Aynı işlevsellik |
CONCAT(a, b) | CONCAT(a, b) | Aynı |
GROUP_CONCAT(...) | string_agg(...) | Farklı isim |
LIMIT x OFFSET y | LIMIT x OFFSET y | Aynı |
NOW() | NOW() | Aynı |
CREATE INDEX idx ON t(col) | INDEX BUILD t col btree | Farklı sözdizimi |
Genel Göç Stratejisi
- Şema taşınması: Kaynak veritabanındaki tablo yapılarını MenzeletDB CREATE TABLE sözdizimine dönüştürün
- Veri aktarımı: Kaynak veritabanından CSV/Parquet olarak dışa aktarın, MenzeletDB’ye INSERT ile yükleyin
- Sorgu uyarlama: SP ve Trigger’ları uygulama-taraflı mantığa dönüştürün (VIEW desteklenmektedir)
- Test: Sorgu sonuçlarını karşılaştırın
Desteklenen Özellikler
| Özellik | MenzeletDB Karşılığı |
|---|---|
| VIEW | CREATE VIEW, DROP VIEW, SHOW VIEWS |
| Transaction | BEGIN / COMMIT / ROLLBACK (INSERT tamponlama, DDL engellenir) |
| ALTER TABLE | ADD COLUMN, DROP COLUMN, SET NOT NULL, RENAME TO (ALTER TYPE hariç) |
Desteklenmeyen Özellikler İçin Alternatifler
| Özellik | Alternatif |
|---|---|
| Stored Procedure | İstemci/uygulama mantığı |
| Trigger | Uygulama katmanında event handler |
| ALTER TABLE (ALTER TYPE) | DROP TABLE + CREATE TABLE ile yeniden oluşturma |
| AUTO_INCREMENT / SERIAL | uuid() veya istemci-taraflı sayaç |
| Sequence | İstemci-taraflı sayaç |
Sorun Giderme
Bu sayfa, MenzeletDB kullanırken karşılaşılan yaygın sorunları ve çözümlerini içerir.
Bağlantı Sorunları
Sunucuya Bağlanamıyorum
Belirti: İstemci “bağlantı reddedildi” hatası veriyor.
Olası nedenler ve çözümler:
-
Sunucu çalışıyor mu?
- Sunucuyu başlattığınızdan emin olun
cargo run -p menzelet_serverveya./menzelet-server
-
Doğru adres ve port mu?
- Varsayılan:
127.0.0.1:4600 menzelet.tomldosyasındaki[server]bölümünü kontrol edin
- Varsayılan:
-
Güvenlik duvarı?
- Port 4600’un açık olduğundan emin olun
- Windows: Windows Defender Firewall ayarlarını kontrol edin
- Linux:
ufw statusveyaiptables -L
-
telnet/nc kullanıyorum, çalışıyor mu?
- MenzeletDB length-prefix framing protokolü kullanır
telnetvencuyumlu değildir- Her zaman
menzelet-clikullanın
Bağlantı Kopuyor
Belirti: İşlem sırasında bağlantı aniden kapanıyor.
Olası nedenler:
- Hatalı LOGIN girişimi (güvenlik önlemi olarak bağlantı kapatılır)
- Sunucu maksimum bağlantı limitine ulaşmış olabilir (
max_connections) - Ağ zaman aşımı
Kimlik Doğrulama Sorunları
“Kimlik doğrulaması gerekli” Hatası
Neden: LOGIN komutu kullanılmadan SQL çalıştırılmaya çalışıldı.
Çözüm:
menzelet> LOGIN sa şifreniz
Hatalı Şifre
Belirti: LOGIN sonrası bağlantı hemen kapanıyor.
Olası nedenler:
- Şifre yanlış yazılmış olabilir (büyük/küçük harf duyarlı)
- Kullanıcı pasifleştirilmiş olabilir (
is_active = false)
Çözüm:
saile giriş yapın ve kullanıcıyı kontrol edin:SHOW USERS
Yetkilendirme Sorunları
“Permission denied” Hatası
Neden: Kullanıcının ilgili işlem için yetkisi yok.
Çözüm:
saile bağlanın- Kullanıcının yetkilerini kontrol edin:
SHOW GRANTS FOR kullanici_adi - Gerekli yetkileri atayın:
GRANT mnz_db_writer ON DATABASE veritabani_adi TO kullanici_adi
master DB Üzerinde İşlem Yapılamadı
Neden: master sistem veritabanıdır ve bazı işlemler kısıtlıdır.
Bilgi:
mastersilinemezsakullanıcısı silinemez ve pasifleştirilemezmnz_ön ekli roller silinemez
Veri Sorunları
INSERT Hatası: “Anahtar zaten mevcut”
Neden: Aynı birincil anahtarla veri eklenmiş.
Çözümler:
- Farklı bir anahtar kullanın
- Mevcut veriyi güncellemek için:
INSERT OR REPLACE INTO ...
SELECT Sonuç Dönmüyor
Olası nedenler:
- Tablo boş olabilir
- WHERE koşulu hiçbir satırı karşılamıyor olabilir
- Yanlış veritabanı seçili olabilir —
USE dogru_dbile kontrol edin
Türkçe Karakterler Yanlış Sıralanıyor
Neden: Collation ayarı yapılandırılmamış.
Çözüm:
menzelet.tomldosyasında:
[collation]
default_locale = "tr"
strength = "tertiary"
- Sorgularda
ORDER BY collate(sutun)kullanın
Sunucu Sorunları
Sunucu Çökmesi Sonrası Veri Kaybı
Bilgi: MenzeletDB WAL (Write-Ahead Log) sayesinde çökme sonrası otomatik kurtarma yapar.
Adımlar:
- Sunucuyu yeniden başlatın
- WAL dosyaları otomatik replay edilir
- Flush edilmemiş veriler belleğe geri yüklenir
- Normal çalışmaya devam edilir
Sunucu Başlamıyor
Olası nedenler:
-
Port kullanılıyor:
- Başka bir işlem 4600 portunu kullanıyor olabilir
- Windows:
netstat -ano | findstr :4600 - Linux:
lsof -i :4600
-
data/ dizini bozuk:
data/master/dizinindeki Parquet dosyalarını kontrol edin- Yedekten geri yükleyin
-
Yapılandırma hatası:
menzelet.tomldosyasının geçerli TOML formatı olduğunu kontrol edin
Bellek Kullanımı Yüksek
Olası nedenler:
- Çok fazla tablo için bellek tamponu açık
- Büyük indeksler bellekte tutuluyor
- Flush eşiği çok büyük ayarlanmış
Çözüm:
COMPACTkomutu ile flush dosyalarını birleştirinmenzelet.tomliçinde flush eşiğini düşürün
Docker Sorunları
Container Başlamıyor
Kontrol:
docker logs menzelet
Olası nedenler:
MENZELET_SA_PASSWORDortam değişkeni belirlenmemiş- Port çatışması (4600 kullanılıyor)
Dışarıdan Bağlanamıyorum
Çözüm:
- Container’ın
-p 4600:4600ile başlatıldığından emin olun host = "0.0.0.0"ayarının yapılandırıldığını kontrol edin
Performans Sorunları
Sorgular Yavaş
Olası nedenler ve çözümler:
-
İndeks kullanın:
- Sık aranan sütunlarda indeks oluşturun
INDEX BUILD tablo sutun btree
-
Flush ve compaction:
- Çok fazla flush dosyası sorgu performansını düşürür
COMPACTkomutu ile birleştirin
-
WHERE koşulu optimize edin:
- Eşitlik kontrolleri için Hash indeks
- Aralık sorguları için BTree indeks
Yardım ve Destek
Sorunun devam etmesi durumunda:
- Sunucu loglarını inceleyin (stdout)
--pingile sunucu sağlık kontrolü yapın- Prometheus metriklerini kontrol edin (
/metricsendpoint)
Komut Referansı
MenzeletDB’nin desteklediği tüm komutların tam referansı.
Bağlantı Komutları
| Komut | Açıklama |
|---|---|
LOGIN <kullanıcı> <şifre> | Kimlik doğrulama |
EXIT | Bağlantıyı kapat |
QUIT | Bağlantıyı kapat (EXIT ile aynı) |
Veritabanı Komutları
| Komut | Açıklama |
|---|---|
CREATE DATABASE <isim> | Yeni veritabanı oluştur |
DROP DATABASE <isim> | Veritabanını sil |
USE <isim> | Aktif veritabanını değiştir |
SHOW DATABASES | Tüm veritabanlarını listele |
Tablo Komutları
| Komut | Açıklama |
|---|---|
CREATE TABLE <tablo> (<sütunlar>) | Yeni tablo oluştur |
ALTER TABLE <tablo> ADD COLUMN <sütun> <tip> | Tabloya nullable sütun ekle |
ALTER TABLE <tablo> ADD COLUMN <sütun> <tip> NOT NULL DEFAULT <değer> | NOT NULL + varsayılan değerli sütun ekle |
ALTER TABLE <tablo> DROP COLUMN <sütun> | Sütun sil |
ALTER TABLE <tablo> ALTER COLUMN <sütun> SET NOT NULL | Sütunu NOT NULL yap |
ALTER TABLE <tablo> RENAME TO <yeni_isim> | Tabloyu yeniden adlandır |
DROP TABLE <tablo> | Tabloyu sil |
DESCRIBE TABLE <tablo> | Tablo şemasını göster (sütun/tip/nullable) |
SHOW TABLES | Aktif veritabanındaki tabloları listele |
COMPACT <tablo> | Flush dosyalarını birleştir |
VIEW Komutları
| Komut | Açıklama |
|---|---|
CREATE VIEW <isim> AS <SELECT ...> | Görünüm oluştur |
DROP VIEW <isim> | Görünümü sil |
SHOW VIEWS | Aktif veritabanındaki görünümleri listele |
Transaction Komutları
| Komut | Açıklama |
|---|---|
BEGIN / BEGIN TRANSACTION | Transaction başlat (yalnızca INSERT buffer’lanır) |
COMMIT | Buffer’daki INSERT’leri çalıştır |
ROLLBACK | Buffer’ı temizle, değişiklikleri iptal et |
CREATE TABLE Sözdizimi
CREATE TABLE tablo_adi (
sutun1 TIP [NOT NULL],
sutun2 TIP [NOT NULL],
...
)
Desteklenen Veri Tipleri
| SQL Tipi | Eşdeğerler | Açıklama |
|---|---|---|
INT | INTEGER, INT32 | 32-bit tam sayı |
BIGINT | INT64 | 64-bit tam sayı |
SMALLINT | INT16 | 16-bit tam sayı |
TINYINT | INT8 | 8-bit tam sayı |
FLOAT | FLOAT64 | 64-bit ondalıklı sayı |
FLOAT32 | – | 32-bit ondalıklı sayı |
VARCHAR | TEXT, STRING | Metin |
BOOL | BOOLEAN | Mantıksal değer |
DATE | – | Tarih (YYYY-MM-DD) |
TIMESTAMP | – | Zaman damgası |
TIMESTAMPTZ | – | Zaman damgası + UTC |
DECIMAL | – | Sabit noktalı ondalık (38,10) |
BLOB | – | İkili veri |
UUID | – | 128-bit benzersiz tanımlayıcı |
SQL Komutları
SELECT
SELECT [sütunlar | *] FROM tablo
[WHERE koşul]
[ORDER BY sütun [ASC | DESC]]
[LIMIT sayı]
[OFFSET sayı]
INSERT
-- Strict mod (aynı anahtar varsa hata)
INSERT INTO tablo VALUES (değer1, değer2, ...)
-- Upsert mod (aynı anahtar varsa güncelle)
INSERT OR REPLACE INTO tablo VALUES (değer1, değer2, ...)
UPDATE
UPDATE tablo SET sütun = değer [, sütun2 = değer2] WHERE koşul
DELETE
DELETE FROM tablo WHERE koşul
JOIN
SELECT t1.sütun, t2.sütun
FROM tablo1 t1
JOIN tablo2 t2 ON t1.anahtar = t2.anahtar
[WHERE koşul]
GROUP BY
SELECT sütun, COUNT(*) FROM tablo
GROUP BY sütun
[HAVING koşul]
Aggregate Fonksiyonlar
| Fonksiyon | Açıklama |
|---|---|
COUNT(*) | Tüm satırları say (NULL dahil) |
COUNT(sütun) | NULL olmayan satırları say |
SUM(sütun) | Toplam (NULL hariç) |
AVG(sütun) | Ortalama (NULL hariç) |
MIN(sütun) | Minimum değer |
MAX(sütun) | Maksimum değer |
Scalar Fonksiyonlar
| Fonksiyon | Açıklama |
|---|---|
LOWER(metin) | Küçük harfe çevir |
UPPER(metin) | Büyük harfe çevir |
LENGTH(metin) | Karakter sayısı |
SUBSTR(metin, başlangıç, uzunluk) | Alt metin çıkar |
ROUND(sayı, ondalık) | Yuvarla |
CAST(değer AS tip) | Tip dönüşümü |
COALESCE(a, b, ...) | İlk NULL olmayan değer |
NULLIF(a, b) | Eşitse NULL döndür |
Tarih/Saat Fonksiyonları
| Fonksiyon | Açıklama |
|---|---|
NOW() | Geçerli UTC zaman damgası |
date_part('birim', tarih) | Tarih bileşeni çıkar |
EXTRACT(birim FROM tarih) | SQL standart tarih bileşeni |
tarih + INTERVAL 'süre' | Tarihe süre ekle |
Window Fonksiyonları
| Fonksiyon | Açıklama |
|---|---|
ROW_NUMBER() OVER (...) | Satır numarası ata |
FIRST_VALUE(sütun) OVER (...) | Penceredeki ilk değer |
LAST_VALUE(sütun) OVER (...) | Penceredeki son değer |
Collation (Dil Duyarlı Sıralama)
-- Türkçe alfabetik sıralama
SELECT isim FROM musteriler ORDER BY collate(isim)
-- Azalan sırada
SELECT urun_adi FROM urunler ORDER BY collate(urun_adi) DESC
İndeks Komutları
| Komut | Açıklama |
|---|---|
INDEX LIST | Tüm indeksleri listele |
INDEX LOOKUP <tablo> <sütun> <değer> | Eşitlik araması (Hash) |
INDEX SCAN <tablo> <sütun> <başlangıç> <bitiş> | Aralık araması (BTree) |
Kullanıcı Yönetimi Komutları
| Komut | Açıklama |
|---|---|
CREATE USER <isim> PASSWORD '<şifre>' | Kullanıcı oluştur |
ALTER USER <isim> PASSWORD '<şifre>' | Şifre güncelle |
ALTER USER <isim> SET ACTIVE TRUE | Kullanıcıyı aktifleştir |
ALTER USER <isim> SET ACTIVE FALSE | Kullanıcıyı pasifleştir |
DROP USER <isim> | Kullanıcıyı sil |
SHOW USERS | Kullanıcıları listele |
Rol Yönetimi Komutları
| Komut | Açıklama |
|---|---|
CREATE ROLE <isim> | Rol oluştur |
DROP ROLE <isim> | Rol sil |
SHOW ROLES | Rolleri listele |
Yetki Komutları
| Komut | Açıklama |
|---|---|
GRANT <rol> ON DATABASE <db> TO <kullanıcı> | Rol ata |
GRANT <yetki1, yetki2> ON DATABASE <db> TO <rol> | Permission ata |
REVOKE <yetki> ON DATABASE <db> FROM <kullanıcı> | Yetkiyi geri al |
SHOW GRANTS FOR <kullanıcı> | Yetkileri göster |
Yerleşik Roller
| Rol | Kapsam | Açıklama |
|---|---|---|
mnz_sys_admin | Sistem | Tüm yetkiler |
mnz_db_owner | Veritabanı | DDL + DML tam erişim |
mnz_db_reader | Veritabanı | Sadece SELECT |
mnz_db_writer | Veritabanı | SELECT, INSERT, UPDATE, DELETE |
Permissionlar
Sistem seviyesi:
create_database, drop_database, create_user, alter_user, drop_user, create_role, drop_role, assign_permission, revoke_permission, server_admin
Veritabanı seviyesi:
create_table, drop_table, alter_table, select, insert, update, delete, create_index, drop_index, create_view, drop_view
İstemci Bayrakları
| Bayrak | Açıklama |
|---|---|
--lang <dil> | Arayüz dilini ayarla (tr, en, es) |
--ping | Sunucu sağlık kontrolü |
--help | Kullanım bilgisi |
İstemci Meta-Komutları (Kısayollar)
| Kısayol | Açıklama |
|---|---|
\d | Tabloları listele (SHOW TABLES) |
\d <tablo> | Tablo şemasını göster (DESCRIBE TABLE <tablo>) |
\dt | Tabloları listele (SHOW TABLES) |
\du | Kullanıcıları listele (SHOW USERS) |
\dr | Rolleri listele (SHOW ROLES) |
\di | İndeksleri listele (INDEX LIST) |
\dv | Görünümleri listele (SHOW VIEWS) |
\timing | Sorgu zamanlamayı aç/kapat |
\x | Genişletilmiş görünümü aç/kapat |
\q | Çıkış |
\? | Meta-komut yardımını göster |