MariaDB'de view (görünüm), kaydedilmiş bir SELECT sorgusunun sonucu üzerine kurulan sanal bir tablodur ve CREATE VIEW ad AS SELECT ... ile oluşturulur. View veri saklamaz; her sorgulandığında tanımındaki SELECT çalışır. Karmaşık birleştirmeleri gizlemek, kullanıcılara yalnızca belirli sütun ve satırları göstermek ve uygulamayı tablo yapısındaki değişikliklerden korumak için kullanılır.
Bu yazıda MariaDB 12.3 LTS belgelerine göre CREATE VIEW sözdizimini, OR REPLACE, ALTER VIEW ve DROP VIEW kullanımını, MERGE ve TEMPTABLE algoritmalarını, DEFINER ve SQL SECURITY ile güvenlik bağlamını, güncellenebilir view kurallarını ve WITH CHECK OPTION davranışını anlatıyoruz. Temel SELECT ve JOIN bilgisini SELECT, WHERE, ORDER BY ve JOIN ve alt sorgular yazılarında bulabilirsiniz.
View ne işe yarar?

Belgelerdeki hızlı başlangıç rehberi view'ların faydalarını birkaç başlıkta toplar. İlki karmaşıklığı gizlemektir: birkaç tabloyu birleştiren, tarih hesapları yapan uzun bir sorguyu bir kez view olarak tanımlarsınız, ardından herkes SELECT * FROM view_adi yazarak aynı sonucu alır. İkincisi sütun düzeyinde güvenliktir: ev adresi veya telefon gibi hassas sütunları view'a hiç koymazsanız, yalnızca view üzerinde yetkisi olan kullanıcı bu verileri göremez. Üçüncüsü satır düzeyinde kısıtlamadır: view'ın WHERE koşulu kullanıcının hangi satırları göreceğini belirler.
Dördüncü fayda soyutlamadır. Tablolar bölünür, birleştirilir veya yeniden adlandırılırsa view tanımını güncellersiniz ve uygulama aynı view'ı sorgulamaya devam eder. Son olarak, sık kullanılan bir sorguyu bir kez iyi yazıp view'a koymak, herkesin kendi verimsiz sürümünü yazma riskini azaltır. Bununla birlikte view kendi başına sorguyu hızlandırmaz; çalışan şey yine altındaki SELECT'tir.
CREATE VIEW sözdizimi
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW [IF NOT EXISTS] view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]View bir veritabanına aittir; ad nitelendirilmezse varsayılan veritabanında oluşturulur, db_adi.view_adi yazarak başka bir veritabanında da oluşturabilirsiniz. Tablolar ve view'lar aynı ad alanını paylaştığı için bir veritabanında aynı adı taşıyan bir tablo ile bir view bulunamaz. View sütun adları benzersiz olmalıdır; varsayılan olarak SELECT listesindeki adlar kullanılır, isterseniz view adından sonra parantez içinde kendi adlarınızı verebilirsiniz. Bu listedeki ad sayısı SELECT'in döndürdüğü sütun sayısına eşit olmalıdır.
CREATE TABLE t (qty INT, price INT);
INSERT INTO t VALUES(3, 50);
CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;
SELECT * FROM v;
+------+-------+-------+
| qty | price | value |
+------+-------+-------+
| 3 | 50 | 150 |
+------+-------+-------+CREATE VIEW için view üzerinde CREATE VIEW yetkisi ve seçilen her sütun için bir yetki gerekir. OR REPLACE kullanıyorsanız DROP yetkisi de aranır. Yetkilerin nasıl verildiğini GRANT ve REVOKE ile yetkiler yazısında anlattık. Belgelere göre CREATE VIEW, MariaDB 10.6.1'den beri atomik bir DDL işlemidir.
Tanım dondurulur: SELECT * ve sonradan eklenen sütunlar
View tanımı oluşturulduğu anda dondurulur. Belgelerin verdiği örnek açıklayıcıdır: bir view'ı SELECT * ile tanımladıktan sonra tabloya yeni bir sütun eklerseniz, bu sütun view'da görünmez. SHOW CREATE VIEW çıktısında yıldızın açılıp sütun adlarına çevrildiğini görürsünüz. Tersi durum da önemlidir: view'ın başvurduğu bir tabloyu veya sütunu sonradan silerseniz view tanımı geçersiz hale gelir ve view'ı sorgulamak hata verir. Bu tür sorunları bulmak için belgeler CHECK TABLE kullanmayı önerir.
ERROR 1356 (HY000): View 'db_name.view_name' references invalid table(s) or
column(s) or function(s) or definer/invoker of view lack rights to use themBelgelerde sayılan diğer tanım kısıtları şunlardır: tanım sistem veya kullanıcı değişkenlerine, hazırlanmış ifade parametrelerine ve saklı program içindeyse program parametrelerine ya da yerel değişkenlere başvuramaz. TEMPORARY bir tabloya başvuramaz ve geçici view oluşturulamaz. Başvurulan tüm tablolar tanım sırasında var olmalıdır. View'a tetikleyici bağlanamaz. Belgedeki kısıt listesi ayrıca FROM kısmında alt sorgu kullanılamayacağını da belirtir.
ORDER BY view tanımında kullanılabilir, ancak view'ı sorgulayan ifadenin kendi ORDER BY'ı varsa yok sayılır. LIMIT için durum daha belirsizdir: hem tanımda hem sorguda LIMIT varsa hangisinin uygulanacağı belgelere göre tanımsızdır. Aynı ilke DISTINCT gibi seçenekler ve FOR UPDATE gibi ifadeler için de geçerlidir. Bu yüzden sıralama ve sayfalamayı view'ı kullanan sorguya bırakmak daha öngörülebilirdir.
View'ın sonucu, oluşturulduktan sonra değiştirdiğiniz sistem değişkenlerinden de etkilenebilir. Belgelerdeki örnekte SELECT 'abc' üzerine kurulu bir view, sql_mode boşken çift tırnaklı "mycol" ifadesini düz metin olarak, ANSI_QUOTES açıkken sütun adı olarak yorumlar ve iki farklı sonuç döndürür:
CREATE VIEW v (mycol) AS SELECT 'abc';
SET sql_mode = '';
SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| mycol |
+-------+
SET sql_mode = 'ANSI_QUOTES';
SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| abc |
+-------+OR REPLACE, IF NOT EXISTS, ALTER VIEW ve DROP VIEW
Var olan bir view'ı aynı adla yeniden oluşturmaya çalışırsanız 1050 numaralı hata alırsınız. CREATE OR REPLACE VIEW view yoksa oluşturur, varsa ALTER VIEW gibi davranarak tanımı değiştirir. IF NOT EXISTS ise view varsa hata yerine bir not üretir; belgelere göre bu iki seçenek birlikte kullanılamaz.
CREATE VIEW v AS SELECT a, a*2 AS a2 FROM t;
ERROR 1050 (42S01): Table 'v' already exists
CREATE OR REPLACE VIEW v AS SELECT a, a*2 AS a2 FROM t;
Query OK, 0 rows affected (0.04 sec)
CREATE VIEW IF NOT EXISTS v AS SELECT a, a*2 AS a2 FROM t;
Query OK, 0 rows affected, 1 warning (0.01 sec)ALTER VIEW yalnızca var olan bir view'ın tanımını değiştirir ve sözdizimi CREATE VIEW'a benzer. CREATE VIEW ve DROP yetkileri gerektirir; belgelere göre yalnızca view'ı tanımlayan kullanıcı veya SUPER yetkisine sahip kullanıcılar çalıştırabilir. Saklı rutinler içinde ALTER VIEW kullanılamaz; orada CREATE OR REPLACE VIEW tercih edilmelidir.
ALTER VIEW v AS SELECT a, a*3 AS a2 FROM t;
DROP VIEW IF EXISTS v, v2, v3;DROP VIEW bir veya birden çok view'ı siler ve her biri için DROP yetkisi gerektirir. Listede olmayan bir view varsa MariaDB hangi view'ları silemediğini adıyla bildirir, ama var olanların hepsini yine de siler. IF EXISTS eklerseniz eksik view'lar için hata yerine not üretilir. Söz diziminde görülen RESTRICT ve CASCADE sözcükleri belgelere göre ayrıştırılır ama yok sayılır; yani bir view'ı silmek ona bağlı başka view'ları silmez, onları bozuk bırakır.
Algoritmalar: MERGE, TEMPTABLE ve UNDEFINED

