SQL Server 2008 ile Gelen Yeni Veri Tipleri-3 (Hiyerarşik Veri Tipleri)

Dark-Man

Kıdemli Üye
5 Ocak 2013
4,430
9
I Don't Know
[FONT=&quot]SQL Server 2008 ile birlikte gelen birçok yenilikten biri de,yeni veri tipleridir.SQL Server 2008’de daha önceki sürümlerde kullandığımız int,varchar,float,datetime gibi veri tiplerine ek olarak sınırlarımızı daha da genişleten yeni veri tipleri karşımıza çıkmaktadır.[/FONT]
[FONT=&quot] SQL Server 2008 ile gelen;bu yeni veri tiplerini aşağıdaki gibi bir gruplamaya sokabiliriz.(Bu makalemizde üçüncü grup olan Hiyerarşik Veri Tipleri üzerinde duracağız)[/FONT]

Ø
[FONT=&quot]Uzaysal Veri Tipleri:
[FONT=&quot] Bu veri tipleri [/FONT][FONT=&quot]GEOMETRY [/FONT][FONT=&quot]ve [/FONT][FONT=&quot]GEOGRAPHY [/FONT][/FONT][FONT=&quot]veri tiplerini içermektedir. Bu verilere de Uzaysal Veriler denmektedir.

[/FONT]Ø [FONT=&quot]Yeni Date ve Time Veri Tipleri:[FONT=&quot] [/FONT][/FONT][FONT=&quot]Bu veri tipleri,esnek Date ve Time verilerinin tutulmasını sağlamaktadır.Örneğin;1753 yılından önceki yılların yada 3.33 milisaniye den daha kısa zaman aralıklarının,veri tabanında saklanmasına imkan sağlıyorlar.

[/FONT]Ø [FONT=&quot]Hierarchyid Veri Tipleri :[/FONT][FONT=&quot]Hiyerarşik verilerin tutulduğu tipler.Örneğin; çalışan => müdür ilişkisinin tutulmasına imkan sağlayan veri tipleridir.[/FONT]Ø [FONT=&quot]FileStream Desteği :[/FONT][FONT=&quot]Büyük objelerin dosyalarda tutulması ve bu dosyaların database ile entegrasyonun sağlanması ise veri tiplerine getirilen bir başka kullanışlı yeniliktir.[/FONT][FONT=&quot]
Şimdi;yeni Hiyerarşik Veri Tiplerine ve sağladığı imkanlara bakalım.(Önceki bağlı makalelerimizde Uzaysal Veri Tiplerini ve Date-Time Veri Tiplerini incelemiştik)
[/FONT]
[FONT=&quot]3)SQL Server 2008’de Yeni Hiyerarşik Veri Tipleri :[/FONT]
[FONT=&quot]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.[/FONT]
[FONT=&quot]SQL Serverda Hiyerarşik veriler 3 farklı yolla ele alınabilir.[/FONT]
Ø [FONT=&quot]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. [/FONT]


Ø [FONT=&quot]Verileri ilişkisel tablolarda tutarak ve sonra bunları [/FONT]SELF JOIN ‘[FONT=&quot]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.[/FONT]


Ø [FONT=&quot]SQL Server 2008 ile gelen yeni [/FONT]hierarchyid [FONT=&quot]veri tipini kullanmak.[/FONT]
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 [FONT=&quot]altında yer almaktadır.Uygulamalarda [/FONT]Microsoft.SqlServer.Types [FONT=&quot]aduzayı aracılıgıyla kullanabilir.[/FONT]
[FONT=&quot]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.[/FONT]
[FONT=&quot]Şimdi [/FONT]Hierarchyid veri tipimizi daha iyi anlayabilmek için hayali bir şirketin,organizasyon şemasını oluşturalım.
1jpg.jpg


