Я пытаюсь найти сценарий, чтобы принять запрос MySQL и превратить его в отдельные запросы, то есть динамически денормализовать запрос.
В качестве теста я построил простую систему статей, которая имеет 4 таблицы:
- статьи
- article_id
- article_format_id
- article_title
- article_body
- article_date
- article_categories
- категории
- category_id
- category_title
- форматы
Статья может относиться к нескольким категориям, но иметь только один формат. Я чувствую, что это хороший пример реальной ситуации.
На странице категории, на которой перечислены все статьи (в том числе и с помощью format_title), это можно легко сделать с помощью следующего запроса:
SELECT articles.*, formats.format_title
FROM articles
INNER JOIN formats ON articles.article_format_id = formats.format_id
INNER JOIN article_categories ON articles.article_id = article_categories.article_id
WHERE article_categories.category_id = 2
ORDER BY articles.article_date DESC
Однако скрипт, который я пытаюсь создать, получит этот запрос, проанализирует его и выполнит запросы по отдельности.
Таким образом, в этом примере страницы категории скрипт эффективно запустит это (работает динамически):
// Select article_categories
$sql = "SELECT * FROM article_categories WHERE category_id = 2";
$query = mysql_query($sql);
while ($row_article_categories = mysql_fetch_array($query, MYSQL_ASSOC)) {
// Select articles
$sql2 = "SELECT * FROM articles WHERE article_id = " . $row_article_categories['article_id'];
$query2 = mysql_query($sql2);
while ($row_articles = mysql_fetch_array($query2, MYSQL_ASSOC)) {
// Select formats
$sql3 = "SELECT * FROM formats WHERE format_id = " . $row_articles['article_format_id'];
$query3 = mysql_query($sql3);
$row_formats = mysql_fetch_array($query3, MYSQL_ASSOC);
// Merge articles and formats
$row_articles = array_merge($row_articles, $row_formats);
// Add to array
$out[] = $row_articles;
}
}
// Sort articles by date
foreach ($out as $key => $row) {
$arr[$key] = $row['article_date'];
}
array_multisort($arr, SORT_DESC, $out);
// Output articles - this would not be part of the script obviously it should just return the $out array
foreach ($out as $row) {
echo '<p><a href="article.php?id='.$row['article_id'].'">'.$row['article_title'].'</a> <i>('.$row['format_title'].')</i><br />'.$row['article_body'].'<br /><span class="date">'.date("F jS Y", strtotime($row['article_date'])).'</span></p>';
}
Сложность этого заключается в разработке правильных запросов в правильном порядке, так как вы можете размещать имена столбцов для SELECT и JOIN в любом порядке в запросе (это то, что MySQL и другие базы данных SQL переводят так хорошо) и разработка информационная логика в PHP.
В настоящее время я выполняю синтаксический анализ запроса с использованием SQL_Parser , который хорошо работает при разбиении запроса на многомерный массив, но решение упомянутых выше проблем является головной болью.
Любая помощь или предложения будут высоко оценены.