pillinetwork hesabınızla giriş yapın.

veritabanı programlayamama yazıları (nested setler)

veritabanı programlayamama konusunda en önemli örneklerden biri, hiyerarşik datalar ve veritabanları. bahsetmek istediğim konu, iç içe geçmiş yorumlar, ağaç şeklindeki menüler vs. gibi basamaklı uygulamalar ve bunların datasının veritabanında saklanması. sırayla kullanılabilecek modelleri inceleyip, örnekle gidip daha sonra kaynakların ekonomik kullanımı konusuna geçelim.

örneğin şöyle bir sayfa oluşturmak istiyoruz :

1
2
3
4
5
6
7
8
yorumlar :
yorum 1
yorum 1 cevap
yorum 2
yorum 3
yorum 4
yorum 4 cevap
yorum 4 cevapa cevap

bunu yapmak için temelde 2 farklı veritabanı modeli kullanabilirsiniz, Adjacency List Model ve Nested Set Model ( çok üzgünüm bunların türkçe isimlerini bilemiyorum, ve bulamıyorum, umarım yorumlarda türkçe karşılıkları verilir, bende yazıyı güncellerim )

Adjacency List Model

bu modelde, temel olarak, bir nesnenin bağlı olduğu diğer nesneleri göstermek için, parent/ebeveyn kolonu kullanıyoruz. muhtemelen bu şekilde uygulamalarla ya karşılaşmışsınızdır yada kendiniz yapmışsınızdır. hızlıca bir örnek verip diğer modele geçeceğiz.

yorumlar tablosu şuna benzer birşey olsun,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
create table yorumlar (
id int not null auto_increment,
yorum text,
parent_id int default 0,
primary key (id)
);
insert into yorumlar set yorum='yorum 1';
insert into yorumlar set yorum='yorum 2';
insert into yorumlar set yorum='yorum 3';
insert into yorumlar set yorum='yorum 4';
insert into yorumlar set parent_id=4, yorum='yorum 4 cevap';
insert into yorumlar set parent_id=5, yorum='yorum 4 cevapa cevap';
insert into yorumlar set parent_id=1, yorum='yorum 1 cevap';

1
2
3
4
5
6
7
8
9
10
11
12
select * from yorumlar;
+----+----------------------+-----------+
| id | yorum | parent_id |
+----+----------------------+-----------+
| 1 | yorum 1 | 0 |
| 2 | yorum 2 | 0 |
| 3 | yorum 3 | 0 |
| 4 | yorum 4 | 0 |
| 5 | yorum 4 cevap | 4 |
| 6 | yorum 4 cevapa cevap | 5 |
| 7 | yorum 1 cevap | 1 |
+----+----------------------+-----------+

şimdi bundan veri çekecek php scripti aşağı yukarı şöyle bir şey olacaktır:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
mysql_connect('localhost','root','123');
$db = mysql_select_db('yazilar');
define('ayrac', "\t");
function printComments($parent = 0, $level = 0){
$s = 'select * from yorumlar where parent_id = '.$parent;
$res = mysql_query($s);
while ($row = mysql_fetch_array($res)){
echo str_repeat(ayrac, $level).$row['yorum']."\n";
printComments($row['id'],$level+1);
}
return $rows;
}
printComments();

çıktısıda şöyle olur :
1
2
3
4
5
6
7
yorum 1
yorum 1 cevap
yorum 2
yorum 3
yorum 4
yorum 4 cevap
yorum 4 cevapa cevap

rekursif şekilde select yapmanın bize maliyeti her farklı parent için 1 query göndermek olacaktır tabii. bir tartışma alanı düşünün, - örneğin digg deki yorumlar gibi - yüzlerce query göndermek zorunda kalırsınız. fakat yeni bir yorum ekleyen fonksiyon ziyadesiyle kolaydır.

1
2
3
function insertComment($yorum, $parent_id){
mysql_query('insert into yorumlar set parent_id='.$parent_id.', yorum="'.$yorum.'"');
}

