Php MySQL中的一对多关系,选择;“儿童”;表信息

Php MySQL中的一对多关系,选择;“儿童”;表信息,php,mysql,json,hierarchical-data,Php,Mysql,Json,Hierarchical Data,我已经编写了一些PHP脚本,使从一系列MySQL表中提取信息变得更容易,但是存在严重的性能问题。因此,我试图减少查询的数量 这些表具有一对多关系: 父表(父id、第一个、最后一个、电话) 子表(子id、父id、日期、请求、详细信息) 因此,对于父表中的任何条目,子表中可能有多个关联行。如何在父表中选择一行并使用父id(主键)从子表中提取所有关联行 SELECT * FROM `Parent Table` WHERE `parent_id` = 5 ……然后 SELECT * FROM `Ch

我已经编写了一些PHP脚本,使从一系列MySQL表中提取信息变得更容易,但是存在严重的性能问题。因此,我试图减少查询的数量

这些表具有一对多关系: 父表(父id、第一个、最后一个、电话) 子表(子id、父id、日期、请求、详细信息)

因此,对于父表中的任何条目,子表中可能有多个关联行。如何在父表中选择一行并使用父id(主键)从子表中提取所有关联行

SELECT * FROM `Parent Table` WHERE `parent_id` = 5 
……然后

SELECT * FROM `Child Table` WHERE `parent_id` = '5'
然后我想获取结果并将其放入一个关联数组中,然后json_编码以json的形式返回

为了澄清这一点,我已经完成了这项工作,但它正在为所选的每一行执行一个额外的查询,因此它不是一个查询,而是对100行执行101个查询

任何帮助都将不胜感激,提前谢谢

更新:有人建议使用联接,但是出现了一个新问题

样本数据: 父表(1,‘albert’、‘smith’、‘12345’) 子表(1,1,2010-10-5,“测试”,“等”),(2,1,2010-10-6,“再次”,“例如”)

执行联接将产生两行

艾伯特,史密斯,12345,1,1,2010-10-5,测试等

艾伯特,史密斯,12345,2,1,2010-10-6,再一次

所以,我有两行,父表信息是重复的。要使用连接,我需要某种方法来清理它,并将其放入层次结构形式中

结果应该是
{parent\u id:1,first:albert,last:smith,电话:12345,child\u table:[{child\u id:1,日期:2010-10-5,请求:测试,细节:'etc'},{child\u id:2,日期:2010-10-6,请求:再次,细节:'eg'}

解决方案:因此,我的答案是使用联接,并编写一个函数将返回的行转换为关联数组

mysqlResult是来自mysql\u查询调用的关联数组, parent_key是父表主键的名称, child_key是子表主键的名称, 子表是子表的名称, 子字段是子表中所有字段名称的关联数组

   function cleanJoin($mysqlResult, $parent_key, $child_key, $child_table, $child_fields)
    {
    $last_parent = 0;
    $last_child = 0;
    $ch_ctr = 0;

    for ($i = 0; $i < count($mysqlResult); $i++)
    {
        if ($mysqlResult[$i][$child_key] != $last_child)
        {
            echo "new child!";
            $pr_ctr = count($answer[$i]);
            foreach ($child_fields as $field => $type)
            {
               $answer[$pr_ctr][$child_table][$ch_ctr][$field] = $mysqlResult[$i][$field];
               unset($mysqlResult[$field]);
            }
            $ch_ctr++;
        }
        if ($mysqlResult[$i][$parent_key] != $last_parent)
        {
            foreach($mysqlResult[$i] as $field => $value)
            {
                $answer[$i][$field] = $value;
            }
        }
        $last_parent = $mysqlResult[$i][$parent_key];
        $last_child = $mysqlResult[$i][$child_key];
    }

    return $answer;
}
函数cleanJoin($mysqlResult、$parent\u key、$child\u key、$child\u table、$child\u fields)
{
$last_parent=0;
$last_child=0;
$CHU ctr=0;
对于($i=0;$i$type的子字段)
{
$answer[$pr_ctr][$child_table][$ch_ctr][$field]=$mysqlResult[$i][$field];
未设置($mysqlResult[$field]);
}
$CHU ctr++;
}
if($mysqlResult[$i][$parent\u key]!=$last\u parent)
{
foreach($mysqlResult[$i]作为$field=>$value)
{
$answer[$i][$field]=$value;
}
}
$last_parent=$mysqlResult[$i][$parent_key];
$last_child=$mysqlResult[$i][$child_key];
}
返回$answer;
}

我建议将JSON缓存在PHP文件中,并仅在某些内容发生更改时更新


不幸的是,这种情况对DB来说是很严重的,我个人不知道怎么做……

也许我看错了问题,但是你看过连接了吗

SELECT * FROM `Parent Table` 
join `Child Table` ON `Child Table`.`Parent ID`=`Parent Table`.`ID`
WHERE `parent_id` = 5 
一致数据的assoc数组示例

 $res = mysql_query($sql);

 $output = array();

 while ($row = mysql_fetch_assoc($res)) {

    $parent_name = $row['parent_name'];  
    $child_name = $row['child_name'];

    $output[$parent_name][] = $child_name; 
}

var_dump($output);

如果您不能切换到嵌套集模型,那么由于MySQL缺乏对递归查询的支持,您或多或少都是运气不佳。我只是不确定如何进行转换。也许一个更好的例子是发表一篇文章,然后对该文章发表一系列评论。注释存储在一个单独的表中,但具有链接到该表的post_id。那我怎么能把帖子和所有的评论都拉出来呢?或者,我怎么能在嵌套的集合模型中使用它呢?您的表没有显示层次结构,只是post和commist之间的一对多关系。你真的需要评论吗?评论到评论?这只是一个例子,对帖子的评论仍然是一个层次结构。即使这样,听起来似乎也没有办法做到这一点?是的,但是当你需要很多(或无限)级别时,你应该使用层次结构。这是一个很好的解决方案,我的问题是它返回的每一个子行都有一行。所以,当我真的想要一行时,您最终得到了5行,其中嵌套了5个子行(因此我可以返回JSON)。我想我必须找到一种方法,将许多行合并到PHPamended答案中的关联数组中,以展示如何从query构建assoc数组结构连接的问题是它只是将所有变量混合在一起,并添加与子表中的行数相同的行数,使用父表中的重复信息。我编辑了最初的帖子来解释连接的问题,以及为什么我仍然需要某种方法来清理数据