dongzhihong3940 2015-04-19 14:12
浏览 49

PHP / MySQL排序多维数组

I'm trying to sort an array in to a three-deep array. This is my current query:

SELECT * FROM question 
INNER JOIN category ON question.category_id = category.id
INNER JOIN difficulty ON question.difficulty_id = difficulty.id 

Expected result is something like:

array(
    '1' => array( // category id 1
        '1' => array( // difficulty id 1
            '1' => array('...'), // question id 1
            '2' => array('...') // question id 2
        ),
        '2' => array(
            '3' => array('...'),
            '4' => array('...')
        )
    )
)

I did have the following:

foreach($categories as $category) {
    foreach($difficulties as $difficulty) {
        foreach($questions as $question) {
            if ($question['category_id'] == $category['id'] && $question['difficulty_id'] == $difficulty['id']) {
                $feed[$category['id']][$difficulty['id']][$question['id']] = $question;
            }
        }
    }
}

But there will be 10,000+ questions and performance will be bad so is there a way I can do this with one query and fewer loops?

  • 写回答

1条回答 默认 最新

  • dongzong8110 2015-04-19 14:30
    关注

    Basically you could just return your query and order by the ids like so:

    Category_ID      Difficulty_ID      Question_ID
         0                0                 0
         0                0                 1
         1                0                 2
         1                3                 3
         1                3                 4
         2                0                 5
         2                1                 6
    

    Then parse everything in a while:

    1. each time the category_ID changes add a new category with empty difficulty and reset previous difficulty
    2. each time the difficulty changes add new difficulty to category with empty question
    3. each time add the question to current difficulty.

    To store this structure performantly in local storage:

    1. define a unique delimiter (note: IE doesn't support control characters, this also means you can't store binary data without encoding it before, e.g. base64)
    2. load each row of each table like this:

      key: unique table prefix + id
      value: columns (delimited with the delimiter defined before)
      

      The easiest way to return a whole table at once is to define a second delimiter and then have some slightly ugly query in the form of:

      SELECT id||delimiter||col1||delimiter||...||colN FROM ...
      

      And then put it all together with a list aggregation using the second delimiter (group_concat() in mysql).

    3. Sometimes you need maps (for N to M relations or also if you want to search questions by difficulty or category), but because each question only has one category and difficulty you are already done.

    Alternative

    If the data is not too big and doesn't change after login, then you can just use the application cache and echo your stuff in script tags.

    评论

报告相同问题?

悬赏问题

  • ¥15 mmocr的训练错误,结果全为0
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