Sonsuz Döngülerden Kaçınma
Derinlik sınırları ve döngü algılama.
Sonsuz Döngülerden Kaçınma, CoddyKit'te ücretsiz bir SQL Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, SQL Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. SQL Academy kursu toplamda 4 dersten oluşur.
Sonsuz Döngü Sorunu
Özyinelemeli CTE'ler güçlüdür, ancak ciddi bir risk taşırlar: sorgunuz hiçbir zaman temel duruma ulaşmazsa sonsuza kadar döngüde kalır, kullanılabilir belleğin tamamını tüketir ve veritabanı oturumunun çökmesine neden olur.
Sonsuz döngülerin neden oluştuğunu anlamak, bunları önlemenin ilk adımıdır.
Bir Döngü Ne Zaman Sona Ermez?
Özyinelemeli bir CTE, yeni satırlar üreten bir duruma hiç ulaşmadan özyinelemeli terim yeni satırlar üretmeye devam ettiğinde sonsuza kadar döngüde kalır.
Bu genellikle iki durumda gerçekleşir: sonlandırma koşulunun eksik veya hatalı olması ya da A düğümünün B'yi, B düğümünün de yeniden A'yı göstermesi gibi döngüsel verilerin bulunması.
-- Simple recursive CTE that WOULD loop forever
-- (do NOT run this as-is; illustration only)
WITH RECURSIVE counter AS (
SELECT 1 AS n -- base case
UNION ALL
SELECT n + 1 -- recursive term
FROM counter
-- no WHERE clause to stop it!
)
SELECT n FROM counter;Derinlik Sınırı Ekleme
En basit güvenlik önlemi bir derinlik sayacı kullanmaktır. Her özyinelemeli adımda 1 artan bir sütun ekleyin ve değer en yüksek derinliği aştığında durun.
Bu, verilerden bağımsız olarak işlemin sonlanmasını garanti eder ve seçtiğiniz sınır bir güvenlik üst sınırı sağlar.
WITH RECURSIVE counter AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1
FROM counter
WHERE n < 10 -- stop at depth 10
)
SELECT n FROM counter;Hiyerarşi Sorgusunda Derinlik Sınırı
Bir çalışan hiyerarşisini dolaşırken derinliği yol ile birlikte izleyebilirsiniz. WHERE depth < 5 yan tümcesi, verilerde daha derin veya döngüsel bağlantılar olsa bile 5 düzeyin ötesine geçilmesini önler.
CREATE TEMP TABLE employees (
id INT PRIMARY KEY,
name TEXT,
manager_id INT
);
INSERT INTO employees VALUES
(1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Carol', 2),
(4, 'Dave', 3);
WITH RECURSIVE hierarchy AS (
SELECT id, name, manager_id, 1 AS depth
FROM employees
WHERE manager_id IS NULL -- root
UNION ALL
SELECT e.id, e.name, e.manager_id, h.depth + 1
FROM employees e
JOIN hierarchy h ON e.manager_id = h.id
WHERE h.depth < 5 -- depth limit
)
SELECT id, name, depth FROM hierarchy ORDER BY depth, id;Döngü Algılama Nedir?
Graf verilerinde, kenarları izlemek sonunda daha önce ziyaret ettiğiniz bir düğüme geri dönüyorsa bir döngü oluşur. Örneğin: A → B → C → A.
Derinlik sınırı, döngüsel verilerde sorguyu yine de sonlandırır, ancak döngünün nerede olduğunu size söylemez. Açık döngü algılama bunu yapar.
CREATE TEMP TABLE edges (
from_node INT,
to_node INT
);
-- Introduce a cycle: 1->2->3->1
INSERT INTO edges VALUES
(1, 2),
(2, 3),
(3, 1), -- cycle back to 1
(1, 4); -- also a non-cyclic branch
SELECT * FROM edges;Ziyaret Edilen Düğümleri Diziyle İzleme
Sağlam bir döngü algılama tekniği, ziyaret edilen düğüm ID'lerinden oluşan bir diziyi özyineleme boyunca taşımaktır. Bir sonraki düğümü ziyaret etmeden önce bunun dizide zaten bulunup bulunmadığını denetleyin. Bulunuyorsa bu düğümü atlayın.
PostgreSQL, ANY(array) işleci ve || diziye ekleme işleci sayesinde bunu kolaylaştırır.
WITH RECURSIVE traverse AS (
-- Start from node 1
SELECT from_node,
to_node,
ARRAY[from_node] AS visited
FROM edges
WHERE from_node = 1
UNION ALL
SELECT e.from_node,
e.to_node,
t.visited || e.from_node
FROM edges e
JOIN traverse t ON e.from_node = t.to_node
WHERE NOT (e.from_node = ANY(t.visited)) -- skip visited nodes
)
SELECT from_node, to_node, visited
FROM traverse;CYCLE Yan Tümcesi (PostgreSQL 14+)
PostgreSQL 14, özyinelemeli CTE'ler için yerleşik bir CYCLE yan tümcesi sunmuştur. Bu yan tümce otomatik olarak iki sütun ekler: bir döngü algılandığında true olan bir mantıksal bayrak ve izlenen yolu kaydeden bir dizi.
Bu, diziyi elle yönetmekten daha temizdir.
WITH RECURSIVE traverse AS (
SELECT from_node, to_node
FROM edges
WHERE from_node = 1
UNION ALL
SELECT e.from_node, e.to_node
FROM edges e
JOIN traverse t ON e.from_node = t.to_node
)
CYCLE from_node SET is_cycle USING path
SELECT from_node, to_node, is_cycle, path
FROM traverse;Derinlik Sınırı ve Döngü Algılamayı Birleştirme
Hem derinlik sınırını hem de döngü algılamayı birlikte kullanmak, en güçlü güvenlik garantisini sağlar:
- Derinlik sınırı, veri kalitesinden bağımsız olarak katı bir üst sınır görevi görür.
- Döngü algılama, bir döngü bulunduğu anda erken durarak gereksiz yinelemeleri önler.
Üretim ortamındaki sorgularda bu güvenlik önlemlerinden en az birini her zaman uygulayın.
WITH RECURSIVE traverse AS (
SELECT from_node,
to_node,
1 AS depth,
ARRAY[from_node] AS visited
FROM edges
WHERE from_node = 1
UNION ALL
SELECT e.from_node,
e.to_node,
t.depth + 1,
t.visited || e.from_node
FROM edges e
JOIN traverse t ON e.from_node = t.to_node
WHERE t.depth < 10 -- depth limit
AND NOT (e.from_node = ANY(t.visited)) -- cycle guard
)
SELECT from_node, to_node, depth, visited
FROM traverse;Tam Yolu Dize Olarak Oluşturma
Döngü algılamanın yanı sıra, insan tarafından okunabilir bir dize olarak tam dolaşım yolunu kaydetmek de yararlıdır. Düğüm ID'lerini -> ile ayırarak birleştirmek, graf boyunca izlenen rotayı görüntülemeyi veya hatalarını ayıklamayı kolaylaştırır.
WITH RECURSIVE traverse AS (
SELECT from_node,
to_node,
1 AS depth,
ARRAY[from_node] AS visited,
from_node::TEXT AS path_str
FROM edges
WHERE from_node = 1
UNION ALL
SELECT e.from_node,
e.to_node,
t.depth + 1,
t.visited || e.from_node,
t.path_str || ' -> ' || e.from_node::TEXT
FROM edges e
JOIN traverse t ON e.from_node = t.to_node
WHERE t.depth < 10
AND NOT (e.from_node = ANY(t.visited))
)
SELECT from_node, to_node, path_str, depth
FROM traverse
ORDER BY depth;Özyinelemeli Yineleme Sayısı Üst Sınırını Ayarlama
Bazı veritabanları (MariaDB, eski MySQL) özyinelemeyi sınırlamak için bir oturum değişkeni kullanır. PostgreSQL'deki eşdeğer yaklaşım, kendiniz yazdığınız derinlik sayacına güvenmek veya ifade düzeyinde zaman aşımı kullanmaktır.
Bir statement_timeout ayarlamak, kontrol dışına çıkan herhangi bir sorguyu belirli bir süre sonra sonlandıran son çare güvenlik önlemidir.
-- PostgreSQL: set a statement timeout as a safety net
SET statement_timeout = '5s';
-- Now any query that runs longer than 5 seconds is cancelled
WITH RECURSIVE counter AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM counter WHERE n < 1000000
)
SELECT MAX(n) FROM counter;
-- Reset to default when done
SET statement_timeout = '0';Doğru Derinlik Sınırını Seçme
Evrensel bir derinlik sınırı yoktur. Sınırınızı verilerinizdeki gerçekçi en yüksek derinliğe göre seçin:
- Kuruluş şemaları nadiren 10-15 düzeyi aşar — rahat bir pay bırakmak için
depth < 20kullanın. - Bir dosya sistemi ağacı 50-100 düzey derinliğe ulaşabilir.
- Bir sosyal ağ grafında dolaşma genellikle 3-6 adımla sınırlandırılır.
Geçerli verileri kapsayacak kadar yüksek, ancak kontrolden çıkan sorguları erken yakalayacak kadar düşük bir sınır belirleyin.
-- Example: org chart with a generous but safe depth cap
WITH RECURSIVE org AS (
SELECT id, name, manager_id, 1 AS depth
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, o.depth + 1
FROM employees e
JOIN org o ON e.manager_id = o.id
WHERE o.depth < 20 -- realistic upper bound for an org chart
)
SELECT id, name, depth
FROM org
ORDER BY depth, name;Derinlik Sınırları ve Döngü Algılama
Hangi tekniği kullanmalısınız?
Özet: Özyinelemeli Sorguları Güvenli Tutma
Özyinelemeli CTE'lerde sonsuz döngülerden kaçınma konusunda öğrendiklerinizin özeti:
- Derinlik sınırı — bir sayaç sütunu ekleyin ve
WHERE depth < Nile durun. Her zaman etkilidir ve uygulaması kolaydır. - Dizi tabanlı döngü algılama — ziyaret edilen düğüm ID'lerini bir dizide taşıyın ve dizide zaten bulunan düğümleri atlayın. İlk döngüde erken durur.
- CYCLE yan tümcesi (PostgreSQL 14+) — döngü izlemeyi
is_cyclevepathsütunlarıyla otomatikleştiren yerleşik söz dizimi. - İfade zaman aşımı — kontrolden çıkan sorgular için veritabanı düzeyinde bir güvenlik önlemidir; doğru mantığın yerine geçmez.
- En güçlü garanti için üretimde hem derinlik sınırını hem de döngü algılamayı birlikte kullanın.
Bu tekniklerle hiyerarşileri ve grafları, veritabanı çökmeleri riskine girmeden güvenle dolaşabilirsiniz.
Sıkça Sorulan Sorular
“Sonsuz Döngülerden Kaçınma” dersi ücretsiz mi?
Evet — “Sonsuz Döngülerden Kaçınma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve SQL Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. SQL Academy kursu toplamda 4 dersten oluşur.
“Sonsuz Döngülerden Kaçınma” dersinde ne öğreneceğim?
Derinlik sınırları ve döngü algılama. SQL Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
SQL Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te SQL Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“Sonsuz Döngülerden Kaçınma” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu SQL Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her SQL Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Özyinelemeli CTE'ler Nasıl Çalışır
- Kategori Ağacında İlerleme
- Seriler ve Diziler Oluşturma
- Sonsuz Döngülerden Kaçınma