SQL Server 2008 ile Gelen Yeni Veri Tipleri (Hierarchyid Veri Tipleri)

by Bilgehan 18. Mart 2009 03:59


Bu Makalemizde;SQL Server 2008 ile gelen veri tiplerini incelemeye devam ediyoruz.Hiyerarşik Veri Tiplerine ve sağladığı imkanlara bakacağız.(Önceki bağlı makalelerimizde Uzaysal Veri Tiplerini ve Date-Time Veri Tiplerini incelemiştik)

3)SQL Server 2008’de Yeni Hiyerarşik Veri Tipleri :
Hiyerarşik verilere örnek olarak;organizasyon ve yönetim tabloları,ürün katalogları,dizin yapılarının tutulma şekilleri gösterilebilir.Hiyerarşik veriler birbiriyle ilişki halinde olan üyelerden oluşan bir yapıdır.Basitçe ifade etmek gerekirse parent-child ilişkisi bir hiyerarşik yapıdır.(üst-ast ilişkisi olarak düşünülebilirler.)Parent denilen kök üyenin;türeyen kolları (child),olabileceği gibi olmaya da bilir,aynı durum child için de geçerlidir.SQL Serverda Hiyerarşik veriler 3 farklı yolla ele alınabilir.

Ø 
XML yapıları kullanarak.Bu durum bütün uygulama ve kullanıcıların verilerinin XML ile ilişkilendirilmesini gerektirir.Fakat heterojen yapılar için XML veriler bazen aşırı zorlayıcı olabilirler.

Ø 
Verileri ilişkisel tablolarda tutarak ve sonra bunları SELF JOIN
lerle birleştirerek.Bu da tabii ki karmaşık T-SQL sorguları gerektirmektedir.Ayrıca yönetim ve sürdürülebilme gibi konularda zorluklar ortaya çıkabilmektedir.

Ø 
SQL Server 2008 ile gelen yeni hierarchyid veri tipini kullanmak.Hierarchyid veri tipi ; hiyerarşik verilerimizi tanımlayabilmenin yanında,ilişkili veriler arasında yeni gelen fonksiyonlar aracılığıyla işlem yapabilme imkanını da tanımaktadır.Hierarchyid veri tipi;DATE ve TIME veri tipleri gibi yerel bir tip değildir,sistem tanımlı UDT(User Definied Type) bir tiptir.Bu yeni tipimiz; Microsoft.SqlServer.Types.dll altında yer almaktadır.Uygulamalarda Microsoft.SqlServer.Types aduzayı aracılıgıyla kullanabilir.Teknik olarak Hieararchyid veri tipleri CLR UDT’dir bu yüzden SQL Serverda CLR’yi aktif yapmanız gerektiğini düşünebilirsiniz ama Hieararchyid tipler sistem tanımlı tip olduğundan dolayı CLR aktif yapmanız gerekmemektedir.

Şimdi Hierarchyid veri tipimizi daha iyi anlayabilmek için hayali bir şirketin,organizasyon şemasını oluşturalım.



Şekildeki gibi bir organizasyon şemasına sahip şirketimizin;yönetim yapısını SQL Serverda ,yeni
hierarchyid tipini kullanarak saklamak isteyelim.Önce Sirket isimli veri tabanımızı oluşturuyoruz,daha sonra Calisanlar isimli tablomuzu oluşturuyoruz.Bundan sonrasında yazacağım sorgularla,şirketimizin hiyerarşik yapısını adım adım oluşturacağım.Yukarda ki organizasyon şeması şirket yapısını daha iyi anlamanız içindir.

CREATE
TABLE Calisanlar
(Dugum hierarchyid PRIMARY KEY CLUSTERED,
Basamak AS dugum.GetLevel() PERSISTED,
Calisan_ID INT UNIQUE,
Calisan_Isim VARCHAR(30) NOT NULL)

