【问题标题】:Optimizing multiple queries in MySQL and PHP优化 MySQL 和 PHP 中的多个查询
【发布时间】:2013-02-17 06:47:07
【问题描述】:

问题

  1. 我应该如何进行查询以获得此结果?

  2. 我应该为数据库表使用不同的结构吗?

 

详情

我想从 3 个表中获取结果:

+------------------------------+-------------------+
| courses                      | id                | <-------+
|                              | name              |         |
|                              |                   |         |
+------------------------------+-------------------+         |
| sections                     | id                | <-------|----------+
|                              | course_id         | <- FK(courses.id)  |
|                              | name              |                    |
+------------------------------+-------------------|                    |
| resources                    | id                |                    |
|                              | section_id        | <- FK(sections.id)-+
|                              | name              |
+------------------------------+-------------------+

我想将结果存储在这样的 PHP 数组中:

Array
(
    [courses] => Array
        (
            [id] => 1
            [name] => course 1
            [sections] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [course_id] => 1
                            [name] => course 1 section 1
                            [resources] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 1
                                            [section_id] => 1
                                            [name] => resource 1
                                        )

                                )

                        )

                )

        )

)

编辑

我做了什么:

$cources = DB::query(Database::SELECT,
'select * from courses')->execute($db,false)[0];  // Get all courses as array

foreach($courses as &$course) {
    $sections = DB::query(Database::SELECT,
    'select * from sections where course_id = '.$courses['id']);

    $course['sections'] = $sections;

    foreach($course['sections'] as &&section) {
        $resources = DB::query(...); // Get array of resources
        $section['resources'] = $resources;
    }
}

【问题讨论】:

  • 优化什么查询?你没有附上。您无法从 MySQL 获得多维结果。
  • 我用 PHP 代码更新了问题

标签: php mysql database scalability


【解决方案1】:

数据库结构已规范化 - 这是正确并且应该被更改。

但是,对于 N+ 连接,SQL 会返回非规范化或“扁平化”的数据:在单个结果集中只能返回一组同质记录。 (某些数据库,如 SQL Server,允许通过支持 XML 生成来返回结构。)

要在 PHP 中获得所需的数组结构,需要:

  1. 单独的查询/结果集(如帖子所示):ick!

    大约会有一个查询/对象。虽然理论上的界限可能相似,但实际实现的效率会低得多,而且开销将远远超过单个查询。请记住,每个查询都会产生(至少)往返惩罚 - 因此,这不可扩展,尽管它可能适用于较小的数据集或用于“时间不敏感”的操作。

  2. 重新规范化生成的结构:

    这对于支持“分组依据”操作非常简单,如 C#/LINQ 中所示。我不确定如何在 PHP1 中 [轻松地] 解决这个问题。这也不是完美的,但假设散列用于分组,这应该能够很好地扩展 - 它肯定会比 #1 更好。

如果可能,考虑以这样一种方式编写查询,以使“平面”结果可以在当前问题/范围内使用,而不是上述方法。也就是说,分析数组将如何使用 - 然后围绕该问题编写查询。这通常是一种更好的方法,可以非常很好地扩展。


1与重新归一化数据相关,YMMV:

【讨论】:

  • 所以,如果我理解的话,我会得到如下结果:每个查询行的(course_info), (section_info), (resource_info) 并使用 PHP “过滤”数据。就这样?
  • @GiovanneAfonso 对于#2,其中“过滤器”表示“重新规范化”,那么是的。如果您需要 每条 记录,请参阅 Travis G 的回答,但如果您 需要一些(即使用 WHERE),那么如 MIIB 的回答中所示的 JOIN 就是方法去。请注意,它们返回明显不同的结果,因此必须以不同方式重新归一化。
【解决方案2】:

你不能从 mysql 得到多维结果。获取元素的查询应该是这样的:

select courses.id as coursesId,courses.name as coursesName,sections.id as sectionsId,sections.name as sectionsName,resources.id as resourcesId, resources.name as resourcesName
from courses
left join sections on courses.id=sections.course_id
left join resources on sections.id=resources.section_id;

但它当然不会给你你喜欢的数组。

【讨论】:

    【解决方案3】:

    你可以试试这样的

    SELECT * FROM (
    select c.id, c.name from courses c
    union
    select s.id, r.name,s.course_ID from sections s
    union
    select r.id, r.name,r.section_ID from resources r
    )
    

    【讨论】:

    • 我在每个表中还有很多不同的列(没有放在那里以使其易于阅读)。所以我会为每个表得到不同的“列数”。我还能用这样的东西吗?
    【解决方案4】:
            if you are familiar with php then you can use this code i am writing only 2nd level you can write same way with third label
        $final=array();
               $c=-1;
               $cid=false;
               $cname=false;
               $query = "SELECT c.*,s.*,r.* FROM  courses AS c LEFT JOIN sections AS s ON c.id=s.course_id LEFT JOIN resources AS r ON r.section_id =s.id";
               $result=mysql_query($query, $this->con) or die(mysql_error());
               while($row=  mysql_fetch_array($result)){
                   if($cid!=$row[2]){
                       $final['cources'][++$c]['id']=$cid=$row[0];
                       $final['cources'][$c]['name']=$cname=$row[1];
                       $s=-1;
    
    
                   }
                   $final['cources'][$c]['sections'][++$s]['id']=$row[2];
                   $final['cources'][$c]['sections'][$s]['course_id']=$row[3];
                  $final['cources'][$c]['sections'][$s]['name']=$row[4];
               }
               echo "<pre>";
               print_r($final);
               echo "</pre>";
    
    //Outpur
    Array
    (
        [cources] => Array
            (
                [0] => Array
                    (
                        [id] => 1
                        [name] => c1
                        [sections] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 1
                                        [course_id] => 1
                                        [name] => s1-1
                                    )
    
                                [1] => Array
                                    (
                                        [id] => 1
                                        [course_id] => 1
                                        [name] => s1-1
                                    )
    
                            )
    
                    )
    
                [1] => Array
                    (
                        [id] => 2
                        [name] => c2
                        [sections] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 2
                                        [course_id] => 2
                                        [name] => s1-2
                                    )
    
                            )
    
                    )
    
            )
    
    )
    

    【讨论】:

      猜你喜欢
      • 2013-07-14
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多