PHP - 如何从MySQL创建多维数据库JSON?

时间:2017-02-01 20:43:20

标签: php mysql json multidimensional-array one-to-many

我需要从两个MySQL表创建一个多维JSON。我的代码工作正常,但我认为编写得非常糟糕,因为它首先连接数据库值然后在PHP中爆炸结果字符串。必须有更好(更快)的方法来做到这一点。

我知道有很多次问过类似的问题,但我是一个菜鸟,我无法弄清楚如何将答案应用到我的案例中。

所以,我有以下MySQL表:

    tbl1
-----------------------------
id| question   |correctanswer
-----------------------------
 1|'Yes or no?'|    'Yes'
 2|   'Who?'   |    'Peter'

    tbl2
-----------------------------
id|questionid| answeroptions
-----------------------------
1 |         1|'Yes'
2 |         1|'No'
3 |         2|'Peter'
4 |         2|'John'
5 |         2|'James'
6 |         2|'Jack'

我想构建类似的JSON字符串:

{
    "id":"1",
    "question":"Yes or no?",
    "correct_answer":"Yes",
    "answeroptions":[
                    "Yes",
                    "No"
                    ]
}
{
    "id":"2",
    "question":"Who?",
    "correct_answer":"Peter",
    "answeroptions":[
                    "Peter",
                    "John",
                    "James",
                    "Jack"
                    ]
}

这是我的代码:

$sql = "SELECT tabl1.id, tabl1.question, tabl1.correctanswer, 
    GROUP_CONCAT(DISTINCT tbl2.answeroptions)
    FROM tabl1
    LEFT JOIN tbl2 ON (tabl1.id = tbl2.questionid)
    GROUP BY tabl1.id;";

$jsonarray = array();
$result = $conn->query($sql);
$i = 0;

while ($row = mysqli_fetch_array($result, MYSQL_NUM)) {
    $jsonarray[$i]["topic"] = $row[0];
    $jsonarray[$i]["id"]=$row[1];
    $jsonarray[$i]["question"]=$row[2];
    $jsonarray[$i]["correct_answer"]=$row[3];
    $jsonarray[$i]["answeroptions"] = array();
    $jsonarray[$i]["answeroptions"] = explode(",",$row[4]);
    $i++;
}

for ($d=0; $d<count($jsonarray);$d++){
    echo json_encode($jsonarray[$d])."<br>";
}

UPD: 我对三个用例进行了性能测试:

  1. 布莱克的建议
  2. ded的建议
  3. 将answeroptions组合到tbl1中的新列中以消除第二个请求并使用相应的ded脚本进行修改。
  4. 我使用for循环* 100次,结果如下:

    1. 0.16780591011047 sec
    2. 0.0067291259765625 sec
    3. 0.0005500316619873 sec
    4. 因此,基于性能,我得出结论,在DB中使用一对多关系并不总是最佳选择。对于这些简单的任务,所有数据都可以存储在同一个表中。

      谢谢你们的帮助!

2 个答案:

答案 0 :(得分:0)

你应该真正做两个查询以获得最佳性能。试试这段代码(未经测试)

# Question array holder
$questions = [];


# Loading the questions
$query = "  SELECT
                `id`,
                `question`,
                `correctanswer`
            FROM
                `tabl1`";
$result = mysqli_query( $conn, $query );


# Nothing to send
if( mysqli_num_rows( $result ) == 0 ) {
    exit( '[]' );
}


# Adding questions to array
while( $question_data = mysqli_fetch_assoc( $result ) ) {
    $question_data[ 'answeroptions' ] = [];
    $questions[ $question_data[ 'id' ] ] = $question_data;
}


# Loading the answer
$query = "  SELECT
                *
            FROM
                `tabl2`
            WHERE
                `questionid` IN (" . implode( ',', array_keys( $questions ) ) . ")";
$result = mysqli_query( $conn, $query );


# Adding answers to array
while( $answer_id = mysqli_fetch_assoc( $result ) ) {
    $questions[ $answer_id[ 'questionid' ] ][ 'answeroptions' ][] = $answer_id[ 'answeroptions' ];
}


# Sending the questions
echo json_encode( array_values( $questions ) );

答案 1 :(得分:0)

$sql = "SELECT tabl1.id, tabl1.question, tabl1.correctanswer,
GROUP_CONCAT(DISTINCT tbl2.answeroptions)
FROM tabl1
LEFT JOIN tbl2 ON (tabl1.id = tbl2.questionid)
GROUP BY tabl1.id;";

$result = $conn->query($sql);
$jsonarray = mysqli_fetch_all($result, MYSQLI_ASSOC);

foreach ($jsonarray as $row) {
    $row["answeroptions"] = explode(",", $row["answeroptions"]);
}

echo json_encode($jsonarray)."<br>";