Toon posts:

[PHP] Loterij script

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo allemaal..

Ik wil een loterij gaan scripten voor m'n online spelletje, dat ze met ingame cash loten kunnen kopen voor een bepaald bedrag per lot. Om niet 1000den querys mijn database in te raggen zoek ik een goed idee om toch onbeperkt loten te laten kopen, maar om dan ook echt bij de trekking van de winnaars wel echt een goede loterij trekking te hebben dus niet bijv dat je evenveel kans hebt als iemand die 100x zoveel loten meer heeft..

gewoon meeste loten = meeste kans :)

iemand tips voor de SQL ?

id
login

(hoeveel keer je erin staat, zoveel loten heb je..) of zou dit beter anders kunnen?
En dan bij het kopen bijv dat er per seconde xx loten in de db worden gezet..

alvast bedankt

Acties:
  • 0 Henk 'm!

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 22-09 09:45

Onbekend

...

Geef elk een lotnummer.
En geeft elke nieuwe koop een lotnummer die 1 hoger ligt dan de vorige.

Bij het loten doe je random(aantal loten) en je krijgt een waarde eruit.
Vervolgens zoek je de gene op die dat lotnummer heeft.


Edit:
Na nog eens de vraag gelezen te hebben begrijp ik hem beter denk ik... :)

Je wilt dus dat iemand kan invullen dat ie 1000 loten willt kopen.
Waarom wil iemand dat? (Is dat zo'n crimes spelletje misschien?)

Ik denk dat je beter iedereen een begrenst aantal loten kan laten kopen.
Straks heb je iemand die altijd 1 miljoen loten koopt en altijd wint t.o. iemand die maar 1 of 2 loten koopt.

[ Voor 47% gewijzigd door Onbekend op 15-03-2008 16:47 ]

Speel ook Balls Connect en Repeat


Acties:
  • 0 Henk 'm!

  • verytallman
  • Registratie: Augustus 2001
  • Laatst online: 18-08 18:12
Verwijderd schreef op zaterdag 15 maart 2008 @ 16:39:
Hallo allemaal..

Ik wil een loterij gaan scripten voor m'n online spelletje, dat ze met ingame cash loten kunnen kopen voor een bepaald bedrag per lot. Om niet 1000den querys mijn database in te raggen zoek ik een goed idee om toch onbeperkt loten te laten kopen, maar om dan ook echt bij de trekking van de winnaars wel echt een goede loterij trekking te hebben dus niet bijv dat je evenveel kans hebt als iemand die 100x zoveel loten meer heeft..

gewoon meeste loten = meeste kans :)

iemand tips voor de SQL ?

id
login

(hoeveel keer je erin staat, zoveel loten heb je..) of zou dit beter anders kunnen?
En dan bij het kopen bijv dat er per seconde xx loten in de db worden gezet..

alvast bedankt
Maak een tabel met loten en zet er een userId bij. Dan gewoon random een rij trekken uit de DB? Mensen met meer loten zijn "vertegenwoordigd" in meer rijen en hebben daardoor ook meer kans.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Klopt idd,

Alleen ik heb 1 probleem.. er worden echt heel veel loten gekocht en ook tegelijk..
Hoe kan ik het maken dat ik niet 2000 database inserts per uur heb hierdoor ?

En nee ik wil geen maximaal aantal loten per lid :$

Acties:
  • 0 Henk 'm!

Verwijderd

Wat gaat er mis bij 2000 insert queries per uur? Ik doe er weleens tientallen per seconde.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik bedoel ermee te zeggen dat we continu 500 querys per seconde hebben, soms zelfs meer.. soms minder.. en als er dan opeens 2000 bij komen in die paar seconde's merk je dat echt enorm..

per uur wat ik net bedoelde was per seconde, sorry

Acties:
  • 0 Henk 'm!

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 22-09 09:45

Onbekend

...

Ik weet misschien wel iets, maar dan kan iemand eenmalig een aantal loten kopen.


Maak 2 kolommen in een tabel. Een min. kolom en een max. kolom.

