2009-05-12 14 views

cevap

8

Kullanım CTE 's. ağaç benzeri tablo yapısı göz önüne alındığında

:

WITH v (id, parent, level) AS 
     (
     SELECT id, parent, 1 
     FROM table 
     WHERE parent = 0 
     UNION ALL 
     SELECT id, parent, v.level + 1 
     FROM v 
     JOIN table t 
     ON  t.parent = v.id 
     ) 
SELECT * 
FROM v 

id parent name 
1 0  Electronics 
2 1  TV 
4 2   LCD 
5 2   Plasma 
3 1  Hi-Fi 
6 3   Amplifiers 
7 3   Speakers 

sadece almak için parent = @parent ile parent = 0 değiştirin:

id parent name 
1 0  Electronics 
2 1  TV 
3 1  Hi-Fi 
4 2  LCD 
5 2  Plasma 
6 3  Amplifiers 
7 3  Speakers 

, bu sorgu id, parent ve derinlik düzeyini dönecektir, bir ağaç olarak sipariş bir ağaç dalı.

table (parent)'da bir dizin belirtiliyorsa, bu sorgu, her ebeveyn için tüm chilrden öğelerini bulmak için INDEX LOOKUP'u kullanacağı için çok büyük bir tabloda verimli bir şekilde çalışacaktır. @parent şube köküdür

WITH v (id, parent, level) AS 
     (
     SELECT id, parent, 1 
     FROM table 
     WHERE parent = 0 
     UNION ALL 
     SELECT id, parent, v.level + 1 
     FROM v 
     JOIN table t 
     ON  t.parent = v.id 
     ) 
UPDATE table t 
SET  column = newvalue 
WHERE t.id IN 
     (
     SELECT id 
     FROM v 
     ) 

:

belli şube, konuyu güncellemek için.

+0

Tablo yapısı hakkında ayrıntılı bilgi verir misiniz? Bu sorgu büyük bir db ile iyi çalışacak mı? – SirMoreno

+0

teşekkürler, Derin bir güncelleştirme nasıl yapılır? - Bir ebeveynin altındaki tüm düğümleri güncelleyin? (torun dahil) – SirMoreno

+0

hey, bu işe çalışmak için çalışıyorum ve vq madde dosent iş gibi görünüyor, ben 2008 yılında çalışıyorum.Tablonun tabloda gösterilmediği için veritabanında da saklanmak zorunda mıdır? –

2

Hiyerarşi sorununu çözmek için birden çok yöntem için Joe Celko's book on trees and hierarchies'a bakın. Seçtiğiniz model, aramalara ve güncellemelere kıyasla karmaşıklığı nasıl artırdığınıza bağlı olacaktır. Bitişik liste modelini kullanarak aramaları oldukça hızlı (özellikle tüm çocukları bir düğümde almak için) yapabilirsiniz, ancak ağaçtaki güncellemeler daha yavaştır.

+0

Teşekkürler bakacağım. Sendikalar daha verimli, sonra tekrarlayıcı mıdır? Mssql 2005'in ağaçlarla uğraşmanın yeni bir yolu olduğunu duydum, büyük DB'lerle iyi çalışıp çalışmadığını biliyor musunuz? – SirMoreno

+0

Bir CTE içindeki UNION ALL, SQL Server'ın sahne arkasında nasıl işlediğini veya performansın nasıl ayarlandığını bilmesem de yineleyicidir. Performans hakkında emin olmak için CTE'lerle yeterince büyük ölçekli testler yapmadım. –

3

Kendinize şu soruları sormalısınız: 1) Değişikliklerin okunma oranına oranı nedir? (= çoğunlukla statik ağaç veya sürekli değişiyor mu?) 2) Ağacın büyümesi ne kadar büyük ve büyüktür?

İç içe geçmiş kümeler, tüm dallarda işlem yapmanız gereken çoğunlukla statik ağaçlar için idealdir. Derin ağaçları sorunsuz bir şekilde ele alır.

Materyalleştirilmiş yol, kısıtlı/öngörülebilir derinliğe sahip dinamik (değişen) ağaçlar için iyi çalışır.

Özyineli CTE'ler çok küçük ağaçlar için idealdir, ancak şube operasyonları ("bu daldaki tüm çocukları alın") derin/büyük ağaçla çok maliyetlidir.

http://www.sqlteam.com/article/more-trees-hierarchies-in-sql

+1

Ağacım çok dinamik, birçok güncellemedir ancak çoğu da seçmektedir. Ve 10-15 seviyelerine kadar çıkabilmek istiyorum. İç içe geçmiş kümelerle ilgili bu makaleyi buldum: http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/swinging-from-tree-to-tree-using-ctes-part-1-adjacency -to-nested-sets.aspx Bu makalede anlatılan gibi iç içe geçmiş setleri benim en iyi seçenek olur mu? teşekkürler. – SirMoreno

1

, en iyi seçenek kısaca burada açıklanan Path Sayım Modeli, gibi görünüyor . Okumak için çok verimli ve yazmak oldukça kolay.

0

şaşırdım kimse söz bir Closure Table ile devam: Eğer birçok güncelleme ve seçer varsa