Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MySQL查询数据库以显示检查列表的最佳方式_Php_Mysql_Database_Performance - Fatal编程技术网

Php MySQL查询数据库以显示检查列表的最佳方式

Php MySQL查询数据库以显示检查列表的最佳方式,php,mysql,database,performance,Php,Mysql,Database,Performance,我在一个数据库中有4个表,允许我管理一种“检查表”。对于每个病理学,我有一大步(过程)被分解为多个任务。所有这些都链接到摘要表中的特定操作(progress.case\u id) database.pathology +--------------+------------+ | id_pathology | name | +--------------+------------+ | 1 | Pathology1 | | 2 | Path

我在一个数据库中有4个表,允许我管理一种“检查表”。对于每个
病理学
,我有一大步(
过程
)被分解为多个
任务
。所有这些都链接到摘要表中的特定操作(
progress.case\u id

database.pathology
+--------------+------------+
| id_pathology |    name    |
+--------------+------------+
|            1 | Pathology1 |
|            2 | Pathology2 |
|            3 | Pathology3 |
+--------------+------------+

database.process
+------------+----------+--------------+----------------+
| id_process |   name   | pathology_id | days_allocated |
+------------+----------+--------------+----------------+
| 1          | BigTask1 | 2            | 5              |
| 2          | BigTask2 | 2            | 3              |
| 3          | BigTask3 | 2            | 6              |
| ...        | ...      | ...          | ...            |
+------------+----------+--------------+----------------+

database.task
+---------+-------+------------+
| id_task | name  | process_id |
+---------+-------+------------+
| 1       | Task1 | 1          |
| 2       | Task2 | 1          |
| 3       | Task3 | 1          |
| 4       | Task4 | 2          |
| ...     | ...   | ...        |
+---------+-------+------------+

database.progress
+-------------+---------+---------+---------+------------+---------+
| id_progress | task_id | case_id | user_id |    date    | current |
+-------------+---------+---------+---------+------------+---------+
|           1 |       1 |     120 |       2 | 2015-11-02 |       1 |
|           2 |       2 |     120 |       2 | 2015-11-02 |       0 |
|           3 |       1 |     121 |       3 | 2015-11-02 |       1 |
+-------------+---------+---------+---------+------------+---------+
我必须展示这样的东西

我的问题是:最有效的方法是什么

只查询一个表(进度)以显示最多,然后查询另一个表以获取不同进程和天数的名称是否更快

也许联合功能更有效

或者你认为我的数据库结构不合适吗

对于每种情况,我们可以有大约50个任务,并将当前字段转换为复选框。后台脚本也正在运行。它根据剩余天数分析提供的天数,以确定此特定案例是否可能出现延迟

对于每个病例,进度表中已经填写了与病例病理学相关的所有任务。并且当前字段的开头总是“0”

我已经尝试了很多东西,比如

$result = $db->prepare("SELECT DISTINCT process_id,process.name FROM task, progress,process WHERE progress.task_id = task.id_task AND task.process_id = process.id_process AND progress.case_id = ?");     
$result->execute(array($id));
foreach($result as $row)
{
  echo "<b>".$row[1]."</b><br>";
  $result = $db->prepare("SELECT name,id_task FROM task WHERE process_id = ?");     
  $result->execute(array($row[0]));
  foreach($result as $row)
  {
      echo $row[0];
      $result = $db->prepare("SELECT user_id, date, current FROM progress WHERE progress.task_id = ? AND case_id = ?");     
      $result->execute(array($row[1], $id));
      foreach($result as $row)
      {
        if($row[2] == 0)
        {echo "<input type='checkbox' />";}
        else
        {
          echo "<input type='checkbox' checked/>";
          echo "user : ".$row[0]." date : ".$row[1]."<br>";
        }            
      }          
  }
$result=$db->prepare(“从任务、进度、流程中选择不同的流程\u id、流程.name,其中progress.task\u id=task.id\u task和task.process\u id=process.id\u流程和progress.case\u id=?”;
$result->execute(数组($id));
foreach($结果为$行)
{
回显“.”行[1]。“
”; $result=$db->prepare(“从任务中选择名称、id\u任务,其中进程id=?”; $result->execute(数组($row[0]); foreach($结果为$行) { echo$行[0]; $result=$db->prepare(“从progress.task_id=?和case_id=?的进度中选择user_id、date、current FROM progress”); $result->execute(数组($row[1],$id)); foreach($结果为$行) { 如果($row[2]==0) {echo”“;} 其他的 { 回声“; 回显“用户:.$行[0]”。日期:.$行[1]”。
; } } }

但是我很确定我做得不对。我应该改变我的数据库基础设施吗?我应该使用特定的MySQL技巧吗?或者可能只是更高效的PHP处理吗?

就效率而言,数据库查询是您可以执行的最慢的操作之一。您可以做些什么来减少需要执行的查询数量您的make将大大加快应用程序的速度

但更重要的是,您的应用程序需要按设计工作,这意味着开发人员需要了解正在发生的事情,数据不应该只是等待被覆盖,而负责在3年内维护这些数据的初级开发人员也不想把他们的头发扯掉

快总比慢好

慢总比坏好

对于您的特定问题,如果可能的话,不要在循环内进行查询。特别是当循环由您从同一数据库提取的数据控制时。这是一种代码气味,需要正确使用
JOIN
s

Google图像搜索显示了大量的Venn图示例,这些图显示了每个
连接返回的不同类型的数据。如果有疑问,通常需要
左连接

因此,让我们确定您的关系:

  • 病理学

    • 未在结果中使用
    • 找到一种方法将其合并到您的查询中,因为“病理学2”出现在您的模型中
  • 过程

    • 以一对多关系引用病理学。每个过程可以有一个病理学,但每个病理学可以有0个或多个过程
  • 任务

    • 引用一对多关系中的任务。任务包含进程的子进程
  • 进展

    • 引用任务以及未显示的案例和用户。进度似乎是引用特定案例和用户时任务的详细信息
    • 我假设存在一个业务约束,其中task_id、case_id和user_id必须是唯一的……也就是说,对于task 1和case 100,user 1只能有一个进度条目
    • 除了保存任务的详细信息外,它还充当任务、案例和用户之间的桥梁,为三个表提供多对多关系。由于任务是过程的直接子级,而过程是病理学的直接子级,因此它为病理学提供了多对多关系
  • 案例

    • 推断此表是否存在
    • 由任务引用
  • 使用者

    • 推断此表是否存在
    • 由任务引用
基于此表结构,我们的主要分组将是病例、病理学和用户

也就是说,如果您是一个登录用户,并且希望按情况查看进度,您将希望看到以下内容:

Case 110:
    Pathology1:
        BigTask1:
            Task1: X
            Task2: []
        BigTask2:
            Task3: X
    Pathology2:
        BigTask3:
            Task4: []
Case 120:
    Pathology1:
        BigTask1: 
            Task1: []
我们希望用户ID==1; 我们的第一次分类将基于案例 我们的第二个分类将基于病理学 我们的第三个排序将基于流程 我们的最后一次分拣任务是

因此,获得上述结果的数据为:

+------+------------+----------+-------+----------+
| case | pathology  | process  | task  | progress |
+------+------------+----------+-------+----------+
| 110  | Pathology1 | BigTask1 | Task1 | 1        |
| 110  | Pathology1 | BigTask1 | Task2 | 0        |
| 110  | Pathology1 | BigTask2 | Task3 | 1        |
| 110  | Pathology2 | BigTask3 | Task4 | 0        |
| 120  | Pathology1 | BigTask1 | Task1 | 0        |
+------+------------+----------+-------+----------+
我们的“ORDER BY”子句从头到尾…
按任务、过程、病理学、病例排序
…我们可以用PHP对其进行排序,但数据库在这方面比我们做得更好。如果索引设置正确,数据库甚至可能不必排序,它只需按顺序获取即可

获取特定用户的上述数据的查询为:

SELECT
    prog.case_id AS case,
    path.name AS pathology,
    proc.name AS process,
    task.name AS task,
    prog.current AS progress
FROM
    pathology path
LEFT JOIN process proc ON path.id_pathology = proc.pathology_id
LEFT JOIN task ON task.process_id = proc.id_process
LEFT JOIN progress prog ON task.id_task = prog.task_id
WHERE prog.user_id = :userid
ORDER BY task, process, pathology, case
然后,您的PHP可能会遵循

<?php

$sql = <<<EOSQL
SELECT
    prog.case_id AS case,
    path.name AS pathology,
    proc.name AS process,
    task.name AS task,
    prog.current AS progress
FROM
    pathology path
LEFT JOIN process proc ON path.id_pathology = proc.pathology_id
LEFT JOIN task ON task.process_id = proc.id_process
LEFT JOIN progress prog ON task.id_task = prog.task_id
WHERE prog.user_id = :userid
ORDER BY task, process, pathology, case
EOSQL;

$result = $db->prepare($sql);     
$result->execute(array(':userid' => $id));
$rows = $result->fetchAll(PDO::FETCH_ASSOC);

foreach ($rows as $row) {
    var_dump($row);
    // array(5) {
    //     ["case"]=>
    //     int(110)
    //     ["pathology"]=>
    //     string(10) "Pathology1"
    //     ["process"]=>
    //     string(8) "BigTask1"
    //     ["task"]=>
    //     string(5) "Task1"
    //     ["progress"]=>
    //     int(1)
    // }
}

嵌套查询,其中内部查询使用来自外部查询的数据,几乎总是可以更好地编写为单个
联接
ed查询。要添加@MarcB的注释,您应该将嵌套查询识别为软件开发反模式。您应该始终寻找替代方法