2010-07-07 16 views
7

So bin ich stecken. Ich arbeite an einem Kreditsystem mit Ablaufzeiten. Ähnlich wie Kreditkartenmeilen, aber nicht genau. Übrigens tut mir das Buch im Voraus leid, aber ich musste genug Details hinzufügen, um das Gesamtbild zu erhalten.Brauchen Sie Hilfe mit Kredit Ablaufalgorithmus

Was ich brauche, ist ein System, in dem ein Benutzer Kredite für Aktivitäten akkumuliert. Aber sie können diese Kredite auch für Aktivitäten ausgeben. Die Gutschriften sollten nach 30 Tagen ablaufen, wenn sie nicht genutzt werden. Ich scheine, wie ich genau das in einer Charge berechnen kann, die jede Nacht läuft. Irgendwelche Ideen in irgendeiner Sprache würden sehr geschätzt werden, da ich auf einem kleinen Detail festsitze, das ich nicht herumkommen kann. Hier ist ein Beispiel für die Daten:

7/1: 5 - Nutzer sich
7/2: 5 - Benutzer interagiert mit dem System
7/2: -3 - Nutzer kauft Aktivität
7/3: +5 - Benutzer interagiert mit System

Also an diesem Punkt hat der Benutzer 15 Credits erhalten und hat 3 ausgegeben. Lassen Sie ihn mit insgesamt 12 Credits. (Zumindest habe ich grundlegende Mathematik nach unten: P)

Ich sollte hinzufügen, dass wir derzeit mit der Idee spielen, zwei Felder zu haben: zuletzt verarbeitet, als nächstes verarbeitet. So werden diese Werte in dieser Zeit unter der Annahme, es ein neues Anmelde war, sind:

zuletzt verarbeitete Datum: 7/1
Nächster Termin Prozess: 8/1

So, jetzt 8/1 herum kommt. Die Charge startet und prüft alle Credits, die älter als 30 Tage sind. Was an dieser Stelle ist 5.

Hier wird es unscharf.

Dann sollte das System alle Kredite betrachten, die in den letzten 30 Tagen ausgegeben wurden, um zu sehen, ob sie irgendwelche Kredite verwenden. Weil sie nur ablaufen sollten, wenn sie nicht benutzt wurden. Es sind also 3. Also ziehe ich den Benutzer 2 Credits ab, denn das ist die Differenz von Credits, die älter als 30 Tage sind und was ausgegeben wurde. Also beende ich die Charge und stelle die Daten für den nächsten Tag ein. Nimmt man nun an sich nicht mehr ausgegeben haben beginne ich die Berechnung über Kredite verdienten älter als 30, die 5 und Kredite ausgegeben wird, was wiederum 3. Aber ich will natürlich nicht die 3 Credits berücksichtigen, die ich gestern in Betracht gezogen. Was ist ein guter Ansatz, um diese 3 Credits nicht erneut zu berücksichtigen?

Das ist, wo ich feststecke.

Wir denken über das Schreiben eines Lastschrift-Datensatzes für die abgelaufenen Kredite nach, damit wir sie verfolgen können, aber es schwer haben zu sehen, wie ich es in dieser Berechnung verwenden kann.

Wenn Sie so weit lesen, danke. Wenn du dich in der Antwort sogar etwas anstrengst, werde ich dich zumindest für die Mühe stimmen.

EDIT:
Ok @Greg erwähnte etwas, das ich vergessen habe zu adressieren. Die Idee, die berücksichtigten Kredite mit einer Flagge zu versehen. Ein gültiger Punkt, aber nicht einer, der wegen des folgenden Szenarios funktionieren kann:

Angenommen an einem bestimmten Tag gibt ein Benutzer 10 Kredite aus. Aber die abgelaufenen Credits, die die Charge in Betracht zieht, haben sich nur auf 5 angesammelt. Nun, er sollte noch 5 Credits übrig haben, um nicht abgelaufen zu sein, weil er mehr als eine einzige Verfallszeit ausgab. Die Flagge würde also nicht funktionieren, weil wir diese 5 zusätzlichen Credits übersprungen hätten. Hoffnung, die Sinn macht?

Antwort

2

haben Sie auf einer täglichen Basis dieser Batch-Lauf Angenommen, können Sie eine Tabelle, die den Überblick über alle Kredite hält sie verdient, und die Kredite sie verwendet (negative Punkte).

Zu Beginn des nächsten Monats besteht Ihre Aufgabe einfach darin herauszufinden, welche der am ersten Tag verdienten Credits nicht im Laufe des Monats ausgegeben wurden.

