MySQL Простой Форум - PullRequest
       12

MySQL Простой Форум

1 голос
/ 03 января 2009

Итак, я пытаюсь построить простой форум. Это будет список тем в порядке убывания по дате либо темы (если нет ответов), либо последнего ответа. Вот структура БД:

forum_topic

идентификатор, имя, адрес электронной почты, тело, дата

forum_reply

id, email, body, date, topic_id

Сам форум будет состоять из таблицы HTML со следующими заголовками:

Тема, Последнее изменение, # Ответы

Как будет выглядеть запрос или запросы для создания такой структуры? Я думал, что это потребует перекрестного соединения, но не уверен ... Заранее спасибо.

Ответы [ 4 ]

3 голосов
/ 03 января 2009

Примерно так:

select * from forum_topic
inner join forum_reply on forum_topic.id=topc_id

Однако не используйте select *

Это плохая практика:)

И мне не нравится, как вы избегаете нормализации! Значение я бы предпочел:

Пользователи

  • Идентификатор_пользователь
  • Имя
  • E-mail

Тема

  • ThreadID
  • Тема
  • Ответил
  • AskedByUserID
  • Дата

Ответов

  • ReplyID
  • ThreadID
  • Идентификатор_пользователь
  • Ответ
  • Дата

Затем выбираем тему следующим образом:

select ThreadID, Subject, Answered, AksedByUserID, Date from Threads

И выбрав все ответы, как это

select Answer, Date, Name, Email from Threads
inner join Replies on Threads,ThreaID=Replies.ThreadID
inner join Users on AskedByUserID=UserID 
where Threads.ThreadID=xxx

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

1 голос
/ 03 января 2009

Во-первых, мне кажется, noboody на самом деле отвечает на ваш вопрос, который был:

Как будет выглядеть запрос или запросы для создания такой структуры?

с запрошенной структурой

Тема, LastModified, # Ответы.

SQL для создания таблицы результатов с этой структурой, учитывая предоставленные вами структуры таблиц, будет:

SELECT t.Id, t.Name AS Topic, 
       MAX(r.Date) AS LastModified, 
       COUNT(*) AS NumReplies
FROM Forum_Topic t
LEFT OUTER JOIN Forum_Reply r ON t.id = r.topic_id
GROUP BY t.Id, t.Name

(извините, это тестируется только на SQL Server, так как в данный момент у меня нет доступа к MySql)

Кроме того, ваша структура IS уже нормализована. Предложения об обратном делают предположения о том, что вы хотите сделать, например, предполагая, что вы заинтересованы в отслеживании имен пользователей при добавлении к адресам электронной почты. Это вполне разумно, но, тем не менее, является предположением. С точки зрения нормализации нет ничего плохого в использовании адреса электронной почты в качестве уникального идентификатора пользователя.

Теперь, если вы ищете общие рекомендации по настройке базы данных, мы можем дать вам МНОГО таких. Перед нормализацией я бы начал с того, чтобы не использовать потенциальные ключевые слова в качестве имен объектов (например, не давать имена столбцов, такие как «Имя» и «Дата»).

Что касается комментария от Мэтта о том, что значение равно NULL, когда нет ответов: использование функции COALESCE () исправит это. COALESCE () возвращает первый ненулевой аргумент (или NULL, если все аргументы равны NULL). Поэтому замените MAX (r.Date) на MAX (COALESCE (r.Date, t.Date)).

1 голос
/ 03 января 2009

Да, вы должны быть в состоянии получить его с помощью запроса, подобного этому:

SELECT 
  forum_topic.id, 
  forum_topic.name AS Topic,  
  MAX(forum_reply.date) AS Last_Modified, 
  count(*) AS  Replies
FROM forum_topic 
INNER JOIN forum_reply ON (forum_topic.id=forum_reply.topic_id)
GROUP BY forum_topic.id

«Группировка по» - это волшебство, которое дает нам по одной строке на тему, а функции MAX () и COUNT () дают нам необходимые вам агрегированные данные.

(РЕДАКТИРОВАТЬ: я пропустил, что тело первого сообщения было в таблице тем, поэтому сообщения без ответов будут пропущены вышеупомянутым запросом. Филипп имеет правильную идею, предлагая вам нормализовать ваши данные. После нормализации запрос, аналогичный приведенному выше, даст вам необходимые данные).

0 голосов
/ 03 января 2009

Под "нормализованным" вы подразумеваете, что столбец тела "forum_topic" должен быть удален, а фактическое тело темы должно быть первым ответом?

...