Burada ast-üst ilişkisinin SQL Server’a aktarılmasını sağlayan fonksiyonumuz GetLevel() dir.Bu fonksiyonumuz herbir basamakta ki,düğümün değerini  döndürür.Örneğin kök(root) düğümün,Ahmet,Basamak değeri 0 dır.Erdem ve Ali’nin;basamak değeri 1 dir ve aşağılara indikçe basamak değerinin artmasından dolayı da en son basamaktaki,Ada ve Cemil’in,basamak değerleri 3 olarak ifade edilecektir.Tabloyu oluşturduktan sonra kök de(root) beraberinde oluşturulmuş olur.

INSERT INTO Calisanlar VALUES (hierarchyid::GetRoot(),5000,'Ahmet')

GetRoot() fonksiyonumuzsa,root‘un bulunduğu düğümdeki değeri döndürecek bir başka fonksiyonumuzdur.Burada Calisan_ID sinin değeri 5000 ‘den başlarken, basamaklar 0’dan başlayarak artacaktır.Bu iki ifadeyi birbirine karıştırmamamız gerekir.Elinizde root düğüm varsa organizasyonel şemanızı oluşturmaya başlayabilirsiniz demektir.Ahmet’in(root’un),altında çalışanları tanımlayabilmek için GetDescendants fonksiyonunu kullanacağız.Bu fonksiyon ana bir düğümden türeyen düğümleri,child nodeları, döndürmektedir.Bu örneğimiz için ilk düğümü döndürecektir.

--Öncelikle dügümlerde tutulacak gecici degiskenler tanımlayalım.
DECLARE @YoneticiDugum hierarchyid
DECLARE @Sira hierarchyid --Kok dugum,"Ahmet", icin ,Calisan_ID 5000 dir.
SELECT @YoneticiDugum=Dugum FROM Calisanlar WHERE Calisan_ID=5000
--GetDescendant ilk dugumu bize dondurecektir.Ilk dugum "/1"
INSERT INTO Calisanlar VALUES (@YoneticiDugum.GetDescendant(NULL, NULL),5001, 'Ali')

Bu örneğimizde kök düğüm,Ahmet, basamak 0 dır ve “/ ” ile temsil edilir.Aynı şekilde Ahmet’in altında çalışan Ali;basamak 1 dir ve Ahmet’den sonra en kıdemli kişidir, “/1” ile temsil edilir.Aynı şekilde Erdem’i de yapımıza eklediğimizde değeri “/2” olacaktır.

--Kok dugum,"Ahmet", icin ,Calisan_ID 5000 dir.
SELECT @YoneticiDugum=Dugum FROM Calisanlar WHERE Calisan_ID=5000
--GetDescendant ilk dugumu bize dondurecektir.Ilk dugum "/1"
INSERT INTO Calisanlar VALUES (@YoneticiDugum.GetDescendant(NULL, NULL),5001, 'Ali')
--Ali'nin Calisan_ID di 5001 olacaktır.
SELECT @Sira=Dugum FROM Calisanlar WHERE Calisan_ID=5001
--Biz burada GetDescendant fonksiyonunu (Ali,NULL)olarak tanımlamış oluyoruz.
--Eğer tam tersi bir şekilde (NULL,Ali) olarak tanımlasaydık,
--Ali'den sonra düğümler ekleyemeyecektik.  
INSERT INTO Calisanlar VALUES
(@YoneticiDugum.GetDescendant(@Sira, NULL),5002, 'Erdem')

İsterseniz,şu ana kadarki oluşturduğumuz şirketimizin, hiyerarşik yapısını sorgulayalım

SELECT Dugum.ToString() AS Dugumun_Text_Gosterimi,
Dugum AS Dugumun_Binary_Gosterimi,
Dugum.GetLevel() AS Sira,
Calisan_ID,
Calisan_Isim
FROM Calisanlar




Şirketimizin Organizasyon Şemasındaki,Dugumlerin yerleşimi ise şöyle olacaktır.



