Ağaç Veri Yapısı için Veritabanı Yapısı


151

Bir veritabanında özelleştirilebilir (yani, düzeyi bilinmeyen bir ağaç yapısı) ağaç veri yapısını uygulamanın en iyi yolu nedir?

Bunu bir kez yabancı anahtarlı bir masa kullanmadan önce yaptım.

Başka hangi uygulamaları görebiliyordunuz ve bu uygulama anlamlı mı?



Yanıtlar:


80

En yaygın olarak uygulanan, Bitişiklik Listesi'nden bahsediyorsunuz: https://blogs.msdn.microsoft.com/mvpawardprogram/2012/06/25/hierarchies-convert-adjacency-list-to-nested-sets

Gerçekleştirilmiş yol ve iç içe geçmiş kümeler de dahil olmak üzere başka modeller de vardır: http://communities.bmc.com/communities/docs/DOC-9902

Joe Celko, bu konuda genel bir SQL perspektifinden iyi bir referans olan bir kitap yazmıştır (yukarıdaki iç içe geçmiş makale bağlantısında belirtilmiştir).

Ayrıca, Itzik Ben-Gann "Microsoft SQL Server 2005 İçinde: T-SQL Sorgulama" kitabındaki en yaygın seçeneklere iyi bir genel bakışa sahiptir.

Bir model seçerken göz önünde bulundurulması gereken temel noktalar şunlardır:

1) Yapı değişim sıklığı - ağacın gerçek yapısı ne sıklıkta değişir. Bazı modeller daha iyi yapı güncelleme özellikleri sağlar. Bununla birlikte, yapı değişikliklerini diğer veri değişikliklerinden ayırmak önemlidir. Örneğin, bir şirketin organizasyon şemasını modellemek isteyebilirsiniz. Bazı insanlar bunu bir çalışanı amirine bağlamak için çalışan kimliğini kullanarak bir bitişik liste olarak modelleyecektir. Bu genellikle en uygun olmayan bir yaklaşımdır. Genellikle daha iyi çalışan bir yaklaşım, kuruluş yapısını çalışanlardan ayrı olarak modellemek ve çalışanı yapının bir özelliği olarak korumaktır. Bu şekilde, bir çalışan şirketten ayrıldığında, organizasyon yapısının kendisinin değişmesi gerekmez, sadece ayrılan çalışanla ilişkilendirilmesi gerekir.

2) Ağaç yazma-ağır veya okuma-ağır mı - bazı yapılar yapıyı okurken çok iyi çalışır, ancak yapıya yazarken ek yüke maruz kalırlar.

3) Yapıdan ne tür bilgiler edinmeniz gerekir - bazı yapılar yapı hakkında belirli türlerde bilgi sağlamada mükemmeldir. Örnekler arasında bir düğüm ve tüm çocuklarını bulma, bir düğüm ve tüm ebeveynlerini bulma, belirli koşulları karşılayan çocuk düğümlerinin sayısını bulma, vb. Yer alır. ihtiyaçlarınızı.


Merhaba, soruda belirtilen aynı sorunla karşı karşıyayım ve yukarıdaki konular hakkında size bir soru sormak istiyorum. Aynı konudaki ParentId ile bir numaralı konu (örgütsel yapılandırılmış tablo (çalışan yapılandırılmış değil) gibi bir yapı göz önüne alındığında, ben belirli bir alanın patron kim olduğunu ayarlamak gerekir. O alandaki tüm çalışanları doğrudan ona atayacağım. O bölgenin patronunu nereye koyardın? Aynı alanın içinde mi yoksa yukarıdaki bir grupta mı? Yaklaşımım onu ​​yukarıdaki gruba yönlendirmek, bence daha iyi bir yapı kazandırmak. Teşekkürler.
Marcos Buarque

1
İlk bağlantı kopmuş gibi görünüyor.
Jorge Leitao

Mükemmel cevap. Teşekkürler @JeremyDWill!
bobocopy

56

MySQL'de Hiyerarşik Verileri Yönetme konusuna göz atın . İlişkisel bir veritabanında hiyerarşik (ağaç benzeri) verileri depolamak ve yönetmek için iki yaklaşımı tartışır.

İlk yaklaşım, temel olarak tanımladığınız bitişiklik listesi modelidir: tablonun kendisine atıfta bulunan bir yabancı anahtara sahip olmak. Bu yaklaşım basit olmakla birlikte, tüm ağacı oluşturmak gibi belirli sorgular için çok verimsiz olabilir.

Makalede ele alınan ikinci yaklaşım, iç içe küme modelidir. Bu yaklaşım çok daha verimli ve esnektir. Ayrıntılı açıklama ve örnek sorgular için makaleye bakın.


bağlantınızın tartışılması çok ilginç bir konu. Teşekkürler!
Fritz

9

Ağaç veri yapısını düzenlemek için İlişkisel Veri Tabanı'nı kullanmanız gerekiyorsa Postgresql, hiyerarşik ağaç benzeri bir yapıda depolanan veri etiketlerini temsil etmek için veri türü sağlayan havalı ltree modülüne sahiptir. Bu fikri oradan edinebilirsiniz. (Daha fazla bilgi için bkz. Http://www.postgresql.org/docs/9.0/static/ltree.html )

Genel LDAP, kayıtları hiyerarşik yapıda düzenlemek için kullanılır.


2

Yabancı anahtarlı bir masaya sahip olmak bana mantıklı geliyor.

Daha sonra ağacınızı oluşturmak için SQL'de ortak bir tablo ifadesi veya Oracle'daki önceki ifadeye göre bağlan özelliğini kullanabilirsiniz.


Bir LogID kimlik sütunu ve bir Logent sütununa işaret eden bir FK ile bir ParentLogID sütunu ile bir günlük tablosu var. Bir işlemdeki ilk günlük satırı yazıldığında, SCOPE_IDENTITY () alıyorum. Diğer tüm günlük kayıtları bu değerle ParentLogID sütununa yazılır. Bu, birbirine ait olan satırları gruplandırmak için gerçekten yararlıdır. Ne olduğunu görmenin tek gerçek yolu, bu olmadan, hepsi birlikte karışık çoklu işlemlerden oluşan günlük satırlarının büyük bir karmaşası olurdu.
KM.

@KM - "mantıklı değil" değil "mantıklı değil" dedi
John Rasch


1

Ben 2005 SQL SERVER üzerinde aşağıdaki uygulanmasını kullandım Kontrol burada


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.