[статья] Работа с DBTree

Макс

Старожил PHPClub
В статье четко написаны рекомендации автора - использовать класс только для вставки и удаления узлов, а выборки делать вручную.
Вставки и удаление работают на ура. Проверено.
 

Ramzes

Новичок
Можно еще добавить одно замечание.
По рекомендации автора:
PHP:
// SAMPLE DB TABLE STRUCTURE:
//
// CREATE TABLE categories (
//   cat_id        INT UNSIGNED NOT NULL AUTO_INCREMENT,
//   cat_left    INT UNSIGNED NOT NULL,
//   cat_right    INT UNSIGNED NOT NULL,
//   cat_level    INT UNSIGNED NOT NULL,
//   PRIMARY KEY(cat_id),
//   KEY(cat_left, cat_right, cat_level)
// );
//
// This is believed to be the optimal Nested Sets use case. Use `one-to-one`
// relations on `cat_id` field between this `structure` table and 
// another `data` table in your database.
 

Макс

Старожил PHPClub
Ramzes
цитирую статью:
опыт показывает, что структуру с обходом дерева лучше хранить отдельно от
данных, т.к. в этом случае при обновлении таблицы очень долго обновляются
индексы, да и данные могут сделать невозможным формат записи фиксированной
длины, что тоже кардинально скажется на скорости.
Самой оптимальной структурой по-моему будет:

CREATE TABLE categories (
cat_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
cat_left INT UNSIGNED NOT NULL,
cat_right INT UNSIGNED NOT NULL,
cat_level INT UNSIGNED NOT NULL,
PRIMARY KEY(cat_id)
KEY (cat_left, cat_right, cat_level)
);

В итоге MySQL за многими запросами даже не будет обращаться к файлу с данными.
Ему будет хватать файла с индексами. А когда уже пройдёт всё фильтрование в
таблице с деревом, по примари-кею быстро произойдёт линкование с остальными
данными.
:)
 

Chaotik

Guest
Максим, я прочитал на сайте MySQL, что с версии 4.0 в стандартный дистрибудив входит InnoDB storage engine, который transaction safe[color] В связи с чем возникает вопрос, как надо переписать класс DBTree, чтобы его эффективнее задействовать? Ведь использовать транзакции для Nested Sets сам NULL велел, как говориться. Можно конечно все транзакции в приложении поставить типа
PHP:
 					//подкатегория текущей
					$dbh->query("begin");
					$treepath[$clevel+1][]=$id=$Tree->insert ($treepath[$clevel][$level_enum],array());
					if ($dbh->query("INSERT into $tableitems (id, code, name, timestamp) VALUES ('$id', '$str[1]', '$str[2]', '".time()."')"))
						$dbh->query("commit");
					else $dbh->query("rollback");
Но будет ли это работать?
http://dev.mysql.com/doc/mysql/en/ANSI_diff_Transactions.html
 

Макс

Старожил PHPClub
Но будет ли это работать?
а самому попробовать ?

ИМХО лучше просто переписать методы :
insert()
delete()
deleteAll()
moveAll()

примерно так :
PHP:
function delete($ID) { 
      if(!(list($leftId, $rightId, $level) = $this->getNodeInfo($ID))) die("phpDbTree error: ".$this->db->error()); 
       $this->db->query('BEGIN');
      // Deleting record 
      $this->sql = 'DELETE FROM '.$this->table.' WHERE '.$this->id.'=\''.$ID.'\''; 
      if(!$this->db->query($this->sql)) {
       $this->db->query('ROLLBACK');
       die("phpDbTree error: ".$this->db->error()); 
}
      // Clearing blank spaces in a tree 
      $this->sql = 'UPDATE '.$this->table.' SET ' 
         . $this->left.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.','.$this->left.'-1,'.$this->left.'),' 
         . $this->right.'=IF('.$this->right.' BETWEEN '.$leftId.' AND '.$rightId.','.$this->right.'-1,'.$this->right.'),' 
         . $this->level.'=IF('.$this->left.' BETWEEN '.$leftId.' AND '.$rightId.','.$this->level.'-1,'.$this->level.'),' 
         . $this->left.'=IF('.$this->left.'>'.$rightId.','.$this->left.'-2,'.$this->left.'),' 
         . $this->right.'=IF('.$this->right.'>'.$rightId.','.$this->right.'-2,'.$this->right.') ' 
         . 'WHERE '.$this->right.'>'.$leftId 
      ; 
      if(!$this->db->query($this->sql)) {
         $this->db->query('ROLLBACK');
         die("phpDbTree error: ".$this->db->error()); 
}
      $this->db->query('COMMIT');
      return true; 
   }
 

fisher

накатила суть
Максим, у меня маленькое замечание академического характера: не лучше ли добавить ссылку (имхо вообще первой) на базовую публикацию Joe Selko в RDBMS? ;) тем более, что есть русские переводы статьи, а там разжевано очень многое про принципы паковки множеств в реляционую базу.
 

Макс

Старожил PHPClub
fisher
если не сложно, подними эту тему после 27 числа
У меня сейчас диплом все время забирает
 
Сверху