MySQL Simple Forum

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

forum_topic

id, name, email, body, date

forum_reply

id, email, body, date, topic_id

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

Topic, Last Modified, # Replies

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

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

staticsan 06.01.2009 02:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
1
661
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

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

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

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

  • ID пользователя
  • Имя
  • Электронное письмо

Потоки

  • ThreadID
  • Предмет
  • Ответил
  • AskedByUserID
  • Дата

Ответы

  • ReplyID
  • ThreadID
  • ID пользователя
  • Отвечать
  • Дата

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

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

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

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

Paul Dixon 03.01.2009 19:59

Понятия не имею, почему вам отказали. К вашему сведению, столбцы были названы так для простоты объяснения :-)

Matt 03.01.2009 20:03

То, что я предлагаю, - это просто пример того, как будет представлен «лучший» форум, и пример того, как использовать объединения, отрицательное голосование просто превосходно, когда я пытаюсь предоставить несколько хороших примеров.

Filip Ekberg 03.01.2009 20:03

Я подумал, что вы хотите выбрать ветку форума, а не список всех веток, прошу прощения за недоразумение. Для этого вы должны использовать COUNT и использовать предложение GROUP BY.

Filip Ekberg 03.01.2009 20:05

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

Filip Ekberg 03.01.2009 20:08

Да, вы сможете получить его с помощью такого запроса:

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

«Группировать по» - это волшебство, которое дает нам одну строку для каждой темы, а функции МАКСИМУМ() и СЧИТАТЬ() предоставляют нам необходимые агрегированные данные.

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

Это близко, но с этим запросом тема не появится, если на нее нет ответов.

Matt 03.01.2009 20:00

Блин, да пропустил. Предполагается, что первое сообщение было ответом, но поскольку в теме есть тело ....

Paul Dixon 03.01.2009 20:03

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

Вы можете прочитать об этом здесь: devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalizat‌ ion

Filip Ekberg 03.01.2009 20:21

Нормализация в основном означает не повторяться, когда в этом нет необходимости. Например, у вас есть «Электронная почта» более чем в одном месте, я бы предпочел использовать для этого User-table.

Filip Ekberg 03.01.2009 20:22

Верно, это действительно компромисс. Дисковое пространство против процессорного времени. Объединение может быть дорогостоящим - нормализация - не всегда главное. В этом случае мне нужно, чтобы сама тема содержала поле описания. Что нужно сделать, чтобы изменить ваш запрос (или запрос Пола), чтобы отображать темы, даже без ответов?

Matt 03.01.2009 20:32

Не очень много. Вы просто делаете:; выберите * из потоков внутреннего соединения Пользователи в потоках. AskedByUserID = UserID; который присоединится к Usertable, предоставляя вам информацию о пользователях и теме. Однако с ответами вам тоже нужно присоединиться. Дважды я бы сказал, хотите ли вы также запрашивать информацию о пользователе.

Filip Ekberg 03.01.2009 21:56
Ответ принят как подходящий

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

What would the query or queries look like to produce such a structure?

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

Тема, 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)

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

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

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

Это на 99%. Теперь появляются все темы. Единственная проблема сейчас в том, что LastModified = NULL, когда в теме нет ответов. Любые идеи?

Matt 04.01.2009 01:01

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

Filip Ekberg 04.01.2009 05:35

Роб, ты мужчина. Прекрасно работает. Спасибо всем за помощь!

Matt 04.01.2009 05:36

Другие вопросы по теме