考虑数据库表:文件夹
文件夹id parent_id名称1 0 a2 1 b3 2 c
"b"是"a"中的一个文件夹,因此它的parent_id是"a的id"
parent_id为0的文件夹只是表示它在根文件夹中。
我在php中写了一个递归函数,它可以帮助我获得我感兴趣的路径的ID
例如:
echo get_folder_id('a/b/c'); // 3 (3 SQL queries)
echo get_folder_id('a'); // 1 (1 SQL query)
echo get_folder_id('a/b'); // 2 (2 SQL queries)
echo get_folder_id('a/c'); // false (2 SQL queries)
问题:对于路径中的每个文件夹,我都必须对DB服务器进行SQL查询。
问题:如果路径是"a/b/c",有没有办法减少查询次数?
这是我目前的工作解决方案供参考。
function get_folder_id($path, $parent_id=0) {
$path = explode('/', $path);
$id = 0;
//if there's only 1 folder in the path, query the database for the ID
if (count($path) == 1) {
$rs = $this->db->select('id')
->from('folders')
->where('name', $path[0])
->where('parent_id', $parent_id)
->limit(1)
->get();
if ($rs->num_rows() == 0) return FALSE;
$result = $rs->row_array();
return $result['id'];
}
foreach($path AS $i=>$p) {
if ($i==0 && $p=='') continue; //if a path starts with / move on to the next item
$id = $this->get_folder_id($p, $id);
}
return $id;
}
注意:我使用的是CodeIgniter框架,但这与我的问题无关。只是为了让那些想知道我为什么使用$this->get_folder_id()和$this->db
对于您的问题,有一个非常简单的解决方案:
在数据库中创建一个递归存储函数,并从PHP调用它。这应该是DB功能,因为如果您在PHP中实现这一功能,则必须从PHP发送许多查询。
我刚刚提出的一个解决方案是在同一个表上使用一系列LEFT JOIN。
SELECT tb3.id FROM folders AS tb1
LEFT JOIN folders AS tb2 ON tb2.parent_id=tb1.id
LEFT JOIN folders AS tb3 ON tb3.parent_id=tb2.id
WHERE tb1.name='a' AND tb2.name='b' AND tb3.name='c'
LIMIT 1
根据路径中文件夹的数量,我可以动态生成上述SQL。我不确定这是否是一个完美的解决方案,但现在它正在按预期工作。
任何关于这是否是一个好主意的反馈都将不胜感激!
$path = 'a/b/c';
$path = explode('/', $path);
$sql = "SELECT tb".count($path).".id FROM folders AS tb1";
for($x=1, $max = count($path); $x<=$max; $x++) {
$sql .= " LEFT JOIN folders AS tb".($i+2);
$sql .= " ON tb".($i+2).".parent_id = tb"($i+1).".id";
}
$sql .= " WHERE 1";
foreach($path AS $x => $p) {
$sql .= " AND tb".($x=1).".name='".$p."'";
}
$sql .= " LIMIT 1";