Die Anzahl der Credits, die am ersten Tag verdient wurden - die Credits, die sie den gesamten letzten Monat ausgegeben haben. Wenn die Zahl positiv ist, haben sie einige Credits, die abgelaufen sein müssen. So einfach fügen Sie einen Datensatz in der Tabelle mit einem negativen Kredit hinzu.Dies wird die ungenutzten Credits auf Null stellen.

Am nächsten Tag wiederholen Sie den Vorgang, indem Sie sehen, wie viele Credits am zweiten Tag abzüglich der Summe aller im letzten Monat erzielten Credits verdient wurden, unter Berücksichtigung des Datensatzes mit den negativen Credits, die Sie am Vortag erstellt haben .

+0

Ich denke, das ist der Ansatz, mit dem ich versucht habe zu arbeiten und es scheint einfach nicht zu funktionieren. Können Sie ein Beispiel erarbeiten, um dies zu demonstrieren? – spinon

1

Wie wäre es, den Ausgaben eine Flagge hinzuzufügen? Wenn das Kennzeichen nicht gesetzt ist, können Sie diese Ausgaben gegebenenfalls in die Charge aufnehmen. Wenn Sie die Ausgabe verwenden, um einen Ablauf auszugleichen, setzen Sie die Markierung. Beim nächsten Mal ignorieren Sie diese Ausgaben, weil das Flag gesetzt ist.

+0

danke für die Erwähnung, dass ich denke, ich habe ein bisschen Detail aus meinem Beitrag. Lass mich das jetzt hinzufügen. – spinon

3

Ich würde nicht versuchen, die Daten zu verarbeiten, wie Sie es präsentieren. Stattdessen sollten Sie nachverfolgen, wie viele Credits der Nutzer hat und wann diese ablaufen. Auf diese Weise behalten Sie im Auge, welche Credits beim Kauf verwendet wurden, anstatt es später auszuprobieren.

Also, wenn sich der Benutzer auf, sie haben:

5 credits expiring on 8/1 

Nach am nächsten Tag mit dem System interagieren:

5 credits expiring on 8/1 
5 credits expiring on 8/2 

Nach etwas Kauf:

2 credits expiring on 8/1 
5 credits expiring on 8/2 

Und so auf.

+2

Eine großartige UI-Idee, aber das ist ein schlechter Weg, um die Daten tatsächlich zu speichern; Sie möchten einen Audit-Trail, falls ein Fehler behoben werden sollte –

+1

@Heath: In der Tat ist dies kein Ersatz für ein korrektes Transaktionslog. Wenn Sie jedoch so etwas in erster Linie verwenden und das Transaktionsprotokoll grundsätzlich als Append-Only behandeln, es sei denn, etwas stimmt nicht, ist IMO der beste Weg, um weiter zu gehen. –

+0

@Heide Ich muss zustimmen. Ich möchte nicht die Aufzeichnungen berühren, die angeben, wie viele Credits verdient wurden. Ich habe über diese Idee nachgedacht, aber ich denke, für die Zwecke, die Heath in Bezug auf einen Prüfpfad erwähnt hat, kann ich einfach nicht sehen, wie ich das in einem Speichersystem sauber umsetzen könnte. – spinon

1

Verwenden Sie einen Belastungssatz, um normale Ausgaben aufzuzeichnen. Wenn der monatliche Stapeljob ausgeführt wird, kann er die Gesamtbelastungen berechnen, die weniger oder gleich dem auslaufenden Guthaben sind. Wenn Credits ablaufen, fügen Sie einfach einen entsprechenden Lastschrifteintrag ein (=====================================) Auf diese Weise erreicht jeder "laufende Summen" -Code, der nur Gutschriften und Belastungen prüft, das gleiche Guthaben, das Ihr Chargencode beabsichtigt hat.

+0

Ich stimme zu und ich habe das ein wenig erwähnt. Aber das löst immer noch nicht mein Problem, zumindest kann ich nicht sehen, wie es im Moment aussieht, wie man die 3 Credits, die am nächsten Tag in der Charge ausgegeben wurden, nicht in Betracht zieht. Obwohl ich denke, dass da etwas ist. Auch schreiben wir die Lastschrift in die Tabelle und wir aktualisieren die aggregierte Spalte mit dieser Information auch. – spinon

3

Für jeden Benutzer des Systems eine Reihe halten, speichert die Informationen über die Höhe der Kredite für den Benutzer verfügbar für die nächsten 30 aufeinander folgenden Tagen

Zum Beispiel für einige Benutzer die Daten könnte wie folgt

