Mysql родительские дочерние таблицы, уменьшающие вызовы базы данных или слияние в PHP - PullRequest
2 голосов
/ 13 января 2012

Если бы у меня было 2 таблицы, скажем blog_category и blog, каждый «блог» может принадлежать только к определенной категории, поэтому отношение 1-1 основано на ключе «blog_category_id».

Теперь в моем коде я бы сделал что-то вроде:

//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 вызова в БД, теперь размер набора результатов для вызова 2 (блоги) определенно будет больше, но будет ли фактический вызов БД столь же дорогим?

Я бы обычно пошелдля первого варианта, но мне просто интересно, есть ли лучший способ приблизиться к этому, или более вероятно, что дополнительная обработка в PHP будет более дорогой с точки зрения производительности?Также конкретно с точки зрения MVC, если модель возвращает категории, но она также должна возвращать соответствующие блоги для этой категории, я не уверен, как лучше структурировать это, насколько я понимаю, модель не должна возвращать все данныетребуется для просмотра?

Или мне лучше выбрать все категории и блоги, используя внутренние объединения в первом запросе, и создать вывод, который мне нужен?Возможно, используя многомерный массив?

Спасибо

Ответы [ 2 ]

1 голос
/ 14 января 2012

Лучшее решение зависит от того, что вы собираетесь делать с данными.

Ленивая загрузка

Загрузка данных, когда вам это нужно.Это хорошее решение, когда у вас есть, например, 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 для загрузки сообщений для определенной категории фактически выполнялся, когда представление пытается получить доступих.

Что вы думаете?

1 голос
/ 13 января 2012

Вы можете использовать простой запрос 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

Затем, когда вы перебираете возвращенные записи, присваиваете идентификатор текущей категории переменной, которую вы можете использоватьсравнить со следующей категорией записей.Если категория отличается, напечатайте заголовок категории перед печатью записи.Важно отметить, что для того, чтобы это работало, вы должны сначала получить сообщения, упорядоченные по категориям, а затем публиковать их так, чтобы все сообщения в одной категории были вместе.

Например:

$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'];
}

Примечание: , поскольку вы не опубликовали схему этих двух таблиц, мне пришлось составить имена столбцов, которые похожи на то, что я ожидал бы увидеть в подобном коде.Таким образом, приведенный выше код не будет работать с вашим кодом без каких-либо изменений, учитывающих это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...