使用PHP / MySQL

时间:2016-09-27 13:36:40

标签: php mysql codeigniter

我正在尝试使用PHP / MySQL中的闭包表,特别是Codeigniter,对于我正在构建的具有区域的应用程序,每个区域可以有多个位置,部门等。

我一直在使用http://www.slideshare.net/billkarwin/models-for-hierarchical-data来了解它是如何运作的。

我一直在使用https://gist.github.com/dazld/2174233来帮助我掌握访问数据,我可以做得很好,我已经调整了方法来根据需要提取数据,这一切都很好

但是现在我正在尝试插入数据,而我无法理解它。所以我已经从上面的脚本中调整了add方法,但是我不明白它,我无法让它工作

继承区域表

+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| area_id    | int(11)     | NO   | PRI | NULL    | auto_increment |
| area_title | varchar(40) | NO   |     | NULL    |                |
| area_name  | varchar(40) | NO   |     | NULL    |                |
| org_id     | int(11)     | NO   |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

继承了area_hierarchy表

+------------+---------+------+-----+---------+----------------+
| Field      | Type    | Null | Key | Default | Extra          |
+------------+---------+------+-----+---------+----------------+
| id         | int(11) | NO   | PRI | NULL    | auto_increment |
| ancestor   | int(11) | NO   |     | NULL    |                |
| descendant | int(11) | NO   |     | NULL    |                |
| lvl        | int(11) | NO   |     | NULL    |                |
+------------+---------+------+-----+---------+----------------+

这是我试图用来添加条目的方法:

public function add($node_id, $target_id) {

    $sql = 'SELECT ancestor, '.$node_id.', lvl+1
            FROM area_hierarchy
            WHERE descendant = '.$target_id.'
            UNION 
            SELECT '.$node_id.','.$node_id.',0';

    $query = 'INSERT INTO area_hierarchy (ancestor, descendant,lvl) ('.$sql.')';

    $result = $this->db->query($query);

    return $result;

}

具体来说,$ node_id和$ target_id是什么。

什么是lvl + 1?

因此,如果我添加一个新的顶级区域,我会将哪些数据传递给此方法?

查询也失败,并在UNION

之后出现语法错误

1 个答案:

答案 0 :(得分:1)

$node_id将是area_id表中area列的值。据推测,这是你刚刚添加到区域表中的一行。

$target_id将是area_id表中另一行的area列的值,即您标识为“父”的行,即直接祖先。

lvl+1是层次结构中的生成或级别......后代与其父级的“距离”是多远。

如果您要添加新的“顶级”区域,则可以$node_id使用$target_id

了解这一点的最佳方法之一是查看area_hierarchy表的“当前状态”,以及添加节点时表的“结束状态”应该是什么。

如果树中只有一个顶级节点,area_id = 11,则area_hierarchy表将如下所示:

 ancestor descendant lvl 
 -------- ---------- ---
 11       11         0

如果我们将另一行添加到area表,area_id = 22,作为area_id = 11的子(直接后代),我们需要将这两行添加到area_hierarchy:

 ancestor descendant lvl 
 -------- ---------- ---
 11       22         1
 22       22         0

如果我们向area table,area_id = 333添加另一行,作为area_id = 22的子节点,我们需要将这些行添加到area_hierarchy表中:

 ancestor descendant lvl 
 -------- ---------- ---
 11       333        2
 22       333        1
 333      333        0

请注意,我们需要添加的前两行看起来很像表中已存在的行,其中descendant = 22。区别在于新行的后代是333而不是22,并且lvl的值比我们在表中已有的行上的值多一个。

我们需要添加的第三行是对自身的引用。就像我们将area_id = 11作为自己的“父”一样。

我们从UNION之后的部分得到的第三行。我们通过复制area_hierarchy中已有的行来获取前两行,将后代列的值替换为我们要添加的节点的id(333),并将lvl增加1。

一旦了解了需要添加的行,以及我们如何通过复制/修改表中的其他行来派生它们,那么SQL就开始有意义了。

您将完成为area_id = 333添加这三行,调用add函数:

 add(333,22);

如果要将tier_id = 4444添加为层次结构中的新“顶级”:

 add(4444,4444);