[PHP/MySQL] Referal System selber coden

Snyke

Well-known member
ID: 348381
L
27 Mai 2009
400
28
Hi all,

ich bin grad dabei mir zu ueberlegen eine eigene Klammlose seite zu bauen und als zentraler Punkt dabei sehe ich das referal system. Ich bin kein grosser fan von den weit verbreiteten CMS systemen (WMS & co.), also werd' ich's selber schreiben.

Meine Frage ist: wie sollte man am besten ein ref system basteln? Die refs bauen ja einen Baum auf, nur was ich nicht weiss wie man es effektiv umsetzt is das nach oben blubbern von punkten. Dass man das nicht in echtzeit machen kann ist schon klar, aber selbst mit cronjob wird's lustig.

MySQL only Loesung waer' mein Traum aber ob das geht weiss ich ned. Hat da jemand erfahrung, oder hat jemand beispiel code?
 
Ok, also um nochmal alles zusammenzufassen was ich grad gelesen hab':
Ein simple extra tabelle sollte alles loesen:
Code:
[U]werber[/U] | [U]geworben[/U] | level
Wobei die ersten beiden der primary key sind.
Dann muss bei der anmeldung fuer jede Ebene einfach einmal der vater/grossvater/grossgrossvater/... ein insert auf die Tabelle machen, jeweils mit dem level.
Dann wuerde ich einmal am Tag die refs abbuchen:
Jeder user in der user tabelle bekommt eine extra spalte (nennen wir sie snapshot) die die Lose beim letzten update speichert.
Danach ein einfaches Update am Tag mit dem ich die buchungen auslese:
Code:
SELECT
  userid,
  SUM(rl.percents * (users.guthaben - users.snapshot)) as ref_guthaben
FROM
  reflevels rl,
  referals r,
  users u
WHERE
  rl.level = referals.level AND
  u.id = rl.werber
GROUP BY
  u.id
Das sollte soweit funktionieren, ausser wenn mir mein Gin&Tonic wieder mal die Hand uebernommen hat.

Danach einfach die ganzen Eintraege durchgehen und die Buchungen eintragen.

Ich hoffe damit hab' den kram Zusammenfassen koennen, und einen einigermassen guten Praezedenzfall gebaut.

Notfalls baut man noch ein wenig redundanz ein, indem jeder user seinen werber kennt. Dann sollte es auch moeglich sein die referral tabelle neu aufzubauen :)
 
Zuletzt bearbeitet:
Ein simple extra tabelle sollte alles loesen:
Code:
[U]werber[/U] | [U]geworben[/U] | level
Wobei die ersten beiden der primary key sind.

Ich würde eher geworben und level als Primary Key nehmen, denn sonst könnten doch einem User mehrere Werber derselben Ebene zugeordnet werden :?:
 
Mehrere Werber werben einen Referal in mehreren Ebenen.

Beispiel:
Download theHacker -> Cybo -> Maastaaa

Würde so aussehen
werber | geworben |level
theHacker|Cybo|1
Cybo|Maastaaa|1
theHacker|Maastaaa|2
Ok, stimmt, zwei Spalten reichen. Werber und Geworbener bilden eindeutig genau auf ein Level ab :think:

@Cybo:
Nur "geworben" allein reicht nicht, wie du am Beispiel schon siehst, da Maastaaa 2 Werber in unterschiedlichen Ebenen hat.

Für ein einstufiges Referal-System reicht wirklich eine Spalte, die dann auch gleich in die Usertabelle dazu notiert werden kann.
 
Ähm,

werber|geworben|xy
tH|Cybo|xy
Cybo|Maastaaa|...

Du wirbst mich, ich werbe Maastaaa. Warum sollte ich extra festhalten, dass Maastaaa ein Ref von dir in tieferer Ebene ist, das ergibt sich doch aus den Abhängigkeiten.
 
