2012-01-13 47 views
2

如果我有两个表(即blog_category和blog),则每个“blog”只能属于特定类别,因此基于名为“blog_category_id”的键的1-1关系。Mysql父子表减少数据库调用或在PHP中合并

现在在我的代码,我会做这样的事情:

//Loop through categories such as 
foreach($categories as $cat): 
//then for each category create an array of all its posts 
$posts = $cat->getPosts(); // This would be another DB call to get all posts for the cat 
//do stuff with posts 
endforeach; 

现在对我来说这似乎是它可以在数据库方面结束了相当昂贵的调用取决于$类别的大小。这仍然是最好的解决方案吗?或者我能够在代码中做些什么,并首先检索所有类别,然后检索所有博客并以某种方式将它们映射到相应的类别?理论上,这只对数据库有两个调用,现在对于调用2(博客)的结果集的大小明智一定会更大,但实际的数据库调用是否会很昂贵?

我通常会选择第一个选项,但我只是想知道是否会有更好的方法来处理这个问题,或者更有可能PHP中的额外处理在性能方面会更昂贵?具体来说,从MVC的角度来看,如果模型返回类别,但它也应该返回该类别的相应博客,但我不确定如何最好地构建这个模型,根据我的理解,模型不应该返回所有数据视图需要?

或者我会更好地选择在第一个查询中使用内部连接的所有类别和博客,并创建我需要的输出?也许通过使用多维数组?

感谢

回答

1

你可以使用一个简单的SQL查询来获取所有类别和职位如下所示:

SELECT * 
FROM posts p 
JOIN categories c ON c.id = p.blog_category_id 
ORDER BY c.category_name ASC, 
     p.posted_date DESC 

然后,当你遍历返回的记录分配当前的类别ID给一个变量,您可以使用它来比较下一个记录类别。如果类别不同,则在打印记录之前打印类别标题。重要的是要注意,为了这个工作,您需要首先获得按类别排序的帖子,然后发布,以便同一类别中的所有帖子都在一起。

因此,例如:

$category_id = null; 
foreach($posts as $post) { 
    if($post['blog_category_id'] != $category_id) { 
     $category_id = $post['blog_category_id']; 
     echo '<h2>' . $post['category_name'] . '</h2>'; 
    } 
    echo '<h3>' . $post['post_title'] . '</h3>'; 
    echo $post['blog_content']; 
} 

注:你有没有贴上去这两个表我不得不弥补类似于什么,我希望看到在列名的模式这样的代码。所以上面的代码不会与你的代码一起工作,没有一些调整来解决这个问题。

+0

嗨,感谢您的回复,我知道如何进行连接,但具体而言,我一直在寻找建议,了解使用MVC结构进行此操作的最佳方式应该与最佳性能明智的平衡 – TommyBs 2012-01-13 19:41:14

+0

好吧,MVC不会这里真的对这段代码有任何影响。 MVC是一个整体结构,并不决定数据库设计。 MVC中的'M'可能甚至不会与数据库交谈,但可以使用API​​等。我已更新我的答案以包含模板代码。 – Treffynnon 2012-01-13 19:48:11

+0

嗨,再次感谢您的回复,我只是使用伪代码来尝试和简化示例来解释我想要的。我知道它不会真正规定数据库设计,但更多的是关于如何构造代码,以及是否有任何性能优势取决于我做的方式(或者这对MVC项目的方式有影响应该是结构)。感谢您填写答案,我是MVC的新手,并没有真正找到关于如何构建的深入教程,主要是展示示例结构的教程。我会玩一玩,并更新问题 – TommyBs 2012-01-13 19:51:51

1

最好的解决方案取决于你要用数据做什么。当你需要它

延迟加载

加载数据。例如,如果您有20个类别,并且仅为其中的2个类别加载帖子,这是一个很好的解决方案。但是,如果你需要为所有人发布帖子,那么它就不会有效率......这就是所谓的n + 1查询(这真的很糟糕)。

预先加载

在另一方面,如果你要访问您几乎所有的帖子,你应该做一个预先加载。

-- Load all your data in a query 
SELECT * 
FROM categories c 
INNER JOIN posts p ON c.id = p.category_id; 

// Basic example in JSON of how to format your result 
{ 
    'cat1': ['post1', 'post2'], 
    'cat2': ['post5', 'post4', 'post5'], 
    ... 
} 

怎么办?

在你的情况下,我会说一个渴望的加载,因为你加载一切循环。但是,如果您不能访问大部分数据,则应该重新设计模型以执行延迟加载,以便在视图尝试访问时实际执行SQL查询以加载特定类别的帖子他们。

您认为如何?