malum bir sayfada yüzlerce sorgu göndermek ciddi sorunlara yol açacağı için diğer modele geçiyoruz, tabii yazının gerisini okumadan önce, sayfayı olduğu gibi cachelemek, yada yorumları cachelemek gibi çeşitli alternatifleri de düşünebilirsiniz. ama twitter örneğini unutmamak gerek, twitter devamlı sayfalar değiştiği için, page cache kullanamıyor mesela, devamlı cacheyi yazıp okuması, invalidate etmesi daha maliyetli olduğu için. herneyse, diğer modelimiz,

Nested Set Model

bu modeli anlatması, biraz karışık olduğu için, umarım başarabilirim diyerek başlıyorum,

1
2
3
4
5
6
7
create table yorumlar_n (
id int not null auto_increment,
yorum text,
lft int ,
rgt int ,
primary key(id)
);

left ve right diyemediğimiz için, çoğu veritabanı sunucunda reserve kelimedir çünkü, lft ve rgt dedik. şimdi pekii bu lft ve rgt kolonları nedir diye soracak olursanız, şuna benzer bir şekilde veriyi dizdiğimizi düşünün, kumeleri hatirliyorsunuz degil mi ?

1
2
3
4
5
6
____________________________________________________________________________________________________________
| yorumlar |
| (yorum 1 ) (yorum 2) (yorum 3) (yorum 4 ) |
| (yorum 1 cevap) (yorum 4 cevap ) |
| (yorum 4 cevapa cevap) |
|___________________________________________________________________________________________________________|

şimdi de bunları sol baştan başlayarak numaralandırıyoruz
1
2
3
4
5
6
7
8
______________________________________________________________________________________________________
| yorumlar |
| (yorum 1 ) (yorum 2) (yorum 3) (yorum 4 ) |
| | (yorum 1 cevap) | | | | | | (yorum 4 cevap ) | |
| | | | | | | | | | | (yorum 4 cevapa cevap) | | |
| | | | | | | | | | | | | | | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|______________________________________________________________________________________________________|

şimdide veritabanına bu numaralara göre datayı ekliyorum,
1
2
3
4
5
6
7
8
insert into yorumlar_n set yorum='yorumlar', lft=1,rgt=16;
insert into yorumlar_n set yorum='yorum 1', lft=2,rgt=5;
insert into yorumlar_n set yorum='yorum 2', lft=6,rgt=7;
insert into yorumlar_n set yorum='yorum 3', lft=8,rgt=9;
insert into yorumlar_n set yorum='yorum 4', lft=10,rgt=15;
insert into yorumlar_n set yorum='yorum 1 cevap', lft=3,rgt=4;
insert into yorumlar_n set yorum='yorum 4 cevap', lft=11,rgt=14;
insert into yorumlar_n set yorum='yorum 4 cevapa cevap', lft=12,rgt=13;

farkettiyseniz, kimin kime bağlı olduğu yada id kolonuyla ilgilenmiyoruz. bu arada bu yönteme preorder tree traversal algoritması deniyor (üzgünüm bununda tam türkçe karşılığını bilemiyorum )

şimdi gelelim burdan datayı nasıl çekeceğimize, sorgumuz şöyle olacak,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> select id, yorum, lft from yorumlar_n as node order by node.lft;
+----+----------------------+------+
| id | yorum | lft |
+----+----------------------+------+
| 1 | root | 1 |
| 2 | yorum 1 | 2 |
| 6 | yorum 1 cevap | 3 |
| 3 | yorum 2 | 6 |
| 4 | yorum 3 | 8 |
| 5 | yorum 4 | 10 |
| 7 | yorum 4 cevap | 11 |
| 8 | yorum 4 cevapa cevap | 12 |
+----+----------------------+------+
8 rows in set (0.00 sec)