Şekilde de görüldüğü gibi Bilgehan,Erdem’in yöneticiliğinde çalışmaktadır ve düğümsel değeri “/2/1” dir.

SQL kodlarımızla şirketimizin organizasyon şemasını tamamlayalım.

SELECT
@Sira=Dugum FROM Calisanlar WHERE Calisan_ID=5002
INSERT INTO Calisanlar VALUES(@Sira.GetDescendant(NULL, NULL),5003, 'Bilgehan')
--Erdem, yönetici olarak @Sira değişkeninde saklanıyor.
-- Bilgehan'ı ,Erdem altında çalışan biri olarak tanımladık.
DECLARE @dugum1 hierarchyid
--Bilgehan'ın,Calisan_ID si 5003 dür.
SELECT @dugum1=Dugum FROM Calisanlar WHERE Calisan_ID=5003
--GetDescendant,Bilgehan'dan sonraki Dugum 'ü döndürecek.
INSERT INTO Calisanlar VALUES (@Sira.GetDescendant(@dugum1, NULL),5004, 'Aydin')

--Şimdi de Aynı işlemleri Ali'nin Düğümü icin @Sira değişkeniyle gerçekleştiriyoruz.
SELECT @Sira=Dugum FROM Calisanlar WHERE Calisan_ID=5001
--Ali'den türeyen bir düğüm yoktu(NULL,NULL).Şimdi Ali'den sonra Selen düğümünü oluştuyoruz.
INSERT INTO Calisanlar VALUES (@Sira.GetDescendant(NULL,NULL),5005, 'Selen')
--Selen'in Dugum 'ü oluşturuldu.
SELECT @dugum1=Dugum FROM Calisanlar WHERE Calisan_ID=5005

--Tomris'i de Ali'nin yöneticiliğine atıyoruz.
INSERT INTO Calisanlar VALUES (@Sira.GetDescendant(@dugum1,NULL),5006, 'Tomris')
--Ada' da Tomris'in yöneticiliğinde
SELECT @Sira=Dugum FROM Calisanlar WHERE Calisan_ID=5006
--Ada'yı da Tomris'den sonra ki ilk yetkili yapıyoruz.

INSERT INTO Calisanlar VALUES (@Sira.GetDescendant(NULL,NULL),5007, 'Ada')
--Ada'nın Dugum 'ü olusturuldu.
SELECT @dugum1=Dugum FROM Calisanlar WHERE Calisan_ID=5007
--Cemil'i de ,Tomris'in yöneticiliğine sokuyoruz.
INSERT INTO Calisanlar VALUES (@Sira.GetDescendant(@dugum1,NULL),5008, 'Cemil')

Organizasyon şemamızı sorguladığımızda yapımız şöyle olmalıdır.




Diyelim ki organizasyonel yapımızda bir değişikliğe gidilmek zorunda kalındı ve Tomris  ,Ali’nin ekibinden ayrılıp Aydın’ın ekibine dahil oldu.Böyle  bir durum da ne olacak peki ? Tüm bu organizasyonel şema baştan mı oluşturulacak ? Tabii ki Hayır :=)
İşte bu tür;hiyerarşik yapıdaki değişiklikler için, GetReparentedValue() fonksiyonu kullanılmalıdır.(SQL Server 2008 RC0 ‘dan itibaren Reparent() fonksiyonu,GetReparentedValue() olarak değiştirilmiştir)

DECLARE @Basamak hierarchyid
DECLARE @EskiYonetici hierarchyid
DECLARE @YeniYonetici hierarchyid
SELECT @Basamak=Dugum from Calisanlar where Calisan_ID=5006 -- Tomris
SELECT @EskiYonetici=Dugum from Calisanlar where Calisan_ID=5001 -- Ali artık Tomris'i yönetmeyecek.
SELECT @YeniYonetici=Dugum from Calisanlar where Calisan_ID =5004 -- Aydın artık Tomris'in yöneticisi
UPDATE Calisanlar
SET Dugum = @Basamak.GetReparentedValue(@EskiYonetici, @YeniYonetici)
WHERE Dugum = @Basamak

