View Dediğimiz Şey Aslında Kayıtlı Bir Sorgudur
SQLite'ta view, isim verilmiş bir SELECT ifadesinden başka bir şey değildir. Bir kez oluşturduktan sonra view'ı tıpkı bir tabloymuş gibi sorgulayabilirsiniz; ama arka planda hiçbir veri saklanmaz. View'dan her okuma yaptığında SQLite, altındaki sorguyu baştan çalıştırır.
paid_orders görünüş itibariyle bir tablo gibi davranır. Sütunları vardır, SELECT çekebilirsiniz, başka tablolarla JOIN yapabilirsiniz. Ama perde arkasında her sorgu, orijinal WHERE status = 'paid' filtresine açılır.
Aslında SQLite view mantığı tam da bu: view, bir sorguya verilen takma addır.
SQLite View Ne İşe Yarar?
En büyük kazanç isimlendirmedir. Karmaşık bir sorguya kısa ve açıklayıcı bir ad verirsiniz, geri kalan kodun da okunaklı kalır:
View olmasaydı, sorguyu yazan herkes GROUP BY cümlesini kendi başına kurmak zorunda kalırdı — ve birinin filtreyi yanlış yazma ihtimali her zaman var. View ile bu toplama işi bir kez tanımlanır. Çağıranlar sadece customer_totals'ı sorgular, üzerine kendi ek filtrelerini eklerler.
View'lar aynı zamanda bir tür yetki sınırı gibi de iş görür. Bir sorgunun password_hash sütununu açığa çıkarmaması gerekiyorsa, o sütun hariç her şeyi seçen bir view oluşturup uygulama kodunun bu view'ı kullanmasını sağlayabilirsiniz.
CREATE VIEW Söz Dizimi
Tam hâli şöyle:
CREATE [TEMPORARY] VIEW [IF NOT EXISTS] view_name [(column_aliases)] AS
SELECT ...;
Bilmenizde fayda olan birkaç nokta:
IF NOT EXISTS, view zaten varsa oluşturma adımını sessizce atlar.TEMPORARY(ya daTEMP) ile oluşturduğunuz view, bağlantı kapandığında ortadan kalkar.- Parantez içinde verdiğiniz sütun takma adları sayesinde, alttaki
SELECTsorgusuna dokunmadan view'in sütunlarını yeniden adlandırabilirsiniz.
View, kaynak tablodaki kolonların adını değiştirmeden daha okunaklı isimler (item, dollars) sunar.
View Değiştirme ve Silme (DROP VIEW)
SQLite'ta CREATE OR REPLACE VIEW veya ALTER VIEW desteklenmez. Bir view'in tanımını değiştirmek için önce silip yeniden oluşturmanız gerekir:
DROP VIEW IF EXISTS active_orders; en güvenli kullanım şeklidir — view yoksa hata fırlatmaz. View silmek alttaki tabloları asla etkilemez; siz sadece kayıtlı sorguyu siliyorsunuz.
Geçici View'lar (TEMP VIEW)
TEMP VIEW, yalnızca o anki veritabanı bağlantısı boyunca yaşar. Bağlantı kapandığında view de uçup gider. Geride tanım bırakmak istemediğiniz, anlık analiz oturumlarında oldukça işe yarar:
Geçici view'lar ayrıca bir sorgu adını şemaya kalıcı olarak işlemeden gölgelemenize de izin verir — keşif aşamasında oldukça kullanışlıdır.
SQLite View'lar Varsayılan Olarak Salt Okunurdur
İşte en kritik tuzak burada. Bir view üzerinden doğrudan INSERT, UPDATE veya DELETE yapamazsınız:
sqlite> INSERT INTO paid_orders (customer, amount) VALUES ('Eve', 50);
Runtime error: cannot modify paid_orders because it is a view
Burada işi kurtaran şey INSTEAD OF trigger'ları. Yazma işlemi geldiğinde tetiklenen ve bu işlemi alttaki gerçek tabloya yapılan bir operasyona çeviren bir trigger tanımlıyorsunuz:
View yine view olarak kalıyor; sadece artık ona yapılan yazma işlemlerinin gidecek bir yeri var. Trigger'ları bir sonraki sayfada detaylıca ele alacağız.
Materialized View Yok — Kendin Yap
Bazı veritabanları, bir view'ın sonuçlarını diske önbelleğe alıp istediğinde tazelemene izin verir. SQLite'da böyle bir şey yok. View'ı her okuduğunda altta yatan sorgu yeniden çalışır. Çoğu senaryoda bu sorun değil — SQLite hızlı, sorgu planlayıcısı da iyi iş çıkarıyor. Ama defalarca sorgulanan ağır aggregate sorgularda işin doğrusu, gerçek bir tablo oluşturup senkronizasyonunu kendin yönetmek:
Önbelleği belirli aralıklarla yenilemeniz ya da orders tablosuna trigger bağlayıp güncel tutmanız gerekir. Evet, biraz elle iş gerektiriyor — ama SQLite'ta tek yol bu.
SQLite view listeleme
View'lara ait meta bilgiler, tablolar ve indeksler ile birlikte sqlite_master içinde tutulur:
sql sütunu, view'i oluştururken yazdığınız orijinal CREATE VIEW ifadesini geri verir — view'in ne yaptığını unuttuğunda epey işe yarar. CLI tarafında ise .schema view_adi aynı bilgiyi daha derli toplu basar.
View Ne Zaman Kullanılır?
View'ler şu durumlarda gerçekten ekmeğini çıkarır:
- Aynı karmaşık sorguyu üç ya da daha fazla yerde kullanıyorsanız. Bir kez isim verip kullanmak, kopyala-yapıştır yapmaktan çok daha temiz.
- Uygulamanın bir kısmına yalnızca belirli sütunları veya satırları, süzülmüş hâlde göstermek istiyorsanız.
- Bir agregasyon kavramsal olarak tek bir bütünse (
monthly_sales,active_usersgibi) ve çağıranın buna bir isim, bir "şey" gibi davranması gerekiyorsa.
Şu durumlarda ise view kullanmaktan kaçın:
- Sorgu yalnızca tek bir yerde geçiyorsa. Olduğu yerde bırak, view'e gerek yok.
- Performans kritikse ve altta yatan sorgu pahalıysa — bu maliyeti her okumada tekrar tekrar ödüyorsunuz. Bunun yerine sonucu gerçek bir tabloya cache'lemek daha mantıklı.
- View, başka bir view'e dayanıyor, o da başka bir view'e dayanıyorsa. SQLite iç içe geçmiş yapılarla sorunsuz çalışır ama üç-dört view'lik bir zincir, debug sırasında asıl SQL'i takip etmeyi cehenneme çevirir.
Sırada: Trigger'lar
View ve trigger konuları çoğu zaman birlikte karşımıza çıkar — view'leri yazılabilir hâle getiren INSTEAD OF kalıbı, zaten trigger'ların var olma sebeplerinden biri. Ama trigger'lar tek başına da çok işe yarar: denetim (audit) kaydı tutma, ilişkili güncellemeleri zincirleme yayma, veri bütünlüğünü garanti altına alma gibi senaryolarda vazgeçilmezler. Bir sonraki sayfanın konusu tam da bu.
Sıkça Sorulan Sorular
SQLite'ta view nedir?
View, kaydedilmiş bir SELECT sorgusudur ve onu tablo gibi sorgulayabilirsiniz. Aslında veri tutmaz — view'den her okuma yaptığınızda SQLite alttaki sorguyu yeniden çalıştırır. Karmaşık bir sorguya isim verip her yerde tekrar tekrar kullanmak ya da çağıranların görmemesi gereken sütunları gizlemek için çok işe yarar.
SQLite'ta view üzerinden INSERT veya UPDATE yapılabilir mi?
Doğrudan yapılamaz. SQLite'taki view'ler salt okunurdur — view üzerinde INSERT, UPDATE veya DELETE çalıştırmaya kalktığınızda hata alırsınız. View'i yazılabilir hale getirmek için INSTEAD OF tetikleyicileri ekleyip yazma işlemini alttaki tablolar üzerindeki işlemlere çevirmeniz gerekir.
SQLite materialized view destekliyor mu?
Hayır. SQLite yalnızca normal (sanal) view'leri destekler — sorgu, view'den her okuduğunuzda yeniden çalışır. Sonuçları önbelleğe almanız gerekiyorsa gerçek bir tablo oluşturup kendiniz güncellemeniz ya da kaynak tablolarla senkron tutmak için bir tetikleyici kullanmanız gerekir.
Bir SQLite veritabanındaki tüm view'leri nasıl listelerim?
sqlite_master tablosunu sorgulayın: SELECT name FROM sqlite_master WHERE type = 'view';. CLI'da .schema komutu CREATE VIEW ifadelerini gösterir, .tables ise view'leri tablolarla birlikte listeler.