Bir forumda okunmamış öğeleri Belirlenmesi

7 Cevap php

PHP ve MySQL kullanarak, ben kurmaya çalışıyorum bir forum sistemi var. Ne bilmek istiyorum, bir kullanıcı bir forum girişi okuduğunda SADECE kullanıcı için okumak gibi, bunun üzerinde başkasının mesaj kadar olursa olsun, onlar ne forum, gösteriyor ki bunu ayarlayabilirsiniz nasıl olduğunu.

Şu anda, her iş parçacığı için, ben bir POSTID ile bir tablo var, ve (metin olarak) gerçek Post, bağlamak için yayınlanmıştır Kimliğini, ThreadId vardır, sonra tarih / saat o yayınlanmıştır.

Her forumda iplik listesi için threadID (Birincil Anahtar), ThreadName, kendisine, NumPosts, NumViews, LastPostDateTime ve CreateDateTime aittir forumid var. Herhangi bir yardım?

7 Cevap

Kullanıcı bu konuyu okuduğunuzda başka bir tablo kullanıcı kimliği, thread, LastReadDateTime saklanması olabilir.

if (LastPostDateTime > LastReadDateTime) you got an unread post.

Her bir yazma olacak okumak üzerinde ne yazık ki, büyük bir yükü var.

Geleneksel çözüm çizgisinde bir join table şeydir:

CREATE TABLE topicviews (
    userid INTEGER NOT NULL,
    topicid INTEGER NOT NULL,
    lastread TIMESTAMP NOT NULL,
    PRIMARY KEY (userid, topicid),
    FOREIGN KEY (userid) REFERENCES users(id),
    FOREIGN KEY (topicid) REFERENCES topics(id)
);

lastread her zaman güncel olan bir konu okunur. Topics.lastupdated isimli> topicviews.lastread, yeni mesaj varsa, konuların listesini görüntüleyen zaman.

The traditional solution is rubbish and will kill your database! Don't do it!

İlk sorun, her konu görünümünde bir yazma yakında özellikle, sadece tablo düzey kilitleri var MyISAM tabloları üzerinde, yoğun bir forumda onun diz veritabanı sunucusu getirecek olmasıdır. (Tam metin arama dışında her şey için InnoDB kullanmak, MyISAM tabloları kullanmayın).

Sadece konunun okunan yeni mesajlar aslında var lastread zaman içinde yazmak için rahatsız bu durumdan biraz artırabilir. Topic.lastupdated if < Eğer değerini güncelleyerek elde bir şey yok topicviews.lastread. Buna rağmen, yoğun olarak kullanılan forumunda bu bir yük olabilir.

İkinci sorun birleştirici bir patlama meydana geldi. Sadece bin kullanıcı ve bin konuları ve potansiyel bir milyon baþlýkSonraki satır saklamak zorunda: Konuya kullanıcı başına bir satır yakında ekler!

Her kullanıcı için hatırladı konuların sayısını sınırlayarak bu duruma biraz artırabilir. Örneğin belli bir yaş daha yaşlı aldığında Gösterim tabloda herhangi bir konuyu kaldırmak ve sadece tüm eski konuları 'oku' olduğunu varsayıyorum olabilir. Bu, genel olarak arka planda yapılması gereken bir temizleme işi gerekmektedir.

Diğer, daha az yoğun yaklaşımlar şunlardır:

  • Sadece forumda başına bir lastread saati depolamak
  • sadece kullanıcının daha önceki ziyareti (oturum) bu yana güncellenen 'yeni' sadece şeyler olarak göstermek hangi, tüm site genelinde kullanıcı başına bir LastVisit saati depolamak
  • Tüm herhangi lastread bilgiyi depolamak, ancak, konunun URL kendisi son güncelleme süresi dahil değildir. Kullanıcının tarayıcısı son zamanlarda konuyu görmüş ise, URL hatırlamak ve ziyaret olarak işaretlemek. Daha sonra 'yeni mesajları içeren konular' olarak ziyaret bağlantıları stil için CSS kullanabilirsiniz.

Burada genel fikirler doğru, ama onlar ölçeklenebilirlik sorununa bazı bariz çözümler gözardı ettik.

@bobince: The second problem is a combinatorial explosion. One row per user per topic soon adds up: just a thousand users and a thousand topics and you have potentially a million topicview rows to store!

Birinin Hiç bu konu izlendi olmadığı takdirde "topicviews" tablosunda bir kayıt saklamak gerekmez. Sen basitçe boş döndürdü okunmamış mesajları sahip olarak VEYA last_read zaman bir konuyu görüntülemek istiyorum < LAST_POST zaman. Bu büyüklükte belki bir emriyle bu "milyon" satırları azaltacaktır.

@ Gortok: Orada bunu yapmak için birçok yolu vardır, fakat kullanıcı siteyi ziyaret her katlanarak büyüdükçe.

Bu durumda, n-mesaj ya da n-hafta sonra bir forum arşiv ve kilitlemek zaman, "topicviews" tablosunu temizlemek.

Benim ilk önerim açıktır ve hiçbir zararı vardır. Benim ikinci arşivlenmiş konularda kullanılabilirlik azaltır, ancak hızlı bir forum için ödemek için küçük bir fiyat. Yavaş forumları okumak ve yazmak için sadece acı vardır.

Ama dürüst olmak gerekirse? Muhtemelen ölçeklenebilirlik konusunda endişelenmenize gerek olmayacaktır. Hatta bir milyon satır gerçekten o çok değildir.

Bunu yapmanın kolay bir yolu yok. Orada bunu yapmak için birçok yolu vardır, fakat kullanıcı siteyi ziyaret her katlanarak büyüdükçe. Yapmanız ve hala performansı tutmak iyi bir zaman damgası ve 'okunmadı' olarak son ziyaretinizden bu yana güncellenen herhangi forumları işaretlemek için.

Yani belki son kez Kullanıcılar tablodaki başka bir girdiyi OK ... forum sistemi içine girdi

Ve neden birileri -1 olarak işaretlemek mi? Diğer forum yazılımı görülen geçerli bir soru, ve ben elimden geleni tarif ...: (

Sadece kullanıcının tarayıcısı işlevini kullanmak ve bu gibi konuya link son POSTID append olabilir: "id = 12 & lastPost = 122 thread.php?"

Yararlanarak bir: CSS ziyaret, kullanıcı zaten o okumadım olanlar farklı okunan mesajları görüntüleyebilirsiniz.

Bobince iyi öneriler bir sürü vardır. Başka birkaç potansiyel optimizasyonları:

Yeni yazın "Bu yeni mi?" memcached ve MySQL "ARŞİV" masaya bilgiler. Bir toplu iş "gerçek" tablo güncelleyebilirsiniz.

Her kullanıcı için, (tıklandığında "Tüm okumak işaretleycek" için ne zaman) bayrağı bir "$ tarih kadar okuduğunuz her şey" tutun.

Yeni bir şey yayınlanmıştır olduğunda, açık tüm bayrakları "okumak oldu" - down "bayraklar" sayısını tutar ve tablo sadece (topic_id, User_id) olabilir - hiçbir zaman damgaları.