Tablomuzun son haline bakarsak,aşağıdaki gibi değiştiğini göreceksiniz



Görüldüğü gibi;Tomris artık Aydın tarafından yönetilen bir çalışan.

Burada dikkatinizi çektiyse,küçük bir problemle karşı karşıyayız.Şöyle ki Tomris artık Ali tarafından yönetilmekten çıkıp Aydın tarafından yönetilmekte fakat Tomris’in yönettiği çalışanlar yöneticisiz kalmış durumda. ( “/1/2”  şeklinde bir düğüm artık bulunmamakta)

Böyle bir durum sıkıntı yaratacaksa,geliştiriciler olarak duruma müdahale edilmeli ve indexler oluşturulmalıdır.Bu örnek için, 2 tür index tanımlaması yapılabilir.İlki Depth-First Index’dir ve bu index yapısında bütün düğümler,yanyana dizilir,birlikte saklanır ve istenilen özel bir düğüme bağlanabilir.Bütün çalışanların sadece bir yöneticiye bağlı olarak çalıştığı yapılarda kullanılabilir.



İkinci index türümüz ise;
Breadth-First Index’dir.Bu index türünde bütün düğümler,dereceleriyle birlikte sıralı olarak tutulur.Aynı yöneticiye bağlı çalışanlar birlikte tutulurlar




Bir tablo oluşturulduktan sonra,depth first index,direk olarak primary key ile tanımlanmış olur.(Yani default olarak depth first index tanımlanmıştır.)Breadth-First Index tanımlamasını ise şöyle bir komutla biz yapabiliriz

CREATE
Index Breadth on Calisanlar(Dugum,Basamak)

Bu makalemizde SQL Server 2008 ‘in yeni veri tiplerinden olan Hierarchyid Veri Tiplerini ve kullandığı fonksiyonlarını,örnek sorgularla  inceledik.

Bu makaleye bağlı makalelerde SQL Server 2008 ile gelen yeni veri tiplerini incelemeye devam edeceğiz
.

 

Yorumlar (2) -

02.05.2009 15:14:51 #

Cemil UZUN

SQL konusunda uzman kardesim, bir kitap yazarsin yakinda sende. Hadi bakalım, basarilar...

Cemil UZUN Turkey

02.05.2009 15:49:17 #

Bilgehan

Tesekkürler Cemil , hedeflerim arasında aslında kitap yazmak var ama dur bakalım gerçekleştirebilecek miyiz Smile

Olmadı ortak bir kitap yazarız bir tarafı XNA olur, diğer tarafı SQL Server Smile

Bilgehan Turkey

Yorumlar kapalı.

Son Yazılar

Arşiv

Takvim

<<  Şubat 2012  >>
PaSaÇaPeCuCuPa
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar

Son Yorumlar

Comment RSS

En çok yorumu yazanlar

Bilgehan G&#252;r&#252;nl&#252; Bilgehan Gürünlü
3 yorumlar
tr Turkey
Serhat Taş Serhat Taş
2 yorumlar
Mustafa Kaya Mustafa Kaya
2 yorumlar
tr Turkey
murat hacioglu murat hacioglu
2 yorumlar
tr Turkey
Daron Y&#246;ndem Daron Yöndem
1 yorumlar
tr Turkey


>


Yasal Uyarı

Bu sitede sunulan tüm bilgi, dökümanların kullanımından doğacak sorunlardan yazar sorumlu tutulamaz. Bu site ve günce(blog) işverenimin görüşlerini, amaçlarını, planlarını veya stratejilerini temsil etmez. Tüm yazılanlar aksi belirtilmedikçe benim fikrimdir. Uygunsuz yorumlar silinecektir.
© Copyright |Bilgehan Gürünlü | 2007 - 2011

Sosyal Destek

>