bu modelde işin güzel tarafı şöyle birşeyde yapabilirsiniz, yorum 4 ve altındakileri çekmek için, tabloyu kendisiyle join ederek tek sorguda istediğiniz kısmı çekme imkanınız var.

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> SELECT node.id, node.yorum
-> FROM yorumlar_n AS node, yorumlar_n AS parent
-> WHERE node.lft BETWEEN parent.lft AND parent.rgt
-> and parent.id=5
-> ORDER BY node.lft;
+----+----------------------+
| id | yorum |
+----+----------------------+
| 5 | yorum 4 |
| 7 | yorum 4 cevap |
| 8 | yorum 4 cevapa cevap |
+----+----------------------+
3 rows in set (0.00 sec)

kaçıncı levelda (depthte, derinlikte, basamakta) olduklarınıda birlikte çekmek istersek şöyle bir query yapabiliriz,

1
2
3
4
5
6
SELECT node.yorum, (COUNT(parent.yorum) - 1) AS depth
FROM yorumlar_n AS node,
yorumlar_n AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.yorum
ORDER BY node.lft;

1
2
3
4
5
6
7
8
9
10
11
12
13
+----------------------+-------+
| yorum | depth |
+----------------------+-------+
| root | 0 |
| yorum 1 | 1 |
| yorum 1 cevap | 2 |
| yorum 2 | 1 |
| yorum 3 | 1 |
| yorum 4 | 1 |
| yorum 4 cevap | 2 |
| yorum 4 cevapa cevap | 3 |
+----------------------+-------+
8 rows in set (0.00 sec)

veya bir yorumun altındaki diğer yorumların sayısını çekmek istersek, basit aritmetik bilgimizle, şuna benzer birşey yapabiliriz
1
select id, yorum, lft, (rgt - lft +1)/2 as yorum_say from yorumlar_n as node order by node.lft;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> select id, yorum, lft, (rgt - lft +1)/2 as yorum_say from yorumlar_n as node order by node.lft;
+----+----------------------+------+-----------+
| id | yorum | lft | yorum_say |
+----+----------------------+------+-----------+
| 1 | yorumlar | 1 | 8.0000 |
| 2 | yorum 1 | 2 | 2.0000 |
| 6 | yorum 1 cevap | 3 | 1.0000 |
| 3 | yorum 2 | 6 | 1.0000 |
| 4 | yorum 3 | 8 | 1.0000 |
| 5 | yorum 4 | 10 | 3.0000 |
| 7 | yorum 4 cevap | 11 | 2.0000 |
| 8 | yorum 4 cevapa cevap | 12 | 1.0000 |
+----+----------------------+------+-----------+
8 rows in set (0.00 sec)

burdaki (node.rgt - node.lft +1)/2 - 1 formülünü parçalayalım, bir yorumun altındaki her yorumun 2 değeri var, left ve right, o zaman, altındakilerin başlangıç ve bitiş noktaları arasındaki değerleri çıkartır, sonrada 2 ye bölersem, altındaki yorum sayısını bulurum. örneğin yorum 4 altındakileri bulmak için, 15 ten 10 u çıkartır 2 ye bölerim, saymaya 0 dan değil, 1 den başladığım için, 1 çıkartırım (15 - 10) - 1 / 2 = 2 yapar.

1
2
3
4
5
6
SELECT node.yorum, (COUNT(parent.yorum) - 1) AS depth, (node.rgt - node.lft - 1)/2 as yorum_say
FROM yorumlar_n AS node,
yorumlar_n AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.yorum
ORDER BY node.lft;

1
2
3
4
5
6
7
8
9
10
11
12
13
+----------------------+-------+-----------+
| yorum | depth | yorum_say |
+----------------------+-------+-----------+
| yorumlar | 0 | 7.0000 |
| yorum 1 | 1 | 1.0000 |
| yorum 1 cevap | 2 | 0.0000 |
| yorum 2 | 1 | 0.0000 |
| yorum 3 | 1 | 0.0000 |
| yorum 4 | 1 | 2.0000 |
| yorum 4 cevap | 2 | 1.0000 |
| yorum 4 cevapa cevap | 3 | 0.0000 |
+----------------------+-------+-----------+
8 rows in set (0.00 sec)

