MySQL中的一对多关系,选择“child”表信息

发布于 2024-12-10 13:42:00 字数 2395 浏览 0 评论 0原文

我编写了一些 PHP 脚本,以便更轻松地从一系列 MySQL 表中提取信息,但存在严重的性能问题。因此,我正在尝试减少查询数量。

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

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

SELECT * FROM `Parent Table` WHERE `parent_id` = 5 

...然后...

SELECT * FROM `Child Table` WHERE `parent_id` = '5'

我想将结果放入关联数组中,然后 json_encode 以 JSON 形式返回。

澄清一下,我已经完成了这项工作,但它对所选的每一行执行了一个附加查询,因此它不是对 100 行执行 101 次查询,而是执行一个查询。

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

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

示例数据: 父表(1、'albert'、'smith'、'12345') 子表 (1, 1, 2010-10-5, 'test', 'etc etc'), (2, 1, 2010-10-6, 'again', 'eg eg')

进行连接会产生两行

1, albert, smith, 12345, 1, 1, 2010-10-5, 测试等

1, albert, smith, 12345, 2, 1, 2010-10-6, 再次,例如

所以,我有两行父表信息重复。要使用联接,我需要某种方法来清理它,并将其放入分层形式。

结果应该是 {parent_id:1,first:albert,last:smith,电话:12345,child_table:[{child_id:1,date:2010-10-5,request:test,details:'etc etc'},{child_id :2,日期:2010-10-6,请求:再次,详细信息:'eg eg'}]}

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

mysqlResult 是来自 mysql_query 调用的关联数组, parent_key 是父表的主键名称, child_key 是子表的主键名称, child_table 是子表的名称, child_fields 是子表中所有字段名称的关联数组

   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;
}

I have written some PHP scripts to make pulling information out of a series of MySQL tables easier, however there are severe performance problems. As a result I'm trying to reduce the number of queries.

The tables have a one to many relationship:
Parent Table (parent_id, first, last, phone)
Child Table (child_id, parent_id, date, request, details)

So, for any entry in the parent table there may be multiple associated rows in the child table. How, can I select a row in the parent table and use the parent_id (primary key) to pull all the associated rows from the child table?

SELECT * FROM `Parent Table` WHERE `parent_id` = 5 

...and then...

SELECT * FROM `Child Table` WHERE `parent_id` = '5'

I want to then take the result and put it into an associative array, and json_encode to return as JSON.

To clarify, I already have this working, but it's doing an additional query for each row selected, so instead of one query it is doing 101 for 100 rows.

Any help would be greatly appreciated, thanks in advance.

UPDATE: It has been suggested to use Joins, however a new problem arises

Sample data:
Parent table (1, 'albert', 'smith', '12345')
Child table (1, 1, 2010-10-5, 'test', 'etc etc'), (2, 1, 2010-10-6, 'again', 'eg eg')

Doing a join results in two rows

1, albert, smith, 12345, 1, 1, 2010-10-5, test, etc etc

1, albert, smith, 12345, 2, 1, 2010-10-6, again, eg eg

So, I have two rows with the parent table information duplicated. To use joins I need some way of cleaning this up, and putting it into a hierarchical form.

The result should be
{parent_id:1, first:albert, last:smith, phone:12345, child_table:[{child_id:1, date:2010-10-5, request:test, details:'etc etc'},{child_id:2, date:2010-10-6, request:again, details:'eg eg'}]}

SOLUTION: So, the answer for me is to use joins, and write a function to convert the returned rows into an associative array

mysqlResult is an associative array from a mysql_query call,
parent_key is the name of the primary key of the parent table,
child_key is the name of the primary key of the child table,
child_table is the name of the child table,
child_fields is an associative array of the names of all the fields in the child table

   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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

少年亿悲伤 2024-12-17 13:42:00

也许我读错了问题,但是你看过联接吗?

SELECT * FROM `Parent Table` 
join `Child Table` ON `Child Table`.`Parent ID`=`Parent Table`.`ID`
WHERE `parent_id` = 5 

合并数据关联数组的示例

 $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);

maybe i am reading the question wrong, but have you looked at joins?

SELECT * FROM `Parent Table` 
join `Child Table` ON `Child Table`.`Parent ID`=`Parent Table`.`ID`
WHERE `parent_id` = 5 

example of assoc array of consilidated data

 $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);
白云悠悠 2024-12-17 13:42:00

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

不幸的是,这种情况对数据库来说很沉重,我个人不知道有什么方法可以做到这一点......

I would suggest caching your JSON in a PHP file and update it only when something is changed

Such cases unfortunately are heavy to the DB and I personally don't know any way to do it...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文