简体   繁体   English

使用PHP / MySQL插入闭合表

[英]Inserting into a closure table with PHP/MySQL

I'm trying to get my head around using a closure table in PHP/MySQL specifically Codeigniter, for an application I am building that has areas, and each area can have a number of locations, departments etc. 我正在尝试使用PHP / MySQL中的闭包表(特别是Codeigniter)来解决问题,对于我正在构建的具有区域的应用程序,每个区域可以具有多个位置,部门等。

I have been using http://www.slideshare.net/billkarwin/models-for-hierarchical-data to learn how it works. 我一直在使用http://www.slideshare.net/billkarwin/models-for-hierarchical-data来了解其工作原理。

And I have also been using https://gist.github.com/dazld/2174233 to help me get to grips with accessing the data, which I can do fine, I've adapted the methods to pull out data as I need it, which is all good. 而且我还一直在使用https://gist.github.com/dazld/2174233帮助我处理访问数据的问题,我可以做得很好,我已经调整了方法以根据需要提取数据,这一切都很好。

But now I'm trying to insert data, and I cannot get my head around it. 但是现在我正在尝试插入数据,但是我无法理解。 So I've adapted the add method from the above script, but I don't understand it, and I cannot get it to work 所以我从上面的脚本改编了add方法,但是我不明白,也无法使用

Heres the area table 这是面积表

+------------+-------------+------+-----+---------+----------------+
| 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    |                |
+------------+-------------+------+-----+---------+----------------+

Heres the area_hierarchy table 这是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    |                |
+------------+---------+------+-----+---------+----------------+

Heres the method I'm trying to use to add entries: 这是我试图用来添加条目的方法:

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;

}

So specifically, what is $node_id, and $target_id. 因此,具体地说,什么是$ node_id和$ target_id。

What is the lvl+1? lvl + 1是什么?

So if I add a new top level area, what data do I pass to this method? 因此,如果我添加一个新的顶级区域,该方法将传递哪些数据?

The query also fails and gives a syntax error after UNION 查询也会失败,并在UNION之后给出语法错误

$node_id would be the value of the area_id column from the area table. $node_id将是area表中area_id列的值。 Presumably, that's a row you just added to the area table. 大概这就是您刚刚添加到面积表中的行。

$target_id would be the value of the area_id column from another row in the area table, the row you are identifying as the "parent", the direct ancestor. $target_id将是area表中另一行(您标识为“父”的行,直接祖先)的area_id列的值。

The lvl+1 is the generation, or level in the hierarchy... how "far away" a descendant is from it's parent. lvl+1是世代或层次结构中的级别...后代与其父代之间的距离有多远。

If you are adding a new "top level" area, you would use $node_id for $target_id . 如果要添加新的“顶级”区域,则可以将$node_id用作$target_id

One of the best ways to understand this is to look at the "current state" of the area_hierarchy table, and what the "end state" of the table should be when a node is added. 理解此问题的最佳方法之一是查看area_hierarchy表的“当前状态”,以及添加节点时表的“最终状态”。

With just a top level node in the tree, area_id=11, the area_hierarchy table would look like this: 在树中只有一个顶级节点area_id = 11时,area_hierarchy表将如下所示:

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

If we add another row to the area table, area_id=22, as a child (direct descendant) of area_id=11, we need to add these two rows to area_hierarchy: 如果我们将另一行作为area_id = 11的子代(直接后代)添加到面积表area_id = 22,则需要将这两行添加到area_hierarchy中:

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

If we add another row to area table, area_id=333, as a child of area_id=22, we need to add these rows to the area_hierarchy table: 如果我们将另一行作为area_id = 22的子项添加到area表中,area_id = 333,则需要将这些行添加到area_hierarchy表中:

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

Notice that the first two rows we need to add look a lot like the rows that already exist in the table, where descendant=22. 请注意,我们需要添加的前两行看起来很像表中已经存在的行,其后代= 22。 The difference is that descendant on the new rows is 333 instead of 22, and value of lvl is one more than it was on the rows we already had in the table. 区别在于,新行的后代为333而不是22,并且lvl的值比表中我们已有的行多1。

And that third row we need to add is the reference to itself. 我们需要添加的第三行是对自身的引用。 Just like we had area_id=11 as a "parent" of itself. 就像我们将area_id = 11作为其自身的“父代”一样。

That third row we get from the part after the UNION. 第三行来自UNION之后的部分。 The first two rows we get by copying the rows already in area_hierarchy , replacing the value of the descendant column with the id of the node we're adding (333), and increasing lvl by 1. 前两行是通过复制area_hierarchy已经存在的行,将后代列的值替换为我们要添加的节点的ID(333),并将lvl增加1来得到的。

Once you understand what rows need to be added, and how we can derive them by copying/modifying other rows in the table, then the SQL starts to make sense. 一旦了解了需要添加哪些行以及如何通过复制/修改表中的其他行来派生它们,那么SQL就开始有意义了。


You would accomplish adding those three rows for area_id=333, calling the add function: 您将完成对area_id = 333的那三行的添加,调用add函数:

 add(333,22);

If you want to add area_id=4444 as a new "top level" in the hierarchy: 如果要在层次结构中添加area_id = 4444作为新的“顶层”:

 add(4444,4444);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM