【发布时间】:2014-02-04 08:15:24
【问题描述】:
我正在使用 CodeIgniter 构建一个基本论坛,但在处理两个 MySQL 查询时遇到了问题。
这是我的桌子:
mysql> describe forum_posts;
+----------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+-------------------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| topic_id | int(11) | YES | MUL | NULL | |
| user_id | int(11) | YES | MUL | NULL | |
| post | text | YES | | NULL | |
| date | timestamp | YES | | CURRENT_TIMESTAMP | |
| ip | varchar(15) | YES | | NULL | |
+----------+------------------+------+-----+-------------------+----------------+
6 rows in set (0.01 sec)
mysql> describe forum_topics;
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| category_id | int(11) | YES | MUL | NULL | |
| user_id | int(11) | YES | MUL | NULL | |
| name | varchar(100) | YES | | NULL | |
| importance | tinyint(2) | YES | | 0 | |
+-------------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> describe forum_categories;
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(50) | YES | | NULL | |
| order | tinyint(2) | YES | | 0 | |
+-------+------------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
1) 我想选择所有类别及其各自的最新帖子
2) 我想从 ID 为 X 的类别中选择所有主题并显示该主题的最后一篇文章。
这是我到目前为止所做的
(1):
SELECT
C.*,
T.name AS topic_name,
T.id AS topic_id,
P.date AS post_date
FROM forum_categories AS C
LEFT JOIN
(
SELECT id, category_id, name
FROM forum_topics
ORDER BY id DESC
)
T ON C.id = T.category_id
LEFT JOIN
(
SELECT id, topic_id, date
FROM forum_posts
ORDER BY DATE(date) DESC
)
P ON T.id = P.topic_id
GROUP BY C.id
ORDER BY DATE(P.date) DESC
(2):
SELECT
T.*,
P.topic_id,
P.id AS post_id,
P.user_id,
P.date,
users.username
FROM forum_topics AS T
LEFT JOIN
(
SELECT id, topic_id, user_id, date
FROM forum_posts
ORDER BY id DESC
)
P ON P.topic_id = T.id
LEFT JOIN
users ON P.user_id = users.id
WHERE T.category_id = '1'
GROUP BY P.topic_id
ORDER BY
T.id DESC,
P.id DESC
LIMIT 10
基本上我的问题是我不能先对子查询进行排序,然后再对它们进行分组。
我也不确定这些查询是否足够有效。我正在处理子查询。他们会很慢吗?
【问题讨论】:
-
这不会很慢。
-
谢谢。您对我的问题有什么解决方案吗?
-
您想要的数据布局是什么?如果这将是典型的论坛布局,那么您似乎已经完成了此操作。类别可以通过名称/id 自行进入数组。主题查询可以访问该数组,同时显示结果以查找类别。您相应地对主题查询进行排序。另外你想订购什么和分组?按发布时间 DESC 排序并按主题分组?如果这是预期的结果,这似乎是直截了当的。
-
我正在尝试列出所有类别和其中的最新帖子。编辑:实际上,您对仅类别单独查询的建议非常好。我将不得不分别获取包含最新帖子的主题,这似乎要容易得多。谢谢!很好的建议!
-
大多数论坛平台都没有规范化,它们的数据库结构进行了某种预缓存。原因是大多数查询显示线程列表或来自特定线程的帖子列表。例如,为了“选择所有类别及其各自的最新帖子”,您应该考虑“forum_categories”表中的“last_post_id”列。这将大大简化您的查询并提高性能。另一个常见的例子是跟踪线程中的帖子数量,而不是在每次页面加载时计算每个线程的 post_count。