我在MySQL中有无限级别的菜单结构,其中父元素和子元素与列p_id
相关联:
+----+------+------+----------------+
| id | p_id | sort | name_en |
+----+------+------+----------------+
| 1 | 0 | 1 | menu-1 |
| 2 | 0 | 2 | menu-2 |
| 3 | 0 | 6 | menu-3 |
| 4 | 2 | 3 | sub-menu-2-1 |
| 5 | 2 | 4 | sub-menu-2-2 |
| 6 | 5 | 5 | sub-menu-2-2-1 |
+----+------+------+----------------|
使用子菜单元素删除根菜单元素的最佳做法是什么?
我可以通过PHP递归实现它,但它会导致一些查询。
所以我需要找出是否有任何可能的方法来使用一个MySQL查询。
答案 0 :(得分:2)
由于你有name_en
,你不能用那个删除行吗?例如,
DELETE FROM `table` WHERE `id` = 2 OR `name_en` LIKE 'sub-menu-2-%'
新方法:
您可以使用带有约束的Foreign Key。我创建了你的桌子,并将其称为treelist,
CREATE TABLE `treelist` (
`item_id` int(10) unsigned NOT NULL auto_increment,
`parent_id` int(10) unsigned default NULL,
`name_en` varchar(40) NOT NULL,
PRIMARY KEY (`item_id`),
KEY `FK_parent_id` (`parent_id`),
CONSTRAINT `FK_parent_id` FOREIGN KEY (`parent_id`) REFERENCES `treelist` (`item_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
然后我添加了一些测试数据,你在问题中的数据,
INSERT INTO `treelist` (`item_id`, `parent_id`, `name_en`) VALUES (NULL, NULL, 'Menu 1'), (NULL, NULL, 'Menu 2'), (NULL, NULL, 'Menu 3'), (NULL, 2, 'Sub Menu 2-1'), (NULL, 2, 'Sub Menu 2-2'), (NULL, 5, 'Sub Menu 2-2-1');
现在,删除行时,例如
DELETE FROM `treelist` WHERE `item_id` = 2
它也将删除所有儿童,幼儿等。之后表格看起来像,
+----+------+----------------+
| id | p_id | name_en |
+----+------+----------------+
| 1 | NULL | Menu 1 |
| 3 | NULL | Menu 3 |
+----+------+----------------+
答案 1 :(得分:1)
只删除一行及其直接子女(不是孙子):
DELETE FROM tablename where id = 1 or p_id = 1;
更新1:
如果您可以自由地向表中添加列,则可以添加root_id并根据该值轻松执行删除操作。这不会破坏系统中的任何当前查询,只需要一次性运行一个简单的脚本来添加初始数据。
DELETE FROM tablename where id = 1 or root_id = 1;
更新2:
一个非常棒的选项是允许同一个表的外键。因此,您可以向引用id的p_id添加外键,使用on delete cascade
,当您删除根时,所有后代也将被删除。我创建了一个测试表,这对我来说很漂亮。添加on update cascade
也可能是有益的。请记住,p_id和id都需要无符号才能使其正常工作。
ALTER TABLE tablename ADD CONSTRAINT fk_tablename_id FOREIGN KEY (p_id) references tablename(id) ON DELETE CASCADE;
答案 2 :(得分:1)
第一个参数中的类别ID或父ID:
function delete_parent_and_child_subchild($category_id,$all_cate=array())
{
if(!is_array($category_id))
{
$this->db->where('parent_id', $category_id);
$all_cate[]=$category_id;
}
else
{
$this->db->where_in('parent_id', $category_id);
}
$get_categories= $this->db->get('newcategory');
if($get_categories->num_rows()>0)
{
$categories_vales=$get_categories->result();
$new_subcat = array();
foreach($categories_vales as $cate_val)
{
$category_id=$cate_val->category_id;
array_push($new_subcat,$category_id);
}
$all_cate = array_merge($all_cate,$new_subcat);
if(count($new_subcat)>0)
{
$this->delete_parent_and_child_subchild($new_subcat,$all_cate);
}
}
$this->db->where_in('category_id', $all_cate)->delete('newcategory');
return true;
}