Mengelakkan Rekursi Tanpa Henti
Pengesanan kitaran, had kedalaman dan pengawal rekursi yang diperiksa oleh setiap penemu duga
Mengelakkan Rekursi Tanpa Henti ialah pelajaran Persediaan Temu Duga SQL percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Persediaan Temu Duga SQL, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Persediaan Temu Duga SQL merangkumi sejumlah 4 pelajaran.
Soalan di Sebalik Soalan
Selepas Anda menulis CTE rekursif, penemu duga yang tajam mungkin bertanya: "Apakah yang berlaku jika data mempunyai kitaran?" Soalan ini menguji sama ada Anda memahami bahawa rekursi boleh berjalan selama-lamanya — dan sama ada Anda tahu cara melindunginya.
Kitaran berlaku apabila hierarki berpatah balik kepada dirinya sendiri: A melapor kepada B, dan B melapor kepada A. Ahli rekursif yang naif akan berulang-alik antara kedua-duanya tanpa henti.
Bagaimana Kitaran Terbentuk
Pepohon sepatutnya tidak mempunyai kitaran, tetapi data sebenar sering tidak kemas. Kemas kini yang salah boleh menetapkan seorang pekerja sebagai pengurusnya sendiri secara tidak langsung. Graf — seperti "pengguna yang mengikuti pengguna lain" — sememangnya boleh mempunyai kitaran.
Apabila ahli rekursif menemui semula nod yang telah dilawati, nod itu dihasilkan sekali lagi dan mencetuskan semula nod anaknya, lalu gelung tersebut tidak pernah menjadi kosong. Rekursi hanya berhenti apabila suatu langkah tidak mengembalikan baris; kitaran menjamin bahawa baris akan sentiasa dikembalikan.
Perlindungan 1: Had Kedalaman
Jaring keselamatan yang paling mudah ialah kaunter kedalaman dengan had maksimum dalam ahli rekursif. Walaupun terdapat kitaran, rekursi akan berhenti apabila mencapai had tersebut.
Ini ialah pendekatan kasar — ia turut mengehadkan pepohon sah yang dalam — tetapi cepat dan mudah digunakan dalam temu duga.
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 < 50
)
SELECT * FROM org;Perlindungan 2: Laluan yang Dilawati
Pengawal yang lebih tepat menjejaki laluan nod yang telah dilawati dan enggan memasuki semula nod yang sudah berada dalam laluan tersebut. Kumpulkan id ke dalam rentetan atau tatasusunan, kemudian semak keahliannya sebelum meneruskan rekursi.
Kaedah ini menghentikan kitaran dengan tepat sambil membenarkan kedalaman sewenang-wenangnya pada pepohon yang sah.
WITH RECURSIVE org AS (
SELECT id, name, manager_id,
CAST(',' || id || ',' AS VARCHAR(2000)) AS path
FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id,
o.path || e.id || ','
FROM employees e JOIN org o ON e.manager_id = o.id
WHERE o.path NOT LIKE '%,' || e.id || ',%'
)
SELECT id, name, path FROM org;Mengapa Semakan Laluan Berkesan
Syarat path NOT LIKE '%,' || e.id || ',%' bermaksud "ikuti sisi ini hanya jika id anak belum berada dalam laluan." Koma bertindak sebagai pembatas supaya id 1 tidak tersalah padan dalam id 15.
Jika kitaran akan menyebabkan sesuatu nod dilawati semula, WHERE menapis keluar baris tersebut, ahli rekursif akhirnya tidak mengembalikan apa-apa, dan rekursi tamat dengan kemas.
Perlindungan 3: Klausa CYCLE Asli
Postgres moden (14+) dan piawaian SQL menawarkan klausa CYCLE terbina dalam yang mengautomatikkan semakan laluan serta menandakan kitaran untuk Anda. Inilah jawapan yang paling kemas apabila enjin menyokongnya.
WITH RECURSIVE org AS (
SELECT id, name, manager_id FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id
FROM employees e JOIN org o ON e.manager_id = o.id
)
CYCLE id SET is_cycle USING cycle_path
SELECT id, name, is_cycle FROM org;MAXRECURSION pada SQL Server
SQL Server menguatkuasakan had lalai sebanyak 100 aras rekursi. Jika kitaran atau pepohon yang dalam melebihi had itu, pertanyaan akan menghasilkan ralat dan bukannya berulang selama-lamanya — suatu injap keselamatan tersirat.
Anda boleh menaikkan atau membuang had tersebut dengan OPTION (MAXRECURSION n), dengan 0 bermaksud tanpa had. Namun, membuang had tanpa pengawal laluan akan membuka semula risiko gelung tanpa penghujung pada data yang mempunyai kitaran.
-- Cap recursion at 200 levels in SQL Server
SELECT * FROM org
OPTION (MAXRECURSION 200);Mengesan Berbanding Menghalang Kitaran
Penemu duga mungkin membezakan dua matlamat:
- Menghalang — langkau sisi yang mempunyai kitaran secara senyap supaya pertanyaan selesai, menggunakan
WHEREuntuk menyemak laluan. - Mengesan dan melaporkan — paparkan baris yang menjadi sebahagian daripada kitaran supaya pasukan data boleh membaiki data yang salah, menggunakan bendera
is_cycledaripada klausaCYCLE.
Mengetahui kedua-duanya serta bila setiap satunya sesuai digunakan ialah perbezaan pada tahap kanan.
Pertimbangan Prestasi
Rekursi boleh menjadi mahal walaupun tanpa kitaran. Petua yang biasanya ingin didengar oleh penemu duga:
- Indekskan lajur cantuman seperti
manager_idsupaya cantuman pada setiap lelaran berjalan pantas. - Tapis lebih awal dalam sauh supaya hanya subpepohon yang diperlukan dimulakan, bukan seluruh jadual.
- Elakkan
SELECT *— bawa hanya lajur yang diperlukan oleh rekursi, bersama-samadepthdanpathAnda.
Templat Selamat
Gabungkan pengawal tersebut ke dalam templat yang boleh Anda hasilkan semula ketika tertekan: lajur kedalaman sebagai lapisan perlindungan tambahan dan semakan laluan sebagai pengawal yang tepat. Walaupun salah satunya mungkin berlebihan untuk data yang bersih, menunjukkan kedua-duanya menandakan ketelitian.
WITH RECURSIVE walk AS (
SELECT id, parent_id, 1 AS depth,
CAST(',' || id || ',' AS VARCHAR(4000)) AS path
FROM nodes WHERE parent_id IS NULL
UNION ALL
SELECT n.id, n.parent_id, w.depth + 1,
w.path || n.id || ','
FROM nodes n JOIN walk w ON n.parent_id = w.id
WHERE w.depth < 100
AND w.path NOT LIKE '%,' || n.id || ',%'
)
SELECT id, depth FROM walk;Kesilapan Lazim dalam Temu Duga
Perangkap terakhir yang perlu dielakkan:
- Membuang
MAXRECURSIONpada SQL Server tanpa pengawal lain — ini membuka semula risiko gelung tanpa penghujung. - Lajur rentetan laluan diisytiharkan terlalu pendek, lalu menyebabkan pemotongan dan pengawal yang rosak tanpa disedari.
- Memadankan id tanpa pembatas koma, menyebabkan id 1 tersalah padan dalam id 21.
- Menganggap data tidak mempunyai kitaran hanya kerana data itu "sepatutnya" begitu — sentiasa tanyakan perkara ini.
Semakan Pantas
Pilih pengawal yang menghentikan kitaran dengan tepat tanpa mengehadkan kedalaman yang sah.
Rumusan
Setiap jawapan CTE rekursif perlu menangani aspek keselamatan:
- Kitaran menyebabkan ahli rekursif tidak pernah mengembalikan hasil kosong, lalu rekursi tidak pernah berhenti.
- Had kedalaman = perlindungan tambahan yang pantas; semakan laluan yang dilawati = pencegahan kitaran yang tepat; klausa CYCLE = pengesanan asli dalam enjin moden.
MAXRECURSION 100pada SQL Server ialah injap tersirat — jangan buang had ini tanpa pengawal lain.- Indekskan lajur cantuman dan mulakan dengan julat data yang terhad untuk mendapatkan prestasi yang baik.
Sekarang Anda boleh menulis, menelusuri, menjana dan melindungi CTE rekursif dari awal hingga akhir.
Pelajari SQL dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 30
- Pelajaran
- 120
Soalan Lazim
Adakah pelajaran “Mengelakkan Rekursi Tanpa Henti” percuma?
Ya — teks penuh “Mengelakkan Rekursi Tanpa Henti” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Persediaan Temu Duga SQL, tingkat taraf kepada CoddyKit PRO. Kursus Persediaan Temu Duga SQL merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Mengelakkan Rekursi Tanpa Henti”?
Pengesanan kitaran, had kedalaman dan pengawal rekursi yang diperiksa oleh setiap penemu duga Anda berlatih Persediaan Temu Duga SQL menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Persediaan Temu Duga SQL?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Persediaan Temu Duga SQL di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.
Berapa lamakah pelajaran “Mengelakkan Rekursi Tanpa Henti” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Persediaan Temu Duga SQL ini?
Ya. Setiap pelajaran Persediaan Temu Duga SQL menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Ahli Sauh dan Rekursif
- Merentasi Carta Organisasi
- Menjana Siri Nombor dan Tarikh
- Mengelakkan Rekursi Tanpa Henti