şimdi kendimizi biraz daha zorlayıp, nested seti, adjacency list olarak göstermek istersek, şöyle bir query yazabiliriz,

1
2
3
4
5
6
7
8
9
SELECT O.id, I.id as parent_id
FROM yorumlar_n AS O
LEFT OUTER JOIN
yorumlar_n AS I
ON B.lft
= (SELECT MAX(lft)
FROM yorumlar_n AS S
WHERE O.lft > S.lft
AND O.lft < S.rgt);

1
2
3
4
5
6
7
8
9
10
11
12
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | NULL |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
| 6 | 2 |
| 7 | 5 |
| 8 | 7 |
+----+-----------+

şimdi bunun tam tersini yazıp adjacency listi nested viewa çevirmeden, ve nested sete yeni veri girmeden önce phpde görüntülemek için olan fonksiyonu yazalım, ve bu yazıyı toparlayalım.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
mysql_connect('localhost','root','123');
$db = mysql_select_db('yazilar');
define('ayrac', "\t");
function printComments(){
$s = 'SELECT node.yorum, (COUNT(parent.yorum) - 1) AS level, (node.rgt - node.lft - 1)/2 as yorum_say
FROM yorumlar_n AS node, yorumlar_n AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.yorum
ORDER BY node.lft';
$res = mysql_query($s);
while ($row = mysql_fetch_array($res)){
echo str_repeat(ayrac, $row['level']).$row['yorum']." (".$row['yorum_say'].")\n";
}
return $rows;
}
printComments();

çıktısı aynı şekildedir :
1
2
3
4
5
6
7
8
9
yorumlar (7)
yorum 1 (1)
yorum 1 cevap (0)
yorum 2 (0)
yorum 3 (0)
yorum 4 (2)
yorum 4 cevap (1)
yorum 4 cevapa cevap (0)

aradaki fark tüm yorumları ve hatta yorumların altındaki yorum sayılarıyla birlikte sadece tek bir sorgu gönderirken, list kullanarak defalarca sorgu göndermek zorunda kalmıyoruz. örneğin 100 civarı yorum almış bir sayfayı düşünün, göndereceğiniz sorgu sayısı parent_id sayısı kadardır, birde buna yorum sayısı eklemek istediğinizi düşünün, 100lerce sorgu göndermek zorunda kalabiliriz.

bir sonraki yazıda nested sete data ekleme ve çıkartma işlemleriyle devam edip, daha sonra adjacency list modele göre dezavantajlarından bahsedeceğiz. sonrada, her iki modeldeki denormalizasyon opsiyonlarına ve farklı algoritmalara değiniriz. umarım hiyerarşik yapıları kullanan birilerine yardımcı olur bu yazı.

/* aybars badur yazdı. 18 Kasım 2008 09:46. 21 yorum var */

Yorumlar

Çok güzel bir yazı, tebrik ederim. Bence ilk bahsettiğiniz recursive algoritma her zaman yavaş olmayabilir. Verileri önce topluca çekerek (tabii belli kriterlere göre) daha sonradan kod tarafında parent/child yapısına göre işlem yapılırsa her seferinde veritabanına sorgu göndermek zorunda kalınmayacağından çok daha hızlı olacaktır. Tabii php'de bunu yapmak nispeten zor ve yavaş olabilir ama .Net veya Java'da bu daha performanslı olabilir.

Deneyip görmek lazım aslında..

/* kaan.basesistem.com */

harika bir konu. teşekkürler.