Als iemand 20 loten koopt, zet je in de min. kolom 1 en in de max. kolom 20.
Als daarna iemand anders 500 loten koopt, zet je in de min. kolom 21 en in de max. kolom 520.

Je laat de nummers eigenlijk gewoon doortellen.

Je hebt dan maar 1 query....

Speel ook Balls Connect en Repeat


Acties:
  • 0 Henk 'm!

Verwijderd

Wat ernorm kan helpen is inderdaad de te inserten gegevens cachen, en dan regelmatig ineens een hele rij records inserten met een enkele query. Dat kan natuurlijk alleen als die gegevens niet real-time nodig zijn.

Acties:
  • 0 Henk 'm!

  • doskabouter
  • Registratie: Oktober 2004
  • Laatst online: 20:36
Om hoeveel gebruikers gaat het (ordegrootte)?

Als je eerst per gebruiker het deel van de uitgegeven loten uitrekend, dus bv:
user1 0.1
user2 0.05
user3 0.2
enz.

dan een lijstje maken met de som van die getallen tot nog toe
dus:
t/m user1 0.1
t/m user2 0.15
t/m user3 0.35
enz.

kies random een getal <1
en kijk bij welke user dit hoort.

zoiets in ieder geval

Het grote voordeel van windows is dat je meer dos-boxen kan openen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
winnaars trekken etc is geen probleem, het gaat er meer om de inserts..

ik dacht zelf aan iets als:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
if($_POST['kooptweakersloten'] && ctype_digit($_POST['aantal']))
{

  /*
   hier wat checks etc
  */
 
  $j = 0;
  $total = 0;
 
  for($total < $_POST['aantal'])
  {

    $j ++;
    $total ++;
    $sql->query("insert into blabla");
    
    if($j == 50)
    {
      sleep(1); 
      $j = 0;
    } 
  
  }

}

Acties:
  • 0 Henk 'm!

  • doskabouter
  • Registratie: Oktober 2004
  • Laatst online: 20:36
ok, maar op mijn manier hoef je toch alleen maar een insert te doen per koopactie, niet per lot.

[ Voor 0% gewijzigd door doskabouter op 15-03-2008 17:02 . Reden: typo ]

Het grote voordeel van windows is dat je meer dos-boxen kan openen


Acties:
  • 0 Henk 'm!

  • Archiebald
  • Registratie: Juni 2006
  • Laatst online: 22-09 08:05
Verwijderd schreef op zaterdag 15 maart 2008 @ 16:46:
Klopt idd,

Alleen ik heb 1 probleem.. er worden echt heel veel loten gekocht en ook tegelijk..
Hoe kan ik het maken dat ik niet 2000 database inserts per uur heb hierdoor ?

En nee ik wil geen maximaal aantal loten per lid :$
Je kunt ook meerdere records in 1 query toevoegen..

INSERT INTO loterij (userId) VALUES (1),(1)

Doe je uiteindelijk maar 1 query, maar voeg je 2 rijen toe ;)
Je moet wel opletten dat je bij de laatste rij geen , erachter zet.

Dus je kunt doen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
for($i = 0; $i <= $invoer;$i++)
{
  $sql .="(".$userId.")";

  if($i != $invoer)
    $sql .= ", ";
}

mysql_query("INSERT INTO loterij (userId) VALUES ".$sql);
?>