aussehen
8 | 
7 | | 
6 | | | | 
5 | | | | | | | | | | | 
4 | | | | | | | | | | | | | | | | | 
3 | | | | | | | | | | | | | | | | | | | | | | | | 
2 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
    ------------------------------------------------------------- 
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
^^       ^   
    | \_       | 
    today tomorrow    in 15 days 

Jedes Mal, wenn der Benutzer ein Guthaben erhält, erhöhen Sie die Beträge für alle Tage um die Anzahl der verdienten Gutschriften. Wenn der Benutzer beispielsweise 2 Credits erhält, ändert sich die Tabelle wie folgt. Es ist, als würde man das ganze Diagramm aufrichten.

10 | 
9 | | 
8 | | | | 
7 | | | | | | | | | | | 
6 | | | | | | | | | | | | | | | | | 
5 | | | | | | | | | | | | | | | | | | | | | | | | 
4 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
3 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
2 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
    ------------------------------------------------------------- 
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
^^       ^   
    | \_       | 
    today tomorrow    in 15 days 

Wenn der Benutzer heute x Credits hat und verbringt y Kredite, Sie verringern die Menge an Credits ihn zur Verfügung zu x - y, für jeden Tag, als er einen Betrag von mehr als x hat - y. Seit Tagen hat er nicht mehr als x - y, die Menge bleibt gleich. Es ist, als würde man den oberen Teil des Graphen abschneiden. Zum Beispiel, wenn der Benutzer verbringt 3 Credits der Grafik, die Änderungen zu

7 | | | | | | | | | | | 
6 | | | | | | | | | | | | | | | | | 
5 | | | | | | | | | | | | | | | | | | | | | | | | 
4 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
3 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
2 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
    ------------------------------------------------------------- 
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
^^       ^   
    | \_       | 
    today tomorrow    in 15 days 

Jeden Tag können Sie die Grafik nach links verschieben auslaufende Kredite zu modellieren. Der Benutzer wird folgende Beträge morgen

7 | | | | | | | | | | 
6 | | | | | | | | | | | | | | | | 
5 | | | | | | | | | | | | | | | | | | | | | | | 
4 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
3 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
2 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
1 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
    ------------------------------------------------------------- 
    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 
^^       ^   
    | \_       | 
    today tomorrow    in 15 days 
+0

Ich würde dir +1 geben, nur für den Aufwand, den es zu haben scheint. Lass mich ein paar Minuten darüber nachdenken, was du gesagt hast. Aber schnell, wenn Sie es nur gelesen haben, haben Sie erwähnt, dass Sie einen Tisch für jeden Benutzer haben. War das ein Tippfehler oder meinten Sie das? Weil wir fast 100k Benutzer haben und eine Tabelle für jeden etwas außer Kontrolle wäre. Also wollen Sie das Stück sofort verstehen. – spinon

+0

@spinon Ok, danke für die Bemerkung. Tisch ist ein schlechtes Wort. Ein Artefakt meines schlechten Englisch. Ich meine nicht eine Datenbanktabelle, sondern nur eine Struktur, die Beträge enthält und es ermöglicht, sie mit Tagen zu verknüpfen. Es könnte ein einfaches Array außerhalb der Datenbank sein. Ich werde versuchen, es in einem Schnitt umzuformulieren. Im Falle einer Datenbank verwenden Sie einfach 30 Spalten für 30 Tage und speichern Sie die Daten für einen Benutzer in einer Zeile. –

+0

Ok ich verstehe das. Lass mich meine Tests dagegen fortsetzen. – spinon

0

Ein Ansatz für dieses Problem ist, nur die Transaktionen zu speichern, nicht das Guthaben. Dann berechnen Sie bei Bedarf immer das Gleichgewicht in Echtzeit. Hier sind die Daten:

Date : Amount : Expiries 
7/1 : +5 : 7/31 
7/2 : +5 : 8/1 
7/2 : -3 : never 
7/3 : +5 : 8/2 

Der Saldo zu jeder Zeit ist einfach die Summe aller Transaktionen, die noch nicht abgelaufen sind. Sie müssen keine Batch-Prozesse ausführen.

0

In Bezug auf Julians Antwort (die ich noch nicht kommentieren kann), habe ich mit genau dem gleichen Problem zu tun, und Julians Ansatz wird nicht funktionieren, weil das dazu führen würde, dass der Account negativ werden könnte.

Wenn der Benutzer den Service für einen Monat nicht genutzt hat, wäre der Kontostand am 8/4 -3 und eine Aktivität im Wert von 5 würde den Saldo auf 2 bringen, nicht auf 5, wie es sollte.