Bu tarz işlemlerde bende recursive algoritmasını kullanıyorum. Ancak tek bir sorgu yapıp tüm dataları çekip bir nesneye yada çok boyutlu bir diziye tamponluyorum, sonrasında hangi veri nereye bağlı bilindiği için rahatlıkla ekrana basabiliyoruz. Basitçe;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class kategori
{ var $id, $baslik, $ebeveyn; }
$sorgu = mysql_query("SELECT * FROM tablo ORDER BY ebeveyn");
$s = 0;
while($r = mysql_fetch_assoc($sorgu))
{
$k[$s] = new kategori();
$k[$s]->id = $r[id];
$k[$s]->baslik = $r[isim];
$k[$s]->ebeveyn = $r[ebeveyn];
$s++;
}
mysql_free_result($sorgu);
unset($r);

artık elimdeki $k nesne dizisini istediğim gibi kullanabilirim.

/* zekee | 18 Kasım 2008 12:13 */

Öncelikle bana göre çok güzel yazı, teşekkürler diyorum.

Malesef buradaki asıl sorun sadece MySQL e tek sorgu göndermek değildir.

Recursive uygulamada php nin belleğine almanın malesef avantajlı olduğunu söyleyemeyeceğim. PHP C ye göre daha yavaş bir dil olduğu konusunda sanırım herkes hemfikirdir.

Eğer recursive sonuçları alır php nin belleğe atarsanız karşınıza iki sorun çıkmaktadır. İlk olarak ciddi şekilde CPU yükü bindireceksinizdir makineye ve webiniz yavaş çalışmaya başlar. Memory kullanımı ise inanılmaz derecede artacaktır recursive php de her defasında vm deki stack in ciddi şekilde artırılmasına sebep olmaktadır. Bunun için Zend Memory Manager da bildiğim kadarıyla cok ciddi bir optimizasyon yok.

Eğer FastCGI kullanıyorsanız PHP için bu sorguyu atan her php nin ortalama 300 400 Request kadar çok ciddi memory yemesini kabullenmiş olmanız demektir. (Respawn olana kadar). Buda ciddi bir sorundur ve makinenin memory sinin bitmesine kadar uzanır.

FastCGI kullanın yada kullanmayın uzun recursive function call lar sisteminizi saldırı (Denial Of Service Attack) lara açık hale getirir. Ki yorum a yorum gibi kullanıcı girdisi ile olabilecek bir konuda ciddi problemdir bu.

Zaten sorgu attığınız düşünülürse Nested Set Model de ise bu durum MySQL e aktarıldığından hem cpu gücünden hemde memory bakımından avantaj sağlamış olursunuz ve MySQL in query cache'i de hız bakımından imdadınıza yetişecektir. Hemde gereksiz verileri mysql den download etmekle uğraşmayarak MySQL in web servera gönderimdeki işlem yapma süresini kısaltmış olursunuz.

Ben zaten cache kullanıyorum diyorsanız. cache sistemleri yazılırken en baştan cache olacak gibi yazılmalı ama çalışırken asla cache yokmuş gibi çalışabilmelidir. Basitinden crawl eden bir bot geldiğinde bile makinede cache olmadığından sistemsel sorunlara maruz bırakabilir.

Bu yüzden mümkün olduğu kadar eğer yapabiliyorsanız bu tarz işlemlerde Nested Set kullanmanız, projeniz büyüdüğünde başınız ağrımaması için daha iyidir.

Yazı için teşekkürler, çok faydalı olmuş. Okuduktan sonra bir eksik fark ettim, sonradan bir alt yorum eklemek istediğimizde, bazı update işlemleri yapmamız gerekiyor.
Mesela, "yorum 3" ün altına bir "yorum 3 alt" eklemek istersek, bundan etkilenecek kayıtların, lft ve rgh alanlarının update olması lazım.

yorum 3 şu şekilde eklenmişti :

insert into yorumlar_n set yorum='yorum 3', lft=8,rgt=9;

biz başka bir zamanda yorum 3'ün altına, "yorum 3 alt" eklemek için :

update yorumlar_n set rgt = rgt + 2 where rgt > 8;
update yorumlar_n set lft = lft + 2 where lft > 8;

