MySQL Basit Forumu

4 Cevap php

Yani basit bir forum oluşturmak çalışıyorum. Bu konunun ya tarihinden (eğer hiçbir yanıt) veya son cevap ile azalan sırayla konuların listesi olacak. İşte DB yapısı bulunuyor:

forum_topic

id, adı, e-posta, vücut, tarih

forum_reply

id, e-posta, vücut, tarih, topic_id

Forum kendisi aşağıdaki başlıkları içeren bir HTML tablosu oluşacaktır:

Konu, son değiştirilme tarihi, # Cevaplar

Ne sorgu veya sorguları bakmak böyle bir yapıyı üretmek istiyoruz? Ben ... emin Teşekkür peşin bir çapraz birleştirme dahil, fakat düşünüyordum.

4 Cevap

Öncelikle, bu noboody aslında soru, cevap veriyor gibi geliyor bana:

Ne sorgu veya sorguları bakmak böyle bir yapıyı üretmek istiyoruz?

bir istenen yapı ile

Konu, LastModified, # Cevaplar.

Bu yapıda bir sonuç tablo üretmek için SQL, sağlanan tablo yapıları verilmiştir, olacaktır:

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

(Ben şu anda MySQL erişimi yok gibi üzgünüm, bu, yalnızca SQL Server üzerinde test edilmiştir)

Ayrıca, yapı IS zaten normalize. Aksine önerileri addition e-posta adreslerine kullanıcı adlarını izleme ilgi olduğunu varsayarak, siz, örneğin yapmak istedikleriniz hakkında varsayımlar yapıyoruz. Bu oldukça makul olduğunu, ancak yine de bir varsayımdır. Yanlış bir şey benzersiz bir kullanıcı bir tanıtıcı olarak e-posta adresini kullanarak, bir normalleşme açısından vardır.

Eğer bir veritabanı kurmak konusunda genel öneriler arıyorsanız Şimdi, biz size bu çok verebilir. Normalleşme önce, nesne adları (örneğin, sütunlar 'Adı' ve 'Tarih' gibi isimler vermeyin) gibi potansiyel anahtar kelimeleri kullanarak değil ile başlamak istiyorum.

Hiçbir yanıt olduğunda NULL değeri olma konusunda Matt yorumun ilgili: COALESCE kullanarak () fonksiyonu o çözecektir. (Tüm argümanlar null ise veya NULL) COALESCE () NULL olmayan ilk argümanı döndürür. Yani MAX MAX (r.Date) (COALESCE (r.Date, t.Date)) değiştirin.

Biraz böyle:

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

Ancak, kullanmayın select *

Bu kötü bir uygulamadır :)

Ve ben normalleşmesini önlemek beğenmiyorum! Ben daha çok olurdu Anlamı:

Users

  • UserID
  • Isim
  • E-posta

Threads

  • ThreadID
  • Konu
  • Cevaplanan
  • AskedByUserID
  • Tarih

Replies

  • ReplyID
  • ThreadID
  • UserID
  • Cevap
  • Tarih

Sonra böyle bir konuya seçerek:

select ThreadID, Konu, Cevaplanan, AksedByUserID, Tarih from Threads

Ve bu gibi tüm yanıtları seçme

select Cevap, Tarih, Isim, E-posta from Threads
inner join Replies on Threads,ThreaID=Replies.ThreadID
inner join Users on AskedByUserID=UserID 
where Threads.ThreadID=xxx

Şimdi bu sadece kafamın üstünden yazılmıştır, ama siz de bazı grup eklemek gerekebilir.

Evet, böyle bir sorgu ile almak gerekir:

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

"By grup" MAX() ile, bize konu başına bir satır verir sihirli ve COUNT() fonksiyonlar bize ihtiyacınız toplanan verileri veriyor.

(EDIT: I missed that the body of the first post was in the topic table, so posts with no replies would get missed by the above query. Filip has the right idea suggesting you normalize your data. Once normalized, a query similar the above would get you the data you need).

"Normalize" olarak, "forum_topic" vücut kolon kaldırılması gerektiğini demek ve gerçek konu vücut ilk cevap olmalıdır?