MySQL的一些分层数据

时间:2014-11-26 15:17:58

标签: php mysql algorithm recursion

我正在为一个工作项目使用一些有些分层的数据,并试图找到一种更有效的方法来处理它,因为我的第一次尝试可能在很多方面都是可怕的。我已经查看了这个网站上的一些分层数据问题,所以我知道在我的结构中,几乎不可能在单个查询中获取信息。

我正在查询的表是在AS / 400上,每个条目都存储一个步骤的单个部分,所以如果我有PartOne和三个组件进入它,每个条目都有一个条目:

PartOne ComponentOne, PartOne ComponentTwo, PartThree ComponentThree.

重要的是要注意,如果ComponentOne有组件,后续行可能包含:

ComponentOne SubComponentOne, ComponentOne SubComponentTwo.  

考虑到这一点,我正在尝试将所有组件放在树状结构中,以获得给定的成品部件,基本上可以获得最终产品的所有内容。

我无法为此创建一个展平的表,因为我正在尝试动态生成该展平的表。但我可以访问已完成零件的清单。所以我现在的算法就像这样

  1. 获取组件编号,查询组件的时候是创建的零件。
  2. 获取这些组件并查询每个组件作为创建的组件并获取其组件。
  3. 重复直到查询未返回任何条目。
  4. 在这种情况下,7个深度查询。我想知道外面的任何人都在研究一个更好的算法是否对此有意义,而且它已经有一段时间了,因为我已经完成了递归,但这对于递归来说似乎是合理的,至少在创建查询时。考虑创建一个递归函数是否合理,该函数从每个级别传回查询结果,并在那里将信息存储在数组/表/数据库条目中?

1 个答案:

答案 0 :(得分:0)

你想在PHP中使用树结构吗? 然后下一个代码示例可能会很有趣。

这将为类别表中的记录构建一个树,以id为-1000作为根元素,只使用与您希望获得信息的级别数一样多的查询。

表格结构:

TABLE categories (
   id         INT NOT NULL PRIMARY KEY,
   parent_id  INT NULL,
   name       NVARCHAR(40) NOT NULL
)

PHP代码:

class Bom {
   public $Id;
   public $Name;
   public $Components = array();

   function __construct( $id, $name ) {
      $this->Id = $id;
      $this->Name = $name;
   }
}

$parentIds = array( -1000 );  // List of id's to lookup
$rootBom = new Bom( -1000, 'Root' );
$bomsById[ -1000 ][] = $rootBom;  // For each id there can be multiple instances if we want separate instances of Bom for each time it occurs in the tree
$maxLevel = 0;

while ( count( $parentIds ) > 0 
   && $maxLevel++ < 10
   && $result = $mysqli->query( "SELECT * FROM categories WHERE parent_id IN ( " . implode( ", ", $parentIds ) . " ) ORDER BY name" ) )
{
   $parentIds = array();  // Clear the lookup list
   $newBomsById = array();
   while ( $row = $result->fetch_assoc() )
   {
      $boms = $bomsById[ $row[ 'parent_id' ] ];
      if ( $boms )
      {
         foreach ( $boms as $bomToUpdate )
         {
            $compontentBom = new Bom( $row[ 'id' ], $row[ 'name' ] );

            $bomToUpdate->Components[] = $compontentBom;
            $newBomsById[ $compontentBom->Id ][] = $compontentBom;
         }

         $parentIds[] = $row[ 'id' ];  // Build new list of id's to lookup
      }
   }

   $bomsById = $newBomsById;
}

echo '<!--
' . print_r( $rootBom, true ) . '
-->';