insert into yorumlar_n(yorum, lft, rgt) values('yorum 3 alt', 9, 10);

Burada 8, yorum üçün lft değeri, eklenen alt yorum için de lft değerinin 1 fazlası, rgt değeri için de 2 fazlası kullanılmalı.

aynı anda birden fazla yorum gelebileceğini düşünerek, update ve insert işlemlerini tek defada yollamak, hatta transaction bloğu içinde kullanmakta fayda var.

tesekkurler,

@budabenden, yazi cok uzadigi icin 2 parcaya bolmek istedim, - muhtemelen 3 parca olucak gerci - o yuzden sadece tabloya ilk kez veri girilmesini anlattim, ama belki bir iki satirda olsa belirtmek gerekti, yaziyi tamamlaman cok iyi olmus, tesekkurler.

adjacency list kullanmaninda kendine gore artilari var, ornegin bir yorumun altindaki yorumlari sayfalamak zorunda kalirsak gibi, ama ikisi arasindaki karsilastirmalari daha sonraya birakmak zorunda kaldim, yoksa yazi cok uzuyordu. ornegin adjacency listtende tek sorguda da alabilirsiniz sonucta, ama pathi saklamak gerek.

bu arada @iltaren dediklerine aynen katiliyorum, sadece db query olarak dusunmemek gerek.

@zekee, sadece order by parent_id her zaman beklenilen sonucu vermez,

1
2
3
4
5
6
7
8
9
10
11
12
mysql> select * from yorumlar order by parent_id;
+----+----------------------+-----------+
| id | yorum | parent_id |
+----+----------------------+-----------+
| 1 | yorum 1 | 0 |
| 2 | yorum 2 | 0 |
| 3 | yorum 3 | 0 |
| 4 | yorum 4 | 0 |
| 7 | yorum 1 cevap | 1 |
| 5 | yorum 4 cevap | 4 |
| 6 | yorum 4 cevapa cevap | 5 |
+----+----------------------+-----------+

yorum 1 in cevabi yorum 4 altinda gelir, ama sanirim benim kacirdigim, bunu viewa pasladiktan sonra formatliyorsun degil mi ?

/* */

tekrar okuyacagim bi makale olucak bu:)

Teşekkürler, güzel makale.

ihtiyacım olan bazı projelerde "kategori, alt kategori" mantığını daha değişik biçimde ele almıştım, örnek vermek gerekirse:

1
2
3
4
5
6
7
8
9
10
| id | yorum | kod |
----------------------------------------
| 1 | yorum 1 | 001 |
| 2 | yorum 2 | 002 |
| 3 | yorum 3 | 003 |
| 4 | yorum 4 | 004 |
| 7 | yorum 1 cevap | 001001 |
| 5 | yorum 4 cevap | 004001 |
| 6 | yorum 4 cevapa cevap | 004001001 |
----------------------------------------

gibi ..
bu şekilde uygularsak 4.yorumun altındakilerin hepsini çağırmak için
1
... where KOD LIKE '004%'

sadece 4.yorumun cevapları için
1
... where KOD LIKE '004___'

şeklinde tek komutla istediğimiz satırları alabiliyoruz.
dezavantajı, alt mesaj için her zaman bir limitin olması ve kod alanını uzun tanımlama gerekliliği olabilir.

@aybars badur
elbette, verileri nesne dizisine tamponladıktan sonra alt kategorileri veren fonksiyon yardımıyla hangi öğe hengi öğeye bağlı bulabiliyorum.

/* zekee | 19 Kasım 2008 14:05 */

Emeğinize sağlık, bu konu çok su kaldırır. Kolay gelsin :)

Başlı başına bu konuları işleyen bir kitap: Joe Celko's Trees and Hierarchies in SQL for Smarties

Ve bu kitaptan da alıntı yaparak yukarda mevzu bahis meseleyi anlatan bir de yazı: Managing hierarchical data in mysql

