2016-03-21 5 views
1

Ich verwende zwei separate Tabellen in Cassandra, um MAUs und DAUs zu verfolgen. Das Design jeder Tabelle ist gleich:Schema zum Schreiben und Abfragen monatlicher aktiver Benutzer (MAU) und täglich aktiver Benutzer (DAU)?

create table log.MAU(d timestamp, userId varchar, primary key (d, userId)); 

Ich füge in die Tabelle jedes Mal ein, wenn sich ein Benutzer anmeldet oder ihre Sitzung fortsetzt. Für den Zeitstempel verwende ich die entsprechende UTC "Null-Stunde" (z. B. UTC Mitternacht des aktuellen Tages für DAU und UTC Mitternacht für den ersten Tag des aktuellen Monats für MAU).

Die Vorteile meines aktuellen Designs sind Einfachheit (z. B. select count(*) from DAU where d = ?) und Größe (wenn ein Benutzer aktiv ist, wird nur ein Datensatz für jeden Tag/Monat aufbewahrt). Aber die Nachteile sind, dass ich keine rollierenden Perioden machen kann (zB aktive Benutzer in den letzten 24 Stunden), und ich kann auch nicht die Aktivität zu jeder Stunde eines jeden Tages oder jeden Tages verfolgen (obwohl ich andere Cassandra-Logs, die ich möglicherweise zusammenführen könnte, wenn ich die notwendigen Sekundärindizes hinzufüge).

Irgendwelche Gedanken darüber, ob ich DAUs und MAUs besser verfolgen könnte, angesichts der spezifischen Nachteile, die ich erwähnt habe oder von denen ich nicht in Betracht gezogen habe? Vielleicht wäre eine andere DB wie Postgres besser geeignet? Vielen Dank!

Antwort

2

Ich denke, Sie können dies lösen, indem Sie auf eine andere weniger präzise Datumsspalte tippen.

Für Nutzer pro Monat, so etwas wie dies funktionieren würde:

CREATE TABLE mau(
    month bigint, 
    d timestamp, 
    userid text, 
    PRIMARY KEY (month,d,userId)); 

Dann könnten Sie für einen bestimmten Monat abfragen:

SELECT d, userid FROM may WHERE month=201603; 

Und man konnte auch eine Reihe Abfrage im Bereich:

SELECT d, userid FROM mau WHERE month=201603 
    AND d>'2016-03-21 19:40:00+0000' AND d<'2016-03-21 19:50:00+0000'; 

d      | userid 
--------------------------+-------- 
2016-03-21 19:40:13+0000 | tron 
2016-03-21 19:40:20+0000 | yori 
2016-03-21 19:40:28+0000 | quorra 
2016-03-21 19:40:36+0000 | paige 

(4 rows) 

Ob oder nicht month wird für Sie arbeiten, hängt davon ab, wie viele Zeilen Sie erwarten Treffer pro Monat, und wie nahe das Sie an Cassandras Grenze für 2 Milliarden Zellen pro Partition bringen. Bearing, dass es wahrscheinlich eine gute Idee, auch Partition von day, wie dies in den Sinn:

CREATE TABLE mau(
    month bigint, 
    day bigint, 
    d timestamp, 
    userid text, 
    PRIMARY KEY ((month,day),d,userId)); 

Natürlich, dann würden Sie nicht in der Lage sein, einen ganzen Monat zur Abfrage auf einmal. Aber machen Sie sich mit diesem Ansatz herum und finden Sie heraus, ob Sie eine PRIMARY KEY-Strategie finden, die für Ihre Anwendung funktioniert.

EDIT 20160323

So, um die "einzigartige" Anmeldungen zu zählen, würde ich brauche eine "select count (*) verschiedene userId", etc. zu jagen tun. Ich bin mit Cassandra nicht sonderlich vertraut, aber ich weiß, dass es auf dem Partitionsschlüssel funktioniert. Wenn der Partitionsschlüssel in diesem Schema eine Kombination aus drei Spalten (month, d, userId) ist, wird die Zählung für die userId allein erlaubt sein?

Nein, count funktioniert nicht auf userid von iteslf. Zuallererst können Sie PRIMARY KEY-Komponenten nicht überspringen. Zweitens müssen Sie bei Cassandra einen abfragebasierten Modellierungsansatz verwenden. Wenn Sie unterschiedliche Benutzer-IDs abfragen müssen, die sich angemeldet haben, müssen Sie eine Tabelle neu erstellen, um dies zu unterstützen.

CREATE TABLE logins_by_user (
    userid text, 
    d timestamp, 
    PRIMARY KEY(userid,d)) 
WITH CLUSTERING ORDER BY (d DESC); 

Lassen Sie uns sagen, dass ich die gleichen Daten wie oben haben, mit der Ausnahme, dass Benutzer „tron“ meldet sich ein zweites Mal: ​​

SELECT * FROM logins_by_user ; 

userid | d 
--------+-------------------------- 
quorra | 2016-03-21 19:40:28+0000 
    paige | 2016-03-21 19:40:36+0000 
    tron | 2016-03-22 19:37:53+0000 
    tron | 2016-03-21 19:40:13+0000 
    yori | 2016-03-21 19:40:20+0000 

(5 rows) 

Abfragen für einzigartige userids ergeben würde:

SELECT DISTINCT userid FROM logins_by_user ; 

userid 
-------- 
quorra 
    paige 
    tron 
    yori 

(4 rows) 

Nicht sicher, ob das genau das ist, wonach Sie suchen, aber ich hoffe, dass die Idee Sie in die richtige Richtung führt.

+0

Also, um die "einzigartigen" Logins zu zählen, müsste ich eine "Anzahl (*) eindeutige userId" oder so etwas tun. Ich bin mit Cassandra nicht sonderlich vertraut, aber ich weiß, dass es auf dem Partitionsschlüssel funktioniert. Wenn der Partitionsschlüssel in diesem Schema eine Kombination aus drei Spalten (month, d, userId) ist, wird die Zählung für die userId allein erlaubt sein? Vielen Dank! – Adam

+0

@Adam Edit gemacht. – Aaron

Verwandte Themen