Makale Özeti

Bilindiği üzere bir uygulama geliştirme aşamasında en son safha kod yazmaktır. Kod yazmaya geçmeden evvel günler süren analizler yapılır. Kod yazma safhasından önce yine günlerimizi alan bir aşamada veritabanı tasarımıdır. Kullanışlı bir uygulama çıkarmak için veritabanımızında ihtiyaçlarımızı karşılayabilecek şekilde tasarlanmış olması gerekir. Birazdan birçok programcının kâbusu haline gelen Sonsuz Ağaç Yapısı hakkında hep beraber bir çözüm getireceğiz. Müşteri, elinize bir sürü alt kategorisi bulunan ürün katoluğunu veriyor ve sizden çözüm bekliyor.

Makale

0. Giriş
1. Problem Tanımı
2. Çözümü
3. Kullanımı

0.Giriş

Bilindiği üzere bir uygulama geliştirme aşamasında en son safha kod yazmaktır. Kod yazmaya geçmeden evvel günler süren analizler yapılır. Kod yazma safhasından önce yine günlerimizi alan bir aşamada veritabanı tasarımıdır. Kullanışlı bir uygulama çıkarmak için veritabanımızında ihtiyaçlarımızı karşılayabilecek şekilde tasarlanmış olması gerekir. Birazdan birçok programcının kâbusu haline gelen Sonsuz Ağaç Yapısı hakkında hep beraber bir çözüm getireceğiz. Müşteri, elinize bir sürü alt kategorisi bulunan ürün katoluğunu veriyor ve sizden çözüm bekliyor.

1. Problem Tanımı

1   Telefon             MOTOROLA MPx200 
2   Film                GORA (CD) 
3   Ev Elektroniği      SONY PLAYSTATION 2 
4   Spor                MOTORLU KOŞU BANDI 4
5   Telefon             SONY ERICSSON S700i 
6   Telefon             NOKIA 7610 
7   Telefon             NOKIA 7260 
8   Telefon             SONY ERICSSON T630 
9   Telefon             MOTOROLA V3 

Şeklinde bir ürün kataloğumuzu veritabanında tuttuğumuzu düşünelim. Veritabanı normalizasyon kurallarından biri olan "veri tekrar olmamalıdır" düsturu ile hareket edip tablo tasarımızı Master-Detail üzerine inşa ederiz.

Kategoriler Ürünler

Ancak zengin çeşitli bir ürün kataloğu ile karşı karşıya kalırsak bu çözüm bize pek yardımcı olmayacaktır. Çünkü her alt kategori için yeni bir tablo açmak mantıksız ve zor olacaktır. Bu hem performansı düşürür hemde alt kategori seviyesi belli olmayan durumlarda belli bir alt seviyeden sonra ilerleyemez hale geliriz.

2. Çözümü

Aşağıdaki gibi 4ncü alt seviye kadar inmiş bir kategori yapısını veritabanında tutabilmek için bir çözüm geliştirelim.

  |--Donanım
  |
  |  |--Anakartlar
  |  |  |--AMD Tabanlı 
  |  |  |--Intel Tabanlı 
  |  |--RAM
  |  |  |--EDO-RAM
  |  |  |  |--99 Mhz
  |  |  |--SD-RAM
  |  |  |  |--100 Mhz
  |  |  |  |--133 Mhz
  |  |  |--DDR-RAM       
  |  |     |--266 Mhz
  |  |--İşlemciler
  |     |--AMD İşlemciler
  |     |  |--64 Bit 
  |     |  |--Sempron
  |     |--Intel İşlemciler
  |        |--Celeron
  |        |--P4
  |--Yazılım

Ancak birazdan geliştireceğimiz çözümde göreceksiniz ki alt kategori seviyesi ne olursa olsun problemimizi giderecektir.

İlk örneğimizde oluşturduğumuz Kategoriler tablosunu tekrar ele alalım ve bu sefer KategoriID ile isim arasında birde ustID kolonu ekleyelim. İlk önce ana kategorileri gireceğiz ve ana kategorilerin ustID leri 0 "sıfır" olacak. Daha sonra bir alt seviye kategorilere geçelim. Örneğin "Anakartlar". Anakartlar kategorisini girerken dikkat edeceğimiz nokta : Girdiğimiz kategori hangi üst kategorinin altında ?

Yukarıdaki şekilde görüldüğü üzere Anakartlar, Donanım kategorisi altında. Dolayısıyla Anakartlar kategorisinin ustID si Donanım kategorisini ID si olmalı.

Alt kategorileri girmeye devam edelim.

Kategorileri girerlen ustID yi bulmak için iki sorunun cevabını vermemiz yeterli :

Girilecek kategori : AMD Tabanlı.

Soru 1 : AMD Tabanlı kategorisini neyin altında ?
Cevap : Anakartlar.

Soru 2 : Anakrtların ID si kaç ?
Cevap : 3

Görüldüğü gibi kategorileri veritabanına girmek çok basit. Her seferinde bir üst kategorinin ID sini ustID alanına giriyoruz.

Bu bilgiler ışığında yeni Kategoriler tablomuz şöyle görülmeli :

3. Kullanımı

Sınırsız ağaç yapısı için veritabanımız yapılandırdık. Ancak bu kategorileri görüntülerken nasıl yol izleyeceğiz.

Bunu için aşağıdaki kodu ASP.NET ( C# ) ile yazdım.

private void Page_Load(object sender, System.EventArgs e)
{
	if ( !IsPostBack)
	{
		SqlConnection conn = new SqlConnection("server=.;database=makale;uid=sa;password=123;");
		SqlDataAdapter adp = new SqlDataAdapter("select * from kategoriler",conn);
		adp.Fill(dsKategoriler,"dtKategoriler");

	}
}

public void Yazdir(DataTable dt,string ustID,int seviye)
{
	DataRow[] dr;

	seviye++;

	dr = dt.Select("ustID = " + ustID );

	string isim,SiradakiUstID,bosluk;
	for ( int i = 0 ; i < dr.Length ; i++ )
	{	
		SiradakiUstID = dr[i]["KategoriID"].ToString();
		isim = dr[i]["isim"].ToString();
		bosluk = new string('-',seviye);

		Response.Write( String.Format("{0} {1} 
",bosluk,isim) ); Yazdir(dt,SiradakiUstID,seviye); } }

Çıktısı :


- Donanım 
-- Anakartlar 
--- AMD Tabanlı 
--- Intel Tabanlı 
-- RAM 
--- EDO-RAM 
---- 99 Mhz 
--- SD-RAM 
---- 100 Mhz 
---- 133 Mhz 
--- DDR-RAM 
---- 266 Mhz 
-- İşlemciler 
--- AMD İşlemciler 
---- 64 Bit 
---- Sempron 
--- Intel İşlemciler 
---- Celeron 
---- P4 
- Yazılım