ALGORITHM standart SQL'e bir MariaDB eklentisidir ve view'ın nasıl işleneceğini belirler. MERGE algoritmasında view tanımı ile view'ı kullanan sorgu birleştirilip tek bir sorgu olarak çalıştırılır. TEMPTABLE algoritmasında view'ın sonucu önce geçici bir tabloya yazılır, dış sorgu bu tablo üzerinde çalışır. UNDEFINED (veya hiç yazmamak) seçimi MariaDB'ye bırakır; varsayılan değer de budur.
Belgelere göre MERGE genellikle daha verimlidir ve bir view yalnızca bu algoritmayla güncellenebilir. TEMPTABLE ise bazı durumlarda işe yarar: alttaki tablolardaki kilitler, ifadenin işlenmesi bitmeden bırakılabilir. Belgedeki birleştirme örneğinde SELECT * FROM view_name WHERE view_field1 < 8000 sorgusu, view'ın kendi koşuluyla AND ile bağlanıp parantezlerle önceliği korunarak tek bir sorguya dönüştürülür.
Bir view aşağıdakilerden birini içeriyorsa MERGE algoritmasını kullanamaz; böyle bir view'ı ALGORITHM = MERGE ile tanımlasanız bile geçici tablo gerekeceği için algoritma UNDEFINED olarak kalabilir:
HAVING,LIMIT,GROUP BYveyaDISTINCTUNIONveyaUNION ALLMAX(),MIN(),SUM(),COUNT()gibi toplama fonksiyonlarıSELECTlistesinde alt sorgu- Hiç alttaki tablosu olmayan, yalnızca sabit değerlere başvuran tanım
Güvenlik bağlamı: DEFINER ve SQL SECURITY
View sorgulandığında alttaki tablolara erişim yetkisi hangi hesaba göre denetlenir? Bunu SQL SECURITY belirler. Varsayılan değer DEFINER'dır: yetkiler view'ı tanımlayan hesaba göre denetlenir. INVOKER seçilirse view'ı çağıran kullanıcının yetkileri kullanılır. Standart SQL yalnızca INVOKER davranışını tanımlar; DEFINER ve SQL SECURITY yan tümceleri MariaDB'nin eklentileridir.
DEFINER yan tümcesi 'kullanici'@'host' biçiminde bir hesap alır; varsayılan değer view'ı oluşturan kullanıcıdır. SET USER yetkiniz yoksa yalnızca kendi hesabınızı definer olarak yazabilirsiniz. Bu yetkiyle başka bir hesap yazabilirsiniz; hesap yoksa yalnızca uyarı üretilir. Ancak SQL SECURITY DEFINER olan bir view sorgulandığında definer hesabı artık yoksa hata oluşur. Bu yüzden bir kullanıcıyı silmeden önce onun definer olduğu nesneleri kontrol etmek iyi bir alışkanlıktır; kullanıcı yönetimi için CREATE USER ile kullanıcı oluşturma yazısına bakın.
CREATE SQL SECURITY INVOKER VIEW personel_ozet AS
SELECT ad, soyad, gorev
FROM personel;
GRANT SELECT ON sirket.personel_ozet TO 'rapor'@'localhost';Bu örnekte iki yaklaşımın farkını düşünün. View DEFINER güvenliğiyle tanımlansaydı, rapor kullanıcısı personel tablosunda hiçbir yetkiye sahip olmadan yalnızca view üzerindeki SELECT yetkisiyle ad, soyad ve görevleri görebilirdi; bu, sütun gizleme için kullanılan klasik yöntemdir. INVOKER ile tanımlandığı için kullanıcının alttaki tabloda da yetkisi olması gerekir. Belgelerdeki hızlı başlangıç rehberi INVOKER'ı, view'ın sorgulayan kullanıcının izinleriyle çalışması olarak açıklar.
Güncellenebilir view ve WITH CHECK OPTION
Bazı view'lar UPDATE, DELETE ve INSERT ifadelerinde kullanılabilir ve değişiklik alttaki tabloya yansır. Bunun temel şartı, view satırları ile tablo satırları arasında bire bir ilişki olmasıdır. Belgelere göre şu yapılardan biri view'ı güncellenemez yapar: ALGORITHM=TEMPTABLE, HAVING, GROUP BY, DISTINCT, UNION, toplama fonksiyonları, SELECT listesinde alt sorgu, WHERE içinde FROM'daki tabloya başvuran alt sorgu, güncellenemez bir view'a dayanmak, aynı tablo sütununa birden çok başvuru, dış birleştirme (outer join) ve birden fazla tabloyu aynı anda güncelleyen iç birleştirme.
View'a satır eklemek (INSERT) için ek şartlar vardır: view, varsayılan değeri olmayan tüm tablo sütunlarını içermeli ve sütunlar türetilmiş olmamalıdır. fiyat + 25, LOWER(ad), alt sorgu, sabit sayı veya iki sütunun bölümü gibi ifadeler türetilmiş sütun sayılır. MariaDB her view için bir IS_UPDATABLE bayrağı tutar ve bunu INFORMATION_SCHEMA.VIEWS tablosunda görebilirsiniz; bu bayrak güncellenebilirliği gösterir, ekleme yapılabileceğini garanti etmez.
CREATE TABLE table1 (x INT);
CREATE VIEW view1 AS SELECT x, 99 AS y FROM table1;
SELECT TABLE_NAME,IS_UPDATABLE FROM INFORMATION_SCHEMA.VIEWS;
+------------+--------------+
| TABLE_NAME | IS_UPDATABLE |
+------------+--------------+
| view1 | YES |
+------------+--------------+
UPDATE view1 SET y = 5;
ERROR 1348 (HY000): Column 'y' is not updatableWITH CHECK OPTION, güncellenebilir bir view üzerinden yapılan ekleme ve güncellemelerin view'ın WHERE koşulunu sağlamasını zorunlu kılar. Başka bir view üzerine kurulan view'larda kapsamı LOCAL ve CASCADED belirler: LOCAL yalnızca tanımlanan view'ın koşulunu, CASCADED alttaki view'ların koşullarını da denetler. İkisi de yazılmazsa varsayılan CASCADED'dır. Belgedeki örnekte x < 100 koşullu bir view'ın üzerine x > 10 koşullu iki view kurulur; 150 değeri LOCAL view'dan geçer, CASCADED view'da reddedilir:
CREATE VIEW view_check1 AS SELECT * FROM table1 WHERE x < 100 WITH CHECK OPTION;
CREATE VIEW view_check2 AS SELECT * FROM view_check1 WHERE x > 10 WITH LOCAL CHECK OPTION;
CREATE VIEW view_check3 AS SELECT * FROM view_check1 WHERE x > 10 WITH CASCADED CHECK OPTION;
INSERT INTO view_check2 VALUES (150);
INSERT INTO view_check3 VALUES (150);
ERROR 1369 (HY000): CHECK OPTION failed 'test.view_check3'Belgelerde ilginç bir uç durum da anlatılır: WHERE 0 gibi her zaman yanlış olan bir koşula sahip ve WITH CHECK OPTION içeren bir view, hiç satır kabul etmeyen ve hiç satır göstermeyen bir yapıya dönüşür. Aynı koşulla ama CHECK OPTION olmadan tanımlanan eklenebilir bir view ise veriyi kabul eder ama göstermez. İkinci durum, eklenen verinin kaybolduğu izlenimi verdiği için hata ayıklaması zor sorunlara yol açabilir.
View tanımlarını incelemek
Bir view'ın tam tanımını SHOW CREATE VIEW view_adi ile görürsünüz. Tüm view'ları sistem tablosu üzerinden listelemek için INFORMATION_SCHEMA.VIEWS sorgulanır; burada VIEW_DEFINITION, CHECK_OPTION, IS_UPDATABLE, DEFINER, SECURITY_TYPE ve ALGORITHM sütunları bulunur. Özellikle bir kullanıcıyı silmeden veya veritabanını taşımadan önce definer ve güvenlik türünü bu tablodan kontrol etmek, sonradan çıkacak yetki hatalarını önler. Veritabanı dökümü alırken view'ların nasıl ele alındığı için mariadb-dump ile yedekleme yazısına bakabilirsiniz.
SELECT TABLE_NAME, DEFINER, SECURITY_TYPE, ALGORITHM, IS_UPDATABLE
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA = 'sirket';Sık yapılan hatalar

