son ziyaretçi

5 Cevap php

Say you want to display the latest visitors on a users profile page. How would you structure this? Perhaps a table called uservisitors:

  • kimliği (bir ziyaret alır kullanıcı)
  • visitorid (ziyaretçi)
  • zaman

Ve nasıl mysql ile bu seçmek istiyorsunuz? Herhangi bir kopyası olmadan, Ne demek Kullanıcı 1 ziyaretler kullanıcı 2 profilini eğer, daha sonra yeniden ziyaret 5dk, ben sadece son iki girişleri göstermek istemiyorum

şerefe!

5 Cevap

SELECT  visitorid, MAX(time) AS lastvisit
FROM    uservisitors
WHERE   userid = ?
GROUP BY
        userid, visitorid
ORDER BY
        lastvisit DESC
LIMIT 5

Bu daha hızlı çalışması için (userid, visitorid, time) üzerine bir bileşik dizin oluşturmak.

Bu sorgu:

SELECT  visitorid
FROM    uservisitors ui
WHERE   userid = ?
        NOT EXISTS
        (
        SELECT  NULL
        FROM    uservisitors uo
        WHERE   uo.userid = ui.userid
                AND uo.visitorid = ui.visitorid
                AND uo.time > ui.time
        )
ORDER BY
        time DESC
LIMIT 5

Eğer farklı ziyaretçilerin çok varsa daha verimli olabilir.

Bu durumda, (userid, time, visitorid) üzerinde bir dizin gerekir.

Update:

Benim blog Bu makalede her iki yaklaşımı karşılaştırır:

Böyle bir şey çalışması gerekir:

SELECT visitorid, MAX(time)
FROM uservisitors
WHERE userid = 1
GROUP BY visitorid

Eğer sadece bir ziyaretçi değil TÜM ziyaret son ziyareti umurumda varsayarsak, nasıl kimliği / visitorid için benzersiz bir anahtar çifti kullanılarak ve ardından YİNELENEN KEY .. INSERT INTO kullanma hakkında:

CREATE TABLE uservisitors (... UNIQUE (userid, visitorid) );
INSERT INTO uservisitors (userid, visitorid, time) VALUES (....) ON DUPLICATE KEY UPDATE time=NOW();

Sonra onun bir top 5 ziyaretçi almak için select Basit:

SELECT visitorid FROM uservisitors WHERE user_id=1 ORDER BY time DESC LIMIT 5;

Hiçbir yinelenen kayıtları veya grubu tarafından kullanmak zorunda.

Nasıl daha sonra tablodan şeyler silme planlıyorsunuz? Bunu verimli çalışması için başka bir dizin eklemek gerekebilir.

Sadece son 5 Ziyaret istiyorsanız, ben masa denormalize istiyorum (boşluk, endeks kaydeder ve sadece tek bir birincil anahtar arama kullanır) ve süreç içinde, ben artık eski verileri silme konusunda endişelenmenize gerek olacaktır. O zamanla çok büyümek olmayacak böylece Her kullanıcı sadece tablodaki bir satır işgal edecektir. Yani:

CREATE TABLE user_visitors (user_id int primary key,
visitor_1_id int,
visitor_1_time timestamp,
..
visitor_5_id int,
visitor_5_time timestamp);

Bir ziyaret saklamak için, ziyaretçi olarak visitor_1 ile yeni bir satır eklemek istiyorum ya. Çiftleri üzerinde, önceden depolanan değerleri aşağı kayacaktır:

INSERT INTO user_visitors SET ... 
... ON DUPLICATE KEY UPDATE visitor_5_id = visitor_4_id, visitor_5_time = visitor_4_time ...
... visitor_1_id = ?, visitor_1_time = ?

Eğer çiftleri hakkında endişe varsa visitor_id zaten satırda varsa satır güncellendi almazsınız şekilde UPDATE bölümünde IFS, ekleyerek bunu atlatmanın mümkün olabilir. Kodunda güncellenen satır sayısı için kontrol edebilirsiniz. Sıfır ise, oradan yinelenen ziyaretçi zamanlı güncelleme anlaştım. Bazı çalışma gerektirir ama hızlı ve anlaşılması kolay olacak.

Ben burada bu almak benim, bu birkaç kez uğraştım.

Benim tablo şöyle:

CREATE TABLE visitors (
userid int,
visitorid int,
last_visit datetime,
primary key(userid, visitorid),
index(visitorid)
index(userid, last_visit)
) engine = memory;

Veri ekleme:

INSERT INTO visitors (userid, last_visit) VALUES ( 50, now() ) 
ON DUPLICATE KEY UPDATE last_visit = now();

Seçme:

select * from visitors WHERE userid=10 order by last_visit limit 10; # or whatever you need

Bazen tabloyu temizlemek

DELETE from visitors WHERE last_visit < date_add(now(), INTERVAL -1 WEEK);

Bu birkaç nedenden dolayı gitmek için yoludur.

  1. Bellek tabloda bir kullanıyorsanız, bu nedenle diski dokunmayınız.
  2. Endeksi (visitorid, last_update) üzerinde, yani saf dizin arama bulunuyor. Çok hızlı. Bile olmadan, bu hızlı olmalıdır.
  3. Ayrı bir sorgu aracılığıyla kullanıcıları çekerek bunları önbelleğe izin verecek, ancak son zamanlarda siteyi ziyaret ettiyseniz teoride zaten önbelleğe olmalıdır. Eğer önbellek, bir in (kullanıcı (birincil anahtar)) sorgu kullanmıyorsanız bile çok hızlı olmalıdır.

Bir dakika bir kez yedekleme için bu tabloyu bir cron çalıştırabilirsiniz

SELECT * from visitors INTO OUTFILE "/tmp/visitors.txt"