Gösterimler ve anlatım hoş göründüğünden ilgilere yardımcı olabileceğini düşünüyorum.

temiz kod . temiz iş .

ben burda yazılanları tamamen içgüdüsel bir yöntemle yapmıştım, demek ki içgüdülerim kuvvetliymiş

çok faydalı bir yazı teşekkürler

gerçekten çok faydalı bir konu.çok teşekkürler.

Merhaba gerçekten güzel bir yazı teşekkür ederiz.
Ancak sormak istediğim bir iki konu var.
Burada sadece mysql de sorguyu gönderdiğimiz tablonun bir alan belirleyici yani kategori olmasını gözden kaçırmış olabilir misiniz?
Örneğin, bir kategoriye yorum yazmayacaksınızdır ama kategoriye ait bir makaleye yorum yazacaksınızdır. Bu durumda makalenin kategorisi bir field olarak zaten tablosundan yer alacaktır ve kategori tablosundan çağırmanız kolaydır.
Yorumlar da yine ayrıca bir tablo da tutulacağından seri bir işleme tabi tutup, yorum > makele > kategori ilerlemesi, bu durumda Adjacency List Model 'i daha avantajlı kılmaz mı?
Aslında işlem görevini daha çok tablo sayısına bölmek ama aralarında ki ilişkiyi kuran keyleri dorğu düzenlemek, sıkça sorgu alan bölümler için de view cache kullanmak belki en doğrusudur?
Mysql'in performansı istikrarlı değil. Çünkü CPU 'nun durumuna göre tepki veriyor. Bu durumda her daim aynı sorgunun performansı eşit olmayacaktır. Select viewleri ve Insert'leri ayrı sunucu konfigürasyonlarında tutmak için düşünceleriniz nedir?

bu tür fonksiyonlarla uğraşmamak için hazır bir paket var..

php_cat mysql nested set model tree class
http://developer.bloggum.com

http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

ben de kendi çıkarımlarım ile ilk yönetimi kullanmıştım bir sistemde
gelişme kaydetmişiz demeki :)

/* just code it!! */

Gökçe Yalçın'nın zetzetto'nun belirttiği makaleyi çevirisi var. İngilizce sorunu olanlar için yardımcı olacaktır.

/* Günce: http://www.murat-beser.com */

Buda benden! Klasik VBScript ASP için TC Kimlik numarası doğrulama

function isTrueTCId(tcId)
  dim tmp, t1, t2, i, b10, b11
  isTrueTCId = False
  tmp = CStr(tcId)
  if Len(tmp) <> 11 then exit function
  b10 = CInt(Mid(tmp, 10, 1)) ' 10. hane
  b11 = CInt(Mid(tmp, 11, 1)) ' 11. hane
  t1 = 0 ' tek haneler toplamı
  t2 = 0 ' çift haneler toplamı
  for i = 1 to 9 ' tek ve çift hane toplamlarını hesapla
    if i mod 2 = 0 then
      t2 = t2 + CInt(Mid(tmp, i, 1))
    else
      t1 = t1 + CInt(Mid(tmp, i, 1))
    end if
  next
  isTrueTCId = ((7 * t1 - t2) mod 10 = b10) and _
               ((t1 + t2 + b10) mod 10 = b11)
end function

üye olunpillinetwork sitelerine yorum ekleyebilmek ve daha fazlası için, üye olun ya da giriş yapın.

Bu yazıyı rapor et. Kural dışı içeriğe rastladığınızda editörlerimize rapor ederek müdahale edilmesini sağlayabilirsiniz. (Hangi durumlarda rapor edebilirim?)

Bu site

Nokta ve pilli ortak yapımı olan kodaman.org hep birlikte içerik üretip gelirini yazarları ile paylaştığımız kolektif bir kod yazarları blogudur. Siz de katılabilirsiniz.

pilliilan

son yorumlar

arama

pillinetwork