- View'ın veriyi önbelleğe aldığını sanmak: View yalnızca kaydedilmiş bir sorgudur; her çağrıda alttaki
SELECTyeniden çalışır. Performans sorunu varsa sorgunun planına bakın: EXPLAIN ve ANALYZE. - SELECT * ile tanımlayıp yeni sütun beklemek: Tanım oluşturulduğunda dondurulur; yeni sütun için view'ı
CREATE OR REPLACE VIEWile yeniden tanımlayın. - Tablo silinince view'ı unutmak: Bağımlı view bozulur ve 1356 hatası verir.
CHECK TABLEile düzenli kontrol yapın. - Definer hesabını silmek:
SQL SECURITY DEFINERview'lar definer hesabı yoksa hata verir. Hesabı silmeden önceINFORMATION_SCHEMA.VIEWStablosundaDEFINERsütununu kontrol edin. - GROUP BY içeren view'ı güncellemeye çalışmak: Toplama ve gruplama içeren view'lar güncellenemez; değişikliği alttaki tabloya yapın.
- Hem view'da hem sorguda LIMIT kullanmak: Hangisinin uygulanacağı tanımsızdır; sayfalamayı view'ı kullanan sorguya bırakın.
Sık Sorulan Sorular
MariaDB materialized view destekliyor mu?
Yerel belgelerde view'lar yalnızca kaydedilmiş sorgu olarak tanımlanır; sonucu kalıcı olarak saklayan bir view türü anlatılmaz. TEMPTABLE algoritması da sonucu yalnızca sorgu süresince geçici tabloda tutar. Sonucu saklamanız gerekiyorsa ayrı bir tablo oluşturup onu düzenli aralıklarla yenilemeniz gerekir; bunu Event Scheduler ile zamanlayabilirsiniz.
View üzerinden INSERT yapabilir miyim?
Evet, view tek tabloya dayanıyor, güncellenebilirlik şartlarını sağlıyor, varsayılan değeri olmayan tüm sütunları içeriyor ve sütunları türetilmiş değilse. Koşul dışı satırların eklenmesini engellemek için WITH CHECK OPTION ekleyin.
View performansı tablodan kötü mü?
MERGE algoritmasıyla işlenen bir view, tanımı sorguyla birleştirildiği için doğrudan yazılmış eşdeğer sorgu gibi çalışır. TEMPTABLE gerektiren view'larda (örneğin GROUP BY içerenler) önce geçici tablo oluşturulur ve dış sorgudaki koşullar bu tabloya uygulanır; bu yüzden büyük veri kümelerinde planı kontrol etmek önemlidir.
View tanımında değişken kullanabilir miyim?
Hayır. Belgelere göre view tanımı sistem veya kullanıcı değişkenlerine ve hazırlanmış ifade parametrelerine başvuramaz. Parametreli bir mantık gerekiyorsa saklı yordam kullanın: stored procedure ve function.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: MariaDB öğrenme rehberi · SELECT, WHERE, ORDER BY · JOIN ve alt sorgular · GRANT ve REVOKE · Stored procedure ve function · MariaDB trigger · SQL sorgu optimizasyonu