[ Voor 16% gewijzigd door Archiebald op 16-03-2008 03:19 . Reden: typo ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dan heb ik dus bijv:

select * from loterij

1 naam, naam, naam, naam
2 naam
3 naam, naam, naam

hoe kan ik dit dan netjes na-checken bij een loterij trekking? want dan word die weer wat lastiger

Acties:
  • 0 Henk 'm!

  • P.O. Box
  • Registratie: Augustus 2005
  • Niet online
Verwijderd schreef op zaterdag 15 maart 2008 @ 17:47:
Dan heb ik dus bijv:

select * from loterij

1 naam, naam, naam, naam
2 naam
3 naam, naam, naam

hoe kan ik dit dan netjes na-checken bij een loterij trekking? want dan word die weer wat lastiger
nee, het statement van archiebald voegt steeds een nieuw rij in...

dus stel dat piet 3 loten koopt, en jan 2...

dan doe je:
SQL:
1
2
3
insert into loterij (naamkoper) values piet, piet, piet;

insert into loterij (naamkoper) values jan, jan


je resultaat wordt dan:
SQL:
1
2
3
4
5
6
7
select * from loterij;

1 piet
2 piet
3 piet
4 jan
5 jan

Acties:
  • 0 Henk 'm!

  • Rmg
  • Registratie: November 2003
  • Laatst online: 20:10

Rmg

Verwijderd schreef op zaterdag 15 maart 2008 @ 17:47:
Dan heb ik dus bijv:

select * from loterij

1 naam, naam, naam, naam
2 naam
3 naam, naam, naam

hoe kan ik dit dan netjes na-checken bij een loterij trekking? want dan word die weer wat lastiger
met
INSERT INTO loterij (userId) VALUES (1),(1)

insert je gewoon 2 rijen

Acties:
  • 0 Henk 'm!

  • BlackWhizz
  • Registratie: September 2004
  • Laatst online: 08-12-2024
Tabelstructuur:

userId | gekocht

Stel, de tabel wordt gevuld:

UserId | Gekocht
1 | 1000
5 | 1500
1 | 1500

Dan selecteer je ze zo:

MySQL:
1
Select UserId, SUM(gekocht) AS loten FROM gekochteloten GROUP BY UserId


Dan krijg je dus zo'n overzcihtje

UserId | Loten
1 | 2500
5 | 1500

Misschien zo'n opzetje?

Acties:
  • 0 Henk 'm!

  • youngster
  • Registratie: Maart 2004
  • Laatst online: 20-05 09:48
Je kunt ook je loten duurder maken zodat mensen minder loten kopen en je dus minder queries hoeft te doen 8) :P

Real programmers don't comment their code... it was hard to write, it should be hard to read!


Acties:
  • 0 Henk 'm!

  • InfoTracer
  • Registratie: November 2001
  • Laatst online: 20:40
heb er ff over na gedacht
misschien kan je gewoon id_user, aantal_loten table maken
als ie dan meer loten koopt gewoon aantal ophogen
als je dan de trekking wil doen zet je het aantal_lote * id_user aan id_users in een array
en dan doen je array_rand en heb je een winnaar

Acties:
  • 0 Henk 'm!

  • TweakBoy
  • Registratie: Augustus 2001
  • Laatst online: 14-09 22:16

TweakBoy

---

Jongens mijn opzet van het verhaal:

Stap 1
Maak voordat je een loterij start al een vast aantal te vergeven lotnummers:

