代码之家  ›  专栏  ›  技术社区  ›  Giovanne Afonso

优化MySQL和PHP中的多个查询

  •  1
  • Giovanne Afonso  · 技术社区  · 12 年前

    问题

    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;
        }
    }
    
    4 回复  |  直到 12 年前
        1
  •  1
  •   Community Mohan Dere    8 年前

    数据库结构已规范化-这是 对的 并且应该 更改。

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

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

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

      大约会有一个查询/对象。而理论界 可以 类似,实际实施将 效率要低得多 并且开销将比单个查询多得多。记住这一点 每一个 查询(至少)会产生往返惩罚——因此,这是 不可扩展 尽管它可能适用于较小的数据集或“时间不敏感”的操作。

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

      这对于支持C#/LINQ中的“Group By”操作来说是非常微不足道的。我不确定在PHP中如何[轻松]处理这一问题 1. 这也不完美,但假设分组使用哈希,这应该能够很好地扩展——它肯定会比#1更好。

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


    1. 与重新标准化数据有关,YMMV:

        2
  •  1
  •   Travis G    12 年前

    你可以试试这样的

    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
    )
    
        3
  •  1
  •   MIIB    12 年前

    您无法从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;
    

    当然,它不会给您提供您喜欢的数组。

        4
  •  0
  •   Nanhe Kumar    12 年前
            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
                                    )
    
                            )
    
                    )
    
            )
    
    )