Persediaan Temu Duga SQL · Pelajaran

Mengelakkan Rekursi Tanpa Henti

Pengesanan kitaran, had kedalaman dan pengawal rekursi yang diperiksa oleh setiap penemu duga

Pelajaran 4 daripada 413 langkah

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 WHERE untuk menyemak laluan.
  • Mengesan dan melaporkan — paparkan baris yang menjadi sebahagian daripada kitaran supaya pasukan data boleh membaiki data yang salah, menggunakan bendera is_cycle daripada klausa CYCLE.

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_id supaya 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-sama depth dan path Anda.

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 MAXRECURSION pada 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 100 pada 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.

Percuma untuk bermula

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

  1. Ahli Sauh dan Rekursif
  2. Merentasi Carta Organisasi
  3. Menjana Siri Nombor dan Tarikh
  4. Mengelakkan Rekursi Tanpa Henti
← Kembali ke Persediaan Temu Duga SQL