[FONT=&quot]Şekildeki gibi bir organizasyon şemasına sahip şirketimizin;yönetim yapısını SQL Serverda ,yeni [/FONT]hierarchyid [FONT=&quot]tipini kullanarak saklamak isteyelim.Önce [/FONT][FONT=&quot]Sirket[/FONT][FONT=&quot] isimli veri tabanımızı oluşturuyoruz,daha sonra [/FONT][FONT=&quot]Calisanlar[/FONT][FONT=&quot] isimli tablomuzu oluşturuyoruz.[/FONT]
[FONT=&quot]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.[/FONT]
[FONT=&quot]CREATE[/FONT][FONT=&quot] TABLE Calisanlar
[/FONT][FONT=&quot]([/FONT][FONT=&quot]Dugum hierarchyid PRIMARY KEY CLUSTERED,
[/FONT][FONT=&quot]Basamak AS dugum.GetLevel() PERSISTED,
Calisan_ID INT UNIQUE,
[/FONT][FONT=&quot]Calisan_Isim VARCHAR(30) NOT NULL)[/FONT][FONT=&quot] [/FONT]
[FONT=&quot]Burada ast-üst ilişkisinin SQL Server’a aktarılmasını sağlayan fonksiyonumuz [/FONT][FONT=&quot]GetLevel() [/FONT][FONT=&quot]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.[/FONT]
[FONT=&quot]Tabloyu oluşturduktan sonra kök de(root) beraberinde oluşturulmuş olur.[/FONT]
[FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES (hierarchyid::GetRoot(),5000,'Ahmet')[/FONT]
GetRoot() [FONT=&quot]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.[/FONT]
[FONT=&quot]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 [/FONT]GetDescendants [FONT=&quot]fonksiyonunu kullanacağız.Bu fonksiyon ana bir düğümden türeyen düğümleri,child nodeları, döndürmektedir.[/FONT]
[FONT=&quot]Bu örneğimiz için ilk düğümü döndürecektir.[/FONT]
[FONT=&quot]--Öncelikle dügümlerde tutulacak gecici degiskenler tanımlayalım.
[/FONT]
[FONT=&quot]DECLARE[/FONT][FONT=&quot] @YoneticiDugum hierarchyid
[/FONT][FONT=&quot]DECLARE[/FONT][FONT=&quot] @Sira hierarchyid[/FONT]
[FONT=&quot][/FONT]

[FONT=&quot]--Kok dugum,"Ahmet", icin ,Calisan_ID 5000 dir.
[/FONT]
[FONT=&quot]SELECT[/FONT][FONT=&quot] @YoneticiDugum=Dugum FROM Calisanlar WHERE Calisan_ID=5000
[/FONT][FONT=&quot]--GetDescendant ilk dugumu bize dondurecektir.Ilk dugum "/1"[/FONT][FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES (@YoneticiDugum.GetDescendant(NULL, NULL),5001, 'Ali')[/FONT]
[FONT=&quot]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.[/FONT]
[FONT=&quot]--Kok dugum,"Ahmet", icin ,Calisan_ID 5000 dir.
[/FONT]
[FONT=&quot]SELECT[/FONT][FONT=&quot] @YoneticiDugum=Dugum FROM Calisanlar WHERE Calisan_ID=5000
[/FONT][FONT=&quot]--GetDescendant ilk dugumu bize dondurecektir.Ilk dugum "/1"
[/FONT]
[FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES (@YoneticiDugum.GetDescendant(NULL, NULL),5001, 'Ali')
[/FONT][FONT=&quot]--Ali'nin Calisan_ID di 5001 olacaktır.
[/FONT]
[FONT=&quot]SELECT[/FONT][FONT=&quot] @Sira=Dugum FROM Calisanlar WHERE Calisan_ID=5001
[/FONT][FONT=&quot]--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. [/FONT]



[FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES
[/FONT][FONT=&quot]([/FONT][FONT=&quot]@YoneticiDugum.GetDescendant(@Sira, NULL),5002, 'Erdem')[/FONT][FONT=&quot]İsterseniz,şu ana kadarki oluşturduğumuz şirketimizin, hiyerarşik yapısını sorgulayalım [/FONT]
[FONT=&quot]SELECT[/FONT][FONT=&quot] Dugum.ToString() AS Dugumun_Text_Gosterimi,
[/FONT][FONT=&quot]Dugum AS Dugumun_Binary_Gosterimi,
Dugum.GetLevel() AS Sira,
Calisan_ID,
Calisan_Isim
[FONT=&quot]FROM[/FONT][FONT=&quot] Calisanlar[/FONT][/FONT]
1000002149_Hiyerarsik1.jpg

[FONT=&quot]Şirketimizin Organizasyon Şemasındaki,Dugumlerin yerleşimi ise şöyle olacaktır.
1000002149_sirket2.jpg

[FONT=&quot]Şekilde de görüldüğü gibi Bilgehan,Erdem’in yöneticiliğinde çalışmaktadır ve düğümsel değeri “/2/1” dir. [/FONT]
[/FONT][FONT=&quot]SQL kodlarımızla şirketimizin organizasyon şemasını tamamlayalım.
[FONT=&quot]SELECT[/FONT][FONT=&quot] @Sira=Dugum FROM Calisanlar WHERE Calisan_ID=5002
[/FONT][FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES(@Sira.GetDescendant(NULL, NULL),5003, 'Bilgehan')
[/FONT][FONT=&quot]--Erdem, yönetici olarak @Sira değişkeninde saklanıyor.
-- Bilgehan'ı ,Erdem altında çalışan biri olarak tanımladık.
[/FONT]
[FONT=&quot]DECLARE[/FONT][FONT=&quot] @dugum1 hierarchyid
[/FONT][FONT=&quot]--Bilgehan'ın,Calisan_ID si 5003 dür.
[/FONT]
[FONT=&quot]SELECT[/FONT][FONT=&quot] @dugum1=Dugum FROM Calisanlar WHERE Calisan_ID=5003
[/FONT][FONT=&quot]--GetDescendant,Bilgehan'dan sonraki Dugum 'ü döndürecek.
[FONT=&quot][FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES (@Sira.GetDescendant(@dugum1, NULL),5004, 'Aydin')[/FONT][/FONT][/FONT]

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

[FONT=&quot]--Tomris'i de Ali'nin yöneticiliğine atıyoruz.
[/FONT]
[FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES (@Sira.GetDescendant(@dugum1,NULL),5006, 'Tomris')
[/FONT][FONT=&quot]--Ada' da Tomris'in yöneticiliğinde
[/FONT]
[FONT=&quot]SELECT[/FONT][FONT=&quot] @Sira=Dugum FROM Calisanlar WHERE Calisan_ID=5006
[FONT=&quot]--Ada'yı da Tomris'den sonra ki ilk yetkili yapıyoruz.[/FONT][/FONT]
[FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES (@Sira.GetDescendant(NULL,NULL),5007, 'Ada')
[/FONT][FONT=&quot]--Ada'nın Dugum 'ü olusturuldu.
[/FONT]
[FONT=&quot]SELECT[/FONT][FONT=&quot] @dugum1=Dugum FROM Calisanlar WHERE Calisan_ID=5007
[/FONT][FONT=&quot]--Cemil'i de ,Tomris'in yöneticiliğine sokuyoruz.
[FONT=&quot]INSERT[/FONT][FONT=&quot] INTO Calisanlar VALUES (@Sira.GetDescendant(@dugum1,NULL),5008, 'Cemil')[/FONT][/FONT]

[FONT=&quot]Organizasyon şemamızı sorguladığımızda yapımız şöyle olmalıdır.[/FONT]
1000002149_ensonsira.jpg


[FONT=&quot]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 :=)[/FONT]
[FONT=&quot]İşte bu tür;hiyerarşik yapıdaki değişiklikler için,[/FONT] GetReparentedValue() fonksiyonu kullanılmalıdır.[FONT=&quot] [/FONT][FONT=&quot]([/FONT][FONT=&quot]SQL Server 2008 RC0 ‘dan itibaren [/FONT]Reparent[FONT=&quot]() fonksiyonu[/FONT],GetReparentedValue() [FONT=&quot]olarak değiştirilmiştir)[/FONT][FONT=&quot][/FONT]
[FONT=&quot]DECLARE[/FONT][FONT=&quot] @Basamak hierarchyid
[/FONT][FONT=&quot]DECLARE[/FONT][FONT=&quot] @EskiYonetici hierarchyid
[/FONT][FONT=&quot]DECLARE[/FONT][FONT=&quot] @YeniYonetici hierarchyid
[/FONT][FONT=&quot]SELECT[/FONT][FONT=&quot] @Basamak=Dugum from Calisanlar where Calisan_ID=5006 -- Tomris
[/FONT][FONT=&quot]SELECT[/FONT][FONT=&quot] @EskiYonetici=Dugum from Calisanlar where Calisan_ID=5001 -- Ali artık Tomris'i yönetmeyecek.
[/FONT][FONT=&quot]SELECT[/FONT][FONT=&quot] @YeniYonetici=Dugum from Calisanlar where Calisan_ID =5004 -- Aydın artık Tomris'in yöneticisi
[/FONT][FONT=&quot]UPDATE[/FONT][FONT=&quot] Calisanlar
[/FONT][FONT=&quot]SET[/FONT][FONT=&quot] Dugum = @Basamak.GetReparentedValue(@EskiYonetici, @YeniYonetici)
[FONT=&quot]WHERE[/FONT][FONT=&quot] Dugum = @Basamak[/FONT]
[/FONT]
[FONT=&quot]Tablomuzun son haline bakarsak,aşağıdaki gibi değiştiğini göreceksiniz[/FONT]
1000002149_ensonartik.jpg

[FONT=&quot]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)[/FONT]
[FONT=&quot]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 [/FONT][FONT=&quot]Depth-First Index’[/FONT][FONT=&quot]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.[/FONT]
1000002149_Depth-first.gif

[FONT=&quot]İkinci index türümüz ise;[/FONT][FONT=&quot]Breadth-First [/FONT][FONT=&quot]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
1000002149_Breadth-first.gif


[FONT=&quot]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
[FONT=&quot]
CREATE[/FONT]
[FONT=&quot] Index Breadth on Calisanlar(Dugum,Basamak)[/FONT][/FONT]
[/FONT]
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.