SQL:
1
2
3
4
5
6
7
8
9
CREATE TABLE `loterij` (
  `lot_id` int(10) unsigned NOT NULL auto_increment,
  `lot_no` mediumint(8) unsigned NOT NULL,
  `lot_owner` smallint(5) unsigned NOT NULL default '0',
  `lot_last_ts` timestamp NOT NULL default CURRENT_TIMESTAMP,
  PRIMARY KEY  (`lot_id`),
  KEY `lot_no` (`lot_no`),
  KEY `lot_owner` (`lot_owner`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 


SQL:
1
2
3
4
5
6
7
8
9
10
11
INSERT INTO loterij(lot_no) VALUES(100000);
INSERT INTO loterij(lot_no) VALUES(100001);
INSERT INTO loterij(lot_no) VALUES(100002);
INSERT INTO loterij(lot_no) VALUES(100003);
INSERT INTO loterij(lot_no) VALUES(100004);
INSERT INTO loterij(lot_no) VALUES(100005);
INSERT INTO loterij(lot_no) VALUES(100006);
INSERT INTO loterij(lot_no) VALUES(100007);
INSERT INTO loterij(lot_no) VALUES(100008);
INSERT INTO loterij(lot_no) VALUES(100009);
etc....


bijv van nr. 100.000 tot/met 999.999 ( net als staatsloterij, zonder letters )
Vul je tabel hiervoor eerst met een script die de inserts voor je verzorgd ( op een rustig moment of zo ), ik heb het gedaan met een import van een dump die ik weer gegenereerd heb uit een script.

Stap 2
Voor het kopen van loten door de gebruikers, wil je natuurlijk een lot_owner/user_id aan een lot_no.

Dus: Pietje met user_id=1, koopt 5 loten:

SQL:
1
UPDATE loterij SET lot_owner=1 WHERE lot_owner=0 ORDER BY RAND() LIMIT 5;


MySQL zal vervolgens 5 random rijen updaten en daarbij lot_owner koppelen aan user_id=1;

Voordeel dat ik heb gemerkt is dat de index op het lot_no niet opnieuw gegenereerd hoeft te worden. = weer performance winst, nadeel is weer dat ik een index op user_id heb gezet, dus een nieuwe index wordt gezet op kolom lot_owner.

Stap 3
Mag je lekker zelf uitzoeken ;)

ik kan je wel een voorbeeldje geven:
SQL:
1
SELECT * FROM loterij WHERE lot_owner<>0 ORDER BY RAND() LIMIT 1;


Redenatie: mensen die er meer instaan zijn toch weer meer kans, omdat het de trekking baseert op wie er in de lijst staan, loten die niet zijn vergeven hebben toch lot_owner=0

TODO: je moet wel even een user_table maken waar je de lot_owner / user_id koppelt aan een naam e.d.

---


Acties:
  • 0 Henk 'm!

  • Archiebald
  • Registratie: Juni 2006
  • Laatst online: 22-09 08:05
Raz- schreef op zaterdag 15 maart 2008 @ 17:57:
[...]


met
INSERT INTO loterij (userId) VALUES (1),(1)

insert je gewoon 2 rijen
inderdaad,

Als je met mijn "oplossing" een winnaar wilt trekken kan dat met de volgende query
code:
1
SELECT * FROM loterij ORDER BY RAND() LIMIT 1


dan krijg je een willekeurige (voor zover dat kan) rij eruit, die de winnaar is..

Zo heb ik dat vaak zat zien voorkomen op zo'n online spelletje ;)

overigens snap ik niet hoe mensen aan een andere database structuur komen..
een lot kan niet meerdere eigenaren hebben, maar een eigenaar kan wel meerdere loten hebben
dus een:
eigenaar -> lot
veel -> één relatie krijg je..

het meest logische (wat in mij opkomt) is gewoon per lot een insert, en dan een random eruit halen.
Zit je niet met het feit dat je functies moet schrijven om te kijken wie de meeste loten heeft en daar een waarde aan te hangen om vervolgens het winnende lot eruit te trekken, kortom iedereen heeft een kans met zo min mogelijk scripting.

[ Voor 35% gewijzigd door Archiebald op 16-03-2008 03:30 ]


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Je kan hier heel mooi ranges uitgeven.
Stel je hebt de volgende tabel:
LoterijId(EersteLotnummer, niet nodig)LaatsteLotnummerUserId


Bij het updaten is het een kwestie van IFNULL(MAX(LaatsteLotnummer),0)+aantal toevoegen. Wel even de tabel locken voor write waarschijnlijk. Kan heel mooi met een stored procedure/function die de uitgegeven range teruggeeft. Slechts 1 rij per aankoop dus.
Eventueel kun je EersteLotnummer gebruiken, maar die bevat in principe geen extra informatie. Het EersteLotnummer is namelijk gelijk aan IFNULL(MAX(LaatsteLotnummer),0)+1 over alle LaatsteLotnummers die lager liggen.

Het trekken is natuurlijk vrij eenvoudig:
1. Vraag Max(LaatsteLotnummer) op en doe een trekking tussen 1 en het maximum
2. Doe een select en krijg de juiste range terug.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten

Pagina: 1