我正在尝试使用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
之后出现语法错误答案 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);