dann brauchst du aber auch nicht die angesprochene Tabellenstruktur ;)
Dann fügst du einfach in deiner Nutzertabelle eine Spalte für den werber ein.

Die angesprochene Struktur von Hacker verfolgt eben einen anderen Ansatz.

Wobei ich in keinem der beiden Ansätze einen Vorteil gegenüber dem anderen sehe.
 
[...] das ergibt sich doch aus den Abhängigkeiten.
Richtig. Um alle Refs der Ebene n aufzulisten, brauchst du also n Datenbankabfragen, weil potentiell jeder Ref, könnte Refs haben (also Ebene 2 für dich), die wiederum potentiell Refs haben könnten (Ebene 3 für dich), die wiederum .... Refs haben könnten (Ebene n-1 für dich), die wiederum potentiell Refs haben könnten (Ebene n für dich).
Das "...." sind also jede Menge Datenbankabfragen, exakt sinds n Stück.

Warum O(n), wenn ich auch O(1) haben kann? ;)
 
Also ich denke es sollten eher zwei verschiedene unique beziehungen sein:

Werber und geworben zum primary key (denn darueber wuerde ich spaeter drauf zugreifen und joinen) denn user koennen paarweise immer nur in einer eindeutigen ref-beziehung stehen.

Geworben und level wird auch zu einem unique key, denn jeder geworbene user kann maximal 1 werber pro level haben.

Ueber alle drei einen primary zu legen bringt meines erachtens nichts denn dann koennte ich sowohl als werber in 1, 2 3 level angegeben werden, ohne dass ich constraints verletze (1ter punkt oben) und ausserdem koennte dann jemand unendlich viele werber auf level 1 haben (constraint 2 oben).
 
Also ich hab' ein schoen funktionierendes Beispiel:

3 Tabellen (underlined=primary, italic=unique):
kl_users
Code:
[U]uid[/U] | [I]username[/I] | password | guthaben | snapshot
kl_referrals
Code:
[U]referrer | [I]referred[/U] | level[/I]
kl_reflevels
Code:
[U]level[/U] | percents

Sodele, jetzt bauen wir Daten rein:
user 1 (snyke) wirbt user 2 (ref_level_1) und der wirbt wiederum user 3 (ref_level_2) (alle user bekommen 100 punkte zum anfang, die noch nicht den refs gutgeschrieben wurden):
uid | username |-|guthaben|snapshot
1|snyke|-|100|0
2|ref_level_1|-|100|0
3|ref_level_2|-|100|0
Demnach sieht unsere ref tabelle wie folgt aus
referrer|referred|level
1|2|1
2|3|1
1|3|2
Jetzt nur noch schnell die prozentsaetze angeben:
level|percents
1|5
2|3
Und jetzt endlich der interessante Teil, die query:
Code:
SELECT
  u.uid,
  u.username,
  SUM(ROUND(rl.percents * (u2.guthaben - u2.snapshot)/100)) as ref_guthaben
FROM
  kl_reflevels rl,
  kl_referrals r,
  kl_users u,
  kl_users u2
WHERE
  rl.level = r.level AND
  u.uid = r.referrer AND
  u2.uid = r.referred
GROUP BY
  u.uid
Was man damit rausbekommt sind folgende datensaetze:
uid|username|ref_guthaben
1|snyke|8
2|ref_level_1|5
Was ja klar ist, wenn jeder 100 punkte zum hochblubbern hat dann bekommt user snyke 5+3=8 Punkte (von ref_level_1 und ref_level_2) und user ref_level_1 5 punkte von ref_level_2.

Nachdem man dann die ganzen Buchungen gemacht hat (notfalls koennte man das auch noch in eine einzige query verpacken) dann setzt man einfach bei allen usern snapshot auf guthaben so dass die spaeter nicht nochmal hochblubbern:
Code:
UPDATE kl_users SET snapshot = guthaben

Sodele, ich hoffe dass ich ein anschauliches Beispiel liefern konnte, und dass es anderen weiterhilft :D