Özyinelemeli öz birleşimler


15

Bu commentsbasitleştirilebilir bir tablo var :

comments
=======
id
user_id
text
parent_id

burada parent_idnull değeri vardır, ancak üst yorumu için bir anahtar olabilir.


Şimdi, selectbelirli bir yorumun torunlarını nasıl yapabilirim ?
Yorumlar birkaç seviye aşağı olabilir ...

Yanıtlar:


16

Hiyerarşik sorgular , bu özyinelemeli sorgular bilindiği gibi, MySQL için desteklenmez.

Ancak bunlar Oracle, Microsoft SQL Server, DB2 ve PostgreSQL'de desteklenir.

Geçici bir çözüme ihtiyacınız varsa, burada dinamik (ve dolayısıyla potansiyel olarak tehlikeli) bir numara bulabilirsiniz: /programming/8104187/mysql-hierarchical-queries

Hiyerarşik verilerin bir Bitişiklik Listesi (ör. Üst sütun) yerine diğer modellerle nasıl depolanacağı hakkında bir tartışma burada bulabilirsiniz: /programming/192220/what-is-the-most-efficient- zarif yollu to-parse-a-düz masa-içine-a-ağacının /

İyi şanslar!


İkinci bağlantınızdaki çözümün nasıl tehlikeli olabileceğini merak ediyorum. Açıklayabilir misiniz? Aksi takdirde, siteye hoş geldiniz!
dezso

3
@dezso: Sorgunun işçisini Quoth, Quassnoi " * Yükseltme için güvenli değil * çünkü MySQL oturum değişkeni davranışını açıkça tanımlamıyor. Bununla birlikte, bitişik listelerle zamanında moda bir sorguda başa çıkmanın tek yolu ." Tehlikeli bir kelime çok güçlü olabilir ( potansiyel olarak dengesiz ?) Ama dikkat tarafında hata yapmayı tercih ediyorum (artı, Oracle'da MySQL'den daha bilgili olduğum için, bu yüzden ekstra tedbirli olmak istedim). Bu arada hoşgeldin için teşekkürler! SE ağına uzun süredir ilgi duyuyorum ve biraz geri ödeme zamanının geldiğine karar verdim.
Valmoer

2
WITH [RECURSIVE] sözdizimi artık mysql 8.0'dan desteklenmektedir. dev.mysql.com/doc/refman/8.0/en/with.html
ClearCrescendo

6

Bu tablo tasarımı, Bill Karwin tarafından tarif edilen bir SQL antipattern "Naif ağaçlar" dur (SQL Antipatterns Strike Back sunumundaki slayt 48'den başlayarak ). Bu tasarımdaki sorun özellikle bir düğümün tüm torunlarını (veya ebeveynlerini) almanın zorluğudur. MySQL kullandığınız için, diğer RDBMS'lerde bulunan ortak tablo ifadelerini (WITH deyimi ve RECURSIVE değiştiricisi) kullanamazsınız.

Kaldığınız şey:

  • hiyerarşik veri yapısının alternatif bir uygulamasını kullanın ( bu sorunun yanıtları bu konuda iyi bir referans olabilir)
  • derinlik sınırı ile kendi kendine birleştirme sorguları oluşturun. Derinlik = 5 için şu satırlarda bir şey kullanabilirsiniz:

    SELECT *
    FROM comments AS c1
      JOIN comments AS c2 ON (c2.parent_id = c1.id)
      JOIN comments AS c3 ON (c3.parent_id = c2.id)
      JOIN comments AS c4 ON (c4.parent_id = c3.id)
      JOIN comments AS c5 ON (c5.parent_id = c4.id)
  • RECURSIVE İLE destekleyen bir RDBMS kullanın (bu büyük olasılıkla çoğu insan için bir seçenek olmasa da)


2
Burada Bill Karwin ile aynı fikirde değilim. Bitişiklik modeli olmayan bir anti-kalıp. Özyinelemeli sorguları destekleyen modern bir DBMS ile (Oracle bunu 20 yılı aşkın bir süredir desteklemiştir) böyle bir model almak ve güncellemek için çok etkilidir .
a_horse_with_no_name

5

MySQL, ihtiyaç duyduğunuz sorgu gibi özyinelemeli sorguları desteklemez.

Bir süre önce yaptığım, bunu yapmak için modeli sağlayan Saklı Yordamlar yazmaktı.

Tekerleği yeniden icat etmek yerine, size bu konudaki geçmiş yazılarımın bağlantılarını vereceğim:

Kısacası, yaptığım Saklı Yordamlar kuyruk işleme kullanarak ağaçta gezinmeyi ön siparişe sokar

  • GetParentIDByID
  • GetAncestry
  • GetFamilyTree

Tüm Çocuklara Ebeveyn (GetFamilyTree Saklı Yordamı gibi)

  • STEP01) parent_idBir kuyrukta ile başlayın
  • ADIM02) Bir sonrakini parent_idakım olarak ayır
  • ADIM03) Akıma idsahip tüm değerleri sıraylaparent_id
  • ADIM04) Yorumu Yazdırın veya Toplayın
  • ADIM05) Sıra boş değilse, git STEP02
  • ADIM06) İşlemi tamamladınız !!!

Tüm Ebeveyne Çocuk (GetAncestry Saklı Yordamı gibi)

  • STEP01) idBir kuyrukta ile başlayın
  • ADIM02) Bir sonrakini idakım olarak ayır
  • ADIM03) Akımın parent_iddeğerini enquequeid
  • ADIM04) Yorumu Yazdırın veya Toplayın
  • ADIM05) Sıra boş değilse, git STEP02
  • ADIM06) İşlemi tamamladınız !!!

Uygulamayı görmek için lütfen diğer yayınlarımdaki Saklı Yordamlar'a bakın.

Bir şans ver !!!


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.