Açıklanan SQL Görünümleri: Örneklerle Oluşturun, Kullanın ve Tuzaklardan Kaçının
Görünüm, tablo gibi kullanabileceğiniz kayıtlı bir sorgudur. Nasıl oluşturulacağını, görünümlerin raporları neden tutarlı tuttuğunu, performans için ne yapıp ne yapmadıklarını ve bunları bozan tuzakları öğrenin.
- Görünüm, bir tablo gibi seçebileceğiniz, adlandırılmış, depolanmış bir sorgudur.
- Normal bir görünüm hiçbir veri saklamaz, dolayısıyla her zaman güncel sonuçları gösterir.
- Görünümler karmaşık sorguları basitleştirir, iş mantığını tutarlı tutar ve sütunlara erişimi kısıtlayabilir.
- Kendi başlarına bir sorguyu daha hızlı hale getiremezler ancak gerçekleştirilmiş görünümler bunu yapabilir.
Aynı yirmi satırlık rapor sorgusu beş kontrol paneline kopyalandı ve her kopya biraz sürüklendi. Biri iptal edilen siparişleri sayar, diğeri saymaz. SQL görünümleri bu sorunu, bu mantığı veritabanında net bir ad altında bir kez tanımlayarak çözer.
Aşağıdaki her örneği SQLite 3.50’de çalıştırdık ve gösterilen sonuçlar bu çalıştırmadan geliyor. Görünümler standart SQL’dir, ancak bir görünüm aracılığıyla güncelleme, gerçekleştirilmiş görünümler ve bağımlılık yönetimi gibi ayrıntılar veritabanları arasında farklılık gösterir ve bunları belirtiriz.
Görünüm nedir?
Görünüm, veritabanına bir adla kaydedilen bir SELECT ifadesidir. Görünümü sorguladığınızda, veritabanı kaydedilen sorguyu çalıştırır. Okumak için bir tablo gibi davranır ancak normal bir görünüm, verilerin kendi kopyasını barındırmaz.
Bir e-tabloda kayıtlı bir filtreyi düşünün. Filtre, sayfanın ikinci kopyası değildir. Her zaman en son değerleri yansıtan aynı verilere bakmanın bir yoludur.
Örnek tablolar
CREATE TABLE customers (
id INT PRIMARY KEY, name TEXT, city TEXT, email TEXT, credit_limit INT
);
CREATE TABLE orders (
id INT PRIMARY KEY, customer_id INT, total INT, status TEXT
);
INSERT INTO customers VALUES
(1,'Asha','Pune','asha@example.com',50000),
(2,'Ben','Delhi','ben@example.com',20000),
(3,'Chitra','Pune','chitra@example.com',80000);
INSERT INTO orders VALUES
(101,1,1200,'paid'), (102,1,800,'paid'),
(103,2,300,'pending'), (104,3,2500,'paid');
Görünüm oluştur
Bu görünüm her müşterinin siparişlerini özetler. Tek bir basit adın arkasında bir join, gruplandırma ve bir CASE ifadesini gizler:
CREATE VIEW customer_sales AS
SELECT c.id, c.name, c.city,
COUNT(o.id) AS orders,
COALESCE(SUM(CASE WHEN o.status = 'paid' THEN o.total END), 0) AS paid_total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name, c.city;
Artık nasıl çalıştığını bilmeden herkes onu kullanabilir:
SELECT * FROM customer_sales ORDER BY paid_total DESC;
-- 3 | Chitra | Pune | 1 | 2500
-- 1 | Asha | Pune | 2 | 2000
-- 2 | Ben | Delhi | 1 | 0
SELECT name, paid_total FROM customer_sales WHERE city = 'Pune';
-- Asha | 2000
-- Chitra | 2500
Ben sıfırla görünür çünkü görünüm LEFT JOIN ve COALESCE‘yi kullanır. Bir kez göz önüne alındığında alınan bu gibi kararlar, raporların tutarlı kalmasını sağlayan şeydir. NULL işleme konusundaki anlayışınızı tazelemek için SQL NULL değerleri‘ne bakın.
Görünümler her zaman günceldir
Normal bir görünüm her seferinde sorgusunu çalıştırdığından, yeni veriler hemen görünür. Ben için ücretli bir sipariş ekledik ve görünümü tekrar sorguladık:
INSERT INTO orders VALUES (105, 2, 900, 'paid');
SELECT name, paid_total FROM customer_sales WHERE name = 'Ben';
-- Ben | 900
Senkronize edilecek bir yenileme adımı veya kopya yoktu. Sorgu sonuçlarını ayrı bir tabloya kaydetmek arasındaki temel fark budur.
Sütunları gizleme
Görünümler genellikle yalnızca bir kişinin veya uygulamanın ihtiyaç duyduğu sütunları ortaya çıkarmak için kullanılır. Burada e-posta adresleri ve kredi limitleri hariç tutulmuştur:
CREATE VIEW public_customers AS
SELECT id, name, city FROM customers;
-- columns: id, name, city
PostgreSQL, SQL Server ve MySQL gibi izinlere sahip veritabanlarında, raporlayan kullanıcıya görünüme erişim izni verebilirsiniz ancak temel tabloya erişim izni veremezsiniz. SQLite’ın kullanıcı hesabı yok, dolayısıyla yalnızca sütun kısıtlamasının kendisini gösterebildik. Görünümü tek bir koruma katmanı olarak değerlendirin. Hassas veriler hâlâ uygun erişim kontrolüne ihtiyaç duyuyor ve bazı veritabanları, satırların kullanıcıya göre filtrelenmesi için satır düzeyinde güvenlik sunuyor.
Performans: görüntülemeler hız artışı sağlamaz
Yaygın bir efsane, görünümlerin sorguları daha hızlı hale getirmesidir. Sorguladığınızda normal görünümün yerini tanımı alır, böylece veritabanı, sorgunun tamamını kendiniz yazmışsınız gibi aynı işi yapar. Yürütme planımız, görünümün birleştirme ve gruplandırmasının sorgunun bir parçası olarak çalıştırıldığını gösterdi:
EXPLAIN QUERY PLAN SELECT * FROM customer_sales WHERE city = 'Pune';
-- CO-ROUTINE customer_sales
-- SCAN c ...
-- SEARCH o USING AUTOMATIC COVERING INDEX (customer_id=?) LEFT-JOIN
-- USE TEMP B-TREE FOR GROUP BY
-- SCAN customer_sales
Dolayısıyla yavaş bir sorgunun görünümü hala yavaş bir sorgudur. Hız, SQL sorgu optimizasyonu ve SQL dizinlerinin açıklanması‘nda ele alındığı gibi dizinlerden ve iyi sorgu tasarımından gelir. Diğer görünümler üzerine oluşturulan görünümlere de dikkat edin. İç içe geçme katmanları, aynı büyük masaya fark edilmeden birkaç kez katılmayı kolaylaştırır.
Gerçekleştirilmiş görünümler
Gerçekleştirilmiş bir görünüm, sonuçlarını önbelleğe alınmış bir tablo gibi depolar. Okumalar hızlıdır ancak veriler yalnızca son yenileme kadar tazedir.
-- PostgreSQL
CREATE MATERIALIZED VIEW daily_sales AS
SELECT order_date, SUM(total) AS revenue FROM orders GROUP BY order_date;
REFRESH MATERIALIZED VIEW daily_sales;
| Özellik | Normal görünüm | Gerçekleştirilmiş görünüm |
|---|---|---|
| Verileri depolar | Hayır | Evet |
| tazelik | Her zaman güncel | Son yenileme itibarıyla |
| Okuma hızı | Sorguyla aynı | Hızlı |
| Depolama maliyeti | Yok | Evet |
| Şunun için iyi: | Basitleştirme, tutarlılık | Ağır raporlar ve gösterge tabloları |
Destek değişir. PostgreSQL ve Oracle’ın somutlaştırılmış görünümleri vardır ve SQL Server, kendi kurallarıyla indekslenmiş görünümler sunar. SQLite ve MySQL’de bunlar bulunmuyor, bu nedenle insanlar belirli bir programa göre yenilenen düzenli bir özet tablosu kullanıyor. Bu makale için PostgreSQL örneğini çalıştırmadık.
İpucu: Gerçekleştirilmiş bir görünüm oluşturmadan önce, verilerin ne kadar eski olmasına izin verildiğine karar verin. Raporu okuyan kişiler için “Her saat başı yenilenir” ifadesi kabul edilebilir olmalıdır, bu yüzden onlara bunu söyleyin.
Bir görünümü güncelleyebilir misiniz?
Veritabanına ve görünüme bağlıdır. Gruplandırma veya DISTINCT olmadan tek bir tablo üzerinden basit bir görünüm PostgreSQL, MySQL ve SQL Server’da sıklıkla güncellenebilir ve değişiklik tabloya da geçer. Birleşimleri veya toplamaları olan bir görünüm genellikle bunu yapamaz çünkü veritabanı hangi satırın değişeceğini söyleyemez.
SQLite, görünümlere doğrudan yazmaya hiçbir şekilde izin vermez. Girişimimiz başarısız oldu:
INSERT INTO customer_sales (name) VALUES ('X');
-- cannot modify customer_sales because it is a view
Bazı veritabanları, bir görünümü yazılabilir hale getirmek için INSTEAD OF tetikleyicilerini destekler ve çoğu, görünüm aracılığıyla görünmeyecek olan yazma işlemlerini durduran WITH CHECK OPTION tetikleyicilerini destekler. Uygulamada çoğu ekip, görünümleri salt okunur olarak tutar ve tablolara yazar.
Bağımlılıklar ve kırılma
Bir görünüm, okuduğu tablolara bağlıdır. Bir tablo üzerinde bir görünüm oluşturduk, ardından tabloyu bıraktık:
CREATE TABLE ghost AS SELECT 1 AS x;
CREATE VIEW v_ghost AS SELECT x FROM ghost;
DROP TABLE ghost;
SELECT * FROM v_ghost;
-- no such table: main.ghost
SQLite bırakmaya izin verdi ve ancak daha sonra görünüm kullanıldığında başarısız oldu. PostgreSQL gibi diğer veritabanları, görünümü de kaldıran CASCADE eklemediğiniz sürece, görünümün bağlı olduğu bir tabloyu bırakmayı reddeder. Her iki durumda da, bir sütunu yeniden adlandırmak veya bırakmak görünümleri bozabilir; bu nedenle şema değişikliklerinden sonra bunları regresyon testinizde kontrol edin.
Görünümde SELECT * ile ince bir tuzak da vardır. CREATE VIEW star AS SELECT * FROM customers‘yi oluşturduk, ardından tabloya bir sütun ekledik. SQLite’ta görünüm yeni sütunu aldı. PostgreSQL dahil diğer veritabanları, görünüm oluşturulduğunda sütun listesini genişletir, böylece yeni sütunlar görünmez. Bu nedenle sütunları açıkça listeleyin. Görünümü belgeliyor ve her yerde aynı şekilde davranıyor.
Görünümleri yönetme
| Görev | Ortak sözdizimi |
|---|---|
| Oluştur | SEÇİM OLARAK GÖRÜNÜM adını OLUŞTURUN... |
| Değiştir | CREATE OR REPLACE VIEW (PostgreSQL, MySQL, Oracle) |
| SQL Server’da değiştirin | GÖRÜNÜMÜ OLUŞTURUN VEYA DEĞİŞTİRİN |
| Kaldır | DAMLA GÖRÜNÜM adı |
| Güvenli bir şekilde kaldır | VARSA GÖRÜNÜMÜ BIRAKIN adı |
Bir görünümü bırakmak yalnızca kayıtlı sorguyu kaldırır. Testimizde, customers tablosunda public_customers bırakıldıktan sonra hala üç satırın tümü vardı. Geçişlerinizle birlikte görünüm tanımlarını da sürüm kontrolünde tutun, böylece değişiklikler diğer kodlar gibi incelenir.
Görünüm, CTE ve tablo karşılaştırması
| Seçenek | Ömür boyu | Verileri depolar | Şunun için en iyisi: |
|---|---|---|---|
| Görüntüle | Düşene kadar | Hayır | Birçok sorgu tarafından kullanılan ortak mantık |
| CTE | Bir ifade | Hayır | Tek bir karmaşık sorguyu organize etme |
| Gerçekleştirilmiş görünüm | Düşene kadar | Evet | Pahalı sonuçların hızlı okunması |
| Tablo | Düşene kadar | Evet | Gerçek veriler |
Yaygın hatalar
- Hız artışı bekleniyor. Normal bir görünüm, sorgusunu her seferinde çalıştırır.
- Görünümlerde
SELECT *kullanımı. Tablolar değiştiğinde davranış veritabanları arasında farklılık gösterir. - Derin yerleştirme. Görünümler üzerine oluşturulan görünümler pahalı birleştirmeleri gizler.
- Bir görünümün içinde ORDER BY kullanma. Sorguladığınızda sıralama garanti edilmez, bu nedenle dış sorguda sıralayın.
- Anlaşılmayan adlar.
v_gibi bir önek veyacustomer_salesgibi açık bir isim yardımcı olur. - Taşıma sırasında görünümlerin unutulması. Her şema değişikliğinden sonra bunları test edin.
Son sözler
Görünümler, önemli mantığa veritabanında bir yuva vermenin basit bir yoludur. Performans hilesi olarak değil, raporları tutarlı tutmak ve gereksiz sütunları gizlemek için bunları kullanın. Başlamak için, kodunuzda çeşitli yerlerde görünen bir sorgu bulun, bunu açık sütunlar içeren bir görünüme dönüştürün ve arayanları ona yönlendirin.
Sık sorulan sorular
SQL’de görünüm nedir?
Görünüm, adı olan kayıtlı bir SELECT sorgusudur. Bunu bir tablo gibi sorgularsınız ve veritabanı her seferinde temel sorguyu çalıştırır, böylece sonuçlar her zaman güncel olur.
SQL görünümü verileri saklıyor mu?
Normal bir görünüm verileri saklamaz, yalnızca sorguyu depolar. Gerçekleştirilmiş görünüm sonuçları saklar ve güncel kalması için yenilenmesi gerekir.
Görünümler tablolardan daha mı hızlı?
Hayır. Normal bir görünüm, temel sorgusuyla aynı işi yapar. Gerçekleştirilmiş görünümler, depolama ve tazelik pahasına okumaları hızlandırabilir.
Bir görünüme ekleyebilir misiniz?
Bazen. Basit tek tablo görünümleri genellikle PostgreSQL, MySQL ve SQL Server’da güncellenebilir. Birleştirme veya gruplandırma içeren görünümler genellikle böyle değildir ve SQLite buna izin vermez.
Tablo düşerse görünüme ne olur?
Veritabanına bağlıdır. Bazıları bir görünüm ona bağlıyken tabloyu bırakmayı reddederken, diğerleri buna izin verir ve görünüm sorgulandığında başarısız olur.
Öğrenmeye devam et
Test, WordPress veya SEO konusunda yardıma mı ihtiyacınız var?
Ekiplerin daha iyi yazılımlar sunmasına ve sitelerini büyütmesine yardımcı oluyoruz. Bize ne üzerinde çalıştığınızı söyleyin, biz de bir sonraki adım için net bir öneride bulunalım.
Daha fazla kılavuz test, yapay zeka ve modern geliştirme
Bu makaleyi beğendiniz mi? Bir konu seçin ve doğrudan en yeni eğitimlerimize geçin.
Yapay Zeka Halüsinasyonları Açıklandı: Dil Modelleri Neden İşleri Düzeltiyor ve Nasıl Azaltılabilir?
Yapay zeka halüsinasyonları açıkladı: ne olduklarını, dil modellerinin bunları neden ürettiğini, yaygın türlerini, temellendirme ve yönlendirmelerle…
Makaleyi okuyun →DevOpsAçıklanan Ortam Değişkenleri: .env Dosyaları, Sırlar ve Yapılandırma Doğru Yapıldı
Çalıştırdığımız Python örnekleriyle açıklanan ortam değişkenleri: bunları okumak ve ayarlamak, neden her değerin bir dize olduğu, .env dosyaları, sü…
Makaleyi okuyun →Yazılım geliştirmeAPI Hız Sınırlamasının Açıklaması: Algoritmalar, Başlıklar ve 429 Hatalarının Ele Alınması
API hızı sınırlaması, çalıştırdığımız bir simülasyonla açıklanmıştır: belirteç kümesi, sabit pencere, kayan pencere, 429 yanıt, hız sınırı başlıklar…
Makaleyi okuyun →Test otomasyonuPython'da alay etme: Unittest.mock, patch ve Testleri Yalan Yapan Hatalar
Unittest.mock ile Python'da alay etme, test edildi: Sahte ve dönüş_değeri, yan_etki, bir adın kullanıldığı yerde yama uygulama, spesifikasyon ve oto…
Makaleyi okuyun →Yazılım testiKod Kapsamının Açıklaması: Hat ve Şube Kapsamı ve %100'ün Gerçek Anlamı
Kod kapsamı gerçek bir kapsama.py çalışmasıyla açıklanmıştır: hat, şube ve durum kapsamı, bir raporun okunması, %100 kapsamın neden hâlâ hataları ka…
Makaleyi okuyun →Veritabanları ve SQLSQL'de DELETE vs TRUNCATE vs DROP: Farklılıklar, Geri Alma ve Her Biri Ne Zaman Kullanılmalı
DELETE vs TRUNCATE vs DROP test edilmiş SQL ile açıklandı: her birinin neyi kaldırdığı, geri aldığı, tetiklediği, kimlik sıfırlaması, hızı ve Postgr…
Makaleyi okuyun →Veritabanları ve SQLAçıklanan SQL Görünümleri: Örneklerle Tuzakları Oluşturun, Kullanın ve Önleyin
Çalıştırdığımız sorgularla açıklanan SQL görünümleri: görünüm oluşturma, canlı sonuçlar, sütunları gizleme, performans, güncellenebilir ve gerçekleş…
Makaleyi okuyun →Yazılım geliştirmeTypeScript Arayüzü ve Tür: Gerçek Farklılıklar, Derleyiciyle Test Edildi
TypeScript arayüzü ve türü, gerçek derleyiciyle kontrol edildi: her ikisinin de yapabileceği, yalnızca birinin yapabileceği, bildirim birleştirme, g…
Makaleyi okuyun →Yazılım geliştirmePython *args ve **kwargs'ın Açıklaması: Açık Örneklerle Esnek Fonksiyonlar
Python *args ve **kwargs çalıştırdığımız kodla açıklanmıştır: paketleme ve paketten çıkarma, parametre sırası, yalnızca anahtar kelime ve yalnızca k…
Makaleyi okuyun →Yazılım geliştirmePython Lambda İşlevleri: Söz Dizimi, Gerçek Kullanımlar ve Ne Zaman Kullanılmaması Gerektiği
Çalıştırdığımız kodla açıklanan Python lambda işlevleri: sözdizimi, anahtarla sıralama, harita ve filtre, kapatmalar, geç bağlama tuzağı ve normal b…
Makaleyi okuyun →Yapay zekâYapay Zeka Ajanları Nelerdir? Çalıştırabileceğiniz Basit Bir Aracı Döngüsüyle Nasıl Çalışırlar?
Yapay zeka ajanları nedir? Aracı döngüsüne, araçlara, belleğe ve korkuluklara ilişkin basit bir kılavuz, çalıştırdığımız küçük bir Python döngüsü, g…
Makaleyi okuyun →DevOpsİzleme ve Gözlemlenebilirlik: Günlükler, Metrikler ve İzlerle Gerçek Fark
İzleme ve gözlemlenebilirliğin açıklanması: bilinen ve bilinmeyen arızalar, günlükler, ölçümler ve izler, ödeme olayının gözden geçirilmesi, altın s…
Makaleyi okuyun →DevOpsDocker Birimleri ve Bağlama Bağlantıları: Konteyner Verilerini Doğru Şekilde Kalıcılaştırın
Docker birimleri ile bağlama bağlamaları arasındaki karşılaştırma açıklandı: kapsayıcı verilerinin neden kaybolduğu, adlandırılmış birimler, bağlama…
Makaleyi okuyun →Test otomasyonuTDD ve BDD: Temel Farklılıklar, Her İki Şekilde Geliştirilmiş Bir Özellik ve Her Birinin Ne Zaman Kullanılacağı
TDD ve BDD, her iki yönde de oluşturulmuş bir indirim özelliğiyle açıklandı: çalıştırdığımız kodla kırmızı-yeşil-refactor, Verilen-Ne Zaman-O Zaman …
Makaleyi okuyun →Yazılım geliştirmeGit merge vs rebase: farklar, örnekler ve hangisi ne zaman kullanılır
Git merge vs rebase; gerçek log çıktısı, karşılaştırma tablosu, rebase'in altın kuralı ve güvenli bir ekip iş akışıyla anlatılıyor.
Makaleyi okuyun →Yazılım geliştirmePython Liste Üreteci (List Comprehension): Sözdizimi, Örnekler ve Kaçınılacak Durumlar
Python list comprehension anlatımı: sözdizimi, filtreleme, if-else, iç içe döngüler, ölçülmüş süreler ve düz for döngüsünün daha iyi olduğu durumlar.
Makaleyi okuyun →Veritabanları ve SQLSQL JOIN Örneklerle Açıklama (Inner, Left, Right, Full)
SQL JOIN'leri örnek tablolar ve sorgularla adım adım öğrenin: INNER, LEFT, RIGHT, FULL, CROSS ve SELF; yaygın hatalar ve performans ipuçları.
Makaleyi okuyun →