Mysql 如何从数据库中提取孙子
我想从MySQL中取出菜单项Mysql 如何从数据库中提取孙子,mysql,menu,navigation,adjacency-list,Mysql,Menu,Navigation,Adjacency List,我想从MySQL中取出菜单项 Main menu id=1, parentid=0 -Contact us id=2, parentid=1 -Music id=3, parentid=1 --Rock id=8, parentid=3 --Classic id=9, parentid=3 -Car id=4, parentid=1 --Toyota
Main menu id=1, parentid=0
-Contact us id=2, parentid=1
-Music id=3, parentid=1
--Rock id=8, parentid=3
--Classic id=9, parentid=3
-Car id=4, parentid=1
--Toyota id=5, parentid=4,
--Ford id=6, parentid=4,
--Honda id=7, parentid=4
Other menu id=10, parentid=0
-Othermain id=11, parentid=10
--submenu id=12, parentid=11
etc.
我可以从id=1到4拉出数据,并通过“…where parentid=1”等方式显示。
然而,这只会引出顶层
但是我想把所有的数据都拉出来,包括每个菜单(主菜单)的子菜单
谁能告诉我如何在MySQL中为此编写查询
提前感谢。最快的方法是从表中获取所有元素,并在代码端构建菜单树。您需要实现递归以重复调用数据库以检索所有子级。您必须用自己的数据库抽象层实现替换我的数据库抽象层实现,但概念是一样的 memcache解决方案 非memcache解决方案
以上内容未经测试,因此,如果有人发现错误,请告诉我或随时更新。在这里,您将生成
n
SELECT查询的数量。这不是最佳的解决方案。@hsz-我个人喜欢实现缓存解决方案,以避免执行这种数据库密集型功能。由于导航往往是相当静态的,所以很容易实现一个永久缓存,只有在对导航进行管理更新时才会删除/使其无效。@cballou-好的,我同意你的意见-但我们必须实现这个缓存。但是访问n个缓存文件而不是一个缓存文件怎么样?;)@hsz-您将缓存返回的数组,而不是每个级别。@shin-我为您添加了它,但我建议您在memcache上进行搜索,因为它将大大加快导航生成的速度。有人能告诉我为什么这是错误的吗?它只使用一个查询,这是导航菜单的最佳解决方案。+1我完全同意,对于构建菜单树来说,只需一个查询即可
function generateTree($parentid = 0, &$tree) {
$sql = sprintf('SELECT * FROM navigation WHERE parentid = %d', $parentid);
$res = $this->db->results($sql);
if ($res) {
foreach ($res as $r) {
// push found result onto existing tree
$tree[$r->id] = $r;
// create placeholder for children
$tree[$r->id]['children'] = array();
// find any children of currently found child
$tree = generateTree($r->id, $tree[$r->id]['children']);
}
}
}
function getTree($parentid) {
// memcache implementation
$memcache = new Memcache();
$memcache->connect('localhost', 11211) or die ("Could not connect");
$tree = $memcache->get('navigation' . $parentid);
if ($tree == null) {
// need to query for tree
$tree = array();
generateTree($parentid, $tree);
// store in memcache for an hour
$memcache->set('navigation' . $parentid, $result, 0, 3600);
}
return $tree;
}
// get tree with parentid = 0
getTree(0);
function generateTree($parentid = 0, &$tree) {
$sql = sprintf('SELECT * FROM navigation WHERE parentid = %d', $parentid);
$res = $this->db->results($sql);
if ($res) {
foreach ($res as $r) {
// push found result onto existing tree
$tree[$r->id] = $r;
// create placeholder for children
$tree[$r->id]['children'] = array();
// find any children of currently found child
$tree = generateTree($r->id, $tree[$r->id]['children']);
}
}
}
// get tree with parentid = 0
$tree = array();
$parentid = 0;
generateTree($parentid, $tree);
// output the results of your tree
var_dump($tree); die;